UNPKG

@arrows/worker

Version:

Simple, promise-based API for native worker threads (with pools)

59 lines (58 loc) 2.01 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const worker_threads_1 = require("worker_threads"); const os_1 = require("os"); const defaultConfig = { poolSize: os_1.cpus().length, }; /** * Spawns a workers pool from worker defined in a separate file, * returns a function that handles messaging and returns responses as promises. * * Use when you want to separate worker definition from spawning a thread pool. * * @param fileName Path to a worker definition file created with `work` function * @param config Configuration options * @returns Async function that communicates with worker threads */ const spawn = (fileName, config = {}) => { const cfg = { ...defaultConfig, ...config }; const { poolSize, transfer, ...options } = cfg; if (poolSize <= 0) { throw new Error("Pool size has to be > 0"); } const promises = new Map(); const workers = Array.from({ length: poolSize }, () => new worker_threads_1.Worker(fileName, options).on("message", ([id, data, error]) => { if (error) { promises.get(id).reject(error); } else { promises.get(id).resolve(data); } promises.delete(id); })); let workerIndex = 0; const fn = (payload, transferList) => { const id = process.hrtime.bigint(); const promise = new Promise((resolve, reject) => { promises.set(id, { resolve, reject }); }); workers[workerIndex].postMessage([id, payload], transferList); workerIndex = (workerIndex + 1) % poolSize; return promise; }; const task = Object.assign(fn, { ref() { workers.forEach((worker) => worker.ref()); }, unref() { workers.forEach((worker) => worker.unref()); }, terminate() { return Promise.all(workers.map((worker) => worker.terminate())); }, }); return task; }; exports.spawn = spawn; exports.default = spawn;