UNPKG

redis-smq

Version:

A simple high-performance Redis message queue for Node.js.

140 lines 5.49 kB
import { async, Runnable } from 'redis-smq-common'; import { ConsumerConsumeMessageHandlerAlreadyExistsError } from '../errors/index.js'; import { MessageHandler } from '../message-handler/message-handler/message-handler.js'; import { eventBusPublisher } from './event-bus-publisher.js'; export class MessageHandlerRunner extends Runnable { consumer; redisClient; logger; messageHandlerInstances = []; messageHandlers = []; eventBus; constructor(consumer, redisClient, logger, eventBus) { super(); this.consumer = consumer; this.redisClient = redisClient; this.logger = logger; this.eventBus = eventBus; if (this.eventBus) { eventBusPublisher(this, this.eventBus, logger); } } getLogger() { return this.logger; } getMessageHandlerInstance(queue) { const { queueParams, groupId } = queue; return this.messageHandlerInstances.find((i) => { const handlerQueue = i.getQueue(); return (handlerQueue.queueParams.name === queueParams.name && handlerQueue.queueParams.ns === queueParams.ns && handlerQueue.groupId === groupId); }); } getMessageHandler(queue) { const { queueParams, groupId } = queue; return this.messageHandlers.find((i) => i.queue.queueParams.name === queueParams.name && i.queue.queueParams.ns === queueParams.ns && i.queue.groupId === groupId); } createMessageHandlerInstance(handlerParams) { const instance = new MessageHandler(this.consumer, this.redisClient, this.logger, handlerParams, true, this.eventBus); instance.on('consumer.messageHandler.error', (err, consumerId, queue) => { this.removeMessageHandler(queue, () => { this.logger.error(err); }); }); 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 handler = this.createMessageHandlerInstance(handlerParams); handler.run((err) => { if (err) this.removeMessageHandler(handlerParams.queue, () => cb(err)); else { cb(); } }); } shutdownMessageHandler(messageHandler, cb) { const queue = messageHandler.getQueue(); messageHandler.shutdown(() => { this.messageHandlerInstances = this.messageHandlerInstances.filter((handler) => { const iQueue = handler.getQueue(); return !(iQueue.queueParams.name === queue.queueParams.name && iQueue.queueParams.ns === queue.queueParams.ns && iQueue.groupId === queue.groupId); }); cb(); }); } runMessageHandlers = (cb) => { async.each(this.messageHandlers, (handlerParams, _, done) => { this.runMessageHandler(handlerParams, done); }, cb); }; shutDownMessageHandlers = (cb) => { async.each(this.messageHandlerInstances, (handler, queue, done) => { this.shutdownMessageHandler(handler, () => done()); }, () => { this.messageHandlerInstances = []; cb(); }); }; goingUp() { return super.goingUp().concat([this.runMessageHandlers]); } goingDown() { return [this.shutDownMessageHandlers].concat(super.goingDown()); } handleError(err) { if (this.isRunning()) { this.emit('consumer.messageHandlerRunner.error', err, this.consumer.getId()); } super.handleError(err); } removeMessageHandler(queue, cb) { const { queueParams, groupId } = queue; const handler = this.getMessageHandler(queue); if (!handler) cb(); else { this.messageHandlers = this.messageHandlers.filter((handler) => { const handerQueue = handler.queue; return !(queueParams.name === handerQueue.queueParams.name && queueParams.ns === handerQueue.queueParams.ns && groupId === handerQueue.groupId); }); this.logger.info(`Message handler with parameters (${JSON.stringify(queue)}) has been removed.`); const handlerInstance = this.getMessageHandlerInstance(queue); if (handlerInstance) this.shutdownMessageHandler(handlerInstance, cb); else cb(); } } addMessageHandler(queue, messageHandler, cb) { const handler = this.getMessageHandler(queue); if (handler) cb(new ConsumerConsumeMessageHandlerAlreadyExistsError()); else { const handlerParams = { queue, messageHandler, }; this.messageHandlers.push(handlerParams); this.logger.info(`Message handler with parameters (${JSON.stringify(handlerParams)}) has been registered.`); if (this.isRunning()) { this.runMessageHandler(handlerParams, cb); } else cb(); } } getQueues() { return this.messageHandlers.map((i) => i.queue); } } //# sourceMappingURL=message-handler-runner.js.map