lib/trailblazer/circuit.rb in trailblazer-circuit-0.0.1 vs lib/trailblazer/circuit.rb in trailblazer-circuit-0.0.2
- old
+ new
@@ -1,50 +1,45 @@
require "trailblazer/circuit/version"
-# Start, Suspend, Resume, End can return something other than the next symbol?
-# Nested could replace options with local options
-
-
module Trailblazer
- # Circuit executes ties, finds next step and stops when reaching a Stop signal (or derived from).
+ # 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 value.
#
- # circuit.()
- #
- # Cicuit doesn't know anything about contexts, options, etc. tasks: what steps follows? call it!
- class Circuit
+ # result = circuit.(start_at, *args)
+ class Circuit
def initialize(map, stop_events, name)
@name = name
@map = map
@stop_events = stop_events
end
- # the idea is to always have a breakpoint state that has only one outgoing edge. we then start from
- # that vertix. it's up to the caller to test if the "persisted" state == requested state.
- # activity: where to start
Run = ->(activity, direction, *args) { activity.(direction, *args) }
- def call(activity, args, runner: Run, **o) # DISCUSS: should start activity be @activity and we omit it here?
+ # Runs the circuit. Stops when hitting a End event or subclass thereof.
+ # This method throws exceptions when the return value of a task doesn't match
+ # any wiring.
+ # @param activity A task from the circuit where to start
+ # @param args An array of options passed to the first task.
+ def call(activity, args, runner: Run, **o)
# TODO: args
- direction = nil
+ direction = nil
+ flow_options = { runner: runner, debug: @name }.merge(o) # DISCUSS: make this better?
loop do
- # puts "[#{@name}]. #{activity}"
- direction, args = runner.(activity, direction, args, runner: runner, debug: @name, **o)
+ direction, args, flow_options = runner.( activity, direction, args, flow_options )
- # last task in a process is always either its Stop or its Suspend.
- return [ direction, args, **o ] if @stop_events.include?(activity)
+ # Stop execution of the circuit when we hit a stop event (< End). This could be an activity's End of Suspend.
+ return [ direction, args, flow_options ] if @stop_events.include?(activity)
activity = next_for(activity, direction) do |next_activity, in_map|
- # puts "[#{@name}]...`#{activity}`[#{direction}] => #{next_activity}"
-
raise IllegalInputError.new("#{@name} #{activity}") unless in_map
- # last activity didn't emit knowns signal, it's not connected.
raise IllegalOutputSignalError.new("from #{@name};;#{activity}"+ direction.inspect) unless next_activity
end
end
end
+ # Returns the circuit's components.
def to_fields
[ @map, @stop_events, @name]
end
private
@@ -64,59 +59,43 @@
end
class IllegalOutputSignalError < RuntimeError
end
- def Right
- Right
- end
-
- def Left
- Left
- end
-
+ # End event is just another callable task.
+ # Any instance of subclass of End will halt the circuit's execution when hit.
class End
def initialize(name, options={})
@name = name
@options = options
end
- def to_s
- %{#<End: #{@name} #{@options.inspect}>}
- end
-
- def inspect
- to_s
- end
-
def call(direction, *args)
[ self, *args ]
end
end
class Start < End
def call(direction, *args)
- [Right, *args]
+ [ Right, *args ]
end
+ end
- def to_s
- %{#<Start: #{@name} #{@options.inspect}>}
- end
+ # Builder for Circuit::End when defining the Activity's circuit.
+ def self.End(name, options={})
+ End.new(name, options)
end
- # # run a nested process.
+ # Builder for running a nested process from a specific `start_at` position.
def self.Nested(activity, start_with=activity[:Start])
- # TODO: currently, we only support only 1 start event. you can use multiple in BPMN.
- # "The BPMN standard allows for multiple start and end events to be used at the same process level. "
->(start_at, options, *args) {
- # puts "@@@@@ #{options.inspect}"
activity.(start_with, options, *args)
}
end
- class Direction; end
+ class Direction; end
class Right < Direction; end
- class Left < Direction; end
+ class Left < Direction; end
end
end
require "trailblazer/circuit/activity"
require "trailblazer/circuit/task"