UNPKG

@future-agi/sdk

Version:

We help GenAI teams maintain high-accuracy for their Models in production.

83 lines 2.47 kB
import { setTimeout } from "timers/promises"; /** * BoundedExecutor behaves as a ThreadPoolExecutor which will block on * calls to submit() once the limit given as "bound" work items are queued for * execution. * @param bound - Integer - the maximum number of items in the work queue * @param maxWorkers - Integer - the size of the thread pool */ export class BoundedExecutor { constructor(bound, maxWorkers) { this.workers = new Set(); this.queue = []; this.isShutdown = false; this.semaphore = bound + maxWorkers; this.maxWorkers = maxWorkers; } /** * Submit a function for execution */ async submit(fn, ...args) { if (this.isShutdown) { throw new Error('Executor has been shutdown'); } // Acquire semaphore await this.acquireSemaphore(); return new Promise((resolve, reject) => { const task = async () => { try { const result = await fn(...args); resolve(result); } catch (error) { reject(error); } finally { this.releaseSemaphore(); } }; if (this.workers.size < this.maxWorkers) { // Start worker immediately this.startWorker(task); } else { // Queue the task this.queue.push(task); } }); } /** * Shutdown the executor */ async shutdown(wait = true) { this.isShutdown = true; if (wait) { // Wait for all workers to complete await Promise.all(Array.from(this.workers)); } } async acquireSemaphore() { while (this.semaphore <= 0) { await setTimeout(1); } this.semaphore--; } releaseSemaphore() { this.semaphore++; } startWorker(task) { const workerPromise = this.runWorker(task); this.workers.add(workerPromise); workerPromise.finally(() => { this.workers.delete(workerPromise); }); } async runWorker(initialTask) { let currentTask = initialTask; while (currentTask && !this.isShutdown) { await currentTask(); currentTask = this.queue.shift(); } } } //# sourceMappingURL=executor.js.map