interface QueuePluginOptions

Options for configuring the queue plugin.

Properties

The adapter type to use (default 'memory').

optional
name: string

Instance name for multi-instance support.

optional
url: string

Connection URL (used when adapter is 'redis' or 'rabbitmq').

optional
client: IRedisQueueClient | IAmqpQueueConnection

Injected client (bypasses lazy import).

optional
defaultMaxAttempts: number

Default max attempts for jobs (default 3).

optional
pollIntervalMs: number

Poll interval for worker loop (default 1000ms).

optional
prefix: string

Queue name prefix for RabbitMQ adapter (default 'he.queue').

Since 0.3.0
optional
deadLetterTtlMs: number

How long a dead-lettered job's payload is retained, in milliseconds.

Omitted (the default) keeps today's behaviour: the payload is retained indefinitely "for debugging", so the jobs hash grows without bound for the lifetime of the deployment (X8-4). Applied only by the Redis adapter, and only when the injected client exposes expire.

Enforced PER PAYLOAD: each dead-letter sweeps the dead set — scored by dead-letter time — and deletes every entry older than this, so a queue that keeps failing still drops its oldest payloads. Setting it also relocates a dead job's payload from queue:<name>:jobs, which holds every queued job's payload for that name, into queue:<name>:dead:jobs.

The retention it delivers is a bound rather than a deadline: AT LEAST this long, and AT MOST this long past the LAST dead-letter on the queue — so a payload that dies just before a short burst can live for just under twice this value. The sweep runs only when a dead-letter arrives, and the key-level backstop beside it carries one deadline for a shared key, which must be the newest or it would take newer payloads with it. It errs late deliberately: dropping a payload early discards the debugging data this option exists to keep.

optional
sqs: import("../adapters/sqs-queue.ts").SqsQueueOptions

SQS-specific options (required when adapter is 'sqs').

Since 0.3.0
readonly
optional
processors: readonly QueueProcessorEntry[]

Processors registered declaratively, as an alternative to calling queue.process(name, processor, options) imperatively after start(). Each entry — instance or RegistryFactory — produces one process() call, so a processor can be declared where the plugin is composed instead of after the application has started.

Instance entries register during the plugin's register() phase, identical to the imperative timing. The one exception is an array that also carries a FACTORY: the whole array then registers in onInit, in DECLARED order, because process() is last-wins on a job name and registering instances first would let a leading factory beat a trailing instance. Factory entries are resolved in the onInit phase — the first at which the registry holds every capability — so a factory can build its processor from a resolved capability. A factory that throws rejects start() with an error naming QueuePlugin({ processors }) and the entry's index in THIS declared array, not its position among the factories.

Registering two entries under one job name keeps the service's existing last-wins behaviour: exactly what two imperative process() calls with the same name do — decided by DECLARED order, so a trailing entry beats a leading one whichever arm each uses.

Since 0.3.0
readonly
optional
behaviors: readonly (IIngressBehavior | RegistryFactory<IIngressBehavior>)[]

Ingress behaviours wrapped around every processor — the queue arm of the transport-neutral behaviour chain shared with the websocket, scheduler, and messaging plugins (IIngressBehavior in @setu-ts/common).

Each behaviour observes an IngressContext carrying kind: 'queue', the job name as name, the delivered IJob as payload, and attempt equal to IJob.attempts, and runs in declared order ahead of the processor. A behaviour that returns without calling next() short-circuits: the processor never sees the job and the job is acknowledged. A behaviour that throws follows the processor's own failure path — requeue with backoff, and ProcessOptions.onFailed plus the dead-letter on the final attempt. Every processor registration is wrapped, imperative process() calls included, so a mixed application cannot leave a handler unchained.

With no behaviours configured, dispatch is byte-identical to the pre-chain behaviour: the processor is handed the job directly, with no chain allocated.

When an entry is a FACTORY, dispatch is HELD until onInit has resolved the whole chain, so nothing reaches a handler through a partial one. That gate covers every registration — this plugin's declared entries and any a later plugin makes imperatively through the resolved capability — which is why no registration's timing has to change. It is released once and costs nothing thereafter.

Instance entries are handed to the service at register(); factory entries are resolved in the onInit phase and a throwing factory rejects start() naming QueuePlugin({ behaviors }) and the entry's index in THIS declared array.

Usage

import { type QueuePluginOptions } from "queue-plugin/src/index.ts";