job package
Simple, safe-by-default Redis job queue for @imqueue services — delayed and scheduled jobs, at-least-once delivery, and re-scheduling driven by whatever the handler returns.
Pick one of three shapes. JobQueue, the default export, both pushes and handles jobs in one process. JobQueuePublisher only pushes and JobQueueWorker only handles, for the usual split where an API enqueues work that a pool of workers drains — those two must be constructed with the same JobQueueOptions.name, which is what makes them the same queue.
Remarks
Delivery is at-least-once, so handlers must be idempotent. Safe delivery is on by default here, which is the opposite of @imqueue/core's own default, and it covers the hand-off of a job to a worker rather than its processing — see JobQueueOptions.safe for what that does and does not guarantee. Two further core defaults are overridden: the key prefix is imq-job rather than imq, and the safe-delivery TTL is 10 seconds rather than 5.
Job data travels as JSON, so anything that does not survive JSON.stringify — class instances, Date, undefined properties, cycles — does not arrive as it left. Push a plain object and re-hydrate it in the handler.
Shutdown is worth knowing about before it matters in production. @imqueue/core installs process-wide SIGTERM, SIGINT and SIGABRT handlers by default; they release the queue's watcher locks and then exit the process without waiting for a running handler to return. So a job in flight when the signal arrives loses that attempt, and is re-delivered later only if safe delivery had the job checked out. Drain work yourself if a half-finished job would do damage.
Example
import JobQueue from '@imqueue/job';
interface Email { to: string; subject: string }
const queue = new JobQueue<Email>({ name: 'Email' });
queue.onPop(async (email: Email) => {
await send(email);
});
await queue.start();
// right away, and again in an hour
queue.push({ to: 'a@b.c', subject: 'Hi' });
queue.push({ to: 'a@b.c', subject: 'Later' }, { delay: 3600000 });
Classes
|
Class |
Description |
|---|---|
|
A job queue that both pushes and handles jobs in the same process — the default export, and the one to start with. Scheduling is per job and optional: push with no options to run as soon as a worker is free, with PushOptions.delay to run later, and with PushOptions.ttl to stop retrying after a while. Register the handler with JobQueue.onPop() before JobQueue.start() — this class insists on it, because a combined queue with no handler would enqueue work that nothing consumes. Split the two ends into JobQueuePublisher and JobQueueWorker when they belong in different processes, which is what scaling the workers out requires. | |
|
The producing end of a job queue: pushes jobs and never handles them. Use this in the process that creates work — an API, a scheduler, a webhook receiver — and pair it with a JobQueueWorker constructed with the same JobQueueOptions.name. It opens a publisher-mode connection only, so it cannot receive jobs even by accident. | |
|
The consuming end of a job queue: handles jobs and never pushes them. Use this in the processes that do the work, paired with a JobQueuePublisher constructed with the same JobQueueOptions.name. Run as many as you like — each job goes to one of them, which is how this scales out. It opens a worker-mode connection only, so it cannot enqueue jobs even by accident. |
Abstract Classes
|
Abstract Class |
Description |
|---|---|
|
Shared base of the three concrete queues, implementing everything that does not depend on which end of the queue you are. |
Interfaces
|
Interface |
Description |
|---|---|
|
What every queue in this package can do regardless of which end it is: report its name, expose its logger, and start, stop or tear down its broker connection.
| |
|
The producing half of a queue: something that can enqueue jobs.
| |
|
The consuming half of a queue: something that can be given a handler to run against each job.
| |
|
Everything a job queue needs to connect and behave, given to every constructor in this package. Only JobQueueOptions.name is required. The rest tune the broker connection, the delivery guarantee and logging, and each carries the default that applies when it is omitted. | |
|
What a worker does with each job, and how it asks for the job to come back. The handler's return value is the re-scheduling instruction, so the retry policy is written in the handler rather than configured on the queue. Pass one to JobQueueWorker.onPop() or JobQueue.onPop(). | |
|
Per-job scheduling options for JobQueuePublisher.push() and JobQueue.push() — when the job may first run, and how long it stays worth retrying. |
Read this page as plain markdown — no HTML, no navigation. For pasting into an LLM, or for an agent to fetch.