Class: Nexo::WorkflowRun

Inherits:
ActiveRecord::Base
  • Object
show all
Defined in:
lib/nexo/workflow_run.rb

Overview

The nexo_workflow_runs record: a run's id, workflow class, status, payload, result, error, and ordered event log. Mirrors the shape of the in-memory store's Run struct so a single Workflow drives either backend.

Constant Summary collapse

STATUSES =

The status vocabulary a run moves through. The sync path is pending → running → done/failed; run_later adds "queued" (enqueued, not yet picked up); reconcile_interrupted! rewrites orphaned "running" runs to "interrupted"; suspend! adds "suspended" (paused, awaiting resume — Spec 13, NOT a failure). There is no distinct "resumed" status: resume re-enters execute, transitioning running → done (or suspended again). Documentation only — status is a plain string column.

%w[pending queued running done failed interrupted suspended].freeze

Instance Method Summary collapse

Instance Method Details

#artifact(name) ⇒ Object

Finds a recorded artifact (Spec 7) by name, tolerating string- or symbol-keyed hashes so it works before and after a json round-trip. Returns the artifact hash or nil.



71
72
73
# File 'lib/nexo/workflow_run.rb', line 71

def artifact(name)
  (artifacts || []).find { |a| (a["name"] || a[:name]) == name.to_s }
end

#artifact_content(name) ⇒ Object

Returns just the stored body of a named artifact (Spec 11 R4), or nil when absent. Nexo exposes content only — serving files stays the host controller's job (no Nexo routes/controllers for artifacts).



78
79
80
# File 'lib/nexo/workflow_run.rb', line 78

def artifact_content(name)
  artifact(name)&.then { |a| a["content"] || a[:content] }
end

#checkpoint_result(name) ⇒ Object

The stored result of a completed checkpoint(name) (Spec 13), or nil when that checkpoint has not run yet. Tolerates string/symbol name like the artifact reader; the reserved "suspend" key is not a checkpoint.



64
65
66
# File 'lib/nexo/workflow_run.rb', line 64

def checkpoint_result(name)
  state&.[](name.to_s)
end

#done?Boolean

Status predicates for a host UI (Spec 11 R3).

Returns:

  • (Boolean)


40
# File 'lib/nexo/workflow_run.rb', line 40

def done? = status == "done"

#failed?Boolean

True when the run ended in failure.

Returns:

  • (Boolean)


43
# File 'lib/nexo/workflow_run.rb', line 43

def failed? = status == "failed"

#push_artifact(a) ⇒ Object

Appends an artifact to the ordered index (Spec 7). Reassigns the array (rather than mutating in place) so ActiveRecord tracks the json column as dirty — mirrors #push_event exactly.



100
101
102
# File 'lib/nexo/workflow_run.rb', line 100

def push_artifact(a)
  self.artifacts = (artifacts || []) + [a]
end

#push_event(ev) ⇒ Object

Appends an event to the ordered log. Reassigns the array (rather than mutating in place) so ActiveRecord tracks the json column as dirty.



87
88
89
# File 'lib/nexo/workflow_run.rb', line 87

def push_event(ev)
  self.events = (events || []) + [ev]
end

#queued?Boolean

True while the run is enqueued but not yet started.

Returns:

  • (Boolean)


49
# File 'lib/nexo/workflow_run.rb', line 49

def queued? = status == "queued"

#running?Boolean

True while the run is executing.

Returns:

  • (Boolean)


46
# File 'lib/nexo/workflow_run.rb', line 46

def running? = status == "running"

#save_artifacts!Object

Persists the artifact index without bumping updated_at, mirroring #save_events!.



106
107
108
# File 'lib/nexo/workflow_run.rb', line 106

def save_artifacts!
  save!(touch: false)
end

#save_events!Object

Persists the event log without bumping updated_at — events accrue incrementally during a run and shouldn't each count as a full touch.



93
94
95
# File 'lib/nexo/workflow_run.rb', line 93

def save_events!
  save!(touch: false)
end

#save_state!Object

Persists the run's checkpoint/suspend state (Spec 13) without bumping updated_at — checkpoints accrue during a run just like events/artifacts, so each shouldn't count as a full touch. The state json object is read/written by Workflow#checkpoint with string keys, so it round-trips identically to the Memory store.



115
116
117
# File 'lib/nexo/workflow_run.rb', line 115

def save_state!
  save!(touch: false)
end

#suspend_reasonObject

The reason recorded when the run was suspended (Spec 13), or nil when the run was never suspended. Reads the reserved "suspend" state entry, tolerating a nil state (a run predating the state column).



57
58
59
# File 'lib/nexo/workflow_run.rb', line 57

def suspend_reason
  state&.dig("__suspend__", "reason")
end

#suspended?Boolean

True while the run is paused awaiting external input (Spec 13).

Returns:

  • (Boolean)


52
# File 'lib/nexo/workflow_run.rb', line 52

def suspended? = status == "suspended"