redis-smq
Version:
A high-performance, reliable, and scalable message queue for Node.js.
176 lines • 8.2 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports._deleteMessage = _deleteMessage;
const redis_smq_common_1 = require("redis-smq-common");
const index_js_1 = require("../../queue-manager/index.js");
const redis_keys_js_1 = require("../../common/redis/redis-keys/redis-keys.js");
const scripts_js_1 = require("../../common/redis/scripts.js");
const index_js_2 = require("../../message/index.js");
const _get_message_js_1 = require("./_get-message.js");
const index_js_3 = require("../../errors/index.js");
function _deleteMessage(redisClient, messageId, lockId, cb) {
const deleteResponse = {
status: 'MESSAGE_NOT_DELETED',
stats: {
processed: 0,
success: 0,
notFound: 0,
inProcess: 0,
},
};
const ids = Array.isArray(messageId) ? messageId : [messageId];
if (!ids.length) {
deleteResponse.status = 'OK';
return cb(null, deleteResponse);
}
const stats = deleteResponse.stats;
const messages = [];
redis_smq_common_1.async.eachOf(ids, (id, _, done) => {
(0, _get_message_js_1._getMessage)(redisClient, id, (err, msg) => {
if (err) {
if (err instanceof index_js_3.MessageNotFoundError) {
stats.notFound += 1;
stats.processed += 1;
return done();
}
return done(err);
}
if (msg)
messages.push(msg);
done();
});
}, (err) => {
if (err)
return cb(err);
if (!messages.length) {
return cb(null, deleteResponse);
}
const messagesByQueueAndGroup = {};
messages.reduce((acc, msg) => {
var _a;
const queue = msg.getDestinationQueue();
const queueId = `${queue.ns}:${queue.name}`;
if (!acc[queueId]) {
acc[queueId] = {};
}
const consumerGroupId = (_a = msg.getConsumerGroupId()) !== null && _a !== void 0 ? _a : '_';
if (!acc[queueId][consumerGroupId]) {
acc[queueId][consumerGroupId] = {
queue,
messages: [],
};
}
acc[queueId][consumerGroupId].messages.push(msg);
return acc;
}, messagesByQueueAndGroup);
redis_smq_common_1.async.eachIn(messagesByQueueAndGroup, (groups, _, done) => {
redis_smq_common_1.async.eachIn(groups, (item, groupId, done) => {
const { queue, messages: batchMessages } = item;
const consumerGroupId = groupId === '_' ? null : groupId;
const { keyQueueProperties, keyQueuePublished, keyQueuePending, keyQueuePriority, keyQueueScheduled, keyQueueAcknowledged, keyQueueDeadLetter, keyQueueDelayed, keyQueueRequeued, } = redis_keys_js_1.redisKeys.getQueueKeys(queue.ns, queue.name, consumerGroupId);
const staticKeys = [
keyQueueProperties,
keyQueuePublished,
keyQueuePending,
keyQueuePriority,
keyQueueScheduled,
keyQueueAcknowledged,
keyQueueDeadLetter,
keyQueueDelayed,
keyQueueRequeued,
];
const staticArgs = [
index_js_1.EQueueProperty.QUEUE_TYPE,
index_js_1.EQueueProperty.MESSAGES_COUNT,
index_js_1.EQueueProperty.ACKNOWLEDGED_MESSAGES_COUNT,
index_js_1.EQueueProperty.DEAD_LETTERED_MESSAGES_COUNT,
index_js_1.EQueueProperty.PENDING_MESSAGES_COUNT,
index_js_1.EQueueProperty.SCHEDULED_MESSAGES_COUNT,
index_js_1.EQueueProperty.DELAYED_MESSAGES_COUNT,
index_js_1.EQueueProperty.REQUEUED_MESSAGES_COUNT,
index_js_1.EQueueType.PRIORITY_QUEUE,
index_js_1.EQueueType.LIFO_QUEUE,
index_js_1.EQueueType.FIFO_QUEUE,
index_js_2.EMessageProperty.STATUS,
index_js_2.EMessagePropertyStatus.PROCESSING,
index_js_2.EMessagePropertyStatus.ACKNOWLEDGED,
index_js_2.EMessagePropertyStatus.PENDING,
index_js_2.EMessagePropertyStatus.SCHEDULED,
index_js_2.EMessagePropertyStatus.DEAD_LETTERED,
index_js_2.EMessagePropertyStatus.UNACK_DELAYING,
index_js_2.EMessagePropertyStatus.UNACK_REQUEUING,
index_js_1.EQueueProperty.OPERATIONAL_STATE,
index_js_1.EQueueOperationalState.LOCKED,
index_js_1.EQueueProperty.LOCK_ID,
lockId !== null && lockId !== void 0 ? lockId : '',
];
const dynamicKeys = [];
for (const msg of batchMessages) {
const { keyMessage, keyMessageUnacknowledgementHistory } = redis_keys_js_1.redisKeys.getMessageKeys(msg.getId());
dynamicKeys.push(keyMessage, keyMessageUnacknowledgementHistory);
}
const dynamicArgs = batchMessages.map((msg) => msg.getId());
const keys = [...staticKeys, ...dynamicKeys];
const argv = [...staticArgs, ...dynamicArgs];
redisClient.runScript(scripts_js_1.ERedisScriptName.DELETE_MESSAGE, keys, argv, (err, reply) => {
if (err)
return done(err);
if (reply === 'QUEUE_LOCKED') {
return done(new index_js_3.QueueLockedError({
message: `Cannot delete messages from queue ${queue.name}: Queue is locked`,
metadata: {
queue: queue,
},
}));
}
if (reply === 'INVALID_LOCK') {
return done(new index_js_3.QueueLockedError({
message: `Cannot delete messages from queue ${queue.name}: Invalid lock ID provided`,
metadata: {
queue: queue,
},
}));
}
if (reply === 'QUEUE_NOT_FOUND') {
return done(new index_js_3.QueueNotFoundError({
metadata: {
queue,
},
}));
}
if (reply === 'INVALID_ARGS_ERROR') {
return done(new index_js_3.UnexpectedScriptReplyError({
message: 'Invalid arguments error in DELETE_MESSAGE script',
metadata: {
reply,
},
}));
}
if (!Array.isArray(reply) || reply.length !== 4) {
return done(new redis_smq_common_1.CallbackInvalidReplyError());
}
const [processed, success, notFound, inProcess] = reply;
stats.processed += processed;
stats.success += success;
stats.notFound += notFound;
stats.inProcess += inProcess;
done();
});
}, done);
}, (err) => {
if (err)
return cb(err);
if (stats.processed === stats.success && stats.processed > 0) {
deleteResponse.status = 'OK';
}
else if (stats.success > 0) {
deleteResponse.status = 'PARTIAL_SUCCESS';
}
else {
deleteResponse.status = 'MESSAGE_NOT_DELETED';
}
cb(null, deleteResponse);
});
});
}
//# sourceMappingURL=_delete-message.js.map