Class: Legion::Gaia::Workflow::Definition

Inherits:
Object
  • Object
show all
Defined in:
lib/legion/gaia/workflow/definition.rb

Overview

DSL class that captures a state machine definition.

Usage (inside a ‘workflow` block):

state :pending, initial: true
state :running
state :done

transition :pending, to: :running
transition :running, to: :done, guard: ->(ctx) { ctx[:result].present? }

checkpoint :running, name: :quality_check, condition: ->(ctx) { ctx[:score] >= 0.8 }

on_enter(:done) { |instance| puts "finished" }
on_exit(:running) { |instance| puts "leaving running" }

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name) ⇒ Definition

Returns a new instance of Definition.



24
25
26
27
28
29
30
31
# File 'lib/legion/gaia/workflow/definition.rb', line 24

def initialize(name)
  @name = name
  @states = {}          # { state_sym => { terminal: bool } }
  @transitions = {}     # { from_sym => [{ to:, guard:, guard_name: }] }
  @checkpoints = {}     # { state_sym => [Checkpoint] }
  @callbacks = {}       # { :enter/:exit => { state_sym => [callable] } }
  @initial_state = nil
end

Instance Attribute Details

#callbacksObject (readonly)

Returns the value of attribute callbacks.



22
23
24
# File 'lib/legion/gaia/workflow/definition.rb', line 22

def callbacks
  @callbacks
end

#checkpointsObject (readonly)

Returns the value of attribute checkpoints.



22
23
24
# File 'lib/legion/gaia/workflow/definition.rb', line 22

def checkpoints
  @checkpoints
end

#initial_stateObject (readonly)

Returns the value of attribute initial_state.



22
23
24
# File 'lib/legion/gaia/workflow/definition.rb', line 22

def initial_state
  @initial_state
end

#nameObject (readonly)

Returns the value of attribute name.



22
23
24
# File 'lib/legion/gaia/workflow/definition.rb', line 22

def name
  @name
end

#statesObject (readonly)

Returns the value of attribute states.



22
23
24
# File 'lib/legion/gaia/workflow/definition.rb', line 22

def states
  @states
end

#transitionsObject (readonly)

Returns the value of attribute transitions.



22
23
24
# File 'lib/legion/gaia/workflow/definition.rb', line 22

def transitions
  @transitions
end

Instance Method Details

#checkpoint(state_name, name:, condition: nil) ⇒ Object

Declare a checkpoint that must pass before leaving a state.

Parameters:

  • state_name (Symbol)
  • name (Symbol)

    identifier for the checkpoint

  • condition (#call, nil) (defaults to: nil)

    lambda ‘(ctx) -> bool`; nil means always pass



61
62
63
64
65
66
67
68
69
# File 'lib/legion/gaia/workflow/definition.rb', line 61

def checkpoint(state_name, name:, condition: nil)
  state_name = state_name.to_sym
  @checkpoints[state_name] ||= []
  @checkpoints[state_name] << Checkpoint.new(
    state: state_name,
    name: name,
    condition: condition
  )
end

#checkpoints_for(state_sym) ⇒ Object

Returns matching checkpoint entries for a state (may be empty).



97
98
99
# File 'lib/legion/gaia/workflow/definition.rb', line 97

def checkpoints_for(state_sym)
  @checkpoints[state_sym.to_sym] || []
end

#enter_callbacks_for(state_sym) ⇒ Object

Returns on_enter callbacks for a state (array, may be empty).



102
103
104
# File 'lib/legion/gaia/workflow/definition.rb', line 102

def enter_callbacks_for(state_sym)
  @callbacks.dig(:enter, state_sym.to_sym) || []
end

#exit_callbacks_for(state_sym) ⇒ Object

Returns on_exit callbacks for a state (array, may be empty).



107
108
109
# File 'lib/legion/gaia/workflow/definition.rb', line 107

def exit_callbacks_for(state_sym)
  @callbacks.dig(:exit, state_sym.to_sym) || []
end

#known_state?(state_sym) ⇒ Boolean

—————————————————————— query helpers

Returns:

  • (Boolean)


87
88
89
# File 'lib/legion/gaia/workflow/definition.rb', line 87

def known_state?(state_sym)
  @states.key?(state_sym.to_sym)
end

#on_enter(state_name) {|instance| ... } ⇒ Object

Register a callback to fire when a state is entered.

Parameters:

  • state_name (Symbol)

Yields:

  • (instance)

    receives the workflow Instance



74
75
76
# File 'lib/legion/gaia/workflow/definition.rb', line 74

def on_enter(state_name, &block)
  register_callback(:enter, state_name.to_sym, block)
end

#on_exit(state_name) {|instance| ... } ⇒ Object

Register a callback to fire when a state is exited.

Parameters:

  • state_name (Symbol)

Yields:

  • (instance)

    receives the workflow Instance



81
82
83
# File 'lib/legion/gaia/workflow/definition.rb', line 81

def on_exit(state_name, &block)
  register_callback(:exit, state_name.to_sym, block)
end

#state(name, initial: false, terminal: false) ⇒ Object

Declare a state.

Parameters:

  • name (Symbol)
  • initial (Boolean) (defaults to: false)

    marks this as the default start state

  • terminal (Boolean) (defaults to: false)

    no transitions out are expected (informational)



39
40
41
42
43
# File 'lib/legion/gaia/workflow/definition.rb', line 39

def state(name, initial: false, terminal: false)
  name = name.to_sym
  @states[name] = { terminal: terminal }
  @initial_state = name if initial
end

#transition(from, to:, guard: nil, guard_name: nil) ⇒ Object

Declare a valid transition.

Parameters:

  • from (Symbol)

    source state

  • to (Symbol)

    target state

  • guard (#call, nil) (defaults to: nil)

    optional lambda ‘(ctx) -> bool`

  • guard_name (Symbol, String, nil) (defaults to: nil)

    label for error messages



50
51
52
53
54
55
# File 'lib/legion/gaia/workflow/definition.rb', line 50

def transition(from, to:, guard: nil, guard_name: nil)
  from = from.to_sym
  to   = to.to_sym
  @transitions[from] ||= []
  @transitions[from] << { to: to, guard: guard, guard_name: guard_name }
end

#transitions_from(from_sym) ⇒ Object

Returns all outgoing transition entries from a state.



92
93
94
# File 'lib/legion/gaia/workflow/definition.rb', line 92

def transitions_from(from_sym)
  @transitions[from_sym.to_sym] || []
end