UNPKG

redis-smq

Version:

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

140 lines 6.59 kB
import { async, CallbackEmptyReplyError, } from 'redis-smq-common'; import { ERedisScriptName } from '../../common/redis/scripts.js'; import { redisKeys } from '../../common/redis/redis-keys/redis-keys.js'; import { EQueueOperationalState, EQueueProperty, EQueueType, } from '../../queue-manager/index.js'; import { MessageNotFoundError, MessageNotRequeuableError, RequeueMessageScriptError, UnexpectedScriptReplyError, } from '../../errors/index.js'; import { _fromMessage } from './_from-message.js'; import { _getMessage } from './_get-message.js'; import { EMessageProperty, EMessagePropertyStatus, } from '../../message/index.js'; import { _validateOperation } from '../../queue-operation-validator/_/_validate-operation.js'; import { EQueueOperation } from '../../queue-operation-validator/index.js'; export function _requeueMessage(redisClient, messageId, cb) { async.waterfall([ (cb) => { _getMessage(redisClient, messageId, (err, message) => { if (err) return cb(err); if (!message) return cb(new CallbackEmptyReplyError()); if (![ EMessagePropertyStatus.ACKNOWLEDGED, EMessagePropertyStatus.DEAD_LETTERED, ].includes(message.getStatus())) { return cb(new MessageNotRequeuableError()); } cb(null, message); }); }, (message, cb) => { const queue = message.getDestinationQueue(); _validateOperation(redisClient, queue, EQueueOperation.REQUEUE_MESSAGE, (err) => { if (err) return cb(err); cb(null, message); }); }, (message, cb) => { const ts = Date.now(); const newMessage = _fromMessage(message); newMessage.producibleMessage.resetScheduledParams(); const newMessageState = newMessage .getMessageState() .setPublishedAt(ts) .setRequeuedMessageParentId(messageId); const { keyMessage: keyOriginalMessage } = redisKeys.getMessageKeys(messageId); const newChildMessageId = newMessageState.getId(); const { keyMessage: keyNewMessage } = redisKeys.getMessageKeys(newChildMessageId); const destinationQueue = message.getDestinationQueue(); const consumerGroupId = message.getConsumerGroupId(); const { keyQueueProperties, keyQueuePending, keyQueuePriority, keyQueuePublished, keyQueueScheduled, keyQueueConsumerGroups, } = redisKeys.getQueueKeys(destinationQueue.ns, destinationQueue.name, consumerGroupId); const keys = [ keyQueueProperties, keyQueuePriority, keyQueuePending, keyQueuePublished, keyQueueScheduled, keyQueueConsumerGroups, keyOriginalMessage, keyNewMessage, ]; const argv = [ EQueueProperty.QUEUE_TYPE, EQueueProperty.MESSAGES_COUNT, EQueueProperty.PENDING_MESSAGES_COUNT, EQueueProperty.SCHEDULED_MESSAGES_COUNT, EQueueType.PRIORITY_QUEUE, EQueueType.LIFO_QUEUE, EQueueType.FIFO_QUEUE, EQueueProperty.OPERATIONAL_STATE, EQueueProperty.LOCK_ID, EQueueOperationalState.ACTIVE, EQueueOperationalState.PAUSED, EQueueOperationalState.STOPPED, EQueueOperationalState.LOCKED, EMessagePropertyStatus.SCHEDULED, EMessagePropertyStatus.PENDING, EMessageProperty.ID, EMessageProperty.STATUS, EMessageProperty.MESSAGE, EMessageProperty.SCHEDULED_AT, EMessageProperty.PUBLISHED_AT, EMessageProperty.PROCESSING_STARTED_AT, EMessageProperty.DEAD_LETTERED_AT, EMessageProperty.ACKNOWLEDGED_AT, EMessageProperty.UNACKNOWLEDGED_AT, EMessageProperty.LAST_UNACKNOWLEDGED_AT, EMessageProperty.LAST_SCHEDULED_AT, EMessageProperty.REQUEUED_AT, EMessageProperty.REQUEUE_COUNT, EMessageProperty.LAST_REQUEUED_AT, EMessageProperty.LAST_RETRIED_ATTEMPT_AT, EMessageProperty.SCHEDULED_CRON_FIRED, EMessageProperty.ATTEMPTS, EMessageProperty.SCHEDULED_REPEAT_COUNT, EMessageProperty.EXPIRED, EMessageProperty.EFFECTIVE_SCHEDULED_DELAY, EMessageProperty.SCHEDULED_TIMES, EMessageProperty.SCHEDULED_MESSAGE_PARENT_ID, EMessageProperty.REQUEUED_MESSAGE_PARENT_ID, EMessageProperty.LAST_PROCESSED_AT, '', newChildMessageId, JSON.stringify(newMessage.toJSON()), message.producibleMessage.getPriority() ?? '', ts, message.getMessageState().getRequeuedAt() ?? ts, ts, consumerGroupId ?? '', ]; redisClient.runScript(ERedisScriptName.REQUEUE_MESSAGE, keys, argv, (err, reply) => { if (err) return cb(err); if (reply === 1) return cb(null, newChildMessageId); if (reply === 0) { return cb(new MessageNotFoundError({ message: `Could not requeue message ID ${messageId}. Message or consumer group not found.`, })); } if (typeof reply === 'string') { if (reply.startsWith('REQUEUE_ERROR:')) { return cb(new RequeueMessageScriptError({ metadata: { scriptReply: reply, }, })); } return cb(new RequeueMessageScriptError({ metadata: { scriptReply: reply, }, })); } cb(new UnexpectedScriptReplyError({ metadata: { reply }, })); }); }, ], cb); } //# sourceMappingURL=_requeue-message.js.map