Class: Ruote::Exp::ConcurrentIteratorExpression

Inherits:
ConcurrenceExpression show all
Includes:
IteratorMixin
Defined in:
lib/ruote/exp/fe_concurrent_iterator.rb

Overview

This expression is a cross between 'concurrence' and 'iterator'.

Please look at the documentation of 'iterator' to learn more about the common options between 'iterator' and 'concurrent-iterator'.

pdef = Ruote.process_definition :name => 'test' do
  concurrent_iterator :on_val => 'alice, bob, charly', :to_var => 'v' do
    participant '${v:v}'
  end
end

will be equivalent to

pdef = Ruote.process_definition :name => 'test' do
  concurrence do
    participant 'alice'
    participant 'bob'
    participant 'charly'
  end
end

The 'on' and the 'to' attributes follow exactly the ones for the iterator expression.

When there is no 'to', the current iterated value is placed in the variable named 'i'.

The variable named 'ii' contains the current iterated index (an int bigger or egal to 0).

'concurrent_iterator' does not understand commands like rewind/break/jump/… like 'iterator' does, since it fires all its branches when applied.

:on and arrays

Given a workitem field named 'x' containing the array value

'a', 'b', 'c'

and a workitem field 'y' containing the string 'a, b, c',

this:

concurrent_iterator :on_field => 'x', :to_f => 'xx' do
  # ...
end

is equivalent to

concurrent_iterator :on => '$f:x', :to_f => 'xx' do
  # ...
end

is equivalent to

concurrent_iterator :on => '${f:y}', :to_f => 'xx' do
  # ...
end

:to_field and :to_f, :to_var and :to_v, :to

Those 4 lines are equivalent:

concurrent_iterator :on => [ 'ceo', 'cto' ], :to_field => 'a' do ...
concurrent_iterator :on => [ 'ceo', 'cto' ], :to_f => 'a' do ...
concurrent_iterator :on => [ 'ceo', 'cto' ], :to => 'f:a' do ...
concurrent_iterator :on => [ 'ceo', 'cto' ], :to => 'a' do ...

Those 3 lines are equivalent:

concurrent_iterator :on => [ 'ceo', 'cto' ], :to_var => 'a' do ...
concurrent_iterator :on => [ 'ceo', 'cto' ], :to_v => 'a' do ...
concurrent_iterator :on => [ 'ceo', 'cto' ], :to => 'v:a' do ...

:times and :branches

Similarly to the iterator expression, the :times or the :branches attribute may be used in stead of the 'on' attribute.

pdef = Ruote.process_definition :name => 'test' do
  concurrent_iterator :times => 3 do
    participant 'user${v:i}'
  end
end

is equivalent to

pdef = Ruote.process_definition :name => 'test' do
  concurrence do
    participant 'user0'
    participant 'user1'
    participant 'user2'
  end
end

ruote 2.3.0 and the citerator children

Prior to ruote 2.3.0, the concurrent-iterator only considered one child expression:

concurrent_iterator :times => 3 do
  participant 'al'
  participant 'bob' # 'bob' would never be reached
end

So one had to write:

concurrent_iterator :times => 3 do
  sequence do
    participant 'al'
    participant 'bob' # 'bob' would never be reached
  end
end

Ruote 2.3.0 lifts that restriction.

options

the concurrent_iterator accepts the same options for merging as its bigger brother, the concurrence expression.

:count, :merge (override, mix, isolate, stack, union, concat, deep, ignore), :remaining (cancel, forget) and :over.

add branches

The 'add_branches'/'add_branch' expression can be used to add branches to a concurrent-iterator while it is running.

concurrent_iterator :on => 'a, b, c' do
  sequence do
    participant :ref => 'worker_${v:i}'
    add_branches 'd, e', :if => '${v:/not_sufficient}'
  end
end

In this example, if the process level variable 'not_sufficient' is set to true, workers d and e will be added to the iterated elements.

Read more at the 'add_branches' expression description.

'citerator'

'citerator' is an alias for 'concurrent_iterator'.

pdef = Ruote.process_definition :name => 'test' do
  citerator :on_val => 'alice, bob, charly', :to_var => 'v' do
    participant '${v:v}'
  end
end

Constant Summary

ADD_BRANCHES_FIELD =
'__add_branches__'

Constants inherited from ConcurrenceExpression

Ruote::Exp::ConcurrenceExpression::COUNT_R

Constants inherited from FlowExpression

FlowExpression::COMMON_ATT_KEYS

Instance Attribute Summary

Attributes inherited from FlowExpression

#context, #error

Instance Method Summary collapse

Methods inherited from ConcurrenceExpression

#apply, #is_concurrent?

Methods inherited from FlowExpression

#ancestor?, #applied_workitem, #att, #att_text, #attribute, #attribute_text, #attributes, #await, #cancel, #cancel_flanks, #cfei_at, #child_id, #child_ids, #compile_atts, #compile_variables, #debug_id, #deflate, #do, do_action, #do_apply, #do_cancel, #do_fail, #do_pause, #do_persist, #do_reply, #do_reply_to_parent, #do_resume, #do_unpersist, dummy, #fei, fetch, from_h, #handle_on_error, #has_attribute, #initial_persist, #initialize, #is_concurrent?, #iterative_var_lookup, #launch_sub, #lookup_val, #lookup_val_prefix, #lookup_variable, #name, names, #parent, #parent_id, #pause_on_apply, #persist_or_raise, #reply_to_parent, #root, #root_id, #set_variable, #tree, #tree_children, #try_persist, #try_unpersist, #unpersist_or_raise, #unset_variable, #update_tree, #variables, #wfid

Methods included from WithMeta

#class_def, included

Methods included from WithH

#h, #h=, included, #to_h

Constructor Details

This class inherits a constructor from Ruote::Exp::FlowExpression

Instance Method Details

#add_branches(list) ⇒ Object



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
232
233
234
235
236
237
# File 'lib/ruote/exp/fe_concurrent_iterator.rb', line 201

def add_branches(list)

  if h.times_iterator && list.size == 1

    count = (list.first.to_i rescue nil)

    list = (h.list_size + 0...h.list_size + count) if count
  end

  list.each do |val|

    h.list_size += 1

    workitem = Ruote.fulldup(h.applied_workitem)

    variables = { 'ii' => h.list_size - 1 }

    if h.to_v
      variables[h.to_v] = val
    else #if to_f
      workitem['fields'][h.to_f] = val
    end

    expid, subtree = if tree_children.size > 1
      [ h.fei['expid'], [ 'sequence', {}, tree_children ] ]
    else
      [ "#{h.fei['expid']}_0", tree_children[0] ]
    end

    launch_sub(
      expid,
      subtree,
      :workitem => workitem,
      :variables => variables,
      :child_id => h.list_size - 1)
  end
end

#register_child(fei) ⇒ Object

Overrides FlowExpression#register_child to make sure that persist is not called.



196
197
198
199
# File 'lib/ruote/exp/fe_concurrent_iterator.rb', line 196

def register_child(fei)

  h.children << fei
end

#reply(workitem) ⇒ Object



239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
# File 'lib/ruote/exp/fe_concurrent_iterator.rb', line 239

def reply(workitem)

  if ab = workitem['fields'].delete(ADD_BRANCHES_FIELD)

    add_branches(ab)

    if
      h.fei['wfid'] != workitem['fei']['wfid'] ||
      ( ! workitem['fei']['expid'].match(/^#{h.fei['expid']}_\d+$/))
    then
      do_persist
      return
    end
  end

  super(workitem)
end