import log4js from "logger"; const logger = log4js.getLogger("SCHEDULER"); type QueuedTask = { run: () => void; }; export class ExecutorPool { private running = 0; private queue: QueuedTask[] = []; private maxConcurrency: number; constructor(maxConcurrency = 5) { this.maxConcurrency = maxConcurrency; } get activeCount(): number { return this.running; } get queuedCount(): number { return this.queue.length; } async execute(fn: () => Promise): Promise { if (this.running >= this.maxConcurrency) { logger.info( "Pool full (%d/%d), queuing task (%d in queue)", this.running, this.maxConcurrency, this.queue.length + 1 ); await new Promise((resolve) => { this.queue.push({ run: resolve }); }); } this.running++; try { await fn(); } finally { this.running--; const next = this.queue.shift(); if (next) { next.run(); } } } }