Build a workflow engine (Temporal / Airflow / Cadence style) (13 scenes)
Scene 12 · Design canvas: choose the right engine
Match each workload to its model — code-as-workflow replay, a DAG scheduler, or a state machine — and defend every choice with the scene that taught the requirement.
Previously

You've earned every mechanism. The capstone isn't a new one — it's choosing the right tool. The same ORDER #1001 can be expressed as Temporal-style code, an Airflow DAG, or a Step Functions state machine. Each fits a different shape of workload, and seeing the 30-day wait and the cancel signal go awkward in a DAG is the cleanest proof of what durable execution is actually for.

Scene 12
Design canvas: choose the right engine
Diagram
Each workload card is matched to an orchestration MODEL. Code-as-workflow replay (durable execution — the model this course taught: you write normal-looking code and durability comes from event history plus deterministic replay) suits long-running, stateful, crash-surviving orchestration. A DAG scheduler (a batch/ETL orchestrator: a directed graph of short, stateless tasks with task-level retry and NO deterministic replay or long in-process wait) suits nightly pipelines. A state-machine workflow (a declarative, serverless model — the workflow is JSON, not code — so there's no determinism worry, at the cost of expressiveness and cloud lock-in) suits cloud-native approval flows. The verifier cites the scene behind every requirement: durable timers (scene 7) and signals (scene 8) are why the 30-day-wait + cancel order needs durable execution and is awkward as a DAG; the absence of any long wait or external input is why the nightly ETL refresh belongs on a DAG. Every knob label echoes a term you already earned.
DESIGN CANVAS — match each workload to its orchestration modelrequirement weight:long-running-statefulAOrder fulfillment (30-day wait + canc…✓ 30-day wait✓ signals○ batch-DAGRECOMMENDED MODELTemporalcode-as-workflow repl…durable timer + signal — fits replayscene 7 / 8BNightly warehouse ETL refresh○ 30-day wait○ signals✓ batch-DAGRECOMMENDED MODELAirflowDAG schedulershort stateless tasks, no waitDAG homeCMulti-month subscription billing✓ 30-day wait○ signals○ batch-DAGRECOMMENDED MODELTemporalcode-as-workflow repl…durable state, ContinueAsNewscene 11DServerless approval flow (AWS-native)○ 30-day wait○ signals○ batch-DAGRECOMMENDED MODELStep Functionsstate machinedeclarative JSON, no code to replaycloud-nativeORDER #1001 · Order fulfillment (30-day…the same order rendered three waysTemporalcode-as-workflow replayrecommendedChargeCardReserveShipEmail⏱ durable timer · 30 days✉ cancel signal · nativewait + cancel are first-class — fits cleanlyAirflowDAG schedulerChargeCardReserveShipEmail✕ sensor idles a worker 30d✕ no actor to signal cancelno deterministic replay · no long in-process waitStep Functionsstate machineChargeCardReserveShipEmail{ "States": { "ChargeCard": { "Next": … } } }declarative JSON · no code to replay · cloud-nativeblue = workflow code (replayed, deterministic) · red = activity (runs once, recorded)verifier cites the scene behind every requirement; the model that fits the shape wins.
DAG scheduler = a graph of short stateless tasks, no long wait — the nightly ETL's home
No new machinery this time — just the payoff. Watch a workload land on the canvas: a nightly data-warehouse refresh (Workload B). It's a directed graph of short, stateless tasks — extract, transform, load — with no long wait and nothing to react to mid-run. That shape has a name you already half-know: a **DAG scheduler** (think Airflow) — a batch/ETL orchestrator that runs a graph of short tasks with task-level retry, and notably has NO deterministic replay and no long in-process wait. The verifier flashes green: nothing here needs the durability you spent eleven scenes building, so the DAG is its home. Now the same ORDER #1001 you've followed all arc — charge, reserve, ship, email — rendered three ways at a glance. As **code-as-workflow replay** (Temporal-style: normal-looking code made durable by event history + deterministic replay) the 30-day wait and the cancel signal are first-class. As a **state-machine workflow** (Step Functions: the flow is declarative JSON, serverless, no code to replay) it's tidy but cloud-bound. Drop it on the DAG, though, and watch the 30-day wait and the cancel go visibly awkward — a sensor idling a worker for a month, a cancel with no running actor to message. That awkwardness IS the proof of what durable execution is for.
Implementation
chooseModel
maps a workload's shape to its orchestration model
1def chooseModel(w):
2 if w.needs_long_wait or w.needs_signals:
3 # durable timer + signal must survive crashes
4 return CODE_AS_WORKFLOW_REPLAY
5 if w.is_batch_dag:
6 # short stateless tasks, task-level retry
7 return DAG_SCHEDULER
8 return STATE_MACHINE # declarative, serverless
OrderWorkflow.run (code-as-workflow replay)
the 30-day wait + cancel are first-class durable events
1def run(order):
2 charge_card(order) # activity, runs once
3 reserve(order) # activity, runs once
4 # durable timer: dormant, survives crashes
5 fired = workflow.await(
6 timer = sleep(days=30),
7 signal = 'cancel',
8 )
9 if fired == 'cancel':
10 return compensate(order) # refund, release
11 ship(order); email(order)
nightly_etl_dag (DAG scheduler)
short stateless tasks, no long wait, no signal
1dag = DAG('nightly_etl', schedule='@daily')
2extract = task(extract, retries=3)
3transform = task(transform, retries=3)
4load = task(load, retries=3)
5extract >> transform >> load # dependency edges
6# no durable timer, no in-process wait, no signal,
7# no deterministic replay — just retry a failed task
Not sure what to ask? Tap a question — the staff engineer answers in the chat panel.