@beenotung/tslib
Version:
utils library in Typescript
85 lines (84 loc) • 2.67 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ThreadPool = void 0;
const tslib_1 = require("tslib");
const os = tslib_1.__importStar(require("os"));
const util_1 = require("util");
const worker_threads_1 = require("worker_threads");
function defaultWeights() {
return os.cpus().map(cpu => cpu.speed);
}
/**
*
* dispatcher of workers created from `worker_threads.Worker`
*
* only support request-response batch-by-batch
* DO NOT support multiple interlaced concurrent batches
* */
class ThreadPool {
totalWeights;
workers;
dispatch = (0, util_1.promisify)((inputs, cb) => {
const n = inputs.length;
const outputs = new Array(n);
let offset = 0;
let pending = 0;
for (const worker of this.workers) {
const start = offset;
const count = Math.ceil((worker.weight / this.totalWeights) * n);
const end = offset + count;
offset = end;
const xs = inputs.slice(start, end);
pending++;
worker.worker.once('message', ys => {
for (let o = start, c = 0; o < end; o++, c++) {
outputs[o] = ys[c];
}
pending--;
if (pending === 0) {
cb(undefined, outputs);
}
});
worker.worker.postMessage(xs);
if (end >= n) {
break;
}
}
});
constructor(options) {
if ('workers' in options) {
if (options.workers.length === 0) {
throw new Error('require at least 1 workers');
}
this.workers = options.workers;
this.totalWeights = 0;
this.workers.forEach(x => (this.totalWeights += x.weight));
return;
}
let { weights, overload } = options;
if (!weights) {
weights = defaultWeights();
}
if (weights.length === 0) {
throw new Error('require at least 1 weights');
}
if (!overload) {
overload = 1;
}
const n = weights.length * overload;
this.workers = new Array(n);
this.totalWeights = 0;
for (let i = 0; i < n; i++) {
const weight = weights[i % weights.length];
this.totalWeights += weight;
this.workers[i] = {
weight,
worker: new worker_threads_1.Worker(options.modulePath),
};
}
}
close() {
this.workers.forEach(worker => worker.worker.terminate());
}
}
exports.ThreadPool = ThreadPool;