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, {people: [:get, :filter]}, :filter]},
  :usecases, :launch_jobs,
  {post_launch: [:usecases, :launch_jobs]},
  :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, #new_class, #resolve_class, #to_constant

Constructor Details

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

Returns a new instance of Workflow.



43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/eco/api/session/config/workflow.rb', line 43

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.



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

def config
  @config
end

#nameObject (readonly)

Returns the value of attribute name.



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

def name
  @name
end

Class Method Details

.modelObject



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

def model
  super || {}
end

.stagesObject



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

def stages
  model_attrs
end

.validate_stage(stage) ⇒ Object



25
26
27
# File 'lib/eco/api/session/config/workflow.rb', line 25

def validate_stage(stage)
  "Unknown Workflow stage '#{stage}'. Should be any of #{stages}" unless stages.include?(stage)
end

.workflow_class(key) ⇒ Object



29
30
31
32
33
34
35
# File 'lib/eco/api/session/config/workflow.rb', line 29

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:

Returns:



165
166
167
168
169
170
171
172
173
# File 'lib/eco/api/session/config/workflow.rb', line 165

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:

Returns:



143
144
145
146
147
148
149
150
151
# File 'lib/eco/api/session/config/workflow.rb', line 143

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:



89
90
91
92
93
94
95
96
97
# File 'lib/eco/api/session/config/workflow.rb', line 89

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:

Returns:



109
110
111
112
113
114
115
116
117
# File 'lib/eco/api/session/config/workflow.rb', line 109

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



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

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:

Returns:



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

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:

Returns:



196
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
# File 'lib/eco/api/session/config/workflow.rb', line 196

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!



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

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


75
76
77
78
79
# File 'lib/eco/api/session/config/workflow.rb', line 75

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