UNPKG

@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
"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