Class: Legion::Gaia::Workflow::Instance

Inherits:
Object
  • Object
show all
Includes:
Logging::Helper
Defined in:
lib/legion/gaia/workflow/instance.rb

Overview

A running instance of a workflow Definition.

Each instance has:

- a reference to its Definition
- a current_state (Symbol)
- a transition history (Array of hashes)
- arbitrary metadata provided at creation
- an id (auto-generated Integer, or user-supplied)

Thread-safety: each instance holds a Mutex so concurrent calls to ‘transition!` serialize correctly.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(definition:, metadata: {}, id: nil) ⇒ Instance

Returns a new instance of Instance.

Parameters:

  • definition (Definition)
  • metadata (Hash) (defaults to: {})

    arbitrary caller-supplied data stored on the instance

  • id (Integer, String, nil) (defaults to: nil)

    optional identifier; auto-incremented if nil



27
28
29
30
31
32
33
34
35
# File 'lib/legion/gaia/workflow/instance.rb', line 27

def initialize(definition:, metadata: {}, id: nil)
  @definition   = definition
  @metadata     = .dup.freeze
  @id           = id || self.class.next_id
  @created_at   = Time.now
  @history      = []
  @mutex        = Mutex.new
  @current_state = definition.initial_state
end

Instance Attribute Details

#created_atObject (readonly)

Returns the value of attribute created_at.



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

def created_at
  @created_at
end

#current_stateObject (readonly)

Returns the value of attribute current_state.



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

def current_state
  @current_state
end

#definitionObject (readonly)

Returns the value of attribute definition.



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

def definition
  @definition
end

#historyObject (readonly)

Returns the value of attribute history.



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

def history
  @history
end

#idObject (readonly)

Returns the value of attribute id.



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

def id
  @id
end

#metadataObject (readonly)

Returns the value of attribute metadata.



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

def 
  @metadata
end

Class Method Details

.next_idObject



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

def next_id
  @id_mutex.synchronize { @id_counter += 1 }
end

.reset_id_counter!Object

Reset counter — for test isolation only



112
113
114
# File 'lib/legion/gaia/workflow/instance.rb', line 112

def reset_id_counter!
  @id_mutex.synchronize { @id_counter = 0 }
end

Instance Method Details

#available_transitionsObject

Returns the list of states reachable from the current state (no guard eval).



84
85
86
# File 'lib/legion/gaia/workflow/instance.rb', line 84

def available_transitions
  definition.transitions_from(current_state).map { |t| t[:to] }
end

#can_transition_to?(to_state) ⇒ Boolean

Returns true if the instance can transition to to_state right now (definition-level check only — does not evaluate guards).

Returns:

  • (Boolean)


78
79
80
81
# File 'lib/legion/gaia/workflow/instance.rb', line 78

def can_transition_to?(to_state)
  to_state = to_state.to_sym
  definition.transitions_from(current_state).any? { |t| t[:to] == to_state }
end

#in_state?(state) ⇒ Boolean

Returns true if the instance is currently in state.

Returns:

  • (Boolean)


72
73
74
# File 'lib/legion/gaia/workflow/instance.rb', line 72

def in_state?(state)
  current_state == state.to_sym
end

#statusObject

Human-readable status summary



89
90
91
92
93
94
95
96
97
98
99
# File 'lib/legion/gaia/workflow/instance.rb', line 89

def status
  {
    id: id,
    workflow: definition.name,
    current_state: current_state,
    history_length: history.size,
    available_transitions: available_transitions,
    created_at: created_at,
    last_transitioned_at: history.last&.dig(:at)
  }
end

#transition(to_state, strict: false, **ctx) ⇒ Boolean

Non-raising variant — returns true on success, false on transition failure. Pass strict: true to propagate unknown-state and invalid-transition errors.

Parameters:

  • to_state (Symbol)
  • ctx (Hash)

Returns:

  • (Boolean)


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

def transition(to_state, strict: false, **ctx)
  transition!(to_state, **ctx)
  true
rescue GuardRejected, CheckpointBlocked, UnknownState, InvalidTransition => e
  raise if strict && (e.is_a?(UnknownState) || e.is_a?(InvalidTransition))

  handle_exception(e, level: :debug, operation: 'gaia.workflow.instance.transition',
                      workflow: definition.name, to_state: to_state)
  false
end

#transition!(to_state, **ctx) ⇒ self

Attempt to transition to to_state, passing ctx to guards, checkpoints, and callbacks.

Raises on any failure (guard rejection, checkpoint block, unknown state, or invalid transition).

Parameters:

  • to_state (Symbol)
  • ctx (Hash)

    passed to guards and checkpoint conditions

Returns:

  • (self)


48
49
50
51
52
# File 'lib/legion/gaia/workflow/instance.rb', line 48

def transition!(to_state, **ctx)
  to_state = to_state.to_sym
  @mutex.synchronize { perform_transition!(to_state, ctx) }
  self
end