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.

: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

options

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

:count, :merge (override, mix, isolate), 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 collapse

ADD_BRANCHES_FIELD =
'__add_branches__'

Constants inherited from FlowExpression

FlowExpression::COMMON_ATT_KEYS

Instance Attribute Summary

Attributes inherited from FlowExpression

#context, #error, #h

Instance Method Summary collapse

Methods inherited from ConcurrenceExpression

#apply

Methods included from MergeMixin

#merge_workitem, #merge_workitems

Methods inherited from FlowExpression

#ancestor?, #att, #attribute, #attribute_text, #attributes, #cancel, #compile_atts, #compile_variables, do_action, #do_apply, #do_cancel, #do_fail, #do_pause, #do_persist, #do_reply, #do_resume, #do_unpersist, #expand_atts, #fei, fetch, from_h, #handle_on_error, #has_attribute, #initial_persist, #initialize, #iterative_var_lookup, #launch_sub, #lookup_on_error, #lookup_val, #lookup_val_prefix, #lookup_variable, #name, names, #parent, #parent_id, #persist_or_raise, #reply_to_parent, #set_variable, #to_h, #tree, #tree_children, #try_persist, #try_unpersist, #unpersist_or_raise, #unset_variable, #update_tree, #variables

Methods included from WithMeta

#class_def, included

Methods included from WithH

included

Constructor Details

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

Instance Method Details

#add_branches(list) ⇒ Object



142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/ruote/exp/fe_concurrent_iterator.rb', line 142

def add_branches(list)

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

    count = (list.first.to_i rescue nil)

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

  list.each do |val|

    h.list_size += 1

    workitem = Ruote.fulldup(h.applied_workitem)
    #workitem = Rufus::Json.dup(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

    launch_sub(
      "#{h.fei['expid']}_0",
      tree_children[0],
      :workitem => workitem,
      :variables => variables)
  end
end

#register_child(fei) ⇒ Object

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



137
138
139
140
# File 'lib/ruote/exp/fe_concurrent_iterator.rb', line 137

def register_child(fei)

  h.children << fei
end

#reply(workitem) ⇒ Object



174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/ruote/exp/fe_concurrent_iterator.rb', line 174

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+$/))

      do_persist
      return
    end
  end

  super(workitem)
end