How to use mix components
Best practices on how to or how not to use specific operations and patterns to meet your specific needs.
Using fields
Fields normally carry data that can be of different type. Fields are also used for ensuring sequencing.
Use FLAGs instead of unrelated fields
FLAGS are fields without type that are not supplied to services in a data event. They can be used for sequencing purposes instead of regular fields that are not related to a sequence. The unrelated field could be removed at a later time, thus changing or breaking the sequence. In such cases, FLAGs can ensure the sequencing stays the same.
Undesirable | Idiomatic |
---|---|
<folder name="myFolder"> <field name="field1" type="string"/> <field name="field2" type="string"/> <field name="doAInfo" type="string"/> <field name="doZInfo" type="string"/> <mix name="myMix"> <notify fields="field1 field2"/> <request name="GetInfo" fields="field1"> <reply name="Ok" fields="doAInfo doZInfo"/> </request> <consume name="DoOpB" fields="doAInfo field2"/> </mix> </folder> |
<folder name="myFolder"> <field name="field1" type="string"/> <field name="field2" type="string"/> <field name="doAInfo" type="string"/> <field name="doZInfo" type="string"/> <field name="DO_B"/> <mix name="myMix"> <notify fields="field1 field2"/> <request name="GetInfo" fields="field1"> <reply name="Ok" fields="doAInfo doZInfo DO_B"/> </request> <consume name="DoOpB" fields="DO_B field2"/> </mix> </folder> |
Do not overuse FLAGs
Use FLAGs only if regular fields are not enough to enforce sequencing.
Undesirable | Idiomatic |
---|---|
<folder name="myFolder"> <field name="field1" type="string"/> <field name="field2" type="string"/> <field name="doAInfo" type="string"/> <field name="DO_A"/> <mix name="myMix"> <notify fields="field1 field2"/> <request name="GetAInfo" fields="field1"> <reply name="Ok" fields="doAInfo DO_A"/> </request> <consume name="DoOpA" fields="doAInfo DO_A field2"/> </mix> </folder> |
<folder name="myFolder"> <field name="field1" type="string"/> <field name="field2" type="string"/> <field name="doAInfo" type="string"/> <mix name="myMix"> <notify fields="field1 field2"/> <request name="GetAInfo" fields="field1"> <reply name="Ok" fields="doAInfo"/> </request> <consume name="DoOpA" fields="doAInfo field2"/> </mix> </folder> |
Using operations
There are four types of operations in SPARKL that make possible different patterns and combinations. Find here some pieces of advice on where and how to apply particular operations.
Do not use request/reply operations that are not needed to satisfy a goal
Requests are not themselves goals. They only get sequenced if they help the Sequencer reach a goal. Goals in SPARKL are to generate responses to solicits, and to satisfy consume operations.
Undesirable | Idiomatic |
---|---|
<folder name="myFolder"> <field name="field1" type="string"/> <field name="field2" type="string"/> <mix name="myMix"> <notify fields="field1"/> <request fields="field1"> <reply name="Ok" fields="field2"/> </request> ... </mix> </folder> |
<folder name="myFolder"> <field name="field1" type="string"/> <field name="field2" type="string"/> <mix name="myMix"> <notify fields="field1"/> <consume fields="field1"> <reply name="Ok" fields="field2"/> </consume> ... </mix> </folder> |
Use consume operations instead of request operations when there is overlap between input fields and fields of at least one reply
Field data is immutable in SPARKL unless it crosses a consume boundary. One purpose of consume/reply operations is to allow mutability for fields. A consume/reply creates a parallel thread of execution.
Undesirable | Idiomatic |
---|---|
<folder name="myFolder"> <field name="myField" type="string"/> <mix name="myMix"> <notify fields="myField"/> <request fields="myField"> <reply name="Ok" fields="myField"/> </request> ... </mix> </folder> |
<folder name="myFolder"> <field name="myField" type="string"/> <mix name="myMix"> <notify fields="myField"/> <consume fields="myField"> <reply name="Ok" fields="myField"/> </consume> ... </mix> </folder> |
Parallel threads of execution
A consume/reply creates a parallel thread of execution, whether we have used it as a goal in itself, or simply to allow mutability of field data. Goal events behave differently in that a response can be satisfied once per transaction while a consume can be satisfied once per thread.
Operation | Satisfied |
---|---|
Response |
|
Consume |
|
Be careful how you want consume operations to fire around solicits, particularly when the solicit has already been satisfied.
Also, be careful that even though more than one of the threads could satisfy the solicit, it can be satisfied only by the one that "gets there first".
You may use FLAGs to ensure a response is sent only at the right time, in the right thread.
Tie unnecessary parallel threads created by consume/reply operations
A consume/reply creates a consequent field set, thus a parallel thread of execution. If your only goal is to allow for mutability in fields, make sure that only the new thread continues.
Undesirable | Idiomatic |
---|---|
<folder name="myFolder"> <field name="field1" type="string"/> <field name="field2" type="string"/> <field name="field3" type="string"/> <mix name="myMix"> <notify fields="field1 field2"/> <consume name="ConsumeA" fields="field1"> <reply name="Ok" fields="field1"/> </consume> <request name="myRequest" fields="field2"> <reply name="Ok" fields="field3"/> </request> <consume name="ConsumeB" fields="field3"/> </mix> </folder> |
<folder name="myFolder"> <field name="field1" type="string"/> <field name="field2" type="string"/> <field name="field3" type="string"/> <field name="AFLAG"/> <mix name="myMix"> <notify fields="field1 field2"/> <consume name="ConsumeA" fields="field1"> <reply name="Ok" fields="field1 AFLAG"/> </consume> <request name="myRequest" fields="AFLAG field2"> <reply name="Ok" fields="field3"/> </request> <consume name="ConsumeB" fields="field3"/> </mix> </folder> |