redis-smq
Version:
A simple high-performance Redis message queue for Node.js.
124 lines • 4.94 kB
JavaScript
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