v0.4.0
·
14 commits
to master
since this release
Breaking change (minor): PgFetcher's phantom _marker field is no longer public — construct the marker fetcher via Default instead.
Fixed
- Decode-stranding: a claimed row whose payload failed to decode was stranded in
Runningfor as long as the claiming worker kept heartbeating (ack needs a decoded task; orphan recovery only reclaims rows of stale workers). The decode stage now releases such rows through the normal retry budget —Failedwith the decode error inlast_result, terminalKilledonce attempts are exhausted — guarded by the exact claim epoch (lock_by,lock_at,attempts) so a delayed release never touches a row that was acked, swept, or re-claimed in the meantime. - Concurrent
reenqueue_orphanedsweeps could double-apply to the same stale row under READ COMMITTED: burning an extra attempt, prematurely killing a job, or flipping an already-acked row back toPending. The sweep now repeats the status predicate on the outer UPDATE and claims candidates withFOR UPDATE OF jobs SKIP LOCKED. - The shared notify listener returned its pooled connection to r2d2 without
UNLISTEN, so the next pool user inherited the subscription and notifications accumulated unread in libpq's receive buffer. Every listener exit now removes the subscription first. Debugoutput ofPgAck(and the publicPgMiddleware) printed the per-processlease_tokenverbatim; it is now redacted.with_codecrebuilt the sink from scratch, silently dropping buffered tasks and any in-flight flush; both now carry over.- With both
tokioandntexfeatures enabled, calling the backend from the ntex executor panicked insidetokio::task::spawn_blocking; the backend now falls back to ntex's blocking pool when no Tokio runtime is present. - The checked-in Diesel schema was missing
workers.lease_token; new specs pinsrc/schema.rsagainstinformation_schemaso the next migration cannot leave the typed schema stale silently. - CI's postgres job ran only 3 of the 11 integration test binaries; it now runs
--tests, gating every current and future test binary.
Changed
- Pool-path enqueue batches without an
idempotency_keyskip the conflict-recovery machinery on the sink's hot flush path; the outbox path (push_with_conn/push_task_with_conn) keeps full SAVEPOINT semantics — a failing INSERT rolls back only the batch and never aborts the caller's outer transaction. - apalis RC dependencies are pinned exactly (
=…-rc.9) socargo updatecannot silently pull a breakingrc.10. - The
Sinkimpl onPostgresStorageno longer requiresArgs: Send + Sync + 'static.
Documentation
- The handler examples now run business transactions on a separate backend pool injected via
Data<PgPool>, matching the "Connection pool isolation" guidance they previously contradicted.
Full details: CHANGELOG.md