@lexamica-modules/job-queue
Version:
The package for the Lexamica Job Queue SDK powered by Redis and BullMQ
102 lines (90 loc) • 2.67 kB
text/typescript
import { Job, Worker } from "bullmq";
import {
JobExecuter,
WorkerCompleteHandler,
WorkerErrorHandler,
WorkerFailedHandler,
WorkerOptions,
} from "../types";
import { Redis } from "ioredis";
import { handleErrorWithInfo } from "../util/errors";
import { decryptPayload } from "../util/encryption";
/**
* Management class for all Workers
*/
export class Workers {
// connection to the redis cloud
private _connection: Redis;
/**
* Initialize an instance of the Worker Management Class
* @param {Redis} connection the Redis connection to use
*/
constructor(connection: Redis) {
this._connection = connection;
}
/**
* Add a worker to a given queue with an executer function
* @param {string} queue_name the name of the queue to add this worker to
* @param {JobExecuter} executer function to execute when processing jobs
* @returns {Worker}
*/
addWorker = (
queue_name: string,
executer: JobExecuter,
options: WorkerOptions,
onCompleted?: WorkerCompleteHandler,
onFailed?: WorkerFailedHandler,
onError?: WorkerErrorHandler,
): Worker => {
// configuration
const removeOnComplete = process.env.JOB_QUEUE_COMPLETIONS
? Number(process.env.JOB_QUEUE_COMPLETIONS)
: 5000;
const removeOnFailure = process.env.JOB_QUEUE_FAILURES
? Number(process.env.JOB_QUEUE_FAILURES)
: 5000;
// configure the handler with the decryption wrapper around the executer
const handler = async (job: Job) => {
// decrypt job data
const decryptedData = decryptPayload(job.data);
job.data = decryptedData;
await executer(job);
};
// create the worker
const worker = new Worker(queue_name, handler, {
connection: this._connection,
removeOnComplete: { count: removeOnComplete },
removeOnFail: { count: removeOnFailure },
...options,
});
// optional handlers
if (onCompleted) {
worker.on("completed", onCompleted);
}
if (onFailed) {
worker.on("failed", onFailed);
}
// safety handler
if (onError) {
worker.on("error", onError);
} else {
worker.on("error", (err) => {
handleErrorWithInfo({
message: `A worker experienced an unexpected error`,
job: "Unknown",
error: err,
});
});
}
// return the worker
return worker;
};
/**
* Finish the worker's current job and then pause it from processing more jobs.
* @param {Worker} worker the worker instance
* @returns {Promise<void>}
*/
closeWorker = async (worker: Worker): Promise<void> => {
return worker.close();
};
}