X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Futils%2FAsyncLock.ts;h=f6b793a60748beaa8454fdb80e13510553a25898;hb=8a4f882a2486682b72195ad978ec1d81604b452b;hp=16ad4f2b1cdcf53b44a90f6b6970858cff789e28;hpb=f31d1d0c5175efb4d1f0ca6c0d9c228f920aba28;p=e-mobility-charging-stations-simulator.git diff --git a/src/utils/AsyncLock.ts b/src/utils/AsyncLock.ts index 16ad4f2b..f6b793a6 100644 --- a/src/utils/AsyncLock.ts +++ b/src/utils/AsyncLock.ts @@ -1,52 +1,64 @@ -// Partial Copyright Jerome Benoit. 2021-2023. All Rights Reserved. +// Partial Copyright Jerome Benoit. 2021-2024. All Rights Reserved. -import Queue from 'mnemonist/queue.js'; +import { Queue } from 'mnemonist' + +import { Constants } from './Constants.js' export enum AsyncLockType { configuration = 'configuration', - performance = 'performance', + performance = 'performance' } -type ResolveType = (value: void | PromiseLike) => void; +type ResolveType = (value: void | PromiseLike) => void export class AsyncLock { - private static readonly asyncLocks = new Map(); - private acquired: boolean; - private readonly resolveQueue: Queue; + private static readonly asyncLocks = new Map() + private acquired: boolean + private readonly resolveQueue: Queue + + private constructor () { + this.acquired = false + this.resolveQueue = new Queue() + } - private constructor() { - this.acquired = false; - this.resolveQueue = new Queue(); + public static async runExclusive(type: AsyncLockType, fn: () => T | Promise): Promise { + return await AsyncLock.acquire(type) + .then(fn) + .finally(() => { + AsyncLock.release(type).catch(Constants.EMPTY_FUNCTION) + }) } - public static async acquire(type: AsyncLockType): Promise { - const asyncLock = AsyncLock.getAsyncLock(type); + private static async acquire (type: AsyncLockType): Promise { + const asyncLock = AsyncLock.getAsyncLock(type) if (!asyncLock.acquired) { - asyncLock.acquired = true; - return; + asyncLock.acquired = true + return } - return new Promise((resolve) => { - asyncLock.resolveQueue.enqueue(resolve); - }); + await new Promise(resolve => { + asyncLock.resolveQueue.enqueue(resolve) + }) } - public static async release(type: AsyncLockType): Promise { - const asyncLock = AsyncLock.getAsyncLock(type); + private static async release (type: AsyncLockType): Promise { + const asyncLock = AsyncLock.getAsyncLock(type) if (asyncLock.resolveQueue.size === 0 && asyncLock.acquired) { - asyncLock.acquired = false; - return; + asyncLock.acquired = false + return } - const queuedResolve = asyncLock.resolveQueue.dequeue(); - return new Promise((resolve) => { - queuedResolve(); - resolve(); - }); + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const queuedResolve = asyncLock.resolveQueue.dequeue()! + await new Promise(resolve => { + queuedResolve() + resolve() + }) } - private static getAsyncLock(type: AsyncLockType): AsyncLock { + private static getAsyncLock (type: AsyncLockType): AsyncLock { if (!AsyncLock.asyncLocks.has(type)) { - AsyncLock.asyncLocks.set(type, new AsyncLock()); + AsyncLock.asyncLocks.set(type, new AsyncLock()) } - return AsyncLock.asyncLocks.get(type); + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + return AsyncLock.asyncLocks.get(type)! } }