Redis queue adapter implementation.
Uses Redis sorted sets (ZSET) for ready/processing/dead sets and hashes (HASH) for job payloads. Implements the claim-based reserve pattern to prevent double-dispatch.
Key structure per job name:
queue:<name>:ready- ZSET (score = availableAtMs, member = jobId)queue:<name>:processing- ZSET (score = reservedAtMs, member = jobId)queue:<name>:dead- ZSET (score = deadLetterAtMs, member = jobId)queue:<name>:jobs- HASH (field = jobId, value = JSON job)queue:<name>:dead:jobs- HASH (dead payloads; only when a TTL is configured)
Recurring jobs:
queue:recurring:due- ZSET (score = nextRunAtMs, member = recurringId)queue:recurring:jobs- HASH (field = recurringId, value = JSON recurring)
RedisQueue(options?: RedisQueueOptions)
depths: (name: string) => Promise<QueueDepths>
M70k (X8-4): counts this name's three states with one ZCARD each.
Absent on a client that does not expose zcard, which is why the member is
an assigned property rather than a declared method — the health indicator
must be able to tell "cannot report" from "nothing there". Absent again
after disconnect, for the same reason isHealthy is: the closure
captures the client it was installed for, so leaving it in place would
answer a depth read with that dead client's rejection instead of the
absence that says the adapter cannot count right now.
isHealthy: () => Promise<boolean>
M70c: present only when the client exposes ping(); its absence is
unknown reachability, not false (a minimal injected fake has not told
us the server is dead).
ack(name: string,id: string,_claimToken?: string): Promise<void>
Acknowledges a job as successfully processed.
advanceRecurring(id: string,nextRunAtMs: number): Promise<void>
Advances a recurring job's next run time.
connect(): Promise<void>
Connects the adapter to its backend.
deadLetter(name: string,id: string,nowMs: number,_claimToken?: string): Promise<void>
Moves a job to the dead letter queue.
disconnect(): Promise<void>
Disconnects the adapter.
enqueue<T>(job: StoredJob<T>): Promise<void>
Enqueues a job.
fetchRecurringDue(nowMs: number): Promise<readonly StoredRecurring[]>
Fetches recurring jobs that are due.
isReady(): boolean
Checks if the adapter is ready/connected.
requeue<T>(name: string,id: string,availableAtMs: number,attempts: number,_claimToken?: string): Promise<void>
Requeues a job with a new available timestamp.
reserve<T>(name: string,limit: number,nowMs: number): Promise<readonly StoredJob<T>[]>
Reserves up to limit jobs that are due (availableAtMs <= nowMs).
CLAIMS jobs: moves them from ready set to processing set. A reserved job is not returned by subsequent reserve calls.
storeRecurring(rec: StoredRecurring): Promise<void>
Stores a recurring job.