Class: AceMQ::AMQP::Patterns::SagaResult
- Inherits:
-
Object
- Object
- AceMQ::AMQP::Patterns::SagaResult
- Defined in:
- lib/acemq/amqp/patterns/saga.rb
Overview
What a saga did.
Returned rather than raised, because a failed saga is not an exceptional condition to a caller that has to decide what happens next — and because the interesting part is not the exception but #unresolved, the list of things that could not be undone.
Frozen, like Envelope, for the same reason: it describes something that has already happened, and a report that could be edited after the fact is not a report.
Instance Attribute Summary collapse
-
#completed ⇒ Object
readonly
The steps that ran, in order, before the failure.
-
#failed_at ⇒ Object
readonly
The step whose action raised, or nil when every step ran.
-
#failure ⇒ Object
readonly
What it raised, or nil.
-
#saga ⇒ Object
readonly
What the saga is called.
-
#unresolved ⇒ Object
readonly
The steps whose compensation raised.
Class Method Summary collapse
- .compensated_run(saga, failed_at, failure, completed, unresolved) ⇒ Object private
- .completed_run(saga, completed) ⇒ Object private
Instance Method Summary collapse
-
#compensated? ⇒ Boolean
Whether a step failed and the earlier ones were undone.
-
#complete? ⇒ Boolean
Whether every step ran.
-
#initialize(saga:, completed:, failed_at: nil, failure: nil, unresolved: []) ⇒ SagaResult
constructor
A new instance of SagaResult.
- #to_s ⇒ Object
-
#unresolved? ⇒ Boolean
Whether anything was left in a state nobody intended.
Constructor Details
#initialize(saga:, completed:, failed_at: nil, failure: nil, unresolved: []) ⇒ SagaResult
Returns a new instance of SagaResult.
57 58 59 60 61 62 63 64 |
# File 'lib/acemq/amqp/patterns/saga.rb', line 57 def initialize(saga:, completed:, failed_at: nil, failure: nil, unresolved: []) @saga = saga @failed_at = failed_at @failure = failure @completed = completed.dup.freeze @unresolved = unresolved.dup.freeze freeze end |
Instance Attribute Details
#completed ⇒ Object (readonly)
The steps that ran, in order, before the failure.
41 42 43 |
# File 'lib/acemq/amqp/patterns/saga.rb', line 41 def completed @completed end |
#failed_at ⇒ Object (readonly)
The step whose action raised, or nil when every step ran.
35 36 37 |
# File 'lib/acemq/amqp/patterns/saga.rb', line 35 def failed_at @failed_at end |
#failure ⇒ Object (readonly)
What it raised, or nil.
38 39 40 |
# File 'lib/acemq/amqp/patterns/saga.rb', line 38 def failure @failure end |
#saga ⇒ Object (readonly)
What the saga is called.
32 33 34 |
# File 'lib/acemq/amqp/patterns/saga.rb', line 32 def saga @saga end |
#unresolved ⇒ Object (readonly)
The steps whose compensation raised.
44 45 46 |
# File 'lib/acemq/amqp/patterns/saga.rb', line 44 def unresolved @unresolved end |
Class Method Details
.compensated_run(saga, failed_at, failure, completed, unresolved) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
52 53 54 55 |
# File 'lib/acemq/amqp/patterns/saga.rb', line 52 def self.compensated_run(saga, failed_at, failure, completed, unresolved) new(saga: saga, failed_at: failed_at, failure: failure, completed: completed, unresolved: unresolved) end |
.completed_run(saga, completed) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
47 48 49 |
# File 'lib/acemq/amqp/patterns/saga.rb', line 47 def self.completed_run(saga, completed) new(saga: saga, completed: completed) end |
Instance Method Details
#compensated? ⇒ Boolean
Whether a step failed and the earlier ones were undone.
70 |
# File 'lib/acemq/amqp/patterns/saga.rb', line 70 def compensated? = !@failed_at.nil? |
#complete? ⇒ Boolean
Whether every step ran.
67 |
# File 'lib/acemq/amqp/patterns/saga.rb', line 67 def complete? = @failed_at.nil? |
#to_s ⇒ Object
82 83 84 85 86 87 88 |
# File 'lib/acemq/amqp/patterns/saga.rb', line 82 def to_s return "SagaResult{#{@saga} completed: #{@completed.join(" -> ")}}" if complete? trailer = @unresolved.empty? ? "" : ", UNRESOLVED #{@unresolved.join(", ")}" "SagaResult{#{@saga} failed at #{@failed_at}, compensated " \ "#{@completed.join(", ")}#{trailer}}" end |
#unresolved? ⇒ Boolean
Whether anything was left in a state nobody intended.
This is the flag to alert on. Everything else a saga reports is
recoverable by construction; these are real-world effects that
happened, were meant to be undone, and were not. Nothing else in the
system knows about them, no retry will resolve them, and a person has
to. Java spells it hasUnresolved(); the has_ is dropped here
because Ruby says the same thing with the question mark.
80 |
# File 'lib/acemq/amqp/patterns/saga.rb', line 80 def unresolved? = !@unresolved.empty? |