adonisjs-jobs
Version:
Job processing for AdonisJS
91 lines (90 loc) • 3.56 kB
JavaScript
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()));
}
}