class Eco::API::Session::Config::Workflow
Constants
- WORKFLOW_MODEL
Attributes
Public Class Methods
# File lib/eco/api/session/config/workflow.rb, line 22 def model super || {} end
# File lib/eco/api/session/config/workflow.rb, line 44 def initialize(name = nil, _parent: self, config:) @config = config @name = name @stages = {} @_parent = _parent @pending = true # moments @on = nil @before = [] @after = [] end
# File lib/eco/api/session/config/workflow.rb, line 18 def stages model_attrs end
# File lib/eco/api/session/config/workflow.rb, line 26 def validate_stage(stage) "Unknown Workflow stage '#{stage}'. Should be any of #{stages}" unless stages.include?(stage) end
# File lib/eco/api/session/config/workflow.rb, line 30 def workflow_class(key) class_name = to_constant(key.to_s) new_class(class_name, inherits: Eco::API::Session::Config::Workflow) do |klass| klass.model = model[key] end end
Public Instance Methods
Used in configuration time **add previous** `callbacks` after the `on` callback of the (sub)stage `key` is actually `run` @note
- it will **not** `yield` it immediately, but when the _workflow_ reaches the target stage - in this case, you can define multiple `callbacks`
@param key [Symbol, nil] cases:
- if `key` is not provided, it targets the _current stage_ - if `key` is provided, it targets the specific _sub-stage_
@yield [stage_workflow, io] one of the things to do after the `on` callback of the (sub)stage `key` is actually `run` @yieldparam stage_workflow [Eco::API::Session::Config::Workflow] the _target stage_ referred by `key` @yieldparam io [Eco::API::UseCases::BaseIO] the input/output object carried througout all the workflow @yieldreturn [Eco::API::UseCases::BaseIO] `io` the input/output object carried througout all the workflow @return [Eco::API::Session::Config::Workflow] the current stage object (to ease chainig).
# File lib/eco/api/session/config/workflow.rb, line 166 def after(key = nil, &block) raise "A block should be given." unless block if !key @after.push(block) else stage(key).after(&block) end self end
Used in configuration time **add previous** `callbacks` before the `on` callback of the (sub)stage `key` is actually `run` @note
- it will **not** `yield` it immediately, but when the _workflow_ reaches the target stage - in this case, you can define multiple `callbacks`
@param key [Symbol, nil] cases:
- if `key` is not provided, it targets the _current stage_ - if `key` is provided, it targets the specific _sub-stage_
@yield [stage_workflow, io] one of the things to do before the `on` callback of the (sub)stage `key` is actually `run` @yieldparam stage_workflow [Eco::API::Session::Config::Workflow] the _target stage_ referred by `key` @yieldparam io [Eco::API::UseCases::BaseIO] the input/output object carried througout all the workflow @yieldreturn [Eco::API::UseCases::BaseIO] `io` the input/output object carried througout all the workflow @return [Eco::API::Session::Config::Workflow] the current stage object (to ease chainig).
# File lib/eco/api/session/config/workflow.rb, line 144 def before(key = nil, &block) raise "A block should be given." unless block if !key @before.push(block) else stage(key).before(&block) end self end
Used in configuration time **to configure** the workflow of the target (sub)stage `key` @note if a `block` is provided it will `yield` the target stage immediately @param key [Symbol, nil] cases:
- if `key` is not provided, it targets the _current stage_ - if `key` is provided, it targets the specific _sub-stage_
@yield [stage_workflow] further workflow configuration `for` the target stage `key` @yieldparam stage_workflow [Eco::API::Session::Config::Workflow] the _target stage_ referred by `key` @return [Eco::API::Session::Config::Workflow] the current stage object (to ease chainig).
# File lib/eco/api/session/config/workflow.rb, line 90 def for(key = nil) raise "A block should be given." unless block_given? if !key yield(self) else stage(key).for(&Proc.new) end self end
Used in configuration time **to define** the behaviour the target (sub)stage `key` @note if a `block` is provided it will not `yield` the target stage immediately, but when the workflow reaches the stage @param key [Symbol, nil] cases:
- if `key` is not provided, it targets the _current stage_ - if `key` is provided, it targets the specific _sub-stage_
@yield [stage_workflow, io] the behaviour of the target stage `key` when the workflow reaches it @yieldparam stage_workflow [Eco::API::Session::Config::Workflow] the _target stage_ referred by `key` @yieldparam io [Eco::API::UseCases::BaseIO] the input/output object carried througout all the workflow @yieldreturn [Eco::API::UseCases::BaseIO] the `io` input/output object carried througout all the workflow @return [Eco::API::Session::Config::Workflow] the current stage object (to ease chainig).
# File lib/eco/api/session/config/workflow.rb, line 110 def on(key = nil, &block) raise "A block should be given." unless block if !key @on = block else stage(key).on(&block) end self end
Has this stage run yet? @note it does not include sub-stages that run `before` @return [Boolean] `true` if it has run, `false` otherwise
# File lib/eco/api/session/config/workflow.rb, line 61 def pending? @pending end
When there is an `Exception`, you might have defined some `callback` to do something with it (i.e. register, email) @yield [exception, io] the `callback` to do something with an `Exception` raised within this workflow stage @yieldparam exception [Exception] the exception object that was raised @yieldparam io [Eco::API::UseCases::BaseIO] the input/output object carried througout all the workflow @yieldreturn [Eco::API::UseCases::BaseIO] the `io` input/output object carried througout all the workflow @return [Eco::API::Session::Config::Workflow] the current stage object (to ease chainig).
# File lib/eco/api/session/config/workflow.rb, line 126 def rescue(&block) return @rescue unless block @rescue = block self end
Used in run time to **execute the workflow** of the (sub)stage `key` @note if a `block` is not provided:
- it will run the `before` _callbacks_ defined during the configuration time - it will run the _workflow_ of any defined _**substage**_ of the `key` stage - it will run the `on` _callback_ defined during the configuration time - it will mark the stage as **not** `pending?`. - it will run the `after` _callbacks_ defined during the configuration time
@note if a `block` is provided:
- it will **not** run the workflow of the substages to `key` stage - it will **not** run the `callback` for `on` defined during the configuration time - it will rather `yield` the target stage after all the `before` _callbacks_ have been run - aside of this, the rest will be the same as when the _block_ is provided (see previous note)
@param key [Symbol, nil] cases:
- if `key` is not provided, it targets the _current stage_ - if `key` is provided, it targets the specific _sub-stage_
@param io [Eco::API::UseCases::BaseIO] the input/output object @yield [stage_workflow, io] if a `block` is provided, see `note` @yieldparam stage_workflow [Eco::API::Session::Config::Workflow] the _target stage_ referred by `key` @yieldparam io [Eco::API::UseCases::BaseIO] the input/output object carried througout all the workflow @yieldreturn [Eco::API::UseCases::BaseIO] the `io` input/output object carried througout all the workflow @return [Eco::API::Session::Config::Workflow] the current stage object (to ease chainig).
# File lib/eco/api/session/config/workflow.rb, line 197 def run(key = nil, io:, &block) raise "Missing BaseIO object" unless io.is_a?(Eco::API::UseCases::BaseIO) begin if key io = stage(key).run(io: io, &block) elsif pending? @before.each {|c| io = c.call(self, io)} unless skip? io.session.logger.debug("(Workflow: #{path}) running now") if block io = block.call(self, io) else existing_stages.each {|stg| io = stg.run(io: io)} unless ready? msg = "(Workflow: #{path}) 'on' callback is not defined, nor block given" io.session.logger.debug(msg) end io = @on.call(self, io) if ready? end @pending = false end @after.each {|c| io = c.call(self, io)} end rescue SystemExit exit rescue Interrupt => i raise rescue Exception => e self.rescue.call(e, io) if self.rescue raise end io end
Do not run this stage!
# File lib/eco/api/session/config/workflow.rb, line 66 def skip! @skip = true @pending = false end
Has this stage been marked as to be skipped @return [Boolean] depends on this order:
- `true` if `skip!` was called - `false` if the current _stage_ is `root?` (the top stage of the hierarchy) - `true` if its parent task is to be skipped
# File lib/eco/api/session/config/workflow.rb, line 76 def skip? return @skip if instance_variable_defined?(:@skip) return false if root? @_parent.skip? end
Protected Instance Methods
# File lib/eco/api/session/config/workflow.rb, line 249 def existing_stages # sort defined stages by stage order sorted_keys = self.class.stages & @stages.keys sorted_keys.map {|k| stage(k)} end
# File lib/eco/api/session/config/workflow.rb, line 236 def path return name if root? "#{@_parent.path}:#{name}" end
# File lib/eco/api/session/config/workflow.rb, line 245 def ready? !!@on end
# File lib/eco/api/session/config/workflow.rb, line 255 def ready_stages exiting_stages.select {|s| s.ready?} end
# File lib/eco/api/session/config/workflow.rb, line 241 def root? @_parent == self end
# File lib/eco/api/session/config/workflow.rb, line 263 def stage(key) self.class.validate_stage(key) @stages[key] ||= self.class.workflow_class(key).new(key, _parent: self, config: config) end
# File lib/eco/api/session/config/workflow.rb, line 259 def stages_ready? existing_stages.all? {|s| s.ready?} end