Class: Novel::Saga

Inherits:
Object
  • Object
show all
Defined in:
lib/novel/saga.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name:, workflow:, executor:) ⇒ Saga

Returns a new instance of Saga.



9
10
11
12
13
14
# File 'lib/novel/saga.rb', line 9

def initialize(name:, workflow:, executor:)
  @name = name

  @workflow = workflow
  @executor = executor
end

Instance Attribute Details

#executorObject (readonly)

Returns the value of attribute executor.



7
8
9
# File 'lib/novel/saga.rb', line 7

def executor
  @executor
end

#workflowObject (readonly)

Returns the value of attribute workflow.



7
8
9
# File 'lib/novel/saga.rb', line 7

def workflow
  @workflow
end

Instance Method Details

#call(params: {}, saga_id: SecureRandom.uuid) ⇒ Object



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/novel/saga.rb', line 16

def call(params: {}, saga_id: SecureRandom.uuid)
  start_result = executor.start_transaction(saga_id, params, workflow.activity_steps.first)
  return start_result if start_result.value![:status] == :waiting

  context, saga_state = start_result.value![:context]

  if context.success?
    activity_flow_result = executor.call_activity_flow(context, saga_state, workflow.activity_steps_from(context.last_competed_step))

    activity_flow_result.or do |error_result|
      compensation_result = sync_compensation_result_for(error_result[:context], saga_state, error_result)

      Failure(status: :saga_failed, compensation_result: compensation_result, context: compensation_result.value![:context])
    end
  else
    compensation_steps = workflow.compensation_steps_from(context.last_competed_compensation_step)
    compensation_result = executor.call_compensation_flow(context, saga_state, compensation_steps)

    Failure(status: :saga_failed, compensation_result: compensation_result, context: compensation_result.last.value![:context])
  end
end