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