@lexamica-modules/job-queue
Version:
The package for the Lexamica Job Queue SDK powered by Redis and BullMQ
149 lines (137 loc) • 3.93 kB
text/typescript
import { Queue, QueueOptions } from "bullmq";
import { Redis } from "ioredis";
import { handleErrorWithInfo } from "../util/errors";
import { QUEUES_INIT } from "../util/config";
import { SHARED_QUEUES } from "../util/constants";
/**
* Message Queue Management Class
*/
export class Queues {
// connection to the redis cloud
private _connection: Redis;
/**
* Initialize a Queues instance with the Redis connection to use
* @param {Redis} connection the Redis connection to use
*/
constructor(connection: Redis) {
this._connection = connection;
}
/**
* Create a new queue
* @param {string} queue_name the name to give the queue instance
* @param {QueueOptions} options additional options to give the queue
* @returns {Queue<unknown, unknown, string> | void}
*/
create = (
queue_name: string,
options: QueueOptions = {},
): Queue<unknown, unknown, string> | void => {
try {
const queue = new Queue(queue_name, {
connection: this._connection,
...options,
});
return queue;
} catch (error) {
handleErrorWithInfo({
message: `Failed to create a new queue named: ${queue_name}`,
job: "Create Queue",
error: error as Error,
});
return;
}
};
/**
* Drain a queue instance of all pending jobs
* @param {Queue} queue The queue instance to drain
* @returns {Promise<boolean>}
*/
drain = async (queue: Queue): Promise<boolean> => {
if (!queue) {
handleErrorWithInfo({
message: `Queue: ${queue} has not been created and registered`,
job: "Drain Queue",
error: new Error("Queue does not exist"),
});
return false;
}
if (SHARED_QUEUES.includes(queue.name)) {
throw new Error(
`Cannot drain shared queues. Queue: ${queue.name} cannot be drained`,
);
}
try {
await queue.drain();
return true;
} catch (error) {
handleErrorWithInfo({
message: `Queue: ${queue.name} failed to be drained`,
job: "Drain Queue",
error: error as Error,
});
return false;
}
};
/**
* Pause job execution on a queue. Jobs can be added but will not be processed until queue is unpaused
* @param {Queue} queue The queue instance to pause
* @returns {Promise<boolean>} Boolean indication if queue was paused
*/
pause = async (queue: Queue): Promise<boolean> => {
try {
await queue.pause();
return true;
} catch (error) {
handleErrorWithInfo({
message: `Queue: ${queue.name} failed to be paused`,
job: "Pause Queue",
error: error as Error,
});
return false;
}
};
/**
* Continue job execution on a queue that is paused.
* @param queue The queue instance to unpause.
* @returns {Promise<boolean>} Boolean indication if queue was unpaused
*/
resume = async (queue: Queue): Promise<boolean> => {
try {
if (await queue.isPaused()) {
await queue.resume();
return true;
}
return false;
} catch (error) {
handleErrorWithInfo({
message: `Queue: ${queue.name} failed to be resumed`,
job: "Resume Queue",
error: error as Error,
});
return false;
}
};
/**
* Delete a queue from Redis.
* @param queue The queue instance to delete
* @returns {Promise<boolean>}
*/
delete = async (queue: Queue): Promise<boolean> => {
if (QUEUES_INIT[queue.name]) {
throw new Error(
`Cannot obliterate non-custom queues from this function. Queue: ${queue.name} is a standard queue`,
);
}
try {
await queue.obliterate();
return true;
} catch (error) {
handleErrorWithInfo({
message: `Queue: ${queue.name} failed to be deleted`,
job: "Delete Queue",
error: error as Error,
});
return false;
}
};
}