UNPKG

redis-smq

Version:

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

124 lines 4.94 kB
import { async, Runnable, } from 'redis-smq-common'; import { _getConsumerGroups } from '../consumer-groups/_/_get-consumer-groups.js'; import { _getQueueProperties } from '../queue/_/_get-queue-properties.js'; import { _getQueues } from '../queue/_/_get-queues.js'; import { EQueueDeliveryModel, } from '../queue/index.js'; export class QueueConsumerGroupsCache extends Runnable { redisClient; eventBus; producerId; logger; consumerGroupsByQueues = {}; constructor(producer, redisClient, eventBus, logger) { super(); this.redisClient = redisClient; this.eventBus = eventBus; this.producerId = producer.getId(); this.logger = logger; } getLogger() { return this.logger; } goingUp() { return super.goingUp().concat([this.subscribe, this.loadConsumerGroups]); } goingDown() { return [this.unsubscribe, this.cleanUpConsumerGroups].concat(super.goingDown()); } addConsumerGroup = (queue, groupId) => { this.consumerGroupsByQueues[`${queue.name}@${queue.ns}`] = this.consumerGroupsByQueues[`${queue.name}@${queue.ns}`] || []; const group = this.consumerGroupsByQueues[`${queue.name}@${queue.ns}`]; if (!group.includes(groupId)) { group.push(groupId); } }; deleteConsumerGroup = (queue, groupId) => { const groups = this.consumerGroupsByQueues[`${queue.name}@${queue.ns}`]; if (groups && groups.includes(groupId)) { this.consumerGroupsByQueues[`${queue.name}@${queue.ns}`] = groups.filter((i) => i !== groupId); } }; addQueue = (queue, properties) => { if (properties.deliveryModel === EQueueDeliveryModel.PUB_SUB) { this.consumerGroupsByQueues[`${queue.name}@${queue.ns}`] = []; } }; deleteQueue = (queue) => { if (this.consumerGroupsByQueues[`${queue.name}@${queue.ns}`]) delete this.consumerGroupsByQueues[`${queue.name}@${queue.ns}`]; }; subscribe = (cb) => { const instance = this.eventBus.getInstance(); if (instance instanceof Error) cb(instance); else { instance.on('queue.queueCreated', this.addQueue); instance.on('queue.queueDeleted', this.deleteQueue); instance.on('queue.consumerGroupCreated', this.addConsumerGroup); instance.on('queue.consumerGroupDeleted', this.deleteConsumerGroup); cb(); } }; unsubscribe = (cb) => { const instance = this.eventBus.getInstance(); if (instance instanceof Error) cb(instance); else { instance.removeListener('queue.queueCreated', this.addQueue); instance.removeListener('queue.queueDeleted', this.deleteQueue); instance.removeListener('queue.consumerGroupCreated', this.addConsumerGroup); instance.removeListener('queue.consumerGroupDeleted', this.deleteConsumerGroup); cb(); } }; loadConsumerGroups = (cb) => { const redisClient = this.redisClient.getInstance(); if (redisClient instanceof Error) cb(redisClient); else { async.waterfall([ (cb) => _getQueues(redisClient, cb), (queues, cb) => { async.eachOf(queues, (queue, _, done) => { async.waterfall([ (cb) => _getQueueProperties(redisClient, queue, cb), (properties, cb) => { if (properties.deliveryModel === EQueueDeliveryModel.PUB_SUB) { _getConsumerGroups(redisClient, queue, (err, reply) => { if (err) cb(err); else { this.consumerGroupsByQueues[`${queue.name}@${queue.ns}`] = reply ?? []; cb(); } }); } else cb(); }, ], done); }, cb); }, ], cb); } }; cleanUpConsumerGroups = (cb) => { this.consumerGroupsByQueues = {}; cb(); }; getConsumerGroups(queue) { const key = `${queue.name}@${queue.ns}`; if (this.consumerGroupsByQueues[key]) { return { exists: true, consumerGroups: this.consumerGroupsByQueues[key], }; } return { exists: false, consumerGroups: [], }; } } //# sourceMappingURL=queue-consumer-groups-cache.js.map