Class: Eco::Language::Models::Workflow

Inherits:
Object
  • Object
show all
Extended by:
Klass::HelpersBuilt, Hierarchy
Defined in:
lib/eco/language/models/workflow.rb

Overview

Execution workflow

Direct Known Subclasses

API::UseCases::Workflow

Instance Attribute Summary collapse

Attributes included from Hierarchy

#model

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Klass::InheritableClassVars

#inheritable_attrs, #inheritable_class_vars, #inherited

Methods included from Klass::Naming

#instance_variable_name, #to_constant

Methods included from Klass::Hierarchy

#descendants, #descendants?

Methods included from Klass::Builder

#new_class

Methods included from Klass::Uid

#uid

Methods included from Klass::Resolver

#class_resolver, #resolve_class

Methods included from Klass::Const

#if_const, #redef_without_warning

Methods included from Hierarchy

model_attrs, parse_model

Constructor Details

#initialize(name = nil, config:, _parent: self) ⇒ Workflow

rubocop:disable Lint/UnderscorePrefixedVariableName



39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/eco/language/models/workflow.rb', line 39

def initialize(name = nil, config:, _parent: self) # rubocop:disable Lint/UnderscorePrefixedVariableName

  @config   = config
  @name     = name || 'root'

  @stages   = {}
  @_parent  = _parent

  @pending  = true
  # moments

  @on       = nil
  @before   = []
  @after    = []
end

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config.



37
38
39
# File 'lib/eco/language/models/workflow.rb', line 37

def config
  @config
end

Class Method Details

.modelObject



12
13
14
# File 'lib/eco/language/models/workflow.rb', line 12

def model
  super || {}
end

.stagesObject



8
9
10
# File 'lib/eco/language/models/workflow.rb', line 8

def stages
  model_attrs
end

.validate_stage!(stage) ⇒ Object

Raises:

  • (ArgumentError)


16
17
18
19
20
21
# File 'lib/eco/language/models/workflow.rb', line 16

def validate_stage!(stage)
  return true if stages.include?(stage)

  msg = "Unknown Workflow stage '#{stage}'. Should be any of #{stages}"
  raise ArgumentError, msg
end

.workflow_class(key, prefix: nil) ⇒ Object



23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/eco/language/models/workflow.rb', line 23

def workflow_class(key, prefix: nil)
  class_name = "#{key}::#{uid}"
  class_name = "#{prefix}::#{class_name}" if prefix
  class_name = to_constant(class_name)

  new_class(
    class_name,
    inherits: Eco::API::Session::Config::Workflow
  ) do |klass|
    klass.model = model[key]
  end
end

Instance Method Details

#after(key = nil) {|stage_workflow, io| ... } ⇒ Eco::API::Session::Config::Workflow

Note:
  • it will not yield it immediately, but when the workflow reaches the target stage
  • in this case, you can define multiple callbacks

Used in configuration time add previous callbacks after the on callback of the (sub)stage key is actually run

Parameters:

  • key (Symbol, nil) (defaults to: nil)

    cases:

    • if key is not provided, it targets the current stage
    • if key is provided, it targets the specific sub-stage

Yields:

  • (stage_workflow, io)

    one of the things to do after the on callback of the (sub)stage key is actually run

Yield Parameters:

  • stage_workflow (Eco::API::Session::Config::Workflow)

    the target stage referred by key

  • io (INPUT_OUTPUT_CLASS)

    the input/output object carried througout all the workflow

Yield Returns:

  • (INPUT_OUTPUT_CLASS)

    io the input/output object carried througout all the workflow

Returns:

Raises:

  • (ArgumentError)


205
206
207
208
209
210
211
212
213
214
215
216
# File 'lib/eco/language/models/workflow.rb', line 205

def after(key = nil, &block)
  msg = 'A block should be given.'
  raise ArgumentError, msg unless block_given?

  if key
    stage(key).after(&block)
  else
    @after.push(block)
  end

  self
end

#before(key = nil) {|stage_workflow, io| ... } ⇒ Eco::API::Session::Config::Workflow

Note:
  • it will not yield it immediately, but when the workflow reaches the target stage
  • in this case, you can define multiple callbacks

Used in configuration time add previous callbacks before the on callback of the (sub)stage key is actually run

Parameters:

  • key (Symbol, nil) (defaults to: nil)

    cases:

    • if key is not provided, it targets the current stage
    • if key is provided, it targets the specific sub-stage

Yields:

  • (stage_workflow, io)

    one of the things to do before the on callback of the (sub)stage key is actually run

Yield Parameters:

  • stage_workflow (Eco::API::Session::Config::Workflow)

    the target stage referred by key

  • io (INPUT_OUTPUT_CLASS)

    the input/output object carried througout all the workflow

Yield Returns:

  • (INPUT_OUTPUT_CLASS)

    io the input/output object carried througout all the workflow

Returns:

Raises:

  • (ArgumentError)


178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/eco/language/models/workflow.rb', line 178

def before(key = nil, &block)
  msg = 'A block should be given.'
  raise ArgumentError, msg unless block_given?

  if key
    stage(key).before(&block)
  else
    @before.push(block)
  end

  self
end

#cloneObject Also known as: dup

We don't support cloning



54
55
56
# File 'lib/eco/language/models/workflow.rb', line 54

def clone
  self
end

#exit_handle(&block) ⇒ Object

Called on SystemExit exception



157
158
159
160
161
162
# File 'lib/eco/language/models/workflow.rb', line 157

def exit_handle(&block)
  return @exit_handle unless block_given?

  @exit_handle = block
  self
