@apiratorjs/locking-redis
Version:
An extension to the core @apiratorjs/locking library, providing Redis-based implementations of distributed mutexes and semaphores for true cross-process concurrency control in Node.js.
62 lines • 2.42 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.BaseDistributedPrimitive = void 0;
const assert = require("node:assert");
const distributed_releaser_1 = require("./distributed-releaser");
class BaseDistributedPrimitive {
constructor(props) {
this.implementation = "redis";
this._isDestroyed = false;
const { name, redisClient } = props;
assert.ok(name, "name must be provided");
this.name = name;
this._redisClient = redisClient;
this._queue = [];
}
get isDestroyed() {
return this._isDestroyed;
}
;
async ensureSubscriber() {
if (this._redisSubscriber) {
return;
}
this._redisSubscriber = this._redisClient.duplicate();
await this._redisSubscriber.connect();
await this._redisSubscriber.subscribe(`${this.name}:cancel`, (message) => {
if (!message.startsWith("cancel")) {
return;
}
const errMessage = message.split(":")[1];
while (this._queue.length > 0) {
const deferred = this._queue.shift();
if (deferred.timer) {
clearTimeout(deferred.timer);
deferred.timer = null;
}
deferred.reject(new Error(errMessage || "Cancelled"));
}
});
await this._redisSubscriber.subscribe(`${this.name}:release`, async (token) => {
while (this._queue.length > 0) {
const nextInQueue = this._queue.shift();
const acquireToken = await this.tryAcquire(nextInQueue.ttlMs);
if (!acquireToken) {
this._queue.unshift(nextInQueue);
break;
}
if (nextInQueue.timer) {
clearTimeout(nextInQueue.timer);
nextInQueue.timer = null;
}
const releaser = new distributed_releaser_1.DistributedReleaser(() => this.release(acquireToken), acquireToken);
nextInQueue.resolve(releaser);
}
});
await this._redisSubscriber.subscribe(`${this.name}:destroy`, async () => {
await this.destroy();
});
}
}
exports.BaseDistributedPrimitive = BaseDistributedPrimitive;
//# sourceMappingURL=base-distributed-primitive.js.map