Class: Omnibot::Workflow::Runner

Inherits:
Object
  • Object
show all
Defined in:
lib/omnibot/workflow/runner.rb

Overview

Runs inside run.with_lock, always.

Constant Summary collapse

MAX_STEPS_PER_ACTIVATION =
100

Instance Method Summary collapse

Constructor Details

#initialize(run) ⇒ Runner

Returns a new instance of Runner.



9
10
11
12
# File 'lib/omnibot/workflow/runner.rb', line 9

def initialize(run)
  @run = run
  @workflow = run.workflow_class
end

Instance Method Details

#enter(step, input: nil) ⇒ Object

Enter step (fresh entry or re-entry), then follow transitions until an interrupt, terminal step, or error stops the loop.



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/omnibot/workflow/runner.rb', line 16

def enter(step, input: nil)
  iterations = 0
  loop do
    iterations += 1
    if iterations > MAX_STEPS_PER_ACTIVATION
      return fail_run("activation exceeded #{MAX_STEPS_PER_ACTIVATION} step entries " \
                       "(transition loop at :#{step}?)")
    end
    record_entry(step)
    ctx = ExecutionContext.new(@run, @workflow, input)
    outcome = execute_body(step, ctx)
    case outcome
    in { interrupt: :wait_input } then return checkpoint("waiting_for_input")
    in { interrupt: :handover }   then return checkpoint("waiting_for_human")
    in { interrupt: :poll_again } then return schedule_poll(step)
    in { error: e }               then return fail_run(e.message)
    in { completed: true }
      input = nil # input is consumed by the first step that runs after resume
      nxt = next_step_from(step, ctx)
      return if nxt.nil? # fail_run already called
      return complete(nxt) if TERMINAL_STEPS.include?(nxt)
      step = nxt
    end
  end
end

#poll_tick(step) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/omnibot/workflow/runner.rb', line 42

def poll_tick(step)
  poll = @workflow.steps.fetch(step)[:poll]
  if @run.attempts >= poll[:max_attempts]
    target = @workflow.timeouts[step]&.fetch(:to) || :expired
    if TERMINAL_STEPS.include?(target)
      complete(target)
    else
      @run.update!(status: "running")
      enter(target)
    end
    return
  end
  enter(step)
end