redis-smq
Version:
A simple high-performance Redis message queue for Node.js.
216 lines • 11.8 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.QueueConsumerGroupsCache = void 0;
const redis_smq_common_1 = require("redis-smq-common");
const index_js_1 = require("../../config/index.js");
const _get_consumer_groups_js_1 = require("../consumer-groups/_/_get-consumer-groups.js");
const _get_queue_properties_js_1 = require("../queue/_/_get-queue-properties.js");
const _get_queues_js_1 = require("../queue/_/_get-queues.js");
const index_js_2 = require("../queue/index.js");
class QueueConsumerGroupsCache extends redis_smq_common_1.Runnable {
constructor(producer, redisClient, eventBus) {
super();
this.consumerGroupsByQueues = {};
this.addConsumerGroup = (queue, groupId) => {
const queueKey = `${queue.name}@${queue.ns}`;
this.logger.debug(`Adding consumer group ${groupId} to queue ${queueKey}`);
this.consumerGroupsByQueues[queueKey] =
this.consumerGroupsByQueues[queueKey] || [];
const group = this.consumerGroupsByQueues[queueKey];
if (!group.includes(groupId)) {
this.logger.debug(`Consumer group ${groupId} not found in queue ${queueKey}, adding it`);
group.push(groupId);
}
else {
this.logger.debug(`Consumer group ${groupId} already exists in queue ${queueKey}, skipping`);
}
};
this.deleteConsumerGroup = (queue, groupId) => {
const queueKey = `${queue.name}@${queue.ns}`;
this.logger.debug(`Deleting consumer group ${groupId} from queue ${queueKey}`);
const groups = this.consumerGroupsByQueues[queueKey];
if (groups && groups.includes(groupId)) {
this.logger.debug(`Found consumer group ${groupId} in queue ${queueKey}, removing it`);
this.consumerGroupsByQueues[queueKey] = groups.filter((i) => i !== groupId);
this.logger.debug(`Queue ${queueKey} now has ${this.consumerGroupsByQueues[queueKey].length} consumer groups`);
}
else {
this.logger.debug(`Consumer group ${groupId} not found in queue ${queueKey}, nothing to delete`);
}
};
this.addQueue = (queue, properties) => {
const queueKey = `${queue.name}@${queue.ns}`;
this.logger.debug(`Adding queue ${queueKey} with delivery model ${index_js_2.EQueueDeliveryModel[properties.deliveryModel]}`);
if (properties.deliveryModel === index_js_2.EQueueDeliveryModel.PUB_SUB) {
this.logger.debug(`Queue ${queueKey} is PUB_SUB, initializing empty consumer groups array`);
this.consumerGroupsByQueues[queueKey] = [];
}
else {
this.logger.debug(`Queue ${queueKey} is not PUB_SUB, skipping consumer groups initialization`);
}
};
this.deleteQueue = (queue) => {
const queueKey = `${queue.name}@${queue.ns}`;
this.logger.debug(`Deleting queue ${queueKey} from consumer groups cache`);
if (this.consumerGroupsByQueues[queueKey]) {
this.logger.debug(`Found queue ${queueKey} in cache, removing it`);
delete this.consumerGroupsByQueues[queueKey];
}
else {
this.logger.debug(`Queue ${queueKey} not found in cache, nothing to delete`);
}
};
this.subscribe = (cb) => {
this.logger.debug('Subscribing to queue events');
const instance = this.eventBus.getInstance();
if (instance instanceof Error) {
this.logger.error('Failed to get event bus instance', instance);
cb(instance);
}
else {
this.logger.debug('Successfully got event bus instance, registering event handlers');
instance.on('queue.queueCreated', this.addQueue);
instance.on('queue.queueDeleted', this.deleteQueue);
instance.on('queue.consumerGroupCreated', this.addConsumerGroup);
instance.on('queue.consumerGroupDeleted', this.deleteConsumerGroup);
this.logger.info('Successfully subscribed to all queue events');
cb();
}
};
this.unsubscribe = (cb) => {
this.logger.debug('Unsubscribing from queue events');
const instance = this.eventBus.getInstance();
if (instance instanceof Error) {
this.logger.error('Failed to get event bus instance', instance);
cb(instance);
}
else {
this.logger.debug('Successfully got event bus instance, removing event handlers');
instance.removeListener('queue.queueCreated', this.addQueue);
instance.removeListener('queue.queueDeleted', this.deleteQueue);
instance.removeListener('queue.consumerGroupCreated', this.addConsumerGroup);
instance.removeListener('queue.consumerGroupDeleted', this.deleteConsumerGroup);
this.logger.info('Successfully unsubscribed from all queue events');
cb();
}
};
this.loadConsumerGroups = (cb) => {
this.logger.debug('Loading consumer groups for all queues');
const redisClient = this.redisClient.getInstance();
if (redisClient instanceof Error) {
this.logger.error('Failed to get Redis client instance', redisClient);
cb(redisClient);
}
else {
this.logger.debug('Successfully got Redis client instance, fetching queues');
redis_smq_common_1.async.waterfall([
(cb) => {
this.logger.debug('Getting all queues');
(0, _get_queues_js_1._getQueues)(redisClient, cb);
},
(queues, cb) => {
this.logger.info(`Found ${queues.length} queues, processing each queue`);
redis_smq_common_1.async.eachOf(queues, (queue, index, done) => {
const queueKey = `${queue.name}@${queue.ns}`;
this.logger.debug(`Processing queue ${queueKey} (${index + 1}/${queues.length})`);
redis_smq_common_1.async.waterfall([
(cb) => {
this.logger.debug(`Getting properties for queue ${queueKey}`);
(0, _get_queue_properties_js_1._getQueueProperties)(redisClient, queue, cb);
},
(properties, cb) => {
this.logger.debug(`Queue ${queueKey} has delivery model ${index_js_2.EQueueDeliveryModel[properties.deliveryModel]}`);
if (properties.deliveryModel === index_js_2.EQueueDeliveryModel.PUB_SUB) {
this.logger.debug(`Queue ${queueKey} is PUB_SUB, getting consumer groups`);
(0, _get_consumer_groups_js_1._getConsumerGroups)(redisClient, queue, (err, reply) => {
if (err) {
this.logger.error(`Failed to get consumer groups for queue ${queueKey}`, err);
cb(err);
}
else {
const groupCount = (reply === null || reply === void 0 ? void 0 : reply.length) || 0;
this.logger.debug(`Found ${groupCount} consumer groups for queue ${queueKey}`);
this.consumerGroupsByQueues[queueKey] = reply !== null && reply !== void 0 ? reply : [];
cb();
}
});
}
else {
this.logger.debug(`Queue ${queueKey} is not PUB_SUB, skipping consumer groups`);
cb();
}
},
], (err) => {
if (err) {
this.logger.error(`Error processing queue ${queueKey}`, err);
}
else {
this.logger.debug(`Successfully processed queue ${queueKey}`);
}
done(err);
});
}, (err) => {
if (err) {
this.logger.error('Failed to process all queues', err);
}
else {
this.logger.info('Successfully loaded consumer groups for all queues');
}
cb(err);
});
},
], (err) => {
if (err) {
this.logger.error('Failed to load consumer groups', err);
}
else {
this.logger.info('Consumer groups cache initialized successfully');
}
cb(err);
});
}
};
this.cleanUpConsumerGroups = (cb) => {
this.logger.debug('Cleaning up consumer groups cache');
const groupCount = Object.keys(this.consumerGroupsByQueues).length;
this.consumerGroupsByQueues = {};
this.logger.info(`Cleared ${groupCount} entries from consumer groups cache`);
cb();
};
this.redisClient = redisClient;
this.eventBus = eventBus;
this.producerId = producer.getId();
this.logger = redis_smq_common_1.logger.getLogger(index_js_1.Configuration.getSetConfig().logger, this.constructor.name.toLowerCase());
this.logger.debug(`QueueConsumerGroupsCache instance created for producer ${this.producerId}`);
}
getLogger() {
return this.logger;
}
goingUp() {
this.logger.debug('QueueConsumerGroupsCache is going up');
return super.goingUp().concat([this.subscribe, this.loadConsumerGroups]);
}
goingDown() {
this.logger.debug('QueueConsumerGroupsCache is going down');
return [this.unsubscribe, this.cleanUpConsumerGroups].concat(super.goingDown());
}
getConsumerGroups(queue) {
const key = `${queue.name}@${queue.ns}`;
this.logger.debug(`Getting consumer groups for queue ${key}`);
if (this.consumerGroupsByQueues[key]) {
const groupCount = this.consumerGroupsByQueues[key].length;
this.logger.debug(`Found queue ${key} in cache with ${groupCount} consumer groups`);
return {
exists: true,
consumerGroups: this.consumerGroupsByQueues[key],
};
}
this.logger.debug(`Queue ${key} not found in cache, returning empty result`);
return {
exists: false,
consumerGroups: [],
};
}
}
exports.QueueConsumerGroupsCache = QueueConsumerGroupsCache;
//# sourceMappingURL=queue-consumer-groups-cache.js.map