Cycles and Re-entry Safety
Visualization boundary: the diagrams show loop semantics only; JSON/YAML export still depends on named handlers and conditions.
TriggerFlow can implement loops, but the recommended form is always a loop with a provable stop condition.
1. Three safe loop patterns
How to read this diagram
- Safety does not come from “being able to loop”; it comes from clear stop conditions and clear control ownership.
- These three modes correspond to internal control, approval-driven control, and externally driven control.
2. Bounded self-loop
The simplest safe pattern is to encode an explicit termination rule:
python
async def loop_step(data):
count = int(data.state.get("count", 0) or 0)
if count >= 3:
data.set_result({"done": True, "count": count})
return
data.state.set("count", count + 1, emit=False)
await data.async_emit("Loop", count + 1)3. Pause/resume round loop
A more stable pattern is to pause after each round and let an external system decide whether to continue:
step -> pause_for()- external
continue_with() ResumeLoop -> emit("Loop")
Suitable for:
- human-in-the-loop workflows
- approval flows
- long-running transactions
4. External event re-entry
Often the safest “loop” is no self-loop at all. The execution simply waits for repeated outside re-entry:
python
execution.emit("Tick", 1)
execution.emit("Tick", 1)
execution.emit("Tick", 1)Suitable for:
- webhooks
- MQ consumers
- scheduled triggers
5. Key principles
- every round must have an explicit exit condition
- if the loop owns the final result, call
set_result()or end the chain explicitly - never treat infinite spinning as the default control flow