Class: Trailblazer::Activity::Circuit

Inherits:
Object
  • Object
show all
Defined in:
lib/trailblazer/activity/circuit.rb

Overview

Running a Circuit instance will run all tasks sequentially depending on the former’s result. Each task is called and retrieves the former task’s return values.

Note: Please use #Activity as a public circuit builder.

This is the “pipeline operator”‘s implementation.

Defined Under Namespace

Classes: IllegalSignalError

Constant Summary collapse

Run =
->(task, args, **circuit_options) { task.(args, **circuit_options) }

Instance Method Summary collapse

Constructor Details

#initialize(map, stop_events, start_task:, name: nil) ⇒ Circuit

Returns a new instance of Circuit.



18
19
20
21
22
23
# File 'lib/trailblazer/activity/circuit.rb', line 18

def initialize(map, stop_events, start_task:, name: nil)
  @map         = map
  @stop_events = stop_events
  @name        = name
  @start_task  = start_task
end

Instance Method Details

#call(args, start_task: @start_task, runner: Run, **circuit_options) ⇒ last_signal, ...

Runs the circuit until we hit a stop event.

This method throws exceptions when the returned value of a task doesn’t match any wiring.

NOTE: returned circuit_options are discarded when calling the runner.

Parameters:

  • task

    An event or task of this circuit from where to start

  • options

    anything you want to pass to the first task

  • flow_options

    Library-specific flow control data

Returns:

  • (last_signal, options, flow_options, *args)


40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/trailblazer/activity/circuit.rb', line 40

def call(args, start_task: @start_task, runner: Run, **circuit_options)
  circuit_options = circuit_options.merge( runner: runner ).freeze # TODO: set the :runner option via arguments_for_call to save the merge?
  task            = start_task

  loop do
    last_signal, args, _discarded_circuit_options = runner.(
      task,
      args,
      **circuit_options
    )

    # Stop execution of the circuit when we hit a stop event (< End). This could be an task's End or Suspend.
    return [ last_signal, args ] if @stop_events.include?(task) # DISCUSS: return circuit_options here?

    if (next_task = next_for(task, last_signal))
      task = next_task
    else
      raise IllegalSignalError.new(
        task,
        signal: last_signal,
        outputs: @map[task],
        exec_context: circuit_options[:exec_context], # passed at run-time from DSL
      )
    end
  end
end

#to_hObject

Returns the circuit’s components.



68
69
70
# File 'lib/trailblazer/activity/circuit.rb', line 68

def to_h
  { map: @map, end_events: @stop_events, start_task: @start_task }
end