Class: SagaForge::TimeoutJob

Inherits:
ActiveJob::Base
  • Object
show all
Includes:
Execution::PostCommit
Defined in:
lib/saga_forge/timeout_job.rb

Overview

A stale timer firing late is discarded by the version fence — the same principle that powers stalling. The clock resets on each handled event because every commit bumps version and re-arms (§A.1).

Constant Summary collapse

CONCURRENCY_KEY =

See ExecutionJob::CONCURRENCY_KEY for why this is a constant. * soaks up the job's other two arguments (event_name, armed_version) — only the state matters for the lock key.

->(state_id, *) {
  state = State.find_by(id: state_id)
  state ? "SagaLock:#{state.saga_class}:#{state.correlation_id}" : "SagaLock:none"
}

Instance Method Summary collapse

Methods included from Execution::PostCommit

#arm_timeouts, #guard_forward_only!, #redeliver_parked

Instance Method Details

#perform(state_id, event_name, armed_version) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/saga_forge/timeout_job.rb', line 22

def perform(state_id, event_name, armed_version)
  state = State.find_by(id: state_id)
  return unless state
  return if state.version != armed_version # stale timer — cheap pre-check

  definition = state.saga_definition
  handler = definition.handler_for(event_name)
  return unless handler&.timeout

  # Definition#validate_timeouts! guarantees on_timeout is present
  # (:fail! or a declared state) whenever timeout: is declared — no nil
  # case to handle here.
  case handler.on_timeout.to_sym
  when :fail!
    fail_saga!(state, armed_version)
  else
    branch!(state, definition, handler.on_timeout, armed_version)
  end
end