subprocess

An expression for invoking a subprocess.

              pdef = Ruote.process_definition do
                sequence do
                  subprocess :ref => 'delivering'
                  subprocess 'invoicing'
                  refill_stock :if => '${v:stock_size} < 10'
                end
                define 'delivering' do
                  # ...
                end
                define 'invoicing' do
                  # ...
                end
                define 'refill_stock' do
                  # ...
                end
              end
            
            

passing attributes as variables

The attributes of the subprocess expression are passed as variables of
the new subprocess instance.

              Ruote.define do
                subprocess 'sub0', :a => 'A', :b => 'B'
                define :sub0 do
                  echo '${v:a}:${v:b}'
                end
              end
            

This example (and useless) process example will output “A:B” to STDOUT.

              Ruote.define :name => 'whatever' do
            
                call :who => 'the cops', :when => 'if I\'m not back at 3'
            
                define 'call' do
                  participant :ref => '${v:who}', :msg => 'this is a call'
                end
              end
            

This binds the variables ‘who’ and ‘when’ in the subprocess instance.

Of course you can combine parameters and blocks passing.

Using a “f:” or “field:” prefix is OK to pass arguments as workitem
fields instead of process variables:

              Ruote.define do
                set 'address' => { 'city' => 'boston' }
                sub0(
                  'f:a' => 'fa',
                  'field:b' => 'mi',
                  'var:c' => 'sol',
                  'f:address.city' => 'nyc')
                define 'sub0' do
                  echo '${a} ${b} ${v:c} ${address.city}'
                end
              end
                #
                # will output 'fa mi sol nyc'
            
            

passing ‘blocks’ to subprocesses

When the subprocess expression has children, the first of them is passed
to the subprocess instance as the ‘tree’ variable, readily available for
an ‘apply’ expression.

              Ruote.process_definition :name => 'double review' do
                sequence do
                  sub0 do
                    review_board
                  end
                  sub0 do
                    review_board
                  end
                end
                define 'sub0' do
                  concurrence do
                    apply :i => 0
                    apply :i => 1
                    apply :i => 2
                  end
                end
              end
            

This example will send 2 × 3 concurrent workitems to the participant
named ‘review_board’ (note that it could also be the name of another
subprocess).

pointing to subprocesses via their URI

It’s OK to invoke subprocesses via a URI

              subprocess :ref => 'pdefs/definition1.rb'
            

or

              subprocess :ref => 'http://pdefs.example.org/account/def1.xml'
            

Remember that the ‘remote_definition_allowed’ option of the engine has
to be set to true for the latter to work, else the engine will refuse
to load definitions over HTTP.

Shorter :

              subprocess 'http://pdefs.example.org/account/def1.xml'
            
            

subprocess URIs bound at engine level

There is a class of variables accessible to process instances in read-only
mode : engine level variables.

They can be set via the engine’s initialization code (or later) like in
this example :

              engine.variables['inventory_check'] = 'http://pdefs.example.com/ic0.rb'
            

All the process instance in the engine may then trigger this process in
these 3 ways :

              subprocess :ref => 'inventory_check'
              subprocess 'inventory_check'
              inventory_check
            

The latter may make process definitions quite readable (but blur the
distinction between expressions, call to participants or to subprocesses).

subprocess trees bound at engine level

It’s OK to place a process tree directly in an engine variable :

              engine.variables['inventory_check'] = Ruote.process_definition do
                cursor do
                  manager :task => 'hire inventory team'
                  floor_manager :task => 'lead inventory'
                  manager :task => 'check results'
                  rewind :unless => '${inventory_successful}'
                end
              end
            

Then, from the main process :

              sequence do
                # ...
                inventory_check
                # ...
              end