Class: StatesLanguageMachine::Execution
- Inherits:
-
Object
- Object
- StatesLanguageMachine::Execution
- Defined in:
- lib/ruby_slm/execution.rb
Instance Attribute Summary collapse
-
#cause ⇒ String?
The cause of failure if execution failed.
-
#context ⇒ Hash
The execution context.
-
#current_state ⇒ String?
The current state name.
-
#end_time ⇒ Time?
The execution end time.
-
#error ⇒ String?
The error type if execution failed.
-
#history ⇒ Array<Hash>
The execution history.
-
#input ⇒ Hash
readonly
The original input data.
-
#logger ⇒ Logger?
The logger for execution.
-
#name ⇒ String
readonly
The execution name.
-
#output ⇒ Hash
The current output data.
-
#start_time ⇒ Time
readonly
The execution start time.
-
#state_machine ⇒ StateMachine
readonly
The state machine being executed.
-
#status ⇒ Symbol
The execution status (:running, :succeeded, :failed).
Instance Method Summary collapse
-
#add_history_entry(state_name, output) ⇒ Object
Add an entry to the execution history.
-
#execution_time ⇒ Float
The total execution time in seconds.
-
#failed? ⇒ Boolean
Whether the execution failed.
-
#initialize(state_machine, input = {}, name = nil, context = {}) ⇒ Execution
constructor
A new instance of Execution.
-
#run_all ⇒ Execution
Run the entire execution to completion.
-
#run_next ⇒ Execution
Run the next state in the execution.
-
#running? ⇒ Boolean
Whether the execution is still running.
-
#succeeded? ⇒ Boolean
Whether the execution succeeded.
-
#to_h ⇒ Hash
The execution details as a Hash.
-
#to_json ⇒ String
The execution details as JSON.
-
#update_output(new_output) ⇒ Object
Update the execution output.
Constructor Details
#initialize(state_machine, input = {}, name = nil, context = {}) ⇒ Execution
Returns a new instance of Execution.
39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/ruby_slm/execution.rb', line 39 def initialize(state_machine, input = {}, name = nil, context = {}) @state_machine = state_machine @input = input.dup @name = name || "execution-#{Time.now.to_i}-#{SecureRandom.hex(4)}" @current_state = state_machine.start_state @output = input.dup @status = :running @history = [] @logger = context[:logger] @context = context @start_time = Time.now @end_time = nil end |
Instance Attribute Details
#cause ⇒ String?
Returns the cause of failure if execution failed.
16 17 18 |
# File 'lib/ruby_slm/execution.rb', line 16 def cause @cause end |
#context ⇒ Hash
Returns the execution context.
22 23 24 |
# File 'lib/ruby_slm/execution.rb', line 22 def context @context end |
#current_state ⇒ String?
Returns the current state name.
8 9 10 |
# File 'lib/ruby_slm/execution.rb', line 8 def current_state @current_state end |
#end_time ⇒ Time?
Returns the execution end time.
24 25 26 |
# File 'lib/ruby_slm/execution.rb', line 24 def end_time @end_time end |
#error ⇒ String?
Returns the error type if execution failed.
14 15 16 |
# File 'lib/ruby_slm/execution.rb', line 14 def error @error end |
#history ⇒ Array<Hash>
Returns the execution history.
18 19 20 |
# File 'lib/ruby_slm/execution.rb', line 18 def history @history end |
#input ⇒ Hash (readonly)
Returns the original input data.
29 30 31 |
# File 'lib/ruby_slm/execution.rb', line 29 def input @input end |
#logger ⇒ Logger?
Returns the logger for execution.
20 21 22 |
# File 'lib/ruby_slm/execution.rb', line 20 def logger @logger end |
#name ⇒ String (readonly)
Returns the execution name.
31 32 33 |
# File 'lib/ruby_slm/execution.rb', line 31 def name @name end |
#output ⇒ Hash
Returns the current output data.
10 11 12 |
# File 'lib/ruby_slm/execution.rb', line 10 def output @output end |
#start_time ⇒ Time (readonly)
Returns the execution start time.
33 34 35 |
# File 'lib/ruby_slm/execution.rb', line 33 def start_time @start_time end |
#state_machine ⇒ StateMachine (readonly)
Returns the state machine being executed.
27 28 29 |
# File 'lib/ruby_slm/execution.rb', line 27 def state_machine @state_machine end |
#status ⇒ Symbol
Returns the execution status (:running, :succeeded, :failed).
12 13 14 |
# File 'lib/ruby_slm/execution.rb', line 12 def status @status end |
Instance Method Details
#add_history_entry(state_name, output) ⇒ Object
Add an entry to the execution history
124 125 126 127 128 129 130 131 |
# File 'lib/ruby_slm/execution.rb', line 124 def add_history_entry(state_name, output) @history << { state_name: state_name, input: @output, # Current input before execution output: output, timestamp: Time.now } end |
#execution_time ⇒ Float
Returns the total execution time in seconds.
149 150 151 152 |
# File 'lib/ruby_slm/execution.rb', line 149 def execution_time return @end_time - @start_time if @end_time Time.now - @start_time end |
#failed? ⇒ Boolean
Returns whether the execution failed.
139 140 141 |
# File 'lib/ruby_slm/execution.rb', line 139 def failed? @status == :failed end |
#run_all ⇒ Execution
Run the entire execution to completion
55 56 57 58 59 60 |
# File 'lib/ruby_slm/execution.rb', line 55 def run_all while @status == :running && @current_state run_next end self end |
#run_next ⇒ Execution
Run the next state in the execution
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 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/ruby_slm/execution.rb', line 64 def run_next return self unless @status == :running && @current_state state = @state_machine.get_state(@current_state) begin logger&.info("Executing state: #{@current_state}") # Execute the current state @output = state.execute(self, @output) # Check if the state set the execution to failed if @status == :failed logger&.info("Execution failed in state: #{@current_state}") @end_time ||= Time.now return self end # Determine next state - for choice states, we need to pass the output next_state = state.next_state_name(@output) logger&.info("State #{@current_state} completed. Next state: #{next_state}") if state.end_state? @status = :succeeded unless @status == :failed @current_state = nil @end_time = Time.now logger&.info("Execution completed successfully") elsif next_state @current_state = next_state logger&.info("Moving to next state: #{next_state}") else @status = :failed @error = "NoNextState" @cause = "State '#{@current_state}' has no next state and is not an end state" @end_time = Time.now logger&.error("Execution failed: #{@cause}") end rescue => e @status = :failed @error = e.is_a?(ExecutionError) ? e.cause : "ExecutionError" @cause = e. @end_time = Time.now logger&.error("Execution failed in state #{@current_state}: #{e.message}") logger&.error(e.backtrace.join("\n")) if logger end self end |
#running? ⇒ Boolean
Returns whether the execution is still running.
144 145 146 |
# File 'lib/ruby_slm/execution.rb', line 144 def running? @status == :running end |
#succeeded? ⇒ Boolean
Returns whether the execution succeeded.
134 135 136 |
# File 'lib/ruby_slm/execution.rb', line 134 def succeeded? @status == :succeeded end |
#to_h ⇒ Hash
Returns the execution details as a Hash.
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/ruby_slm/execution.rb', line 155 def to_h { name: @name, status: @status, current_state: @current_state, input: @input, output: @output, error: @error, cause: @cause, start_time: @start_time, end_time: @end_time, execution_time: execution_time, history: @history } end |
#to_json ⇒ String
Returns the execution details as JSON.
172 173 174 |
# File 'lib/ruby_slm/execution.rb', line 172 def to_json JSON.pretty_generate(to_h) end |
#update_output(new_output) ⇒ Object
Update the execution output
117 118 119 |
# File 'lib/ruby_slm/execution.rb', line 117 def update_output(new_output) @output = new_output end |