Skip to content

Commit 3e5ba37

Browse files
author
Tihomir Surdilovic
authored
New example - filling up a glass of water (#279)
* New example - filling up a glass of water Signed-off-by: Tihomir Surdilovic <[email protected]> * fixed arrow in image Signed-off-by: Tihomir Surdilovic <[email protected]> * changed stateFilter back to stateDataFilter Signed-off-by: Tihomir Surdilovic <[email protected]> * fix per comments Signed-off-by: Tihomir Surdilovic <[email protected]>
1 parent 996941d commit 3e5ba37

File tree

3 files changed

+180
-6
lines changed

3 files changed

+180
-6
lines changed

examples/README.md

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ Provides Serverless Workflow language examples
2626
- [Accumulate room readings and create timely reports (ExecTimeout and KeepActive)](#Accumulate-room-readings)
2727
- [Car vitals checks (SubFlow state Repeat)](#Car-Vitals-Checks)
2828
- [Book Lending Workflow](#Book-Lending)
29+
- [Filling a glass of water (Expression functions)](#Filling-a-glass-of-water)
2930

3031
### Hello World Example
3132

@@ -3753,3 +3754,122 @@ events: file://books/lending/events.json
37533754
</td>
37543755
</tr>
37553756
</table>
3757+
3758+
### Filling a glass of water
3759+
3760+
#### Description
3761+
3762+
In this example we showcase the power of [expression functions](../specification.md#Using-Functions-For-Expression-Evaluation).
3763+
Our workflow definition is assumed to have the following data input:
3764+
3765+
```json
3766+
{
3767+
"counts": {
3768+
"current": 0,
3769+
"max": 10
3770+
}
3771+
}
3772+
```
3773+
3774+
Our workflow simulates filling up a glass of water one "count" at a time until "max" count is reached which
3775+
represents our glass is full.
3776+
Each time we increment the current count, the workflow checks if we need to keep refilling the glass.
3777+
If the current count reaches the max count, the workflow execution ends.
3778+
To increment the current count, the workflow invokes the "IncrementCurrent" expression function.
3779+
Its results are then merged back into the state data according to the "toStateData" property of the event data filter.
3780+
3781+
#### Workflow Diagram
3782+
3783+
<p align="center">
3784+
<img src="../media/examples/examples-fill-glass.png" height="300px" alt="Fill Glass of Water Example"/>
3785+
</p>
3786+
3787+
#### Workflow Definition
3788+
3789+
<table>
3790+
<tr>
3791+
<th>JSON</th>
3792+
<th>YAML</th>
3793+
</tr>
3794+
<tr>
3795+
<td valign="top">
3796+
3797+
```json
3798+
{
3799+
"id": "fillgrassofwater",
3800+
"name": "Fill glass of water workflow",
3801+
"start": "Check if full",
3802+
"functions": [
3803+
{
3804+
"name": "Increment Current Count Function",
3805+
"type": "expression",
3806+
"operation": ".counts.current += 1 | .counts.current"
3807+
}
3808+
],
3809+
"states": [
3810+
{
3811+
"name": "Check if full",
3812+
"type": "switch",
3813+
"dataConditions": [
3814+
{
3815+
"name": "Need to fill more",
3816+
"condition": "${ .counts.current < .counts.max }",
3817+
"transition": "Add Water"
3818+
},
3819+
{
3820+
"name": "Glass full",
3821+
"condition": ".counts.current >= .counts.max",
3822+
"end": true
3823+
}
3824+
]
3825+
},
3826+
{
3827+
"name": "Add Water",
3828+
"type": "operation",
3829+
"actions": [
3830+
{
3831+
"functionRef": "Increment Current Count Function",
3832+
"actionDataFilter": {
3833+
"toStateData": ".counts.current"
3834+
}
3835+
}
3836+
],
3837+
"transition": "Check If Full"
3838+
}
3839+
]
3840+
}
3841+
```
3842+
3843+
</td>
3844+
<td valign="top">
3845+
3846+
```yaml
3847+
id: fillgrassofwater
3848+
name: Fill glass of water workflow
3849+
start: Check if full
3850+
functions:
3851+
- name: Increment Current Count Function
3852+
type: expression
3853+
operation: ".counts.current += 1 | .counts.current"
3854+
states:
3855+
- name: Check if full
3856+
type: switch
3857+
dataConditions:
3858+
- name: Need to fill more
3859+
condition: "${ .counts.current < .counts.max }"
3860+
transition: Add Water
3861+
- name: Glass full
3862+
condition: ".counts.current >= .counts.max"
3863+
end: true
3864+
- name: Add Water
3865+
type: operation
3866+
actions:
3867+
- functionRef: Increment Current Count Function
3868+
actionDataFilter:
3869+
toStateData: ".counts.current"
3870+
transition: Check If Full
3871+
```
3872+
3873+
</td>
3874+
</tr>
3875+
</table>
116 KB
Loading

specification.md

Lines changed: 60 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1081,10 +1081,9 @@ In addition to defining RESTful and RPC services and their operations, workflow
10811081
can also be used to define expressions that should be evaluated during workflow execution.
10821082

10831083
Defining expressions as part of function definitions has the benefit of being able to reference
1084-
them by their logical name through workflow states where expression evaluation is required, thus making them
1085-
reusable definitions.
1084+
them by their logical name through workflow states where expression evaluation is required.
10861085

1087-
Expression expression functions must declare their `type` parameter to be `expression`.
1086+
Expression functions must declare their `type` parameter to be `expression`.
10881087

10891088
Let's take at an example of such definitions:
10901089

@@ -1106,9 +1105,9 @@ Let's take at an example of such definitions:
11061105
```
11071106

11081107
Here we define two reusable expression functions. Expressions in Serverless Workflow
1109-
are evaluated against the workflow data. Note that different data filters play a big role as to which parts of the
1110-
workflow data are selected. Reference the
1111-
[State Data Filtering](#State-data-filters) section for more information on this.
1108+
can be evaluated against the workflow, or workflow state data. Note that different data filters play a big role as to which parts of the
1109+
workflow data are being evaluated by the expressions. Reference the
1110+
[State Data Filtering](#State-Data-Filtering) section for more information on this.
11121111

11131112
Our expression function definitions can now be referenced by workflow states when they need to be evaluated. For example:
11141113

@@ -1138,6 +1137,61 @@ Our expression function definitions can now be referenced by workflow states whe
11381137
}
11391138
```
11401139

1140+
Our expression functions can also be referenced and executed as part of state [action](#Action-Definition) execution.
1141+
Let's say we have the following workflow definition:
1142+
1143+
```json
1144+
{
1145+
"name": "simpleadd",
1146+
"functions": [
1147+
{
1148+
"name": "Increment Count Function",
1149+
"type": "expression",
1150+
"operation": ".count += 1 | .count"
1151+
}
1152+
],
1153+
"start": "Initialize Count",
1154+
"states": [
1155+
{
1156+
"name": "Initialize Count",
1157+
"type": "inject",
1158+
"data": {
1159+
"count": 0
1160+
},
1161+
"transition": "Increment Count"
1162+
},
1163+
{
1164+
"name": "Increment Count",
1165+
"type": "operation",
1166+
"actions": [
1167+
{
1168+
"functionRef": "Increment Count Function",
1169+
"actionFilter": {
1170+
"toStateData": "${ .count }"
1171+
}
1172+
}
1173+
],
1174+
"end": true
1175+
}
1176+
]
1177+
}
1178+
```
1179+
1180+
The starting [inject state](#Inject-State) "Initialize Count" injects the count element into our state data,
1181+
which then becomes the state data input of our "Increment Count" [operation state](#Operation-State).
1182+
This state defines an invocation of the "Increment Count Function" expression function defined in our workflow definition.
1183+
1184+
This triggers the evaluation of the defined expression. The input of this expression is by default the current state data.
1185+
Just like with "rest", and "rpc" type functions, expression functions also produce a result. In this case
1186+
the result of the expression is just the number 1.
1187+
The actions filter then assigns this result to the state data element "count" and the state data becomes:
1188+
1189+
``` json
1190+
{
1191+
"count": 1
1192+
}
1193+
```
1194+
11411195
Note that the used function definition type in this case must be `expression`.
11421196

11431197
For more information about functions, reference the [Functions definitions](#Function-Definition) section.

0 commit comments

Comments
 (0)