workerama
Version:
Run sync/async function across Worker Threads
74 lines (60 loc) • 2.29 kB
JavaScript
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;