Vibrations example - Filtered subroutines

In this example, we use conditionalized subroutines. Depending on the value of a vibration generated in the master transaction, one of three subroutines fires.

Figure: Vibrations example - The mix


Tip: Get the code from the SPARKL public repository.
Table 1. Vibrations - Filtered subroutines markup
Markup Description
<folder name="Vibrations_subr">
  <service name="Sequencer"
    provision="sequencer"/>
  <folder name="Vibration">
    <service name="Vibrations" 
      provision="expr"/>
    <service name="Master" 
      provision="subr">
      <prop name="subr.import" 
        key="VibrKey"/>
    </service>
    <mix name="MasterMix">
      ...
    </mix>
  </folder>
  <folder name="Alerts">
    <service name="Subr" 
      provision="subr">
      <prop name="subr.export" 
        key="VibrKey"/>
    </service>
    <service name="AlertSys" 
      provision="expr">
      <prop name="expr.state" 
        Colour="NewColour"/>
    </service>
    <mix name="GreenSlave">
    ...
    </mix>
    <mix name="AmberSlave">
    ...
    </mix>
    <mix name="RedSlave">
    ...
    </mix>
  </folder>
</folder>
This example comprises two sets of components:
  1. The components that make up the master process:
    • The Vibrations service, provisioned using the Expressions extension
    • The Master service, provisioned using the Subroutine extension
    • MasterMix, the mix comprising the operations that generate the sequencing graph of the master process
  2. The components that make up the subroutine processes:
    • The Subr service, provisioned using the Subroutine extension
    • The AlertSys service, provisioned using the Expressions extension
    • GreenSlave, AmberSlave and RedSlave, three subroutine mixes that generate the sequencing graphs of the slave processes
The Master and Subr services use the subr.import and subr.export property pairs with matching keys. Thus, Master can import and use the operations on the Subr service.
<mix name="MasterMix">
  <field name="vibration" 
      type="integer"/>
  <notify name="GenVibr" 
    service="Sequencer" 
    clients="Vibrations" 
    fields="vibration">
    <prop name="expr.bind.out" 
      Vibration="vibration"/>
    <prop name="expr.src" 
      content-type="text/x-erlang"><![CDATA[
Vibration = rand:uniform(100),
  true.
    ]]></prop>
    <prop name="expr.auto"/>
  </notify>
  <consume name="SetVibr" 
    service="Master" 
    fields="vibration">
    <prop name="subr.spec" 
      function="VibrFun" 
      Alert="vibration"/>
  </consume>
</mix>
The MasterMix mix comprises:
  • The GenVibr notify that starts the master process
  • The SetVibr consume that calls the three subroutine notifies, thus starting the slave processes
Due to its expr.auto property, the GenVibr notify is triggered every 30 seconds, as long as the Vibrations service is in started state.

The expressions contained in the notify generate a random value of 1 to 100 for the Vibration variable, which is bound to the notify's output field.

The last expression, the atom true, makes sure the notify is fired every time it is triggered.

The SetVibr consume specifies the VibrFun subroutine function and binds its input field to the Alert parameter.

<mix name="GreenSlave">
  <field name="green" 
    type="integer"/>
  <notify name="GreenAlert" 
    service="Sequencer" 
    clients="Subr" 
    fields="green">
    <prop name="subr.spec" 
      function="VibrFun" 
      Alert="green"><![CDATA[
Alert =< 30.
    ]]></prop>
  </notify>
  <consume name="SetGreen" 
    service="AlertSys" 
    fields="green">
    <prop name="expr.src" 
      content-type="text/x-erlang"><![CDATA[
NewColour = green.
    ]]></prop>
  </consume>
</mix>
The GreenSlave mix comprises:
  • The GreenAlert notify that starts a slave process
  • The SetGreen consume, a goal of the subroutine transaction, that changes the state of the AlertSys service
The GreenAlert notify subroutine can be called by the SetVibr consume, because:
  1. The notify is on the Subr service, which offers its operations to all svc_subr services that has the VibrKey key
  2. The notify specifies the same function and parameter as the consume in the subr.spec property
  3. The fields, vibrations and green, which are matched to the Alert parameter, are both of type integer
Due to the expression used in its subr.spec property, the GreenAlert notify is only called if the value of the Alert parameter is less than or equal to 30.

If it receives the field green, SetGreen changes the state of the AlertSys service to green.

<mix name="AmberSlave">
  <field name="amber" 
    type="integer"/>
  <notify name="AmberAlert" 
    service="Sequencer" 
    clients="Subr" 
    fields="amber">
    <prop name="subr.spec" 
      function="VibrFun" 
      Alert="amber"><![CDATA[
Alert < 70 andalso Alert > 30.
    ]]></prop>
  </notify>
  <consume name="SetAmber" 
    service="AlertSys" 
    fields="amber">
    <prop name="expr.src" 
      content-type="text/x-erlang"><![CDATA[
NewColour = amber.
    ]]></prop>
  </consume>
</mix>
The AmberSlave mix comprises:
  • The AmberAlert notify that can start a slave process
  • The SetAmber consume, a goal of the subroutine transaction, which changes the state of the AlertSys service
The AmberAlert notify subroutine is called the same way as the GreenAlert notify - through the matching function and parameter.

The difference is the expression content of the subr.spec property.

The AmberAlert notify is only called if the value of the Alert parameter is bigger than 30 but smaller than 70.

If it receives the field amber, SetAmber changes the state of the AlertSys service to amber.

<mix name="RedSlave">
  <field name="red" 
    type="integer"/>
  <notify name="RedAlert" 
    service="Sequencer" 
    clients="Subr" 
    fields="red">
    <prop name="subr.spec" 
      function="VibrFun" 
      Alert="red"><![CDATA[
Alert >= 70.
    ]]></prop>
  </notify>
  <consume name="SetRed" 
    service="AlertSys" 
    fields="red">
    <prop name="expr.src" 
      content-type="text/x-erlang"><![CDATA[
NewColour = red.
    ]]></prop>
  </consume>
</mix>
The RedSlave mix comprises:
  • The RedAlert notify that can start a slave process
  • The SetRed consume, a goal of the subroutine transaction, which changes the state of the AlertSys service
The RedAlert notify subroutine specifies the same function and parameter as the GreenAlert and AmberAlert notifies.

The difference is the expression content of the subr.spec property.

The RedAlert notify is only called if the value of the Alert parameter is bigger than or equal to 70.

If it receives the field red, SetRed changes the state of the AlertSys service to red.