CHANGELOG
Changelog
All notable changes to MongoDB::Queue are documented here.
The format follows Keep a Changelog and the project uses Semantic Versioning.
[0.1.1] ā 2026-03-22
Changed
Added mandatory
typeparameter toenqueue,dequeue,enqueue-many,dequeue-many,size,in-flight,failed,total, andstatsā every queue instance now supports multiple job types on a single collection.listengains:typenamed parameter (replaces hard-coded default).Indexes updated to include
typefield in both compound index keys.Updated both test suites (
t/01-basic.rakutest,t/02-battle.rakutest) to pass thetypeargument throughout.
[0.1.0] ā 2026-03-21
Added
Core queue operations
enqueue(Hash $payload, :$priority, :$delay, :$max-attempts)ā insert a job; returns its_idstring.dequeue(:$worker-id)ā atomically claim the next visible, highest-priority job; returns the full job document orNilwhen the queue is empty.ack(Str $id)ā mark a jobdoneafter successful processing.nack(Str $id, :$delay)ā return a job to the queue for retry; ifmax_attemptsis exhausted the job is automatically moved tofailed.fail(Str $id)ā permanently fail a job, bypassing remaining attempts.
Job scheduling
Priority delivery: higher
priorityvalue is always dequeued first.Delayed delivery:
:delay(N)hides a job for N seconds before it becomes visible.Configurable
max-attemptsper job or as a queue-wide default.
Maintenance
reclaim-stale(:$older-than)ā re-queue (or fail)processingjobs whoselocked_atis older than the threshold; used to recover from crashed workers. Called automatically bylisteneveryreclaim-everyseconds.purge()ā delete alldoneandfaileddocuments.clear()ā delete every document regardless of status (testing/reset).drop()ā drop the entire collection.ensure-indexes()ā create the two compound indexes needed for efficient operation; idempotent and called automatically on construction.
Metrics
size()ā count ofpendingjobs.in-flight()ā count ofprocessingjobs.failed()ā count offailedjobs.total()ā count of all jobs in the collection.stats()ā snapshotHashwithpending,processing,failed,total.
Event loop
listen(&callback, :$worker-id, :$poll-interval, :$reclaim-every)ā blocking loop that dequeues jobs and calls&callback; acks on success, nacks on exception, sleepspoll-intervalseconds when the queue is empty.
Factory constructor
MongoDB::Queue.connect(:$host, :$port, :$username, :$password, :$db, :$collection, *%args)ā creates aMongoDB::Fastclient and returns a ready-to-use queue in one call.
Job document schema
| Field | Type | Notes |
|---|---|---|
_id | Str | 32-char random hex |
payload | Hash | arbitrary application data |
status | Str | pending | processing | done | failed |
priority | Int | higher = dequeued first (default 0) |
available_at | Int | epoch seconds; gates delayed delivery |
created_at | Int | epoch seconds |
locked_at | Int | epoch seconds when claimed (Any if pending) |
locked_by | Str | worker identifier (Any if pending) |
attempts | Int | incremented on every dequeue |
max_attempts | Int | permanent failure threshold |
done_at | Int | epoch seconds when acked/failed (Any if not) |
Implementation notes
Atomic dequeue uses an optimistic-lock pattern: a small batch of candidates is retrieved sorted by
priority DESC, then each is claimed withupdate-onethat rechecksstatus = 'pending'ā only one worker wins per document, eliminating duplicate delivery under concurrent load.The sort uses a single-key
{ priority => -1 }specification to avoid Raku's unorderedHashserialisation producing a wrong MongoDB sort order when multiple sort keys are present (a limitation ofMongoDB::Fast's BSON encoder'sCMD-KEYWORDSordering heuristic).available_atis enforced exclusively through the query filter, not the sort.Indexes are created with
tryso that conflicting index names left over from previous runs are silently ignored rather than crashing startup.
Test suite
t/01-basic.tā 10 subtests covering the fundamental enqueue ā dequeue ā ack/nack/fail lifecycle, priority ordering, delayed delivery, stale reclaim, stats, and purge.t/02-battle.tā 27 subtests covering payload edge cases (empty, nested, unicode, arrays, 50 KB blobs, integers/booleans), idempotency guards, priority correctness, timing-based delay and nack-with-delay, full retry exhaustion, stale reclaim of multiple workers (including exhausted-attempts auto-fail), concurrent producers (8 Ć 10 = 80 jobs, no lost inserts), concurrent consumers (6 workers, zero duplicate deliveries), stats consistency, cross-instance sharing of the same collection, throughput smoke test, and purge/clear semantics.