ADR 006: Crash Recovery and Resume Semantics¶
Context¶
Long-running workflows (especially multi-step AI pipelines) can experience abrupt process termination (e.g. host reboot, SIGKILL, container eviction). The engine needs to resume execution without re-executing already completed work or leaving tasks stuck in transient states.
Decision¶
- Implement
resume_run(conn, run_id, task_runner, time_source, *, sleep=time.sleep): - If the run is already in a terminal status (
SUCCEEDEDorFAILED), return its status immediately without invoking the runner. - Reconstruct the
Workflowobject by deserializingdefinition_jsonstored in therunsrecord. - Restore each task's latest state,
attempt_count, andnext_retry_atby scanningtask_eventsfor the run. - For any task left in
RUNNINGstatus (the process died while running it), treat it as an interrupted attempt: settask.last_error = "interrupted: process exited while running"and invokefail_taskto transition it toRETRY_WAITorFAILEDaccording to its retry policy. - Resume the normal scheduling loop via
run_workflow. Tasks inSUCCEEDEDstatus are never re-executed.
Consequences¶
- Workflows are fully resilient against unexpected process crashes.
- Interrupted tasks respect their configured retry policies and failure tracking.