once

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
                  open_customer_support_account
                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 (http://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.