UNPKG

workerama

Version:

Run sync/async function across Worker Threads

74 lines (60 loc) 2.29 kB
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.workerama = void 0; var _path = _interopRequireDefault(require("path")); var _worker_threads = require("worker_threads"); var _getCallerFile = _interopRequireDefault(require("get-caller-file")); var _iterama = require("iterama"); var _piall = require("piall"); var _asyncIterableFinally = require("./async-iterable-finally"); const workerama = options => { if (options.maxThreadCount <= 0) { throw new Error('`maxThreadCount` should be greater than zero (tip: pass Infinity to set no limits)'); } const workerPath = require.resolve('./worker'); const callerDir = _path.default.dirname((0, _getCallerFile.default)()); const fullFnFilePath = require.resolve(_path.default.resolve(callerDir, options.fnFilePath)); const threadCount = Math.min(options.items.length, options.maxThreadCount); const workers = Array.from({ length: threadCount }, () => { return new _worker_threads.Worker(workerPath, { workerData: { fnFilePath: fullFnFilePath, fnName: options.fnName, fnArgs: options.fnArgs } }); }); const busyWorkerIds = new Set(); const resultsIterable = (0, _asyncIterableFinally.asyncIterableFinally)((0, _piall.piAll)((0, _iterama.map)(item => () => { const worker = workers.find(({ threadId }) => !busyWorkerIds.has(threadId)); busyWorkerIds.add(worker.threadId); return new Promise((resolve, reject) => { worker.on('error', reject).on('message', message => { worker.removeAllListeners('error'); worker.removeAllListeners('message'); busyWorkerIds.delete(worker.threadId); if (message.type === 'done') { resolve(message.value); } else if (message.type === 'error') { reject(message.value); } }).postMessage({ value: item }); }); })(options.items), threadCount), () => (0, _piall.piAll)((0, _iterama.map)(worker => () => { return new Promise(resolve => { worker.on('exit', resolve).postMessage({ done: true }); }); })(workers))); return resultsIterable; }; exports.workerama = workerama;