UNPKG

redis-smq

Version:

A simple high-performance Redis message queue for Node.js.

154 lines 6.16 kB
import { async, CallbackEmptyReplyError, } from 'redis-smq-common'; import { _deleteMessage } from '../../message/_/_delete-message.js'; import { _parseQueueExtendedParams } from '../../queue/_/_parse-queue-extended-params.js'; import { _validateQueueExtendedParams } from '../_/_validate-queue-extended-params.js'; export class QueueMessagesManagerAbstract { redisClient; message; requireGroupId = false; redisKey; messageStorage; constructor(redisClient, messagesStorage, message, redisKey) { this.redisClient = redisClient; this.messageStorage = messagesStorage; this.message = message; this.redisKey = redisKey; } getTotalPages(pageSize, totalItems) { if (pageSize <= 0) { return 1; } const totalPages = Math.ceil(totalItems / pageSize); return totalPages > 0 ? totalPages : 1; } getPaginationParams(cursor, totalItems, pageSize) { const totalPages = this.getTotalPages(pageSize, totalItems); const currentPage = cursor < 1 || cursor > totalPages ? 1 : cursor; const offsetStart = (currentPage - 1) * pageSize; const offsetEnd = offsetStart + pageSize - 1; return { offsetStart, offsetEnd, currentPage, totalPages }; } getMessagesIds(queue, page, pageSize, cb) { async.waterfall([ (next) => this.messageStorage.count(queue, this.redisKey, next), (totalItems, next) => { const { currentPage, offsetStart, offsetEnd, totalPages } = this.getPaginationParams(page, totalItems, pageSize); const nextCursor = currentPage < totalPages ? currentPage + 1 : 0; if (totalItems === 0) { return next(null, { cursor: nextCursor, totalItems, items: [], }); } this.messageStorage.fetchItems(queue, this.redisKey, offsetStart, offsetEnd, (err, items) => { if (err) return next(err); next(null, { cursor: nextCursor, totalItems, items: items ?? [], }); }); }, ], cb); } purge(queue, cb) { const parsedParams = _parseQueueExtendedParams(queue); if (parsedParams instanceof Error) return cb(parsedParams); this.redisClient.getSetInstance((err, client) => { if (err) return cb(err); if (!client) return cb(new CallbackEmptyReplyError()); _validateQueueExtendedParams(client, parsedParams, this.requireGroupId, (err) => { if (err) return cb(err); this._purgeMessages(client, parsedParams, cb); }); }); } _purgeMessages(client, parsedParams, cb) { const purgeBatch = (cursor = '0') => { async.waterfall([ (next) => { this.getMessagesIds(parsedParams, Number(cursor), 1000, next); }, (page, next) => { const { items, cursor: nextCursor } = page; if (items.length === 0) { return next(null, String(nextCursor)); } _deleteMessage(client, items, (err) => { if (err) return next(err); next(null, String(nextCursor)); }); }, ], (err, nextCursor) => { if (err) return cb(err); if (nextCursor !== '0') { purgeBatch(String(nextCursor)); } else { cb(); } }); }; purgeBatch('0'); } getMessages(queue, page, pageSize, cb) { const parsedParams = _parseQueueExtendedParams(queue); if (parsedParams instanceof Error) return cb(parsedParams); this.redisClient.getSetInstance((err, client) => { if (err) return cb(err); if (!client) return cb(new CallbackEmptyReplyError()); _validateQueueExtendedParams(client, parsedParams, this.requireGroupId, (err) => { if (err) return cb(err); this.getMessagesIds(parsedParams, page, pageSize, (err, pageResult) => { if (err) return cb(err); if (!pageResult) return cb(new CallbackEmptyReplyError()); if (pageResult.items.length === 0) { return cb(null, { ...pageResult, items: [] }); } this.message.getMessagesByIds(pageResult.items, (err, messages) => { if (err) return cb(err); cb(null, { ...pageResult, items: messages ?? [] }); }); }); }); }); } countMessages(queue, cb) { this.redisClient.getSetInstance((err, client) => { if (err) return cb(err); if (!client) return cb(new CallbackEmptyReplyError()); const parsedParams = _parseQueueExtendedParams(queue); if (parsedParams instanceof Error) return cb(parsedParams); _validateQueueExtendedParams(client, parsedParams, this.requireGroupId, (err) => { if (err) return cb(err); this.messageStorage.count(parsedParams, this.redisKey, cb); }); }); } shutdown(cb) { async.waterfall([ (next) => this.message.shutdown(next), (next) => this.redisClient.shutdown(next), ], cb); } } //# sourceMappingURL=queue-messages-manager-abstract.js.map