16ad4f2b1cdcf53b44a90f6b6970858cff789e28
1 // Partial Copyright Jerome Benoit. 2021-2023. All Rights Reserved.
3 import Queue from
'mnemonist/queue.js';
5 export enum AsyncLockType
{
6 configuration
= 'configuration',
7 performance
= 'performance',
10 type ResolveType
= (value
: void | PromiseLike
<void>) => void;
12 export class AsyncLock
{
13 private static readonly asyncLocks
= new Map
<AsyncLockType
, AsyncLock
>();
14 private acquired
: boolean;
15 private readonly resolveQueue
: Queue
<ResolveType
>;
17 private constructor() {
18 this.acquired
= false;
19 this.resolveQueue
= new Queue
<ResolveType
>();
22 public static async acquire(type: AsyncLockType
): Promise
<void> {
23 const asyncLock
= AsyncLock
.getAsyncLock(type);
24 if (!asyncLock
.acquired
) {
25 asyncLock
.acquired
= true;
28 return new Promise((resolve
) => {
29 asyncLock
.resolveQueue
.enqueue(resolve
);
33 public static async release(type: AsyncLockType
): Promise
<void> {
34 const asyncLock
= AsyncLock
.getAsyncLock(type);
35 if (asyncLock
.resolveQueue
.size
=== 0 && asyncLock
.acquired
) {
36 asyncLock
.acquired
= false;
39 const queuedResolve
= asyncLock
.resolveQueue
.dequeue();
40 return new Promise((resolve
) => {
46 private static getAsyncLock(type: AsyncLockType
): AsyncLock
{
47 if (!AsyncLock
.asyncLocks
.has(type)) {
48 AsyncLock
.asyncLocks
.set(type, new AsyncLock());
50 return AsyncLock
.asyncLocks
.get(type);