redis-smq
Version:
A simple high-performance Redis message queue for Node.js.
166 lines • 6.15 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MessageHandler = void 0;
const uuid_1 = require("uuid");
const events_1 = require("../../../common/events/events");
const events_2 = require("events");
const consumer_queues_1 = require("../consumer-queues");
const processing_queue_1 = require("./processing-queue");
const dequeue_message_1 = require("./dequeue-message");
const consume_message_1 = require("./consume-message");
const redis_smq_common_1 = require("redis-smq-common");
const retry_message_1 = require("./retry-message");
class MessageHandler extends events_2.EventEmitter {
constructor(consumer, queue, handler, dequeueRedisClient, sharedRedisClient, logger) {
super();
this.id = (0, uuid_1.v4)();
this.consumer = consumer;
this.consumerId = consumer.getId();
this.queue = queue;
this.dequeueRedisClient = dequeueRedisClient;
this.sharedRedisClient = sharedRedisClient;
this.handler = handler;
this.powerManager = new redis_smq_common_1.PowerManager();
this.logger = logger;
this.dequeueMessage = new dequeue_message_1.DequeueMessage(this, dequeueRedisClient);
this.consumeMessage = new consume_message_1.ConsumeMessage(this, dequeueRedisClient, logger);
this.registerEventsHandlers();
}
registerEventsHandlers() {
this.on(events_1.events.UP, () => {
this.logger.info('Up and running...');
this.dequeueMessage.dequeue();
});
this.on(events_1.events.MESSAGE_NEXT, () => {
if (this.powerManager.isRunning()) {
this.dequeueMessage.dequeue();
}
});
this.on(events_1.events.MESSAGE_ACKNOWLEDGED, (msg) => {
this.logger.info(`Message (ID ${msg.getRequiredId()}) acknowledged`);
this.emit(events_1.events.MESSAGE_NEXT);
});
this.on(events_1.events.MESSAGE_DEAD_LETTERED, (msg, cause) => {
this.logger.info(`Message (ID ${msg.getRequiredId()}) dead-lettered (cause ${cause})`);
});
this.on(events_1.events.MESSAGE_UNACKNOWLEDGED, (msg, cause) => {
this.emit(events_1.events.MESSAGE_NEXT);
this.logger.info(`Message (ID ${msg.getRequiredId()}) unacknowledged (cause ${cause})`);
});
this.on(events_1.events.MESSAGE_RECEIVED, (msg) => {
if (this.powerManager.isRunning()) {
this.logger.info(`Consuming message (ID ${msg.getRequiredId()}) with properties (${msg.toString()})`);
this.consumeMessage.handleReceivedMessage(msg);
}
});
this.on(events_1.events.DOWN, () => this.logger.info('Down.'));
}
cleanUp(cb) {
MessageHandler.cleanUp(this.getConfig(), this.sharedRedisClient, this.consumerId, this.queue, undefined, (err, reply) => {
if (err)
cb(err);
else if (reply) {
this.logger.debug(`Message ID ${reply.message.getId()} has been ${reply.status === retry_message_1.ERetryStatus.MESSAGE_DEAD_LETTERED
? 'dead-lettered'
: 'unacknowledged'}.`);
cb();
}
else
cb();
});
}
handleError(err) {
if (this.powerManager.isRunning() || this.powerManager.isGoingUp()) {
this.emit(events_1.events.ERROR, err);
}
}
dequeue() {
this.dequeueMessage.dequeue();
}
run(cb) {
this.powerManager.goingUp();
this.dequeueMessage.run((err) => {
if (err)
cb(err);
else {
this.powerManager.commit();
this.emit(events_1.events.UP);
cb();
}
});
}
shutdown(cb) {
const goDown = () => {
this.powerManager.goingDown();
redis_smq_common_1.async.waterfall([
(cb) => this.dequeueMessage.quit(cb),
(cb) => this.cleanUp(cb),
(cb) => this.dequeueRedisClient.halt(cb),
], (err) => {
if (err)
cb(err);
else {
this.powerManager.commit();
this.emit(events_1.events.DOWN);
cb();
}
});
};
if (this.powerManager.isGoingUp())
this.once(events_1.events.UP, goDown);
else
goDown();
}
getQueue() {
return this.queue;
}
getConsumerId() {
return this.consumerId;
}
getId() {
return this.id;
}
getConfig() {
return this.consumer.getConfig();
}
isRunning() {
return this.powerManager.isRunning();
}
getHandler() {
return this.handler;
}
static cleanUp(config, redisClient, consumerId, queue, pendingMulti, cb) {
const multi = pendingMulti !== null && pendingMulti !== void 0 ? pendingMulti : redisClient.multi();
let status = false;
redis_smq_common_1.async.waterfall([
(cb) => {
processing_queue_1.processingQueue.cleanUpProcessingQueue(config, redisClient, consumerId, queue, multi, (err, reply) => {
if (err)
cb(err);
else {
status = reply !== null && reply !== void 0 ? reply : false;
cb();
}
});
},
(cb) => {
consumer_queues_1.consumerQueues.removeConsumer(multi, queue, consumerId);
cb();
},
], (err) => {
if (err)
cb(err);
else if (pendingMulti)
cb(null, status);
else
multi.exec((err) => {
if (err)
cb(err);
else
cb(null, status);
});
});
}
}
exports.MessageHandler = MessageHandler;
//# sourceMappingURL=message-handler.js.map