import { type ConnectionOptions, type Processor, Queue, type QueueOptions, Worker, type WorkerOptions } from 'bullmq'; import { addLog } from '../system/log'; import { newQueueRedisConnection, newWorkerRedisConnection } from '../redis'; const defaultWorkerOpts: Omit = { removeOnComplete: { count: 0 // Delete jobs immediately on completion }, removeOnFail: { count: 0 // Delete jobs immediately on failure } }; export enum QueueNames { websiteSync = 'websiteSync' } export const queues = (() => { if (!global.queues) { global.queues = new Map(); } return global.queues; })(); export const workers = (() => { if (!global.workers) { global.workers = new Map(); } return global.workers; })(); export function getQueue( name: QueueNames, opts?: Omit ): Queue { // check if global.queues has the queue const queue = queues.get(name); if (queue) { return queue as Queue; } const newQueue = new Queue(name.toString(), { connection: newQueueRedisConnection(), ...opts }); // default error handler, to avoid unhandled exceptions newQueue.on('error', (error) => { addLog.error(`MQ Queue [${name}]: ${error.message}`, error); }); queues.set(name, newQueue); return newQueue; } export function getWorker( name: QueueNames, processor: Processor, opts?: Omit ): Worker { const worker = workers.get(name); if (worker) { return worker as Worker; } const newWorker = new Worker(name.toString(), processor, { connection: newWorkerRedisConnection(), ...defaultWorkerOpts, ...opts }); // default error handler, to avoid unhandled exceptions newWorker.on('error', (error) => { addLog.error(`MQ Worker [${name}]: ${error.message}`, error); }); newWorker.on('failed', (jobId, error) => { addLog.error(`MQ Worker [${name}]: ${error.message}`, error); }); workers.set(name, newWorker); return newWorker; } export * from 'bullmq';