Class: Statecraft::Pipeline

Inherits:
Object
  • Object
show all
Includes:
EdgeResolution, Versioning
Defined in:
lib/statecraft/pipeline.rb,
lib/statecraft/pipeline/surface.rb,
lib/statecraft/pipeline/versioning.rb,
lib/statecraft/pipeline/edge_resolution.rb

Overview

Executes one transition through the protocol pipeline:

persisted? -> metadata normalize+freeze -> edge resolution ->
dirty check (lock only) -> transaction(requires_new: true) [
lock+reload -> conflict check against the resolved edge -> guards ->
before_transition -> CAS UPDATE -> log INSERT (insert path) ->
after_transition
] -> after_commit registration on the outermost real commit

The CAS statement and the log insert run against base_class; the log row is written via the insert path, past the log model's validations and callbacks — guards and machine callbacks are the single channel of truth.

Defined Under Namespace

Modules: EdgeResolution, Surface, Versioning Classes: Frame, Transition

Constant Summary collapse

STACK_KEY =
:statecraft_transition_stack
MAX_CHAIN_DEPTH =
16

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(record) ⇒ Pipeline

Returns a new instance of Pipeline.



38
39
40
41
42
43
# File 'lib/statecraft/pipeline.rb', line 38

def initialize(record)
  @record = record
  @configuration = record.class.statecraft_mounting
  @graph = @configuration.machine_class.finalize!
  @machine_instance = @configuration.machine_class.new
end

Class Method Details

.transition_stackObject



34
35
36
# File 'lib/statecraft/pipeline.rb', line 34

def self.transition_stack
  ActiveSupport::IsolatedExecutionState[STACK_KEY] ||= []
end

Instance Method Details

#direct(to_state, metadata:, bypass_events:, seen: nil) ⇒ Object



45
46
47
48
49
50
# File 'lib/statecraft/pipeline.rb', line 45

def direct(to_state, metadata:, bypass_events:, seen: nil)
  run(, seen: seen) do |current_state|
    edge = resolve_direct_edge(current_state, to_state.to_sym, bypass_events)
    [edge, nil, bypass_events]
  end
end

#fire(event_name, metadata:, seen: nil) ⇒ Object



52
53
54
55
56
57
# File 'lib/statecraft/pipeline.rb', line 52

def fire(event_name, metadata:, seen: nil)
  run(, seen: seen) do |current_state|
    edge = resolve_event_edge(current_state, event_name.to_sym)
    [edge, event_name.to_sym, false]
  end
end