Static For-Loop Node
A deterministic iteration node for bounded loops. Emits per-iteration output, supports pause/continue/stop control signals, and persists state for crash-safe resume behavior.
Execution Overview
All loop nodes share a common execution model: they suspend between iterations using the bookmark pattern, persisting their current iteration state into the workflow instance. This means a process restart mid-loop resumes at the last completed iteration — not from the beginning.
Each iteration fires an onIteration output port carrying typed data. The loop either continues immediately (fire-and-forget) or waits for an acknowledgement signal from downstream nodes before advancing (ack mode).
Port Overview
Node Properties
Design-time properties that control range behavior, acknowledgement mode, failure handling, and runtime concurrency guarantees.
WorkflowDefinition and cannot be changed at runtime. On each iteration, the current value is emitted via the onIteration output port. Supports external pause, continue, and stop control via input signal ports.
Input Properties
| Property | Type | Default | Description |
|---|---|---|---|
| from | int | required | Starting value of the loop (inclusive).
e.g. from=0 starts the first iteration with value=0
|
| to | int | required | Ending value of the loop (exclusive — like Python range()).
e.g. from=0, to=5 yields values 0,1,2,3,4
|
| step | int | 1 | Increment applied after each iteration. Use a negative value with from > to for countdown loops.
e.g. from=10, to=0, step=-2 yields 10,8,6,4,2
|
| iterationMode | enum | Sequential |
Sequential — next iteration starts only after current completes (or is acked).Concurrent — all iterations fan-out as independent pointers simultaneously.
Concurrent mode requires maxConcurrency to avoid flooding downstream systems.
|
| iterationDelayMs | int | 0 | Milliseconds to wait after an iteration completes before starting the next.
Only applies in Sequential mode.
|
| ack | bool | false |
false — fire and forget. Loop advances immediately after onIteration.true — loop suspends and waits for a signal to the continue input port before advancing.
|
| ackTimeoutMs | int | 0 | Milliseconds to wait for acknowledgement before timing out. 0 = wait indefinitely.
Only relevant when ack: true. Timeout fires the onIterationTimeout port.
|
| ackMode | enum | Any |
Any — resume when any one connected downstream node sends ack.All — resume only when all connected downstream nodes have acked.
Only relevant when ack: true.
|
| maxConcurrency | int | ∞ | Maximum concurrent iterations when iterationMode: Concurrent.
Strongly recommended for IoT command sequences. Has no effect in Sequential mode.
|
| onIterationError | enum | Halt |
Halt — stop the loop and fire onError.Continue — skip the failed iteration and advance.Retry(n) — retry the current iteration up to n times before applying Halt or Continue.
|
from=5, to=3, step=1 (impossible range) is rejected before any instance can be created.
Port Detail
from. Ignored if the loop is already running.ack: true. Dual purpose — context determines behaviour.onStop output port.value: int,
isFirst: bool,
isLast: bool }
stop input port.ackTimeoutMs is exceeded. Only when ack: true and ackTimeoutMs > 0.onIterationError: Halt and an iteration fails.Input port priority
When multiple control signals arrive simultaneously at the same iteration boundary:
Concurrency model
One loop node runs per workflow instance. Two instances of the same definition have completely independent loop state and iteration counters.
maxConcurrency to avoid flooding.
maxConcurrency, a loop with from=0, to=1000 in Concurrent mode dispatches 1000 simultaneous device commands. Always set maxConcurrency when targeting physical devices.
Persisted state (crash recovery)
Written to WorkflowInstance.State.NodeOutputs[nodeId] on every iteration suspension:
Planned Node Types
The following loop node variants are planned for future releases. Design notes are preliminary.
- DynamicForLoopNode — Iterates over a range resolved at runtime from workflow state or a node output. Requires expression evaluation against
WorkflowStateat execution time. - ForEachNode — Iterates over a collection (array) rather than a numeric range. Each iteration emits the current item via
onIteration. Supports both Sequential and Concurrent modes with the same ack model. - WhileLoopNode — Continues iterating while a condition expression evaluates to true. Must include a max-iterations safety cap.
- PollLoopNode — Purpose-built for IoT polling patterns. Fires a device query each iteration, compares against a condition, exits via
onConditionMet. Built-in backoff between polls.