Online edition for BLOGE
0.9.8-RC1· facts verified 2026-09-15 · 中文
Arc 3 Recap — Composition and Time (Chapters 10–13)
You can now compose large workflows out of reusable pieces, iterate over collections, suspend for external events, and survive process restarts.
What You Learned
Chapter 10 — Reuse with Subgraphs introduced the subgraph("name") syntax.
You learned to register a pre-built Graph with
DslCompiler.registerSubGraph(), embed it in a parent graph, and control scope
isolation (isolated vs. parent). You also saw when a dynamicSubGraph —
runtime-generated DSL — is the better choice.
Chapter 11 — Batch and Iteration showed two loop primitives: foreach
(iterate over a collection with one subgraph execution per item) and loop
(repeat with max_iterations, delay, and until). You learned how batch
results are collected and how loopIteration gives each pass a zero-based
counter.
Chapter 12 — Waiting for the World added suspension. With await a graph
pauses without keeping a worker thread blocked, and resumes only when an external signal arrives
or a timeout elapses. You practiced correlating events by key and branching on
whether the signal arrived or timed out.
Chapter 13 — Durable Execution added the stores and identities needed for restart recovery. Accepted checkpoints let an eligible worker skip completed nodes and continue the remaining frontier; effects outside a committed checkpoint still need idempotency or reconciliation.
What You Should Be Able to Do Now
- Extract a reusable pipeline into a named subgraph and embed it in multiple parent graphs.
- Process a collection with
foreachand a polling loop withloop, choosing the right primitive for each use case. - Suspend a graph with
await, correlate an external event, and handle timeout gracefully. - Wire durable stores into a
GraphEngineand demonstrate suspend → crash → cold-recovery → resume. - Explain the relationship between checkpoints, execution identity, and the graph registry.
Common Mistakes at This Stage
| Mistake | Why It Happens | Fix |
|---|---|---|
| Using parent scope when you mean isolated | "The subgraph needs one value from the parent" | Default to isolated scope and pass the needed value explicitly through the subgraph input binding. Parent scope leaks the entire context. |
Infinite loops without until or max_iterations | Forgetting that loop defaults to unbounded | Always set max_iterations as a safety net, even if until normally exits first. |
Treating await like Thread.sleep() | Confusing suspension with blocking | await leaves no worker thread blocked while waiting; the persisted wait, timer, and correlation state still consume system resources. |
| Skipping durable stores in development | "I'll add durability later" | Use in-memory store implementations to practice the API and recovery path, while remembering that their state is lost with the process. |
| Not testing the resume path | Only testing the happy path where nothing crashes | Write at least one test that executes halfway, creates a new engine, and resumes from checkpoint. |
Key Vocabulary Additions
| Term | Meaning |
|---|---|
| Subgraph | A pre-built Graph registered by name and embedded inside a parent graph as a single node. |
foreach | Iterates over a collection, executing the body once per item and collecting results. |
loop | Repeats the body up to max_iterations times, with optional delay and until exit condition. |
loopIteration | Built-in zero-based counter available inside every loop body. |
await | Suspends the graph and releases its thread until an external signal or timeout. |
| Checkpoint | A persisted snapshot of node outputs and execution state after each node completes. |
| Cold recovery | Resuming a graph on a different engine instance by loading its checkpoint from durable storage. |
Try It: Choose the Right Time Model
An order flow processes 200 items, polls inventory up to five times, and may
wait two days for customer confirmation. Assign foreach, loop, or
await to each part, then mark which state must survive process restart.
Explain why replacing await with a sleeping loop would hold the wrong
resource and hide the external signal boundary.
Where to Go Next
Arc 4 shifts from durable one-shot execution to longer-lived orchestration patterns: sessions, state machines, and nested lifecycle ownership. Start with Chapter 14 — Multi-Turn Sessions.