1b61532594b0af1d3148ccddcc6b0779405302b5
[e-mobility-charging-stations-simulator.git] / src / utils / AsyncLock.ts
1 export enum AsyncLockType {
2 configuration = 'configuration',
3 performance = 'performance',
4 }
5
6 export class AsyncLock {
7 private static readonly instances = new Map<AsyncLockType, AsyncLock>();
8 private acquired = false;
9 private readonly resolveQueue: ((value: void | PromiseLike<void>) => void)[];
10
11 private constructor(private readonly type: AsyncLockType) {
12 this.acquired = false;
13 this.resolveQueue = [];
14 }
15
16 public static getInstance(type: AsyncLockType): AsyncLock {
17 if (!AsyncLock.instances.has(type)) {
18 AsyncLock.instances.set(type, new AsyncLock(type));
19 }
20 return AsyncLock.instances.get(type);
21 }
22
23 public async acquire(): Promise<void> {
24 if (!this.acquired) {
25 this.acquired = true;
26 } else {
27 return new Promise((resolve) => {
28 this.resolveQueue.push(resolve);
29 });
30 }
31 }
32
33 public async release(): Promise<void> {
34 if (this.resolveQueue.length === 0 && this.acquired) {
35 this.acquired = false;
36 return;
37 }
38 const queuedResolve = this.resolveQueue.shift();
39 return new Promise((resolve) => {
40 queuedResolve();
41 resolve();
42 });
43 }
44 }