Class: Phronomy::Workflow::PhaseMachineBuilder Private

Inherits:
Object
  • Object
show all
Defined in:
lib/phronomy/workflow/phase_machine_builder.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

Builds the anonymous state-machine Class used by WorkflowRunner.

This class compiles Workflow topology into state_machines declarations. It intentionally does not await Tasks, register completion callbacks, cancel external work, or interpret application event payloads.

Instance Method Summary collapse

Constructor Details

#initialize(entry_point:, declared_states:, wait_state_names:, external_events:, entry_actions:, auto_transitions:, exit_actions:) ⇒ PhaseMachineBuilder

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.

Returns a new instance of PhaseMachineBuilder.



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/phronomy/workflow/phase_machine_builder.rb', line 15

def initialize(
  entry_point:,
  declared_states:,
  wait_state_names:,
  external_events:,
  entry_actions:,
  auto_transitions:,
  exit_actions:
)
  @entry_point = entry_point
  @declared_states = declared_states
  @wait_state_names = wait_state_names
  @external_events = external_events
  @entry_actions = entry_actions
  @auto_transitions = auto_transitions
  @exit_actions = exit_actions
end

Instance Method Details

#buildObject

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.



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/phronomy/workflow/phase_machine_builder.rb', line 33

def build
  entry = @entry_point
  all_states = (@declared_states + @wait_state_names + [:__end__]).uniq
  auto_transitions = @auto_transitions
  external_events = @external_events
  entry_actions = @entry_actions
  exit_actions = @exit_actions
  condition_builder = method(:build_transition_condition)
  entry_callback_builder = method(:build_entry_callback)
  exit_callback_builder = method(:build_exit_callback)
  transition_callback = build_transition_action_callback

  Class.new do
    attr_accessor(
      :context,
      :current_event,
      :selected_transition_action,
      :selected_transition_metadata
    )

    state_machine :phase, initial: entry do
      all_states.each { |state_name| state state_name }

      event :state_completed do
        auto_transitions.each do |transition_definition|
          transition(
            transition_definition[:from] => transition_definition[:to],
            :if => condition_builder.call(transition_definition)
          )
        end
      end

      external_events.each do |event_name, transitions|
        event event_name do
          transitions.each do |transition_definition|
            transition(
              transition_definition[:from] => transition_definition[:to],
              :if => condition_builder.call(transition_definition)
            )
          end
        end
      end

      entry_actions.each do |state_name, callables|
        callables.each do |callable|
          after_transition(
            to: state_name,
            &entry_callback_builder.call(callable, state_name)
          )
        end
      end

      # Both source exit callbacks and the transition action are
      # before_transition callbacks. Register exits first to preserve the
      # required exit -> transition action -> entry ordering.
      exit_actions.each do |state_name, callables|
        callables.each do |callable|
          before_transition(
            from: state_name,
            &exit_callback_builder.call(callable, state_name)
          )
        end
      end

      before_transition(&transition_callback)
    end
  end
rescue => error
  raise ArgumentError, "Failed to build phase machine: #{error.message}"
end