redis-smq
Version:
A high-performance, reliable, and scalable message queue for Node.js.
187 lines • 8.62 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.QueueStateChangeHandler = void 0;
const index_js_1 = require("../../queue-manager/index.js");
const internal_event_bus_js_1 = require("../../event-bus/internal-event-bus.js");
class QueueStateChangeHandler {
constructor(messageHandlerRunner, logger) {
this.pausedQueues = new Map();
this.stoppedQueues = new Map();
this.lockedQueues = new Map();
this.onQueueStateChange = (queue, transition) => {
const queueKey = this.getQueueKey(queue);
const fromState = transition.from;
const toState = transition.to;
this.logger.info(`Queue state changed: ${queueKey} from ${fromState} to ${toState}`);
this.stoppedQueues.delete(queueKey);
this.pausedQueues.delete(queueKey);
this.lockedQueues.delete(queueKey);
switch (toState) {
case index_js_1.EQueueOperationalState.STOPPED:
this.stoppedQueues.set(queueKey, queue);
this.handleQueueStopped(queue);
break;
case index_js_1.EQueueOperationalState.PAUSED:
this.pausedQueues.set(queueKey, queue);
this.handleQueuePaused(queue);
break;
case index_js_1.EQueueOperationalState.LOCKED:
this.lockedQueues.set(queueKey, queue);
this.handleQueueLocked(queue);
break;
case index_js_1.EQueueOperationalState.ACTIVE:
this.handleQueueActive(queue);
break;
default:
this.logger.warn(`Unknown queue state: ${toState} for queue: ${queueKey}`);
}
};
this.shutdown = (cb) => {
this.internalEventBus.removeListener('queue.stateChanged', this.onQueueStateChange);
this.stoppedQueues.clear();
this.pausedQueues.clear();
this.lockedQueues.clear();
this.logger.debug('QueueStateChangeHandler destroyed');
cb();
};
this.messageHandlerRunner = messageHandlerRunner;
this.logger = logger.createLogger(this.constructor.name);
this.internalEventBus = internal_event_bus_js_1.InternalEventBus.getInstance();
this.internalEventBus.on('queue.stateChanged', this.onQueueStateChange);
this.logger.debug('QueueStateChangeHandler initialized');
}
handleQueueStopped(queue) {
this.logger.debug(`Handling STOPPED state for queue: ${queue.name}`);
const queueConfigs = this.getQueueConfigurationsForQueue(queue);
if (queueConfigs.length === 0) {
this.logger.debug(`No queue configurations found for queue: ${queue.name}`);
return;
}
this.stopAllQueueHandlers(queueConfigs, 'STOPPED');
}
handleQueuePaused(queue) {
this.logger.debug(`Handling PAUSED state for queue: ${queue.name}`);
const queueConfigs = this.getQueueConfigurationsForQueue(queue);
if (queueConfigs.length === 0) {
this.logger.debug(`No queue configurations found for queue: ${queue.name}`);
return;
}
this.stopAllQueueHandlers(queueConfigs, 'PAUSED');
}
handleQueueLocked(queue) {
this.logger.debug(`Handling LOCKED state for queue: ${queue.name}`);
const queueConfigs = this.getQueueConfigurationsForQueue(queue);
if (queueConfigs.length === 0) {
this.logger.debug(`No queue configurations found for queue: ${queue.name}`);
return;
}
this.stopAllQueueHandlers(queueConfigs, 'LOCKED');
}
handleQueueActive(queue) {
this.logger.debug(`Handling ACTIVE state for queue: ${queue.name}`);
const queueConfigs = this.getQueueConfigurationsForQueue(queue);
if (queueConfigs.length === 0) {
this.logger.debug(`No queue configurations found for queue: ${queue.name}`);
return;
}
this.startAllQueueHandlers(queueConfigs);
}
getQueueConfigurationsForQueue(queue) {
const allQueues = this.messageHandlerRunner.getQueues();
return allQueues.filter((q) => q.queueParams.ns === queue.ns && q.queueParams.name === queue.name);
}
stopAllQueueHandlers(queueConfigs, state) {
let stoppedCount = 0;
const totalCount = queueConfigs.length;
const checkCompletion = () => {
if (stoppedCount === totalCount) {
this.logger.debug(`All ${totalCount} handler(s) for queue ${queueConfigs[0].queueParams.name} have been ${state.toLowerCase()}`);
}
};
queueConfigs.forEach((queueParsed) => {
this.messageHandlerRunner.stopMessageHandler(queueParsed, (err, wasRunning) => {
if (err) {
this.logger.error(`Failed to ${state.toLowerCase()} message handler for queue ${queueParsed.queueParams.name} (group: ${queueParsed.groupId || 'default'}):`, err);
}
else {
if (wasRunning) {
this.logger.debug(`Message handler ${state.toLowerCase()} for queue: ${queueParsed.queueParams.name} (group: ${queueParsed.groupId || 'default'})`);
}
}
stoppedCount++;
checkCompletion();
});
});
}
startAllQueueHandlers(queueConfigs) {
let startedCount = 0;
const totalCount = queueConfigs.length;
const checkCompletion = () => {
if (startedCount === totalCount) {
this.logger.debug(`All ${totalCount} handler(s) for queue ${queueConfigs[0].queueParams.name} have been started (ACTIVE state)`);
}
};
queueConfigs.forEach((queueParsed) => {
if (this.messageHandlerRunner.isMessageHandlerRunning(queueParsed)) {
this.logger.debug(`Message handler already running for queue: ${queueParsed.queueParams.name} (group: ${queueParsed.groupId || 'default'})`);
startedCount++;
checkCompletion();
return;
}
const handlerConfig = this.messageHandlerRunner.getMessageHandler(queueParsed);
if (!handlerConfig) {
this.logger.debug(`No handler configuration found for queue: ${queueParsed.queueParams.name} (group: ${queueParsed.groupId || 'default'}), skipping`);
startedCount++;
checkCompletion();
return;
}
this.messageHandlerRunner.startMessageHandler(queueParsed, (err, wasStarted) => {
if (err) {
this.logger.error(`Failed to start message handler for queue ${queueParsed.queueParams.name} (group: ${queueParsed.groupId || 'default'}):`, err);
}
else {
if (wasStarted) {
this.logger.debug(`Message handler started for queue: ${queueParsed.queueParams.name} (group: ${queueParsed.groupId || 'default'})`);
}
}
startedCount++;
checkCompletion();
});
});
}
isQueueStopped(queueParams) {
const queueKey = this.getQueueKey(queueParams);
return this.stoppedQueues.has(queueKey);
}
isQueuePaused(queueParams) {
const queueKey = this.getQueueKey(queueParams);
return this.pausedQueues.has(queueKey);
}
isQueueLocked(queueParams) {
const queueKey = this.getQueueKey(queueParams);
return this.lockedQueues.has(queueKey);
}
isQueueActive(queueParams) {
const queueKey = this.getQueueKey(queueParams);
return (!this.stoppedQueues.has(queueKey) &&
!this.pausedQueues.has(queueKey) &&
!this.lockedQueues.has(queueKey));
}
getStoppedQueues() {
return Array.from(this.stoppedQueues.values());
}
getPausedQueues() {
return Array.from(this.pausedQueues.values());
}
getLockedQueues() {
return Array.from(this.lockedQueues.values());
}
getQueueKey(queueParams) {
if ('queueParams' in queueParams) {
return `${queueParams.queueParams.ns}:${queueParams.queueParams.name}`;
}
return `${queueParams.ns}:${queueParams.name}`;
}
}
exports.QueueStateChangeHandler = QueueStateChangeHandler;
//# sourceMappingURL=queue-state-change-handler.js.map