Class: Eco::API::Session::Config::Workflow

Inherits:
Object
  • Object
show all
Extended by:
Common::ClassHierarchy
Defined in:
lib/eco/api/session/config/workflow.rb

Constant Summary collapse

WORKFLOW_MODEL =
[
  :options,
  {load: [{input: [:get, :filter]}, {people: [:get, :filter]}, :filter]},
  :usecases, :launch_jobs,
  {post_launch: [:usecases, :launch_jobs]},
  :report,
  :end, :close
]

Instance Attribute Summary collapse

Attributes included from Common::ClassHierarchy

#model

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Common::ClassHierarchy

model_attrs, parse_model

Methods included from Common::ClassHelpers

#class_resolver, #descendants, #descendants?, #new_class, #resolve_class, #to_constant

Constructor Details

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

Returns a new instance of Workflow.



44
45
46
47
48
49
50
51
52
53
54
55
56
# 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

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config.



41
42
43
# File 'lib/eco/api/session/config/workflow.rb', line 41

def config
  @config
end

#nameObject (readonly)

Returns the value of attribute name.



42
43
44
# File 'lib/eco/api/session/config/workflow.rb', line 42

def name
  @name
end

Class Method Details

.modelObject



22
23
24
# File 'lib/eco/api/session/config/workflow.rb', line 22

def model
  super || {}
end

.stagesObject



18
19
20
# File 'lib/eco/api/session/config/workflow.rb', line 18

def stages
  model_attrs
end

.validate_stage(stage) ⇒ Object



26
27
28
# 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

.workflow_class(key) ⇒ Object



30
31
32
33
34
35
36
# 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

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:

Yield Returns:

Returns:



166
167
168
169
170
171
172
173
174
# 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

#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:

Yield Returns:

Returns:



144
145
146
147
148
149
150
151
152
# 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

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

Note:

if a block is provided it will yield the target stage immediately

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:



90
91
92
93
94
95
96
97
98
# 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

#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:

Yield Returns:

Returns:



110
111
112
113
114
115
116
117
118
# 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

#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



61
62
63
# File 'lib/eco/api/session/config/workflow.rb', line 61

def pending?
  @pending
end

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

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:

Yield Returns:

Returns:



126
127
128
129
130
# File 'lib/eco/api/session/config/workflow.rb', line 126

def rescue(&block)
  return @rescue unless block
  @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)

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 (Eco::API::UseCases::BaseIO)

    the input/output object

Yields:

  • (stage_workflow, io)

    if a block is provided, see note

Yield Parameters:

Yield Returns:

Returns:



197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
# File 'lib/eco/api/session/config/workflow.rb', line 197

def run(key = nil, io:, &block)
  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

#skip!Object

Do not run this stage!



66
67
68
69
# File 'lib/eco/api/session/config/workflow.rb', line 66

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


76
77
78
79
80
# 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