redis-smq
Version:
A high-performance, reliable, and scalable message queue for Node.js.
128 lines • 5.63 kB
JavaScript
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