redis-smq
Version:
A high-performance, reliable, and scalable message queue for Node.js.
94 lines • 4.11 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MultiplexedMessageHandlerRunner = void 0;
const redis_smq_common_1 = require("redis-smq-common");
const multiplexed_message_handler_js_1 = require("../message-handler/multiplexed-message-handler.js");
const message_handler_runner_js_1 = require("./message-handler-runner.js");
class MultiplexedMessageHandlerRunner extends message_handler_runner_js_1.MessageHandlerRunner {
constructor(consumerContext) {
super(consumerContext);
this.multiplexingTickIntervalMs = 1000;
this.index = 0;
this.activeMessageHandler = null;
this.scheduleNextTick = () => {
if (!this.isOperational())
return;
this.schedulerTimer.reset();
this.schedulerTimer.schedule(() => this.execNextMessageHandler(), this.multiplexingTickIntervalMs);
};
this.execNextMessageHandler = () => {
if (!this.isOperational())
return;
const totalHandlers = this.messageHandlerInstances.length;
if (totalHandlers === 0) {
this.scheduleNextTick();
return;
}
for (let i = 0; i < totalHandlers; i += 1) {
const handler = this.getNextMessageHandler();
if (handler && handler.isOperational() && handler.isUp()) {
const queue = handler.getQueue();
if (!this.isQueueActive(queue)) {
continue;
}
this.activeMessageHandler = handler;
this.activeMessageHandler.dequeue();
return;
}
}
this.activeMessageHandler = null;
this.scheduleNextTick();
};
this.schedulerTimer = new redis_smq_common_1.Timer(this.logger);
}
getNextMessageHandler() {
const count = this.messageHandlerInstances.length;
if (count === 0)
return null;
if (this.index >= count)
this.index = 0;
const handler = this.messageHandlerInstances[this.index];
this.index = (this.index + 1) % count;
return handler;
}
createMessageHandlerInstance(handlerParams) {
const instance = new multiplexed_message_handler_js_1.MultiplexedMessageHandler(this.consumerContext, handlerParams, this.scheduleNextTick);
instance.on('consumer.messageHandler.error', (err) => {
this.logger.error(`MultiplexedMessageHandler [${instance.getId()}] has experienced a runtime error: ${err.message}. Shutting down instance. The supervisor will attempt to restart it.`);
this.shutdownMessageHandler(instance, (err) => {
if (err) {
this.logger.error(`Failed to shutdown handler ${instance.getId()}: ${err.message}`);
}
});
});
this.messageHandlerInstances.push(instance);
this.logger.debug(`Created MultiplexedMessageHandler (ID: ${instance.getId()}) for queue: ${handlerParams.queue.queueParams.name}. Total: ${this.messageHandlerInstances.length}`);
return instance;
}
shutdownMessageHandler(messageHandler, cb) {
const wasActive = messageHandler === this.activeMessageHandler;
super.shutdownMessageHandler(messageHandler, () => {
if (wasActive) {
this.activeMessageHandler = null;
setTimeout(() => this.execNextMessageHandler(), 0);
}
cb();
});
}
goingUp() {
return super.goingUp().concat([
(cb) => this.schedulerTimer.run(cb),
(cb) => {
this.execNextMessageHandler();
cb();
},
]);
}
goingDown() {
return [
(cb) => this.schedulerTimer.shutdown(cb),
].concat(super.goingDown());
}
}
exports.MultiplexedMessageHandlerRunner = MultiplexedMessageHandlerRunner;
//# sourceMappingURL=multiplexed-message-handler-runner.js.map