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



105
106
107
# File 'lib/legion/gaia/workflow/instance.rb', line 105

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

.reset_id_counter!Object

Reset counter — for test isolation only



110
111
112
# File 'lib/legion/gaia/workflow/instance.rb', line 110

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).



82
83
84
# File 'lib/legion/gaia/workflow/instance.rb', line 82

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)


76
77
78
79
# File 'lib/legion/gaia/workflow/instance.rb', line 76

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)


70
71
72
# File 'lib/legion/gaia/workflow/instance.rb', line 70

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

#statusObject

Human-readable status summary



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

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, **ctx) ⇒ Boolean

Non-raising variant — returns true on success, false on guard/checkpoint failure. Unknown-state and invalid-transition errors still propagate.

Parameters:

  • to_state (Symbol)
  • ctx (Hash)

Returns:

  • (Boolean)


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

def transition(to_state, **ctx)
  transition!(to_state, **ctx)
  true
rescue GuardRejected, CheckpointBlocked => e
  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