UNPKG

redis-smq

Version:

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

100 lines 4.8 kB
import { async, PanicError } from 'redis-smq-common'; import { ELuaScriptName } from '../../../common/redis-client/scripts/scripts.js'; import { redisKeys } from '../../../common/redis-keys/redis-keys.js'; import { _fromMessage } from '../../message/_/_from-message.js'; import { _getMessages } from '../../message/_/_get-message.js'; import { EMessageProperty, EMessagePropertyStatus, } from '../../message/index.js'; import { EQueueProperty, EQueueType } from '../../queue/index.js'; import { Worker } from './worker.js'; class PublishScheduledWorker extends Worker { work = (cb) => { async.waterfall([this.fetchMessageIds, this.fetchMessages, this.enqueueMessages], cb); }; fetchMessageIds = (cb) => { const redisClient = this.redisClient.getInstance(); if (redisClient instanceof Error) { cb(redisClient); return void 0; } const { keyQueueScheduled } = redisKeys.getQueueKeys(this.queueParsedParams.queueParams, this.queueParsedParams.groupId); redisClient.zrangebyscore(keyQueueScheduled, 0, Date.now(), 0, 9, cb); }; fetchMessages = (ids, cb) => { const redisClient = this.redisClient.getInstance(); if (redisClient instanceof Error) { cb(redisClient); return void 0; } if (ids.length) _getMessages(redisClient, ids, cb); else cb(null, []); }; enqueueMessages = (messages, cb) => { if (messages.length) { const keys = []; const argv = [ EMessageProperty.STATUS, EMessagePropertyStatus.PENDING, EMessageProperty.STATE, EQueueProperty.QUEUE_TYPE, EQueueType.PRIORITY_QUEUE, EQueueType.LIFO_QUEUE, EQueueType.FIFO_QUEUE, EQueueProperty.MESSAGES_COUNT, EMessageProperty.MESSAGE, ]; async.each(messages, (msg, _, done) => { const ts = Date.now(); const messagePriority = msg.producibleMessage.getPriority() ?? ''; const { keyMessage: keyScheduledMessage } = redisKeys.getMessageKeys(msg.getId()); const nextScheduleTimestamp = msg.getNextScheduledTimestamp(); const scheduledMessageState = msg.getMessageState(); const { keyQueueProperties, keyQueuePending, keyQueuePriorityPending, keyQueueScheduled, keyQueueMessages, } = redisKeys.getQueueKeys(msg.getDestinationQueue(), msg.getConsumerGroupId()); let newMessage = null; let newMessageState = null; let newMessageId = ''; let newKeyMessage = ''; if (nextScheduleTimestamp) { newMessage = _fromMessage(msg, null, null); newMessage.producibleMessage.resetScheduledParams(); newMessageState = newMessage .getMessageState() .setPublishedAt(ts) .setScheduledMessageId(msg.getId()); newMessageId = newMessageState.getId(); newKeyMessage = redisKeys.getMessageKeys(newMessageId).keyMessage; scheduledMessageState.setLastScheduledAt(ts); } else { scheduledMessageState.setPublishedAt(ts); } keys.push(newKeyMessage, keyQueuePending, keyQueueMessages, keyQueueProperties, keyQueuePriorityPending, keyQueueScheduled, keyScheduledMessage); argv.push(newMessageId, newMessage ? JSON.stringify(newMessage) : '', newMessageState ? JSON.stringify(newMessageState) : '', messagePriority, msg.getId(), nextScheduleTimestamp, JSON.stringify(scheduledMessageState)); done(); }, (err) => { if (err) cb(err); else { const redisClient = this.redisClient.getInstance(); if (redisClient instanceof Error) { cb(redisClient); return void 0; } redisClient.runScript(ELuaScriptName.PUBLISH_SCHEDULED_MESSAGE, keys, argv, (err, reply) => { if (err) cb(err); else if (reply !== 'OK') cb(new PanicError(String(reply))); else cb(); }); } }); } else cb(); }; } export default (payload) => new PublishScheduledWorker(payload); //# sourceMappingURL=publish-scheduled.worker.js.map