Execution State
In BPMN process execution, the flow is driven by gateways and their conditions, which are based on data. On our platform, this data is managed through the execution state.
An execution state is created at the start of each process using the defined initial state from deployment. As the process runs, the execution state can be updated and extended by various elements such as service tasks, receive tasks, and message intermediate events.
- Each start event initializes a new execution with its own unique execution state.
- Parallel executions, created through gateways or sequence flows, share the same execution state.
- Subprocesses, when called from a root execution, access and update the root execution state.
You can think of the execution state as a live JSON document that evolves during the process lifecycle. We use JSON Path expressions to read, update, and evaluate this state.
JSONPath supports both dot notation $.klines[0].closePrice and bracket notation $['klines'][0]['closePrice'].
Operators
| # | Operator | Description |
|---|---|---|
| 1 | $ | The root element to query. This starts all path expressions. |
| 2 | @ | The current node being processed by a filter predicate. |
| 3 | * | Wildcard. Available anywhere a name or numeric are required. |
| 4 | .. | Deep scan. Available anywhere a name is required. |
| 5 | .<name> | Dot-notated child. |
| 6 | ['<name>' (, '<name>')] | Bracket-notated child or children. |
| 7 | [<number> (, <number>)] | Array index or indexes. |
| 8 | [start:end] | Array slice operator. |
| 9 | [?(<expression>)] | Filter expression. Must evaluate to a boolean. |
Functions
Functions can be invoked at the tail end of a path – the input to a function is the output of the path expression.
| # | Function | Description |
|---|---|---|
| 1 | min() | Returns the minimum value of an array of numbers. |
| 2 | max() | Returns the maximum value of an array of numbers. |
| 3 | avg() | Returns the average value of an array of numbers. |
| 4 | stddev() | Returns the standard deviation of an array of numbers. |
| 5 | length() | Returns the length of an array. |
| 6 | sum() | Returns the sum of an array of numbers. |
| 7 | keys() | Returns the property keys. |
| 8 | concat(X) | Concatenates the path output with a new item. |
| 9 | append(X) | Adds an item to the JSON path output array. |
| 10 | first() | Returns the first item of an array. |
| 11 | last() | Returns the last item of an array. |
| 12 | index(X) | Returns the item at index X; negative indexes count from the end. |
| 13 | add(X,N) | Adds X to all elements of an array or to a number value and returns the result, optionally rounded to N decimal digits. |
| 14 | mul(X,N) | Multiplies all elements of an array or a number value by X and returns the result, optionally rounded to N decimal digits. |
| 15 | round(N) | Rounds all elements of an array or a number value to N decimal digits. |
| 16 | trunc(N) | Truncates all elements of an array or a number value to N decimal digits. |
| 17 | encode() | URL-encodes the output of the path and returns the encoded string. |
| 18 | decode() | URL-decodes the output of the path and returns the decoded string. |
| 19 | replaceAll(S1, R1, S2, R2, ...) | Replaces all occurrences of each search string (S1, S2, ...) in the path output with the corresponding replacement string (R1, R2, ...). Arguments must be provided in pairs (search, replace). If a replacement is omitted for a given search string, the default replacement is an empty string (effectively removing all occurrences of that search string). |
Filter Operators
Filter expressions allow you to conditionally match elements in arrays.
| # | Operator | Description |
|---|---|---|
| 1 | == | Equal to (strict equality, e.g. 1 is not equal to '1'). Example: [?(@.color == 'blue')] |
| 2 | != | Not equal to. |
| 3 | < | Less than. |
| 4 | <= | Less than or equal to. |
| 5 | > | Greater than. Example: [?(@.age > 18 && @.status == 'active')] |
| 6 | >= | Greater than or equal to. |
| 7 | =~ | Matches regex. Example: [?(@.name =~ /foo.*?/i)] |
| 8 | in | Exists in array. Example: [?(@.size in ['S','M'])] |
| 9 | nin | Does not exist in array. |
| 10 | subsetof | Left side is a subset of the right. [?(@.sizes subsetof ['S','M','L'])] |
| 11 | anyof | Has intersection with right side. [?(@.sizes anyof ['M','L'])] |
| 12 | noneof | No intersection with right side. |
| 13 | size | Size of array or string matches right value. |
| 14 | empty | Left (array or string) should be empty. |
Examples
The following examples demonstrate how the execution state is used and extended. Let’s start with an initial execution state:
{
"asset": "BTC",
"symbol": "BTCUSDT",
"quantity": 0.01,
"expectedPrice": 97000.0,
"account": {
"makerCommission": 0,
"buyerCommission": 0,
"canWithdraw": true,
"accountType": "SPOT",
"sellerCommission": 0,
"canTrade": true,
"brokered": false,
"preventSor": false,
"balances": [
{
"asset": "ETH",
"free": 1.0,
"locked": 0.0
},
{
"asset": "BTC",
"free": 1.0,
"locked": 0.0
}
],
"commissionRates": {
"seller": 0.0,
"maker": 0.0,
"taker": 0.0,
"buyer": 0.0
},
"canDeposit": true,
"takerCommission": 0,
"requireSelfTradePrevention": false
}
}
JSON Path Usage Examples
$.asset– Retrieves the root-level property asset.$.quantity– Retrieves the root-level property quantity.$.account.accountType– Accesses the nested property accountType under account.$.account.balances[?(@.asset == $.asset && @.free >= $.quantity)]– Checks if the account has enough free balance of the specified asset.
Extending Execution State
When calling the service task Binance:Klines with result mapping to $.klines, and parameters:
- symbol:
$.symbol - interval: "1m"
- limit: "5"
The execution state is extended with a new property klines, such as:
"klines": [
{
"symbol": "BTCUSDT",
"numberTrades": 3506,
"lowPrice": 109242.38,
"highPrice": 109289.99,
"closeTime": 1748220179999,
"openPrice": 109269.77,
"baseAssetVolume": 16.76604,
"startTime": 1748220120000,
"interval": "1m",
"closePrice": 109248.3,
"quoteAssetVolume": 1832067.9211871
},
...
]
Now, to evaluate a condition such as "current price is higher than expected price", you can write: $[?(@.expectedPrice < $.klines[-1].closePrice)]. This checks whether the closePrice of the last Kline entry exceeds the expected price defined in the initial execution state.