class Transflow::Transaction
Transaction
encapsulates calling individual steps registered within a transflow constructor.
It's responsible for calling steps in the right order and optionally currying arguments for specific steps.
Furthermore you can subscribe event listeners to individual steps within a transaction.
@api public
Attributes
@attr_reader [Array<Symbol>] step_names
The names of registered steps
@api private
@attr_reader [Hash<Symbol => Proc,#call>] steps The step map
@api private
Public Class Methods
@api private
# File lib/transflow/transaction.rb, line 43 def initialize(steps) @steps = steps @step_names = steps.keys.reverse end
Public Instance Methods
Call the transaction
Once transaction is called it will call the first step and its result will be passed to the second step and so on.
@example
my_container = { add_one: -> i { i + 1 }, add_two: -> j { j + 2 } } transaction = Transflow(container: my_container) { step(:one, with: :add_one) { step(:two, with: :add_two) } } transaction.call(1) # 4
@param [Object] input The input for the first step
@param [Hash] options The curry-args map, optional
@return [Object]
@raises TransactionFailedError
@api public
# File lib/transflow/transaction.rb, line 109 def call(input, options = {}) handler = handler_steps(options).map(&method(:step)).reduce(:>>) handler.call(input) rescue StepError => err raise TransactionFailedError.new(self, err) end
Subscribe event listeners to specific steps
@example
transaction = Transflow(container: my_container) { step(:one) { step(:two, publish: true } } class MyListener def self.two_success(*args) puts 'yes!' end def self.two_failure(*args) puts 'oh noez!' end end transaction.subscribe(two: my_listener) transaction.call(some_input)
@param [Hash<Symbol => Object>] listeners The step=>listener map
@return [self]
@api public
# File lib/transflow/transaction.rb, line 74 def subscribe(listeners) if listeners.is_a?(Hash) listeners.each { |step, listener| steps[step].subscribe(listener) } else steps.each { |(_, step)| step.subscribe(listeners) } end self end
Coerce a transaction into string representation
@return [String]
@api public
# File lib/transflow/transaction.rb, line 122 def to_s "Transaction(#{step_names.join(' => ')})" end
Private Instance Methods
@api private
# File lib/transflow/transaction.rb, line 148 def assert_valid_options(options) options.each_key do |name| unless step_names.include?(name) raise ArgumentError, "+#{name}+ is not a valid step name" end end end
@api private
# File lib/transflow/transaction.rb, line 129 def handler_steps(options) if options.any? assert_valid_options(options) steps.map { |(name, op)| args = options[name] if args op.curry.call(args) else op end } else steps.values end.reverse end
Wrap a proc into composable transproc function
@param [#call]
@api private
# File lib/transflow/transaction.rb, line 161 def step(obj) Step[obj] end