lavva.exalushome
Version:
Library implementing communication and abstraction layers for ExalusHome system
51 lines • 1.95 kB
JavaScript
export class AsyncSemaphore {
constructor(initialCount) {
this.initialCount = initialCount;
this._running = 0;
this._waiting = [];
this.Take = () => {
if (this._waiting.length > 0 && this._running < this.initialCount) {
this._running++;
const task = this._waiting.shift();
task === null || task === void 0 ? void 0 : task.Resolve({ Release: this.Release });
}
};
this.IsLocked = () => {
return this._running > 0;
};
/**
* Acquire a lock on the target resource.
* @returns a function to release the lock, it is critical that this function is called when the task is finished with the resource.
*/
this.AcquireAsync = () => {
if (this._running < this.initialCount) {
this._running++;
return Promise.resolve({ Release: this.Release });
}
return new Promise((resolve, reject) => {
this._waiting.push({ Resolve: resolve, Reject: reject });
});
};
this.Release = () => {
if (this._running === 0) {
throw new Error('Release called more times than AcquireAsync');
}
this._running--;
this.Take();
};
/**
* Purge all waiting tasks from the Semaphore instance
*/
this.Purge = () => {
this._waiting.forEach(task => {
task.Reject(new Error('The semaphore was purged and as a result this task has been cancelled'));
});
this._running = 0;
this._waiting = [];
};
if (initialCount < 1) {
throw new Error(`The semaphore was created with a max value of ${initialCount} but the max value cannot be less than 1`);
}
}
}
//# sourceMappingURL=AsyncSemaphore.js.map