hamok
Version:
Lightweight Distributed Object Storage on RAFT consensus algorithm
55 lines (54 loc) • 1.73 kB
JavaScript
"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;