Expand description
Dependency-resolution reconciler (RFC-v0.7 Wave 6a).
Backstop for the per-hop-tx cascade implemented in
crate::dispatch::dispatch_completion (Wave 5a). The cascade
is deliberately NOT wrapped in a single transaction spanning
transitive descendants — a mid-cascade failure (crash, lock
timeout, SERIALIZABLE retry exhaustion) leaves downstream
ff_completion_event rows with dispatched_at_ms IS NULL. This
reconciler sweeps those rows on its interval and re-invokes
dispatch_completion, which is idempotent via the
UPDATE ... RETURNING claim on dispatched_at_ms.
§Transitive-descendant sweep (K-2 round-2)
The reconciler query covers the entire transitive descendant set of any interrupted cascade, not just 1-hop children of the original trigger. Proof by construction:
- Every
PolicyDecision::Satisfied/::Impossiblethat transitions a downstream tocompleted/skippedINSERTs a new row intoff_completion_eventinside the same per-hop tx ([crate::dispatch::advance_edge_group] line ~430). - If the per-hop tx for hop N commits but hop N+1 crashes, the
hop-N event lands durably with
dispatched_at_ms = NULL. - The reconciler finds that row via the partial index
ff_completion_event_pending_dispatch_idxand firesdispatch_completion(event_id), which kicks the cascade at hop N+1. - Hop N+1’s successful execution emits hop N+2’s event, and so
on — the reconciler’s next tick (or the in-process cascade
inside
dispatch_completionitself) carries the chain forward.
So a single crashed cascade of depth D eventually drains in at most D reconciler ticks regardless of where the interruption happened in the chain.
§Interval + threshold
stale_threshold_ms (default 1 000 ms) keeps the reconciler out
of the hot path: the normal in-process dispatcher flips
dispatched_at_ms within sub-millisecond of the commit that
inserted the row, so rows younger than the threshold are left
for the primary dispatcher.
Structs§
- Reconcile
Report - Per-tick work report. Returned so the driving scanner task can emit metrics + logs at cycle boundary without re-querying.
Constants§
- DEFAULT_
STALE_ THRESHOLD_ MS - Default minimum age of a
ff_completion_eventrow before the reconciler will claim it. Keeps this off the hot path — the primary dispatcher has this long to flipdispatched_at_msfrom NULL before the reconciler takes over.
Functions§
- reconcile_
tick - Run one reconciler tick. See module docs for semantics.