Class: RigidWorkflow::Step
- Inherits:
-
ActiveRecord::Base
- Object
- ActiveRecord::Base
- RigidWorkflow::Step
- Defined in:
- app/models/rigid_workflow/step.rb
Overview
Represents a single step within a workflow execution. Tracks activity class, status, input/output, and retry attempts.
Class Method Summary collapse
-
.execute_activity(step_id) ⇒ Object, false
Executes an activity for a given step.
- .runnable?(workflow_run) ⇒ Boolean
Instance Method Summary collapse
- #attempt_count ⇒ Object
- #complete!(output = {}) ⇒ Object
- #completed? ⇒ Boolean
- #current_attempt ⇒ Object
- #error_details ⇒ Object
- #fail!(error_details = {}) ⇒ Object
- #failed_at ⇒ Object
- #finished_at ⇒ Object
- #output ⇒ Object
- #start! ⇒ Object
- #started_at ⇒ Object
Class Method Details
.execute_activity(step_id) ⇒ Object, false
Executes an activity for a given step.
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'app/models/rigid_workflow/step.rb', line 129 def execute_activity(step_id) step = RigidWorkflow::Step.includes(:workflow_run, :attempts).find_by_id( step_id ) return false if step.nil? || step.completed? workflow_run = step.workflow_run return false unless workflow_run return false unless runnable?(workflow_run) step.start! # brakeman:ignore UnsafeReflection # This is intentional - activity_class is a validated string from the workflow definition activity_class = step.activity_class.constantize unless activity_class && activity_class < RigidWorkflow::Activity raise ArgumentError, "#{step.activity_class} is not a valid Activity" end activity = activity_class.new(step) input = step.input.deep_symbolize_keys result = activity.perform(**input) step.complete!(result) RigidWorkflow::Orchestrator.schedule(workflow_run) result rescue StandardError => error step.fail!( error: error.class.to_s, message: error., backtrace: error.backtrace&.first(5) ) # Schedule workflow advancement to handle retries or mark workflow as failed (Bug 3 fix) if workflow_run && !workflow_run.finished? RigidWorkflow::Orchestrator.schedule(workflow_run) end raise error end |
.runnable?(workflow_run) ⇒ Boolean
171 172 173 |
# File 'app/models/rigid_workflow/step.rb', line 171 def runnable?(workflow_run) workflow_run.present? && !workflow_run.finished? end |
Instance Method Details
#attempt_count ⇒ Object
40 41 42 |
# File 'app/models/rigid_workflow/step.rb', line 40 def attempt_count attempts.count end |
#complete!(output = {}) ⇒ Object
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'app/models/rigid_workflow/step.rb', line 86 def complete!(output = {}) RigidWorkflow.instrument( "step.complete", run_id: rigid_workflow_run_id, step_id: id ) do safe_output = if output.nil? {} elsif !output.is_a?(Hash) { result: output } else output end current_attempt&.update!( status: :completed, finished_at: Time.current, output: safe_output ) update!(status: :completed) end end |
#completed? ⇒ Boolean
36 37 38 |
# File 'app/models/rigid_workflow/step.rb', line 36 def completed? status == "completed" end |
#current_attempt ⇒ Object
44 45 46 |
# File 'app/models/rigid_workflow/step.rb', line 44 def current_attempt attempts.last end |
#error_details ⇒ Object
52 53 54 |
# File 'app/models/rigid_workflow/step.rb', line 52 def error_details current_attempt&.error_details end |
#fail!(error_details = {}) ⇒ Object
109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'app/models/rigid_workflow/step.rb', line 109 def fail!(error_details = {}) RigidWorkflow.instrument( "step.fail", run_id: rigid_workflow_run_id, step_id: id ) do current_attempt&.update!( status: :failed, failed_at: Time.current, error_details: error_details ) update!(status: :failed) end end |
#failed_at ⇒ Object
64 65 66 |
# File 'app/models/rigid_workflow/step.rb', line 64 def failed_at current_attempt&.failed_at end |
#finished_at ⇒ Object
60 61 62 |
# File 'app/models/rigid_workflow/step.rb', line 60 def finished_at current_attempt&.finished_at end |
#output ⇒ Object
48 49 50 |
# File 'app/models/rigid_workflow/step.rb', line 48 def output current_attempt&.output || {} end |
#start! ⇒ Object
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'app/models/rigid_workflow/step.rb', line 68 def start! pending_attempt = attempts.where(status: :pending).last if pending_attempt pending_attempt.update!( status: :running, started_at: Time.current ) else attempts.create!( attempt_number: attempts.count + 1, status: :running, input: input, started_at: Time.current ) end update!(status: :running) end |
#started_at ⇒ Object
56 57 58 |
# File 'app/models/rigid_workflow/step.rb', line 56 def started_at current_attempt&.started_at end |