Make run admission durable - #727
Conversation
- Reuse fabro_redact::redacted_url_for_log in safe_error_chain instead of
re-rolling the DisplaySafeUrl parse/redact fallback
- Reuse fabro_util::backoff::BackoffPolicy for admission retry delays
- Reuse projection_failure_message in worker-exit reconciliation
- Flatten AdmissionErrorClass into a { transient, kind } struct so the
class is matched once instead of twice
- Return the resulting RunStatus from persist_cancelled_run_status_to_store,
removing a redundant store read and the Result/Option reconciliation in
finish_cancelled_run_before_execution
- Capture spec, pending_control, and execution_mode at the admission claim
instead of re-reading the run projection up to two more times per
admission; drop the unreachable "managed run disappeared" prologues
- Dedup test fixtures (daemon record helper, RunStarting event counting)
- Cross-reference the server claim from execute_persisted_run's twin
bootstrap transition
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Ran a four-angle cleanup review (reuse, simplification, efficiency, altitude) over this PR and applied the fixes in 95d3216 and ea9ecde (net −50 lines). No behavior changes intended; all fabro-server, fabro-store, and fabro-workflow tests pass, clippy and rustfmt clean. AppliedReuse
Simplification
Efficiency — the biggest win: per admission, the run projection was materialized up to three times (each a SlateDB range scan plus a deep clone of the whole projection, spec included) — once in the Altitude
Flagged but not applied
🤖 Generated with Claude Code |
The server's admission-error classifier hand-mapped all 17 fabro_store::Error variants to transient/permanent plus a snake_case label — store-internals knowledge that would drift on every variant change. Replace it with Error::is_transient() next to the enum and a strum IntoStaticStr derive for the kind labels, and move the structural test to fabro-store where the wrapped error types are natural deps. The server keeps only its own policy: the non-store-error fallback and the retry schedule. This also drops the slatedb dev-dependency that existed solely so the server test could construct a store-internal error. Two log-only kind labels introduced on this branch change with the derive: "serialization" is now "serde" and "internal" is now "other". Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Closing as superseded by a smaller lifecycle correction. The underlying defect is that a worker launch can fail while the durable run is still Runnable, but that state currently permits failure only for cancellation. This implementation expanded into durable scheduler ownership and claim retry behavior that is unnecessary for the current single-server model. We will replace it with a focused change that makes the pre-launch failure transition valid while retaining the existing process-local double-start guard. |
Summary
Observable behavior
The run.starting event is now emitted at scheduler admission, so it can appear earlier than before. The event schema and API remain unchanged.
Testing