Skip to main content

Module attempt

Module attempt 

Source
Expand description

Attempt trait-method family — Postgres implementation.

RFC-v0.7 Wave 4b. Bodies for claim, claim_from_reclaim, renew, progress, complete, fail, delay, wait_children.

§Fence-triple invariants (RFC-003)

Every RMW against ff_attempt is wrapped in a BEGIN/COMMIT + a SELECT ... FOR UPDATE of the target attempt row. The claim cascade uses FOR UPDATE SKIP LOCKED on the exec_core + attempt join so two workers racing on the same lane cannot double-claim. Lease epoch is the authoritative fencing token: every terminal/progress/renew op first re-reads the attempt row under lock and compares lease_epoch against the handle’s embedded epoch. Mismatch → EngineError::Contention(LeaseConflict).

§Isolation level (Q11)

Default READ COMMITTED. The claim query uses SKIP LOCKED to keep the scanner contention-free; terminal ops use row-level FOR UPDATE on the already-identified attempt row. This is enough for the fence-triple invariant because the primary key on ff_attempt is (partition_key, execution_id, attempt_index) — the FOR UPDATE is partition-local and deterministic.

§Isolation note on capability matching

Capability subset-match runs in Rust after the FOR UPDATE SKIP LOCKED row is obtained. If the worker does not satisfy the row’s required_capabilities, we ROLLBACK (releasing the lock) and return Ok(None) so another worker with the right caps can pick the row up. We do NOT try to re-scan within the same claim call — that would blow the blocking-wait budget in a pathological mismatch loop; the caller’s retry cadence is the right scope.