Commit | Line | Data |
---|---|---|
b9b617a2 JB |
1 | // Partial Copyright Jerome Benoit. 2021-2023. All Rights Reserved. |
2 | ||
1227a6f1 JB |
3 | export enum AsyncLockType { |
4 | configuration = 'configuration', | |
5 | performance = 'performance', | |
6 | } | |
7 | ||
8 | export class AsyncLock { | |
dd485b56 | 9 | private static readonly asyncLocks = new Map<AsyncLockType, AsyncLock>(); |
7e0bf360 | 10 | private acquired: boolean; |
1227a6f1 JB |
11 | private readonly resolveQueue: ((value: void | PromiseLike<void>) => void)[]; |
12 | ||
13 | private constructor(private readonly type: AsyncLockType) { | |
14 | this.acquired = false; | |
15 | this.resolveQueue = []; | |
16 | } | |
17 | ||
dd485b56 JB |
18 | public static async acquire(type: AsyncLockType): Promise<void> { |
19 | const asyncLock = AsyncLock.getAsyncLock(type); | |
20 | if (!asyncLock.acquired) { | |
21 | asyncLock.acquired = true; | |
1227a6f1 JB |
22 | } else { |
23 | return new Promise((resolve) => { | |
dd485b56 | 24 | asyncLock.resolveQueue.push(resolve); |
1227a6f1 JB |
25 | }); |
26 | } | |
27 | } | |
28 | ||
dd485b56 JB |
29 | public static async release(type: AsyncLockType): Promise<void> { |
30 | const asyncLock = AsyncLock.getAsyncLock(type); | |
31 | if (asyncLock.resolveQueue.length === 0 && asyncLock.acquired) { | |
32 | asyncLock.acquired = false; | |
1227a6f1 JB |
33 | return; |
34 | } | |
dd485b56 | 35 | const queuedResolve = asyncLock.resolveQueue.shift(); |
1227a6f1 JB |
36 | return new Promise((resolve) => { |
37 | queuedResolve(); | |
38 | resolve(); | |
39 | }); | |
40 | } | |
dd485b56 JB |
41 | |
42 | private static getAsyncLock(type: AsyncLockType): AsyncLock { | |
43 | if (!AsyncLock.asyncLocks.has(type)) { | |
44 | AsyncLock.asyncLocks.set(type, new AsyncLock(type)); | |
45 | } | |
46 | return AsyncLock.asyncLocks.get(type); | |
47 | } | |
1227a6f1 | 48 | } |