1 changed files with 50 additions and 0 deletions
@ -0,0 +1,50 @@ |
|||
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<void>): Promise<void> { |
|||
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<void>((resolve) => { |
|||
this.queue.push({ run: resolve }); |
|||
}); |
|||
} |
|||
|
|||
this.running++; |
|||
try { |
|||
await fn(); |
|||
} finally { |
|||
this.running--; |
|||
const next = this.queue.shift(); |
|||
if (next) { |
|||
next.run(); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue