Class: Omnibot::Workflow
- Inherits:
-
Object
show all
- Defined in:
- lib/omnibot/workflow.rb,
lib/omnibot/workflow/runner.rb
Defined Under Namespace
Classes: ExecutionContext, Runner
Constant Summary
collapse
- TERMINAL_STEPS =
%i[done expired failed cancelled].freeze
- WHILE_RUNNING_MODES =
%i[ignore interrupt].freeze
- INTERRUPT =
:__omnibot_workflow_interrupt
Class Method Summary
collapse
Class Method Details
.cancel!(run) ⇒ Object
96
97
98
99
100
|
# File 'lib/omnibot/workflow.rb', line 96
def cancel!(run)
control(run, allowed: WorkflowRun::ACTIVE_STATUSES) do
run.update!(status: "cancelled")
end
end
|
.on_complete(&blk) ⇒ Object
29
|
# File 'lib/omnibot/workflow.rb', line 29
def on_complete(&blk) = blk ? @on_complete_hook = blk : nil
|
.on_complete_hook ⇒ Object
30
|
# File 'lib/omnibot/workflow.rb', line 30
def on_complete_hook = @on_complete_hook
|
.resume(run, input: nil) ⇒ Object
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
# File 'lib/omnibot/workflow.rb', line 52
def resume(run, input: nil)
run.reload
run.replies = []
run.with_lock do
case run.status
when "waiting_for_input"
step = run.current_step.to_sym
ctx = ExecutionContext.new(run, self, input)
runner = Runner.new(run)
nxt = runner.send(:next_step_from, step, ctx)
break if nxt.nil?
if TERMINAL_STEPS.include?(nxt)
runner.send(:complete, nxt)
else
runner.enter(nxt, input: input)
end
when "running"
if while_running == :interrupt
raise NotImplementedError, "while_running :interrupt ships in v0.3"
end
when "waiting_for_human"
raise WorkflowError::StaleResume, "use resume_from_human for waiting_for_human runs"
else
raise WorkflowError::StaleResume, "cannot resume a #{run.status} run"
end
end
run
end
|
.resume_from_human(run, input: nil) ⇒ Object
82
83
84
85
86
87
|
# File 'lib/omnibot/workflow.rb', line 82
def resume_from_human(run, input: nil)
control(run, allowed: %w[waiting_for_human]) do
run.update!(status: "running")
Runner.new(run).enter(run.current_step.to_sym, input: input)
end
end
|
.retry!(run) ⇒ Object
89
90
91
92
93
94
|
# File 'lib/omnibot/workflow.rb', line 89
def retry!(run)
control(run, allowed: %w[failed]) do
run.update!(status: "running", error: nil)
Runner.new(run).enter(run.current_step.to_sym)
end
end
|
.start(ref: nil, state: {}) ⇒ Object
40
41
42
43
44
45
46
47
48
49
50
|
# File 'lib/omnibot/workflow.rb', line 40
def start(ref: nil, state: {})
first = steps.keys.first or raise WorkflowError, "#{name} declares no steps"
run = WorkflowRun.create!(
type: name, status: "running", current_step: first.to_s,
state: state.transform_keys(&:to_s), attempts: 0, timer_token: 0,
step_entered_at: Time.current, ref: ref
)
run.replies = []
run.with_lock { Runner.new(run).enter(first) }
run
end
|
.state(*keys) ⇒ Object
7
|
# File 'lib/omnibot/workflow.rb', line 7
def state(*keys) = keys.any? ? state_keys.concat(keys) : state_keys
|
.state_keys ⇒ Object
8
|
# File 'lib/omnibot/workflow.rb', line 8
def state_keys = @state_keys ||= []
|
.step(name, poll: nil, &body) ⇒ Object
10
11
12
|
# File 'lib/omnibot/workflow.rb', line 10
def step(name, poll: nil, &body)
steps[name.to_sym] = { body: body, poll: poll }
end
|
.steps ⇒ Object
14
|
# File 'lib/omnibot/workflow.rb', line 14
def steps = @steps ||= {}
|
.timeout(step, after:, to:) ⇒ Object
23
24
25
|
# File 'lib/omnibot/workflow.rb', line 23
def timeout(step, after:, to:)
timeouts[step.to_sym] = { after: after, to: to.to_sym }
end
|
.timeouts ⇒ Object
27
|
# File 'lib/omnibot/workflow.rb', line 27
def timeouts = @timeouts ||= {}
|
.transition(from:, to:, if: nil) ⇒ Object
16
17
18
19
|
# File 'lib/omnibot/workflow.rb', line 16
def transition(from:, to:, if: nil)
cond = binding.local_variable_get(:if)
transitions << { from: from.to_sym, to: to.to_sym, if: cond }
end
|
.transitions ⇒ Object
21
|
# File 'lib/omnibot/workflow.rb', line 21
def transitions = @transitions ||= []
|
.while_running(mode = nil) ⇒ Object
32
33
34
35
36
37
38
|
# File 'lib/omnibot/workflow.rb', line 32
def while_running(mode = nil)
return @while_running || :ignore if mode.nil?
unless WHILE_RUNNING_MODES.include?(mode)
raise ArgumentError, "while_running must be :ignore or :interrupt"
end
@while_running = mode
end
|