UNPKG

redis-smq

Version:

A high-performance, reliable, and scalable message queue for Node.js.

128 lines 5.63 kB
import { BackgroundJobManagerAbstract } from '../../../abstract/background-job/background-job-manager-abstract.js'; import { async } from 'redis-smq-common'; import { redisKeys } from '../../../redis/redis-keys/redis-keys.js'; import { EQueueStateLockOwner, ESystemStateTransitionReason, } from '../../../../queue-state-manager/index.js'; import { EBackgroundJobStatus } from '../../../index.js'; import { randomUUID } from 'node:crypto'; import { BackgroundJobNotFoundError } from '../../../../errors/index.js'; import { _lockQueuelock } from '../../../../queue-state-manager/_/_lock-queue.js'; import { _unlockQueue } from '../../../../queue-state-manager/_/_unlock-queue.js'; export class PurgeQueueJobManager extends BackgroundJobManagerAbstract { constructor(redisClient, logger) { const keys = redisKeys.getMainKeys(); super(redisClient, { keyBackgroundJobs: keys.keyPurgeJobs, keyBackgroundJobsPending: keys.keyPurgeJobsPending, keyBackgroundJobsProcessing: keys.keyPurgeJobsProcessing, }, logger); } create(payload, options = {}, cb) { const jobId = options.id || randomUUID(); async.waterfall([ (next) => { this.lockQueue(payload.queue.queueParams, jobId, next); }, (_, next) => { super.create(payload, { ...options, id: jobId }, (err, job) => { if (err) { _unlockQueue(payload.queue.queueParams, EQueueStateLockOwner.PURGE_JOB, jobId, { reason: ESystemStateTransitionReason.PURGE_QUEUE_FAIL, description: `Purge job failed`, metadata: { jobId }, }, this.logger, () => next(err)); } next(null, job); }); }, ], cb); } complete(jobId, options, cb) { async.waterfall([ (next) => super.complete(jobId, options, next), (job, next) => { _unlockQueue(job.payload.queue.queueParams, EQueueStateLockOwner.PURGE_JOB, jobId, { reason: ESystemStateTransitionReason.PURGE_QUEUE_COMPLETE, description: `Purge job complete`, metadata: { jobId }, }, this.logger, (unlockErr) => { if (unlockErr) { this.logger.error(`Job ${jobId} completed but failed to unlock queue: ${unlockErr.message}`); } next(null, job); }); }, ], cb); } fail(jobId, error, cb) { async.waterfall([ (next) => super.fail(jobId, error, next), (job, next) => { _unlockQueue(job.payload.queue.queueParams, EQueueStateLockOwner.PURGE_JOB, jobId, { reason: ESystemStateTransitionReason.PURGE_QUEUE_FAIL, description: `Purge job failed`, metadata: { jobId }, }, this.logger, (unlockErr) => { if (unlockErr) { this.logger.error(`Job ${jobId} failed but failed to unlock queue: ${unlockErr.message}`); } next(null, job); }); }, ], cb); } cancel(jobId, cb) { async.waterfall([ (next) => super.cancel(jobId, next), (job, next) => { _unlockQueue(job.payload.queue.queueParams, EQueueStateLockOwner.PURGE_JOB, jobId, { reason: ESystemStateTransitionReason.PURGE_QUEUE_CANCEL, description: `Purge job cancelled`, metadata: { jobId }, }, this.logger, (unlockErr) => { if (unlockErr) { this.logger.error(`Job ${jobId} cancelled but failed to unlock queue: ${unlockErr.message}`); } next(null, job); }); }, ], cb); } lockQueue(queueParams, jobId, cb) { _lockQueuelock(queueParams, EQueueStateLockOwner.PURGE_JOB, jobId, { reason: ESystemStateTransitionReason.PURGE_QUEUE_START, description: `Queue is being purged`, }, this.logger, (err) => cb(err)); } hasTerminationStatus(jobId, cb) { async.waterfall([ (next) => this.get(jobId, next), (job, next) => { const r = job.status === EBackgroundJobStatus.COMPLETED || job.status === EBackgroundJobStatus.FAILED || job.status === EBackgroundJobStatus.CANCELED; next(null, r); }, ], (err, result) => { if (err) { if (err instanceof BackgroundJobNotFoundError) { return cb(null, false); } } cb(err, result); }); } updateProgress(jobId, totalPurged, totalItems) { if (totalItems > 0 && totalPurged % Math.max(1, Math.floor(totalPurged / 10)) === 0) { this.update(jobId, { meta: { purged: totalPurged } }, (updateErr) => { if (updateErr) { this.logger.error(`Failed to update progress for job ${jobId}:`, updateErr); } else { this.logger.debug(`Job ${jobId}: Purged ${totalPurged} messages so far`); } }); } } } //# sourceMappingURL=purge-queue-job-manager.js.map