end

#for(key = nil) {|stage_workflow| ... } ⇒ Eco::API::Session::Config::Workflow Also known as: with

Note:
  1. if a block is provided it will yield the target stage immediately
  2. a block is only required when key has not been specified.

Used in configuration time to configure the workflow of the target (sub)stage key

Parameters:

  • key (Symbol, nil) (defaults to: nil)

    cases:

    • if key is not provided, it targets the current stage
    • if key is provided, it targets the specific sub-stage

Yields:

  • (stage_workflow)

    further workflow configuration for the target stage key

Yield Parameters:

Returns:

  • (Eco::API::Session::Config::Workflow)
    1. if block is provided provided, it returns the current stage object (to ease chainig).
    2. if block is not provided, it returns the stage referred by key

Raises:

  • (ArgumentError)


102
103
104
105
106
107
108
109
110
111
112
# File 'lib/eco/language/models/workflow.rb', line 102

def for(key = nil, &block)
  msg = "With no 'key', a block should be given."
  raise ArgumentError, msg unless key || block_given?

  tap do
    next yield(self)            unless key
    next stage(key).for(&block) if block_given?

    return stage(key)
  end
end

#name(with_path: false) ⇒ Object



59
60
61
62
63
# File 'lib/eco/language/models/workflow.rb', line 59

def name(with_path: false)
  return @name if !with_path || root?

  [@_parent.name(with_path: true), @name].compact.join('.')
end

#on(key = nil) {|stage_workflow, io| ... } ⇒ Eco::API::Session::Config::Workflow

Note:

if a block is provided it will not yield the target stage immediately, but when the workflow reaches the stage

Used in configuration time to define the behaviour the target (sub)stage key

Parameters:

  • key (Symbol, nil) (defaults to: nil)

    cases:

    • if key is not provided, it targets the current stage
    • if key is provided, it targets the specific sub-stage

Yields:

  • (stage_workflow, io)

    the behaviour of the target stage key when the workflow reaches it

Yield Parameters:

  • stage_workflow (Eco::API::Session::Config::Workflow)

    the target stage referred by key

  • io (INPUT_OUTPUT_CLASS)

    the input/output object carried througout all the workflow

Yield Returns:

  • (INPUT_OUTPUT_CLASS)

    the io input/output object carried througout all the workflow

Returns:

Raises:

  • (ArgumentError)


126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/eco/language/models/workflow.rb', line 126

def on(key = nil, &block)
  msg = 'A block should be given.'
  raise ArgumentError, msg unless block_given?

  if key
    stage(key).on(&block)
  else
    @on = block
  end

  self
end

#pending?Boolean

Note:

it does not include sub-stages that run before

Has this stage run yet?

Returns:

  • (Boolean)

    true if it has run, false otherwise



68
69
70
# File 'lib/eco/language/models/workflow.rb', line 68

def pending?
  @pending
end

#rescue {|exception, io| ... } ⇒ Eco::API::Session::Config::Workflow Also known as: exception

When there is an Exception, you might have defined some callback to do something with it (i.e. register, email)

Yields:

  • (exception, io)

    the callback to do something with an Exception raised within this workflow stage

Yield Parameters:

  • exception (Exception)

    the exception object that was raised

  • io (INPUT_OUTPUT_CLASS)

    the input/output object carried througout all the workflow

Yield Returns:

  • (INPUT_OUTPUT_CLASS)

    the io input/output object carried througout all the workflow

Returns:



147
148
149
150
151
152
# File 'lib/eco/language/models/workflow.rb', line 147

def rescue(&block)
  return @rescue unless block_given?

  @rescue = block
  self
end

#run(key = nil, io:) {|stage_workflow, io| ... } ⇒ Eco::API::Session::Config::Workflow

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)
Note:

[if the object returned by before, after and run callbacks is not an INPUT_OUTPUT_CLASS, the original io object will be returned instead.

Used in run time to execute the workflow of the (sub)stage key

Parameters:

  • key (Symbol, nil) (defaults to: nil)

    cases:

    • if key is not provided, it targets the current stage
    • if key is provided, it targets the specific sub-stage
  • io (INPUT_OUTPUT_CLASS)

    the input/output object

Yields:

  • (stage_workflow, io)

    if a block is provided, see note

Yield Parameters:

  • stage_workflow (Eco::API::Session::Config::Workflow)

    the target stage referred by key

  • io (INPUT_OUTPUT_CLASS)

    the input/output object carried througout all the workflow

Yield Returns:

  • (INPUT_OUTPUT_CLASS)

    the io input/output object carried througout all the workflow

Returns:



241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
# File 'lib/eco/language/models/workflow.rb', line 241

def run(key = nil, io:, &block)
  raise 'Missing BaseIO object' unless io.is_a?(input_output_class)

  rescuable(io) do
    if key
      io = io_result(io: io) do
        stage(key).run(io: io, &block)
      end
    elsif pending?
      io = run_before(io)
      io = run_it(io, &block) unless skip?
      io = run_after(io)
    end

    io
  ensure
    @pending = false
  end
end

#skip!Object

Do not run this stage!



73
74
75
76
# File 'lib/eco/language/models/workflow.rb', line 73

def skip!
  @skip    = true
  @pending = false
end

#skip?Boolean

Has this stage been marked as to be skipped

Returns:

  • (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


83
84
85
86
87
88
# File 'lib/eco/language/models/workflow.rb', line 83

def skip?
  return @skip if instance_variable_defined?(:@skip)
  return false if root?

  @_parent.skip?
end