Flow execution
For the basic connection rules, read how nodes work. This guide explains what happens when events overlap or a flow needs to keep state.
One event, one execution
Starting a flow starts its enabled triggers. Each trigger event creates an execution with its own ID and follows the green Flow connections. Data wires provide values; they do not schedule the source node. Run a calculation before the node that consumes its result.
Execution settings apply to the whole flow, so events from different triggers in that flow share its queue. Separate flows have separate runtimes and queues. Leaving the editor does not stop a running flow.
Variables and node state
- Flow variables belong to one running flow. Nodes and successive trigger executions in that flow share them; another flow with the same variable name has its own value.
- Starting a flow creates its runtime node instances and resets variables from their defined initial values. Runtime changes are not a persistent settings store.
- SDK node instance state lasts for that runtime instance. It is not automatically saved into the flow JSON.
- Data outputs from one trigger execution are not a general cross-execution cache.
Keep calculations together when they need the same state or strict ordering. Split independent responsibilities into different flows when that makes them easier to maintain. Give a shared external output one clear owner if several flows could otherwise overwrite it.
Trigger queue policies
By default, one trigger execution runs at a time and later events wait in order. A long delay or slow request can therefore hold up later events in the same flow.
| Policy | What happens while executions are busy | Suitable when |
|---|---|---|
wait | Every event waits in an unbounded queue | Every event matters and arrival rate stays manageable |
latestWins | Only the newest pending event is kept | Old state updates are no longer useful |
dropOldest | The queue is bounded; a full queue drops the oldest pending event | A burst needs a defined backlog limit |
Dropping a pending event does not interrupt an execution that already started.
maxQueueLength controls dropOldest; it does not bound the wait queue.
A Throttle reduces downstream actions after
execution reaches it, but it cannot eliminate a backlog of events waiting to enter
the flow.
Advanced execution configuration
The current editor does not expose execution tuning controls. These settings
are stored in the saved flow JSON's execution object. Most flows should keep
the defaults. To change them, stop the flow, save it, close MultiShock, and back
up the flow file. Edit only the existing file's execution object:
{
"execution": {
"maxConcurrency": 1,
"queuePolicy": "dropOldest",
"maxQueueLength": 64,
"parallelizeBranches": false
}
}
This is a fragment, not a complete flow file. Reopen MultiShock and test with a Manual Trigger and Display node before connecting device actions.
maxConcurrencyaccepts 1–16 concurrent trigger executions; the default is 1.maxQueueLengthaccepts 1–1024 pending events fordropOldest; the default is 64.parallelizeBranchesis false by default. Turning it on runs independent outgoing connections concurrently, so side-effect order can change.
Concurrent executions still share flow variables and node instance state. Increasing concurrency does not make a read-modify-write operation atomic or preserve output ordering. Plugins must also support concurrent calls before you rely on this setting.
Flow queues and device queues
A flow's event queue and each shocker's command queue are separate. A flow can finish submitting commands while a shocker is still playing earlier ones. Increasing flow concurrency does not make a shocker play overlapping commands.
Stopping a single flow stops listening and cancels its execution work, but does not clear device commands it already submitted. Stop everything also clears device queues and attempts to stop current output. It does not disable plugins. See safety controls.
Diagnose a busy flow
- Stop device output, then reproduce with Display nodes or vibration only.
- Hover nodes on the running canvas for duration and the last error. A red ! ends that branch; successful later execution clears it.
- Check the event rate, long delays, repeated work, and HTTP or plugin calls. Consider whether every pending event is still useful.
- Open Settings → Advanced → Debug & diagnostics → Performance to inspect the available timings. Collect logs from the same reproduction.
- Test ordering and state with the intended queue policy before enabling device output.
Splitting a flow or increasing concurrency is not automatically a performance improvement. Measure the actual event rate and slow operations first.