UNPKG

hamok

Version:

Lightweight Distributed Object Storage on RAFT consensus algorithm

85 lines (68 loc) 1.75 kB
import { createLogger } from './logger'; const logger = createLogger('WaitingQueue'); type WaitingItem = { action: () => void; reject?: (reason: string) => void; }; export class WaitingQueue { private _queue: WaitingItem[] = []; private _timer?: ReturnType<typeof setTimeout>; private _completed = false; public constructor( public readonly timeoutInMs: number, public readonly onCompleted?: () => void, timeoutReason?: string ) { this._timer = setTimeout(() => { this._timer = undefined; this.clear(timeoutReason ?? 'Waiting Timeout'); }, this.timeoutInMs); logger.trace('WaitingQueue created with timeout %d', this.timeoutInMs); } public get completed() { return this._completed; } public wait<T = unknown>(supplier: () => Promise<T>): Promise<T> { return new Promise<T>((resolve, reject) => { this._queue.push({ action: () => { supplier() .then(resolve) .catch(reject); }, reject, }); }); } public add(action: () => void) { this._queue.push({ action }); } public flush() { if (this._completed) return; this._completed = true; if (this._timer) { clearTimeout(this._timer); this._timer = undefined; } for (const item of this._queue) { logger.trace('WaitingQueue item is executed'); item.action(); } this._queue = []; this.onCompleted?.(); } public clear(rejectReason?: string) { if (this._completed) return; this._completed = true; if (this._timer) { clearTimeout(this._timer); this._timer = undefined; } for (const item of this._queue) { logger.trace('WaitingQueue item is rejected: %s', rejectReason); item.reject?.(rejectReason ?? 'Queue is cleared'); } this._queue = []; this.onCompleted?.(); } }