Default Ecto-based work claims implementation. Works with any Ecto adapter.
Acquisition is race-free without row locks: every takeover is a single
conditional UPDATE ... WHERE <the state we read still holds> and we treat a
zero-row result as "someone else won" (:busy). A brand-new claim is an
INSERT whose unique dedupe_key index turns a concurrent first-acquire into
:busy rather than a duplicate. This preserves at-most-once across nodes on
READ COMMITTED (the Postgres/SQL Server default) — two nodes can never both
believe they hold the same lease.
A SQL Server adapter using UPDLOCK/READPAST hints is an optional
throughput optimization, not a correctness requirement.
The state column is an Ecto.Enum — all reads and writes use atoms
(:claimed, :done, :failed). An expired lease has no distinct state: it's
a :claimed row whose lease_until has elapsed, which the takeover path
steals in place.
Summary
Functions
Lists up to limit claims whose lease has elapsed (still :claimed, just
past lease_until). Read-only — it does not transition or re-acquire them;
a caller re-acquires each via acquire/2, whose takeover path steals the
expired :claimed row. Recovery uses optimistic acquire directly, so the
framework itself doesn't call this — it's here for external maintenance sweeps.
Functions
Lists up to limit claims whose lease has elapsed (still :claimed, just
past lease_until). Read-only — it does not transition or re-acquire them;
a caller re-acquires each via acquire/2, whose takeover path steals the
expired :claimed row. Recovery uses optimistic acquire directly, so the
framework itself doesn't call this — it's here for external maintenance sweeps.