@future-agi/sdk
Version:
We help GenAI teams maintain high-accuracy for their Models in production.
104 lines • 3.8 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.BoundedExecutor = void 0;
const promises_1 = require("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
*/
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
*/
submit(fn, ...args) {
return __awaiter(this, void 0, void 0, function* () {
if (this.isShutdown) {
throw new Error('Executor has been shutdown');
}
// Acquire semaphore
yield this.acquireSemaphore();
return new Promise((resolve, reject) => {
const task = () => __awaiter(this, void 0, void 0, function* () {
try {
const result = yield 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
*/
shutdown() {
return __awaiter(this, arguments, void 0, function* (wait = true) {
this.isShutdown = true;
if (wait) {
// Wait for all workers to complete
yield Promise.all(Array.from(this.workers));
}
});
}
acquireSemaphore() {
return __awaiter(this, void 0, void 0, function* () {
while (this.semaphore <= 0) {
yield (0, promises_1.setTimeout)(1);
}
this.semaphore--;
});
}
releaseSemaphore() {
this.semaphore++;
}
startWorker(task) {
const workerPromise = this.runWorker(task);
this.workers.add(workerPromise);
workerPromise.finally(() => {
this.workers.delete(workerPromise);
});
}
runWorker(initialTask) {
return __awaiter(this, void 0, void 0, function* () {
let currentTask = initialTask;
while (currentTask && !this.isShutdown) {
yield currentTask();
currentTask = this.queue.shift();
}
});
}
}
exports.BoundedExecutor = BoundedExecutor;
//# sourceMappingURL=executor.js.map
;