bunqueue v2.8.36
blog · release
bunqueue v2.8.36
Ships 16 additions. A fast-check asynchronous command model now generates lifecycle, batch, dependency, DLQ, limiter, queue-control, and actual SIGKILL/restart histories against a fresh TCP broker and SQLite database per run.
To install bunqueue v2.8.36
Section titled “To install bunqueue v2.8.36”bun add bunqueue@2.8.36npm install bunqueue@2.8.36To upgrade bunqueue
Section titled “To upgrade bunqueue”bun add bunqueue@latestWhat’s new
Section titled “What’s new”- A
fast-checkasynchronous command model now generates lifecycle, batch, dependency, DLQ, limiter, queue-control, and actualSIGKILL/restart histories against a fresh TCP broker and SQLite database per run. After every command it verifies API state, aggregate counts, lock tokens, MessagePack payloads, priority, physical rows, DLQ membership, and persisted queue controls. Failures shrink and replay by seed viabun run test:model. - The first campaign found and permanently covers two crash-durability bugs:
Updatechanged payload only in memory, andChangePriorityfailed to persist priority/LIFO ordering. Both mutations now flush a pending buffered insert before updating SQLite and survive restart. - Repeated crash recovery now persists each job’s cumulative
stallCountand the queue’s complete custom stall policy before classifying active work. Recovery, heartbeat stalls, and expired locks all enforce bothmaxAttemptsandmaxStalls; terminal recovery restores its DLQ row exactly once even across repeated restarts. - TTL expiry now deletes the persisted row and cancels any pending write-buffer
insert in the same logical transition that removes the job from its heap,
counters and indexes. Expired work cannot reappear through
GetStateor after restart. - Queue obliteration now removes dependency-gated jobs from
waitingDeps,waitingChildren, and the reverse dependency index, then uses the complete removed-ID set to purge global indexes and SQLite. Public embedded and TCP job counts now consistently expose thewaiting-childrenbucket, including zero after obliteration. - Manual and expiry-based DLQ purge now removes terminal jobs from
jobIndex, results, logs, buffered writes, and SQLite in one queue-scoped transactional cleanup. Repeated expiry cleanup is idempotent and cannot delete a newer live generation or another queue’s entry. - Reusing a terminal custom ID now retires its prior DLQ generation before
admitting the replacement. PUSH and PUSHB acquire the target and prior-owner
shards in deterministic order and revalidate after locking; live custom IDs
remain globally idempotent and the broker never exposes two generations with
the same
jobs.id. - Management commands that claim active work (
MoveToDelayed,MoveToWait,MoveToWaitingChildren, and activeDiscard) now release both the live lease and TCP-client ownership through one idempotent cleanup. No stale lock or client tracking remains after the job leavesactive. - The full sandbox gate exposed a tenth persistence-boundary defect after
adding durable stall counters: legacy/low-level jobs without
stallCountviolated the new SQLiteNOT NULLcolumn. Single, buffered, batch, retry, and decode paths now normalize an omitted value to zero while the schema remains strict. - The testing reference now tracks the complete 46-invariant production checklist across 15 categories and names whether each category is owned by the generated lifecycle model or a focused cron, flow, worker, protocol, or storage suite.
What’s new
Section titled “What’s new”- Rust and Elixir join TypeScript, Python, PHP, and Go as official protocol-v2 SDKs, each with Queue, Worker, FlowProducer, verified TLS, auth-first lazy reconnect, typed errors, JavaScript-safe MessagePack handling, structured telemetry, native regression coverage, and the shared 17-check conformance driver.
bun run test:sandbox:sdkbuilds six pinned toolchain images, validates package contents plus every native/conformance suite without runtime network access or host mounts, and writes complete logs, NDJSON resource samples, per-suite JSON, anomaly signals, and slow-test rankings.- The TypeScript, Python, PHP, and Go clients gained frame-boundary, serialization, timeout/reconnect, option-forwarding, worker-lease, TLS, and telemetry regressions. Invalid outgoing data now fails through each SDK’s typed error hierarchy before it can retain an in-flight slot or write a frame.
- Browser WebAssembly remains a documented future target because portable WASM has no raw-TCP API. A future browser bridge or capability-enabled WASI client must pass the same security, telemetry, and conformance contract before it is listed as official.
- All six native suites now include independent-connection idempotency and single-lease races, generated payload invariants, malformed-input fuzz corpora, bounded spike tests, and durable SIGKILL/restart recovery. Go also runs the race detector and a native fuzz target.
- Every SDK has an opt-in long-lived soak/stress profile. Weekly CI runs the profiles for 15 minutes, exercises the full runtime compatibility matrix, and checks package advisory databases; the authoritative local SDK gate remains deterministic, offline, and bounded.
Thanks to 1 contributor!
Section titled “Thanks to 1 contributor!”← bunqueue v2.8.35 · Release on GitHub · Commits since v2.8.35 · Full changelog · All posts