Skip to main content

Queue

Depending on the framework, creating a queue works a bit different. Take a look at the sidebar to find a guide for your framework.

.enqueue

async enqueue(
payload: T,
options: {
id?: string;
override?: boolean;

runAt?: Date;
delay?: number | string;
repeat?: {
every?: number | string;
times?: number;
cron?: string | [schedule: string, timezone: string];
}
retry?: (number | string)[];

exclusive?: boolean;
}
): Promise<Job<T>>

Enqueues a new Job and returns it.

Schedule for a specified date

birthdayQueue.enqueue(user.id, {
runAt: user.birthday,
});

Delay by a week

welcomeUserQueue.enqueue(user.id, {
delay: "7d", // same as 7 * 24 * 60 * 60 * 1000
});

Repeated job

todoReminders.enqueue(todo.id, {
runAt: todo.scheduled_date,
id: todo.id,
repeat: {
every: "1d",
times: 3,
},
});

Runs three times: At scheduled_date, one day later and two days later.

CRON Schedule

Cron Jobs

This example is about regular Jobs, executed on a cron schedule. If you're looking for Cron Jobs, take a look at the more idiomatic CronJob.

billingQueue.enqueue(undefined, {
id: "billing", // makes sure job isn't duplicated
override: true, // if another job with that ID already exists, override it
repeat: {
cron: ["* * * * 1 *", "Europe/Berlin"],
},
});

If no timezone is specified, it defaults to Etc/UTC.

Order Queue

orderQueue.enqueue(
{ ... },
{
id: "1234", // if two jobs share the same `runAt`, they're ordered by ID.
exclusive: true, // make sure only one job is executed at once
}
);

You can also specify { exclusive: true } as the third argument to the Queue constructor.

Retryable

apiIntegrationQueue.enqueue(
{ ... },
{
retry: ["10sec", "5min", "1h"]
}
);

Retries a jobs three times, until it successd: After 10 seconds, 5 minutes and 1 hour.

You can also specify { retry: [ ... ] } as the third argument to the Queue constructor.

Currently, there's a hard limit of 10 retry attempts.

.enqueueMany

async enqueueMany(
jobs: { payload: T; options?: EnqueueJobOpts }[]
): Promise<Job<T>[]>

Works just like .enqueue, but creates multiple jobs at once.

Currently, there's a hard limit of 1000 jobs to be created at once.

.get

*get(): AsyncIterator<Job<T>[]>

A generator function that can be used to iterate over pending jobs:

for await (const jobs of queue.get()) {
// do something
}

.getById

getById(id: string): Promise<Job<T> | null>

Returns a job's representation, if it exists.

.invoke

invoke(id: string): Promise<Job<T> | null>

Gets a job and invokes it, if it exists. Returns the job's representation.

.delete

delete(id: string): Promise<Job<T> | null>

Gets a job and deletes it, if it exists. Returns the job's representation.

Job

A representation of a pending job. Can be retrieved using Queue methods.

id

id: string;

The job's id. If not specified during .enqueue, it's a random UUID generated by Quirrel.

endpoint

endpoint: string;

The HTTP endpoint the job will be executed against. Is always the same.

body

body: T;

The job's payload.

runAt

runAt: Date;

The date the job is scheduled for.

count

count: number;

The repetition of this execution. Starts at 1, increments with each repetition / retry.

repeat

{
cron?: string;
times?: number;
every?: number;
count: number;
}

Repetition options of the job. count starts at 1 and is incremented with every execution.

exclusive

exclusive: boolean;

If a job is marked as exclusive, that means there won't be any other job executed at the same time. If applied to all jobs in a queue, that effectively guarantees serial execution.

.invoke

invoke(): Promise<boolean>

Invokes the job. Returns false if it's already been executed / deleted.

.delete

delete(): Promise<boolean>

Deletes the job. Returns false if it's already been deleted / executed.