Class: Ruote::Exp::OnceExpression

Inherits:
FlowExpression show all
Defined in:
lib/ruote/exp/fe_once.rb

Overview

The 'once' / 'when' expression verifies if a condition is true, if not it will block and after 10 seconds it will check again. If true, it will resume or it will execute its child expression (before resuming).

concurrence do

  once '${v:/invoice_status} == emitted' do
    
  end

  sequence do
    participant 'accounting'
    set 'v:/invoice_status' => 'emitted'
    participant 'accounting 2'
  end
end

The condition is usually something about variables, since the workitem that this expression has access to is always the one that reached it, at apply time.

Without a child expression, this expression behaves in a 'blocking way', and it makes most sense in a 'sequence' or in a 'cursor'.

sequence do
  first_stage
  once '${v:ready_for_second_stage}'
  second_stage
end

When there is a child expression, it will get triggered when the condition realizes. Only 1 child expression is accepted, there is no implicit 'sequence'.

concurrence do
  once :test => '${v:go_on} == yes' do
    subprocess :ref => 'final_stage'
  end
  sequence do
    participant :ref => 'controller'
    set 'v:go_on' => 'yes'
  end
end

:test

Most of the example process definitions until now were placing the condition directly after the expression name itself. In an XML process definition or if you prefer it this way, you can use the :test attribute to formulate the condition :

<once test="${v:ready}">
  <participant ref="role_publisher" />
</once>

In a Ruby process definition :

once :test => '${v:ready}' do
  participant :ref => 'role_publisher'
end

:frequency

As said, the default 'check' frequency is 10 seconds. This can be changed by using the :frequency (or :freq) attribute.

sequence do
  participant 'logistic_unit'
  once '${v:/delivery_ok}', :frequency => '2d'
    # block until delivery is OK (another branch of the process probably)
    # check every two days
  participant 'accounting_unit'
end

:frequency and cron notation

It's OK to pass a 'cron string' to the :frequency attribute.

once '${v:delivery_complete}', :freq => '5 0 * * *'
  # this 'once' will check its condition once per day, five minutes
  # after midnight

See “man 5 crontab” on your favourite unix system for the details of the 'cron string', but please note that ruote (thanks to the rufus-scheduler (rufus.rubyforge.org/rufus-scheduler) accepts seconds as well.

the :timeout attribute common to all expressions

Don't forget that this expression, like all the other expressions accepts the :timeout attribute. It's perhaps better to use :timeout when there is a child expression, so that the child won't get 'triggered' in case of timeout. When there is no child expression and the 'once' behaves in a 'blocking way', a timeout will unblock, as if the condition became true.

$ruby:'hello'

Remember that, if the engine's 'ruby_eval_allowed' is set to true, the condition may contain Ruby code.

once '${r:"hell" + "o"} == hello'

This Ruby code is checked before hand against malicious code, but beware…

aliases

'once', '_when' and 'as_soon_as' are three different names for this expression.

Constant Summary

Constant Summary

Constants inherited from FlowExpression

FlowExpression::COMMON_ATT_KEYS

Instance Attribute Summary

Attributes inherited from FlowExpression

#context, #error

Instance Method Summary collapse

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

#applyObject



148
149
150
151
152
153
154
# File 'lib/ruote/exp/fe_once.rb', line 148

def apply

  h.frequency = attribute(:frequency) || attribute(:freq) || '10s'
  h.triggered = false

  reply(h.applied_workitem)
end

#reply(workitem) ⇒ Object



156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/ruote/exp/fe_once.rb', line 156

def reply(workitem)

  return reply_to_parent(workitem) if h.triggered

  t = attribute(:test) || attribute_text

  if Condition.true?(t)

    h.triggered = true

    @context.storage.delete_schedule(h.schedule_id)
      # especially for a cron...

    if tree_children[0] # trigger first child

      apply_child(0, workitem)

    else # blocking case

      reply_to_parent(workitem)
    end

  else

    reschedule
  end
end