Class: AceMQ::AMQP::Patterns::Saga::Builder
- Inherits:
-
Object
- Object
- AceMQ::AMQP::Patterns::Saga::Builder
- Defined in:
- lib/acemq/amqp/patterns/saga.rb
Overview
Collects the steps of a AceMQ::AMQP::Patterns::Saga.
Building mutates, in the one place this library allows it and for the same reason Topology and RoutingSlip do: a saga is assembled and then run, and threading a new copy through four chained calls would buy an immutability nobody is using. The AceMQ::AMQP::Patterns::Saga that comes out of #build is frozen, which is the copy that matters.
Instance Method Summary collapse
- #build ⇒ Saga
-
#compensate_with {|subject| ... } ⇒ Builder
Gives the most recently added step something that undoes it.
-
#initialize(name) ⇒ Builder
constructor
A new instance of Builder.
-
#step(step_name) {|subject| ... } ⇒ Builder
Adds a step, whose block is the work.
Constructor Details
#initialize(name) ⇒ Builder
Returns a new instance of Builder.
223 224 225 226 |
# File 'lib/acemq/amqp/patterns/saga.rb', line 223 def initialize(name) @name = name @steps = [] end |
Instance Method Details
#build ⇒ Saga
276 277 278 279 280 |
# File 'lib/acemq/amqp/patterns/saga.rb', line 276 def build raise ArgumentError, "saga #{@name} has no steps" if @steps.empty? Saga.new(name: @name, steps: @steps.map(&:freeze)) end |
#compensate_with {|subject| ... } ⇒ Builder
Gives the most recently added step something that undoes it.
261 262 263 264 265 266 267 268 269 270 271 272 |
# File 'lib/acemq/amqp/patterns/saga.rb', line 261 def compensate_with(&compensation) unless compensation raise ArgumentError, "compensate_with needs a block that undoes the last step" end if @steps.empty? raise ArgumentError, "there is no step to compensate yet: call step(...) first" end @steps[-1] = Step.new(name: @steps.last.name, action: @steps.last.action, compensation: compensation) self end |
#step(step_name) {|subject| ... } ⇒ Builder
Adds a step, whose block is the work.
A step added this way has no compensation, which is legitimate for a step that changed nothing and a mistake for one that did. There is no warning for the second case, because a library cannot tell them apart — which is the argument for writing the compensation first and the action second.
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 |
# File 'lib/acemq/amqp/patterns/saga.rb', line 239 def step(step_name, &action) raise ArgumentError, "a saga step needs a name" if step_name.to_s.empty? unless action raise ArgumentError, "saga step #{step_name} needs a block to do the work" end step_name = step_name.to_s if @steps.any? { |existing| existing.name == step_name } raise ArgumentError, "saga #{@name} already has a step called #{step_name.inspect}. Names " \ "identify a step in the compensation report, so two of them would make " \ "that report ambiguous." end @steps << Step.new(name: step_name, action: action, compensation: nil) self end |