UNPKG

adonisjs-jobs

Version:

Job processing for AdonisJS

91 lines (90 loc) 3.56 kB
import { Worker as BullWorker } from 'bullmq'; export class Worker { app; config; workers = []; constructor(app, config = { queues: [], concurrency: 1 }) { this.app = app; this.config = config; } async start() { const config = this.app.config.get('jobs', {}); const logger = await this.app.container.make('logger'); const jobs = await this.app.container.make('jobs.list'); const queues = this.config.queues && this.config.queues.length ? this.config.queues : [config.queue]; const workers = []; this.app.terminating(async () => { await Promise.allSettled(workers.map((worker) => worker.close())); }); for (const queueName of queues) { const worker = new BullWorker(queueName, async (job) => { const jobClass = jobs[job.name]; if (!jobClass) { logger.error(`Cannot find job ${job.name}`); } let instance; try { instance = await this.app.container.make(jobClass); } catch (error) { logger.error(`Cannot instantiate job ${job.name}`); return; } instance.job = job; instance.logger = logger; logger.info(`Job ${job.name} started`); let result = await instance.handle(job.data); logger.info(`Job ${job.name} finished`); return result; }, { ...(config.workerOptions || {}), connection: config.connection, concurrency: this.config.concurrency, }); worker.on('failed', async (job, error) => { logger.error(error.message, []); if (job && (job.attemptsMade === job.opts.attempts || job.finishedOn)) { const jobClass = jobs[job.name]; if (!jobClass) { logger.error(`Cannot find job ${job.name}`); } let instance; try { instance = await this.app.container.make(jobClass); } catch { logger.error(`Cannot instantiate job ${job.name}`); return; } instance.job = job; instance.logger = logger; await instance.failed?.(error); } }); worker.on('completed', async (job, result) => { if (!job) return; const jobClass = jobs[job.name]; if (!jobClass) { logger.error(`Cannot find job ${job.name}`); } let instance; try { instance = await this.app.container.make(jobClass); } catch { logger.error(`Cannot instantiate job ${job.name}`); return; } instance.job = job; instance.logger = logger; await instance.completed?.(job.data, result); }); this.workers.push(worker); } logger.info(`Processing jobs from the ${JSON.stringify(queues)} queues.`); } async stop() { await Promise.allSettled(this.workers.map((w) => w.close())); } }