UNPKG

redis-smq

Version:

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

203 lines 8.52 kB
import { async, CallbackEmptyReplyError, } from 'redis-smq-common'; import { redisKeys } from '../../common/redis/redis-keys/redis-keys.js'; import { _parseQueueExtendedParams } from '../../queue-manager/_/_parse-queue-extended-params.js'; import { _validateQueueExtendedParams } from './_/_validate-queue-extended-params.js'; import { withSharedPoolConnection } from '../../common/redis/redis-connection-pool/with-shared-pool-connection.js'; import { InvalidPurgeQueueJobIdError } from '../../errors/index.js'; import { PurgeQueueJobManager } from '../../common/background-jobs/jobs/purge-queue/purge-queue-job-manager.js'; import { EQueueOperation } from '../../queue-operation-validator/index.js'; import { _validateOperation } from '../../queue-operation-validator/_/_validate-operation.js'; import { _getMessageIds } from './_/_get-message-ids.js'; export class MessageBrowser { redisKey; logger; requireGroupId; messageManager; messageStorage; messageType; constructor(messageManager, messageStorage, messageType, redisKey, requireGroupId, logger) { this.messageManager = messageManager; this.messageStorage = messageStorage; this.messageType = messageType; this.logger = logger; this.redisKey = redisKey; this.requireGroupId = requireGroupId; } validatePurgeOperation(parsedParams, cb) { withSharedPoolConnection((client, done) => { _validateOperation(client, parsedParams.queueParams, EQueueOperation.PURGE, done); }, cb); } createPurgeJob(parsedParams, cb) { this.withPurgeQueueJobManager((purgeQueueJobManager, done) => { const target = { queue: parsedParams, messageType: this.messageType, }; purgeQueueJobManager.create(target, {}, (err, job) => { if (err) { this.logger.error(`Could not create purge job for queue ${parsedParams.queueParams.name}`, err); done(err); return; } done(null, job?.id); }); }, cb); } isJobForQueue(job, parsedParams) { return (job.payload.queue.queueParams.name === parsedParams.queueParams.name && job.payload.queue.queueParams.ns === parsedParams.queueParams.ns && job.payload.queue.groupId === parsedParams.groupId && job.payload.messageType === this.messageType); } withValidatedQueue(queue, operation, cb) { const parsedParams = _parseQueueExtendedParams(queue); if (parsedParams instanceof Error) { this.logger.error(`Error parsing queue parameters: ${parsedParams.message}`); cb(parsedParams); return; } withSharedPoolConnection((client, done) => { _validateQueueExtendedParams(client, parsedParams, this.requireGroupId, (err) => { if (err) { this.logger.error(`Error validating queue parameters: ${err.message}`); done(err); return; } operation(parsedParams, done); }); }, cb); } withPurgeQueueJobManager(operation, cb) { withSharedPoolConnection((client, done) => { async.waterfall([ (next) => { const purgeQueueJobManager = new PurgeQueueJobManager(client, this.logger); purgeQueueJobManager.initialize((err) => { if (err) { next(err); return; } next(null, purgeQueueJobManager); }); }, operation, ], done); }, cb); } purge(queue, cb) { this.logger.info(`Purging queue messages for queue ${JSON.stringify(queue)}`); this.withValidatedQueue(queue, (parsedParams, done) => { this.validatePurgeOperation(parsedParams, (err) => { if (err) { done(err); return; } this.createPurgeJob(parsedParams, done); }); }, cb); } getPurgeJob(queue, jobId, cb) { this.withValidatedQueue(queue, (parsedParams, done) => { this.withPurgeQueueJobManager((purgeQueueJobManager, innerDone) => { purgeQueueJobManager.get(jobId, (err, job) => { if (err) { innerDone(err); return; } if (!job) { innerDone(new CallbackEmptyReplyError()); return; } if (!this.isJobForQueue(job, parsedParams)) { innerDone(new InvalidPurgeQueueJobIdError({ metadata: { jobId }, })); return; } innerDone(null, job); }); }, done); }, cb); } getPurgeJobStatus(queue, jobId, cb) { this.getPurgeJob(queue, jobId, (err, job) => { if (err) { cb(err); return; } if (!job) { cb(new CallbackEmptyReplyError()); return; } cb(null, job.status); }); } cancelPurge(queue, jobId, cb) { this.withValidatedQueue(queue, (parsedParams, done) => { this.withPurgeQueueJobManager((purgeQueueJobManager, innerDone) => { purgeQueueJobManager.get(jobId, (err, job) => { if (err) { innerDone(err); return; } if (!job || !this.isJobForQueue(job, parsedParams)) { innerDone(new InvalidPurgeQueueJobIdError({ metadata: { jobId }, })); return; } purgeQueueJobManager.cancel(jobId, (err) => innerDone(err)); }); }, done); }, cb); } getMessages(queue, page, pageSize, cb) { this.withValidatedQueue(queue, (parsedParams, done) => { this.logger.debug(`Getting messages for ${parsedParams.queueParams.name}, page ${page}, size ${pageSize}`); async.waterfall([ (next) => { _getMessageIds(parsedParams, page, pageSize, this.redisKey, this.messageStorage, this.logger, next); }, (pageResult, next) => { if (pageResult.items.length === 0) { next(null, { ...pageResult, items: [] }); return; } this.messageManager.getMessagesByIds(pageResult.items, (err, messages) => { if (err) { next(err); return; } next(null, { ...pageResult, items: messages ?? [], }); }); }, ], done); }, cb); } countMessages(queue, cb) { this.withValidatedQueue(queue, (parsedParams, done) => { this.logger.debug(`Counting messages for ${parsedParams.queueParams.name}`); const keys = redisKeys.getQueueKeys(parsedParams.queueParams.ns, parsedParams.queueParams.name, parsedParams.groupId); const keyVal = keys[this.redisKey]; this.messageStorage.count(keyVal, (err, count) => { if (err) { this.logger.error(`Error counting messages: ${err.message}`); done(err); return; } this.logger.debug(`Queue ${parsedParams.queueParams.name} has ${count} messages`); done(null, count); }); }, cb); } getMessageIds(queue, page, pageSize, cb) { this.withValidatedQueue(queue, (parsedParams, done) => { _getMessageIds(parsedParams, page, pageSize, this.redisKey, this.messageStorage, this.logger, done); }, cb); } } //# sourceMappingURL=message-browser.js.map