UNPKG

hamok

Version:

Lightweight Distributed Object Storage on RAFT consensus algorithm

55 lines (54 loc) 1.73 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ConcurrentExecutor = void 0; const logger_1 = require("./logger"); const logger = (0, logger_1.createLogger)('ConcurrentExecutor'); class ConcurrentExecutor { maxConcurrencyLevel; _parked = []; _tasks = []; _semaphore; constructor(maxConcurrencyLevel) { this.maxConcurrencyLevel = maxConcurrencyLevel; if (maxConcurrencyLevel < 1) throw new Error('maxConcurrencyLevel must be greater than 0'); this._semaphore = maxConcurrencyLevel; this.postProcess = this.postProcess.bind(this); } execute(action, park = false) { return new Promise((resolve, reject) => { const task = () => action().then(resolve) .catch(reject); if (park) this._parked.push(task); else this._tasks.push(task); this._run(); }); } flushParkedActions() { this._tasks.push(...this._parked); this._parked = []; this._run(); } postProcess() { ++this._semaphore; if (this._semaphore > this.maxConcurrencyLevel) { logger.warn('Semaphore is greater than maxConcurrencyLevel'); this._semaphore = this.maxConcurrencyLevel; } this._run(); } _run() { if (this._tasks.length === 0 || this._semaphore === 0) return; const task = this._tasks.shift(); if (!task) return; --this._semaphore; task() .then(() => this.postProcess()) .catch(this.postProcess); } } exports.ConcurrentExecutor = ConcurrentExecutor;