redis-smq
Version:
A simple high-performance Redis message queue for Node.js.
125 lines • 4.67 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MultiplexedMessageHandlerRunner = void 0;
const message_handler_runner_1 = require("../message-handler-runner");
const redis_smq_common_1 = require("redis-smq-common");
const events_1 = require("../../../../common/events/events");
const multiplexed_message_handler_1 = require("./multiplexed-message-handler");
class MultiplexedMessageHandlerRunner extends message_handler_runner_1.MessageHandlerRunner {
constructor(consumer, logger) {
super(consumer, logger);
this.muxRedisClient = null;
this.index = 0;
this.activeMessageHandler = null;
this.multiplexingDelay = true;
this.ticker = new redis_smq_common_1.Ticker(() => this.dequeue());
}
nextTick() {
if (!this.ticker.isTicking()) {
this.activeMessageHandler = null;
this.ticker.nextTick();
}
}
registerMessageHandlerEvents(messageHandler) {
super.registerMessageHandlerEvents(messageHandler);
messageHandler.on(events_1.events.MESSAGE_NEXT, () => {
if (this.multiplexingDelay)
this.nextTick();
else
this.dequeue();
});
messageHandler.on(events_1.events.MESSAGE_RECEIVED, () => (this.multiplexingDelay = false));
}
getNextMessageHandler() {
if (this.index >= this.messageHandlerInstances.length) {
this.index = 0;
}
const messageHandler = this.messageHandlerInstances[this.index];
if (this.messageHandlerInstances.length > 1) {
this.index += 1;
}
return messageHandler;
}
dequeue() {
this.activeMessageHandler = this.getNextMessageHandler();
if (this.activeMessageHandler) {
this.multiplexingDelay = true;
this.activeMessageHandler.dequeue();
}
else {
this.nextTick();
}
}
createMessageHandlerInstance(redisClient, handlerParams) {
const sharedRedisClient = this.getSharedRedisClient();
const { queue, messageHandler } = handlerParams;
const instance = new multiplexed_message_handler_1.MultiplexedMessageHandler(this.consumer, queue, messageHandler, redisClient, sharedRedisClient, this.logger);
this.registerMessageHandlerEvents(instance);
this.messageHandlerInstances.push(instance);
this.logger.info(`Created a new instance (ID: ${instance.getId()}) for MessageHandler (${JSON.stringify(handlerParams)}).`);
return instance;
}
runMessageHandler(handlerParams, cb) {
const client = this.getMuxRedisClient();
const handler = this.createMessageHandlerInstance(client, handlerParams);
handler.run(cb);
}
getMuxRedisClient() {
if (!this.muxRedisClient) {
throw new redis_smq_common_1.errors.PanicError('Expected a non-empty value');
}
return this.muxRedisClient;
}
shutdownMessageHandler(messageHandler, cb) {
super.shutdownMessageHandler(messageHandler, () => {
if (messageHandler === this.activeMessageHandler) {
this.nextTick();
}
cb();
});
}
run(redisClient, cb) {
redis_smq_common_1.async.waterfall([
(cb) => {
const { redis } = this.config;
(0, redis_smq_common_1.createClientInstance)(redis, (err, client) => {
if (err)
cb(err);
else if (!client)
cb(new redis_smq_common_1.errors.EmptyCallbackReplyError());
else {
this.muxRedisClient = client;
cb();
}
});
},
(cb) => {
super.run(redisClient, cb);
},
], (err) => {
if (err)
cb(err);
else {
this.dequeue();
cb();
}
});
}
shutdown(cb) {
redis_smq_common_1.async.waterfall([
(cb) => {
this.ticker.once(events_1.events.DOWN, cb);
this.ticker.quit();
},
(cb) => super.shutdown(cb),
(cb) => {
if (this.muxRedisClient)
this.muxRedisClient.halt(cb);
else
cb();
},
], cb);
}
}
exports.MultiplexedMessageHandlerRunner = MultiplexedMessageHandlerRunner;
//# sourceMappingURL=multiplexed-message-handler-runner.js.map