redis-smq
Version:
A high-performance, reliable, and scalable message queue for Node.js.
76 lines • 4.03 kB
JavaScript
import { CallbackEmptyReplyError } from 'redis-smq-common';
import { EQueueOperationalState, } from '../../queue-manager/index.js';
import { EQueueStateLockOwner, EStateTransitionReason, } from '../types/index.js';
import { withSharedPoolConnection } from '../../common/redis/redis-connection-pool/with-shared-pool-connection.js';
import { _parseQueueParamsAndValidate } from '../../queue-manager/_/_parse-queue-params-and-validate.js';
import { _getQueueState } from './_get-queue-state.js';
import { QueueLockOwnerMismatchError, QueueStateTransitionError, } from '../../errors/index.js';
import { _transitQueueTo } from './_transit-queue-to.js';
export function _unlockQueue(queue, lockOwner, lockId, options, logger, cb) {
const queueDesc = typeof queue === 'string' ? queue : `${queue.name}@${queue.ns}`;
logger.debug(`Unlocking queue: ${queueDesc} with lock ID: ${lockId}`);
withSharedPoolConnection((client, done) => {
_parseQueueParamsAndValidate(client, queue, (err, queueParams) => {
if (err)
return done(err);
if (!queueParams)
return done(new CallbackEmptyReplyError());
_getQueueState(client, queueParams, (err, currentState) => {
if (err)
return done(err);
if (!currentState)
return done(new CallbackEmptyReplyError());
if (currentState.lockOwner !== lockOwner) {
const error = new QueueLockOwnerMismatchError({
message: `Cannot unlock queue that is locked by other process`,
metadata: {
queue: queueParams,
expectedOwner: EQueueStateLockOwner[lockOwner],
actualOwner: currentState.lockOwner,
},
});
logger.error(error.message, error);
return done(error);
}
if (currentState.to !== EQueueOperationalState.LOCKED) {
const error = new QueueStateTransitionError({
message: `Cannot unlock queue that is not in LOCKED state. Current state: ${currentState.to}`,
metadata: {
from: currentState.to,
to: EQueueOperationalState.ACTIVE,
},
});
logger.error(error.message, error);
return done(error);
}
if (currentState.lockId !== lockId) {
const error = new QueueStateTransitionError({
message: `Lock ID mismatch. Expected: ${currentState.lockId}, Got: ${lockId}`,
metadata: {
from: currentState.to,
to: EQueueOperationalState.ACTIVE,
},
});
logger.error(error.message, error);
return done(error);
}
_transitQueueTo(queue, EQueueOperationalState.ACTIVE, {
reason: options?.reason || EStateTransitionReason.MANUAL,
description: options?.description || 'Manual unlock',
lockId,
metadata: options?.metadata,
}, logger, (err, transition) => {
if (err) {
logger.error(`Error unlocking ${queueParams.name}@${queueParams.ns}: ${err.message}`, err);
return done(err);
}
if (!transition)
return done(new CallbackEmptyReplyError());
logger.info(`Queue ${queueParams.name}@${queueParams.ns} unlocked successfully`);
done(null, transition);
});
});
});
}, cb);
}
//# sourceMappingURL=_unlock-queue.js.map