class Novel::Executor::CompensationFlow

Attributes

container[R]
repository[R]

Public Class Methods

new(container:, repository:) click to toggle source
# File lib/novel/executor/compensation_flow.rb, line 8
def initialize(container:, repository:)
  @container = container
  @repository = repository
end

Public Instance Methods

call(context, state_machine, steps) click to toggle source
# File lib/novel/executor/compensation_flow.rb, line 13
def call(context, state_machine, steps)
  steps.each_with_index.map do |step, index|
    result = execut_step(context, state_machine, step, steps[index + 1])
    context = result.value![:context]

    if result.value![:status] == :waiting
      return result
    else
      result
    end
  end
end

Private Instance Methods

execut_step(context, state_machine, step, next_step) click to toggle source
# File lib/novel/executor/compensation_flow.rb, line 28
def execut_step(context, state_machine, step, next_step)
  result = container.resolve("#{step[:name]}.compensation").call(context)
  status = transaction_status(next_step, state_machine)

  Success(
    status: status,
    result: result,
    context: repository.persist_context(
      context,
      failed: true,
      saga_status: state_machine.state,
      last_competed_compensation_step: step[:name],
      compensation_step_results: context.to_h[:compensation_step_results].merge(step[:name] => result.value!)
    )
  )
end
transaction_status(next_step, state_machine) click to toggle source
# File lib/novel/executor/compensation_flow.rb, line 45
def transaction_status(next_step, state_machine)
  if next_step&.fetch(:async) 
    state_machine.wait

    :waiting
  else
    :processing
  end
end