bunqueue v2.8.5
Fixes 4 bugs. the same custom jobId in two different queues sharing one database, or
To install bunqueue v2.8.5
Section titled “To install bunqueue v2.8.5”bun add bunqueue@2.8.5npm install bunqueue@2.8.5To upgrade bunqueue
Section titled “To upgrade bunqueue”bun add bunqueue@latestBugfixes
Section titled “Bugfixes”A duplicate jobs.id (the global PRIMARY KEY) poisoned the entire atomic write-buffer
flush: the failing batch rolled back as a whole, was retried, and after exhausting
retries every job in that flush window was dropped, including unrelated, valid jobs
that merely happened to be batched together. Silent, unrecoverable, and triggerable by a
single duplicated custom jobId. Two ways to hit it:
- the same custom
jobIdin two different queues sharing one database, or - reusing a custom
jobIdafter its job completed:markCompletedUPDATEs the row (it survives), so the reused, deterministic id collided with it.
Fixes:
- Per-row isolation on flush. When the fast atomic batch INSERT fails, the buffer now re-inserts row by row: valid jobs persist, a constraint violation (e.g. duplicate id) is isolated and dropped (it can never succeed, so it is no longer retried, which is what poisoned every subsequent flush), and genuinely transient failures (disk I/O, full) are retried exactly as before. The success path is unchanged (a single transaction).
- Completed-id reuse evicts the stale job. Re-adding a completed custom
jobIdnow evicts the old completed record (row, result, in-memory state) so the new job starts fresh aswaitinginstead of colliding (andgetJobStateno longer returnscompletedfor the brand-new job).
Note: when the same global jobs.id is genuinely duplicated across queues, the losing
duplicate is dropped from disk (it cannot be persisted twice), it still lives in memory
until restart. This is the correct trade-off and is strictly safer than the previous
behavior, which dropped the unrelated jobs instead.
Bugfixes
Section titled “Bugfixes”Optimization PRAGMAs (e.g. mmap_size, which calls fstat() on the fd) are applied with
error handling: a transient filesystem SQLITE_IOERR during a restart/cleanup race is now
caught and logged instead of propagating out of the SqliteStorage constructor (where, in
a deferred context, it surfaced as an “Unhandled error between tests” and tore down CI).
Thanks to 1 contributor!
Section titled “Thanks to 1 contributor!”← bunqueue v2.8.4 · Release on GitHub · Commits since v2.8.4 · Full changelog · All posts