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"