UNPKG

torotask

Version:

Task queue processing in NodeJS based on BullMQ and Redis

123 lines 5.13 kB
import { Queue } from 'bullmq'; // Import JobsOptions import { TaskJob } from './job.js'; export class TaskQueue extends Queue { taskClient; logger; constructor(taskClient, name, options) { if (!taskClient) { throw new Error('ToroTask instance is required.'); } if (!name) { throw new Error('Queue name is required.'); } options = options || {}; options.prefix = options.prefix || taskClient.queuePrefix; options.connection = options.connection = taskClient.getQueueConnectionOptions(); // Use shared Redis instance for queue connection reusing if enabled const sharedQueueRedisInstance = taskClient.getSharedQueueRedisInstance(); if (sharedQueueRedisInstance) { options.connection = sharedQueueRedisInstance; } super(name, options); this.taskClient = taskClient; this.logger = options.logger || taskClient.logger.child({ taskQueue: name }); } /** * Override the Job class to use TaskJob * @returns {typeof Job} */ get Job() { return TaskJob; } get TaskJob() { return TaskJob; } /** * Get the Redis client instance used by the queue. * @returns The Redis client instance. */ async getRedisClient() { return this.client; } /** * Core logic to add a job to the queue. * Public method intended for use by subclasses or related classes (e.g., SubTask). */ async add(name, payload, options, state) { // Return specific TaskJob const data = { payload, state, }; const job = await super.add(name, data, options); // Cast options to JobsOptions // Cast the result from the base Job to the specific TaskJob return job; } /** * Core logic to add multiple jobs to the queue. * Public method intended for use by subclasses or related classes (e.g., SubTask). */ // Assuming BulkJob's options are compatible with BullMQ's BulkJobOptions async addBulk(jobs) { this.logger.debug(`Bulk adding jobs ${jobs.length} to queue [${this.name}]`); const bulkJobs = jobs.map((job) => { const data = { ...job.data, }; if (job.payload) data.payload = job.payload; if (job.state) data.state = job.state; return { name: job.name, opts: job.options, data: data, }; }); const result = await super.addBulk(bulkJobs); this.logger.debug(`${result.length} Jobs bulk added added to queue [${this.name}]`); return result; } /** * Core logic to add a job and wait for its completion. * Public method intended for use by subclasses or related classes. */ async _runJobAndWait(name, payload, options, state) { // Use specific JobReturn generic const waitLogger = this.logger.child({ jobName: name, action: 'runAndWait' }); waitLogger.debug({ payload, options }, 'Adding job and waiting for completion'); // Call the corrected _runJob const job = await this.add(name, payload, options, state); // Cast data if needed const jobLogger = this.logger.child({ jobId: job.id, jobName: name }); try { jobLogger.debug('Waiting for job completion...'); // Make sure queueEvents is accessible (might need to be passed or stored) // Assuming this.queueEvents exists similar to BaseQueue/WorkerQueue if (!this.queueEvents) { throw new Error('QueueEvents instance not available for waiting.'); } await job.waitUntilFinished(this.queueEvents); if (!job.id) { jobLogger.error('Job ID is missing after waiting. Cannot get result.'); throw new Error('Job ID is missing after waiting. Cannot get result.'); } jobLogger.debug('Refetching job after completion'); // Use the overridden this.Job getter which returns TaskJob const finishedJob = await this.Job.fromId(this, job.id); if (!finishedJob) { jobLogger.error('Failed to refetch job after completion.'); throw new Error(`Failed to refetch job ${job.id} after completion.`); } jobLogger.debug({ returnValue: finishedJob.returnvalue }, 'Job completed successfully'); return finishedJob.returnvalue; } catch (error) { jobLogger.error({ err: error instanceof Error ? error : new Error(String(error)) }, 'Job failed or could not be waited for'); throw error; } } // Add queueEvents property if it's needed by _runJobAndWait and not already present // You might need to initialize this in the constructor similar to WorkerQueue queueEvents; // Replace 'any' with the actual type, e.g., TaskQueueEvents } //# sourceMappingURL=queue.js.map