redis-smq
Version:
A simple high-performance Redis message queue for Node.js.
146 lines • 7.06 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.processingQueue = void 0;
const redis_smq_common_1 = require("redis-smq-common");
const scripts_js_1 = require("../../../../common/redis-client/scripts/scripts.js");
const redis_keys_js_1 = require("../../../../common/redis-keys/redis-keys.js");
const index_js_1 = require("../../../../config/index.js");
const _get_message_js_1 = require("../../../message/_/_get-message.js");
const index_js_2 = require("../../../message/index.js");
const consumer_queues_js_1 = require("../../consumer-queues.js");
const index_js_3 = require("../../errors/index.js");
const index_js_4 = require("./types/index.js");
function getMessageUnknowledgementAction(message, unacknowledgedReason) {
if (unacknowledgedReason === index_js_4.EMessageUnknowledgmentReason.TTL_EXPIRED ||
message.getSetExpired()) {
return {
action: index_js_4.EMessageUnknowledgmentAction.DEAD_LETTER,
deadLetterReason: index_js_4.EMessageUnknowledgmentDeadLetterReason.TTL_EXPIRED,
};
}
if (message.isPeriodic()) {
return {
action: index_js_4.EMessageUnknowledgmentAction.DEAD_LETTER,
deadLetterReason: index_js_4.EMessageUnknowledgmentDeadLetterReason.PERIODIC_MESSAGE,
};
}
if (message.hasRetryThresholdExceeded()) {
return {
action: index_js_4.EMessageUnknowledgmentAction.DEAD_LETTER,
deadLetterReason: index_js_4.EMessageUnknowledgmentDeadLetterReason.RETRY_THRESHOLD_EXCEEDED,
};
}
const delay = message.producibleMessage.getRetryDelay();
return delay
? { action: index_js_4.EMessageUnknowledgmentAction.DELAY }
: { action: index_js_4.EMessageUnknowledgmentAction.REQUEUE };
}
function unknowledgeProcessingQueueMessage(redisClient, consumerId, queue, unknowledgmentReason, keys, args, unacknowledgementStatus, done) {
args.push(JSON.stringify(queue), consumerId);
const { keyConsumerQueues } = redis_keys_js_1.redisKeys.getConsumerKeys(consumerId);
const { keyQueueProcessing } = redis_keys_js_1.redisKeys.getQueueConsumerKeys(queue, consumerId);
const { keyQueueDL, keyQueueProcessingQueues, keyQueueConsumers, keyQueueProperties, keyQueueDelayed, keyQueueRequeued, } = redis_keys_js_1.redisKeys.getQueueKeys(queue, null);
keys.push(keyQueueProcessing, keyQueueDelayed, keyQueueRequeued, keyQueueDL, keyQueueProcessingQueues, keyQueueConsumers, keyConsumerQueues, keyQueueProperties);
exports.processingQueue.fetchProcessingQueueMessage(redisClient, keyQueueProcessing, (err, message) => {
if (err)
return done(err);
if (!message) {
keys.push('');
args.push('', '', '', unknowledgmentReason, '');
return done();
}
const messageId = message.getId();
const { keyMessage } = redis_keys_js_1.redisKeys.getMessageKeys(messageId);
keys.push(keyMessage);
args.push(messageId);
const unknowledgementAction = getMessageUnknowledgementAction(message, unknowledgmentReason);
const { action } = unknowledgementAction;
const messageStatus = action === index_js_4.EMessageUnknowledgmentAction.DEAD_LETTER
? index_js_2.EMessagePropertyStatus.DEAD_LETTERED
: action === index_js_4.EMessageUnknowledgmentAction.REQUEUE
? index_js_2.EMessagePropertyStatus.UNACK_REQUEUING
: index_js_2.EMessagePropertyStatus.UNACK_DELAYING;
args.push(action, action === index_js_4.EMessageUnknowledgmentAction.DEAD_LETTER
? unknowledgementAction.deadLetterReason
: '', unknowledgmentReason, messageStatus);
unacknowledgementStatus[messageId] = unknowledgementAction;
done();
});
}
exports.processingQueue = {
unknowledgeMessage(redisClient, consumerId, queues, logger, unknowledgmentReason, cb) {
const { store, expire, queueSize } = index_js_1.Configuration.getSetConfig().messages.store.deadLettered;
const keys = [];
const args = [
index_js_4.EMessageUnknowledgmentAction.DELAY,
index_js_4.EMessageUnknowledgmentAction.REQUEUE,
index_js_4.EMessageUnknowledgmentAction.DEAD_LETTER,
Number(store),
expire,
queueSize * -1,
index_js_2.EMessageProperty.STATUS,
index_js_4.EMessageUnknowledgmentReason.OFFLINE_CONSUMER,
index_js_4.EMessageUnknowledgmentReason.OFFLINE_MESSAGE_HANDLER,
];
const messageHandlingStatus = {};
redis_smq_common_1.async.waterfall([
(next) => {
if (queues === null) {
consumer_queues_js_1.consumerQueues.getConsumerQueues(redisClient, consumerId, next);
}
else {
next(null, queues);
}
},
(queueParams, next) => {
if (!queueParams.length) {
return next();
}
redis_smq_common_1.async.eachOf(queueParams, (queue, _, done) => {
unknowledgeProcessingQueueMessage(redisClient, consumerId, queue, unknowledgmentReason, keys, args, messageHandlingStatus, done);
}, next);
},
], (err) => {
if (err) {
return cb(err);
}
if (!keys.length) {
return cb();
}
redisClient.runScript(scripts_js_1.ELuaScriptName.HANDLE_PROCESSING_QUEUE, keys, args, (err, reply) => {
if (err) {
return cb(err);
}
if (reply !== 'OK') {
return cb(new index_js_3.ConsumerError(reply ? String(reply) : undefined));
}
Object.keys(messageHandlingStatus).forEach((messageId) => {
const action = messageHandlingStatus[messageId].action ===
index_js_4.EMessageUnknowledgmentAction.DEAD_LETTER
? 'dead-lettered'
: 'unacknowledged';
logger.debug(`Message ID ${messageId} has been ${action}.`);
});
cb(null, messageHandlingStatus);
});
});
},
fetchProcessingQueueMessage(redisClient, keyQueueProcessing, cb) {
redisClient.lrange(keyQueueProcessing, 0, 0, (err, range) => {
if (err) {
return cb(err);
}
if (range && range.length) {
(0, _get_message_js_1._getMessage)(redisClient, range[0], cb);
}
else {
cb();
}
});
},
getQueueProcessingQueues(redisClient, queue, cb) {
const { keyQueueProcessingQueues } = redis_keys_js_1.redisKeys.getQueueKeys(queue, null);
redisClient.hgetall(keyQueueProcessingQueues, cb);
},
};
//# sourceMappingURL=processing-queue.js.map
;