| 'use strict'; |
| |
| Object.defineProperty(exports, '__esModule', { |
| value: true |
| }); |
| exports.default = void 0; |
| |
| function path() { |
| const data = _interopRequireWildcard(require('path')); |
| |
| path = function () { |
| return data; |
| }; |
| |
| return data; |
| } |
| |
| function _mergeStream() { |
| const data = _interopRequireDefault(require('merge-stream')); |
| |
| _mergeStream = function () { |
| return data; |
| }; |
| |
| return data; |
| } |
| |
| function _types() { |
| const data = require('../types'); |
| |
| _types = function () { |
| return data; |
| }; |
| |
| return data; |
| } |
| |
| function _interopRequireDefault(obj) { |
| return obj && obj.__esModule ? obj : {default: obj}; |
| } |
| |
| function _getRequireWildcardCache() { |
| if (typeof WeakMap !== 'function') return null; |
| var cache = new WeakMap(); |
| _getRequireWildcardCache = function () { |
| return cache; |
| }; |
| return cache; |
| } |
| |
| function _interopRequireWildcard(obj) { |
| if (obj && obj.__esModule) { |
| return obj; |
| } |
| if (obj === null || (typeof obj !== 'object' && typeof obj !== 'function')) { |
| return {default: obj}; |
| } |
| var cache = _getRequireWildcardCache(); |
| if (cache && cache.has(obj)) { |
| return cache.get(obj); |
| } |
| var newObj = {}; |
| var hasPropertyDescriptor = |
| Object.defineProperty && Object.getOwnPropertyDescriptor; |
| for (var key in obj) { |
| if (Object.prototype.hasOwnProperty.call(obj, key)) { |
| var desc = hasPropertyDescriptor |
| ? Object.getOwnPropertyDescriptor(obj, key) |
| : null; |
| if (desc && (desc.get || desc.set)) { |
| Object.defineProperty(newObj, key, desc); |
| } else { |
| newObj[key] = obj[key]; |
| } |
| } |
| } |
| newObj.default = obj; |
| if (cache) { |
| cache.set(obj, newObj); |
| } |
| return newObj; |
| } |
| |
| function _defineProperty(obj, key, value) { |
| if (key in obj) { |
| Object.defineProperty(obj, key, { |
| value: value, |
| enumerable: true, |
| configurable: true, |
| writable: true |
| }); |
| } else { |
| obj[key] = value; |
| } |
| return obj; |
| } |
| |
| // How long to wait for the child process to terminate |
| // after CHILD_MESSAGE_END before sending force exiting. |
| const FORCE_EXIT_DELAY = 500; |
| /* istanbul ignore next */ |
| |
| const emptyMethod = () => {}; |
| |
| class BaseWorkerPool { |
| constructor(workerPath, options) { |
| _defineProperty(this, '_stderr', void 0); |
| |
| _defineProperty(this, '_stdout', void 0); |
| |
| _defineProperty(this, '_options', void 0); |
| |
| _defineProperty(this, '_workers', void 0); |
| |
| this._options = options; |
| this._workers = new Array(options.numWorkers); |
| |
| if (!path().isAbsolute(workerPath)) { |
| workerPath = require.resolve(workerPath); |
| } |
| |
| const stdout = (0, _mergeStream().default)(); |
| const stderr = (0, _mergeStream().default)(); |
| const {forkOptions, maxRetries, resourceLimits, setupArgs} = options; |
| |
| for (let i = 0; i < options.numWorkers; i++) { |
| const workerOptions = { |
| forkOptions, |
| maxRetries, |
| resourceLimits, |
| setupArgs, |
| workerId: i, |
| workerPath |
| }; |
| const worker = this.createWorker(workerOptions); |
| const workerStdout = worker.getStdout(); |
| const workerStderr = worker.getStderr(); |
| |
| if (workerStdout) { |
| stdout.add(workerStdout); |
| } |
| |
| if (workerStderr) { |
| stderr.add(workerStderr); |
| } |
| |
| this._workers[i] = worker; |
| } |
| |
| this._stdout = stdout; |
| this._stderr = stderr; |
| } |
| |
| getStderr() { |
| return this._stderr; |
| } |
| |
| getStdout() { |
| return this._stdout; |
| } |
| |
| getWorkers() { |
| return this._workers; |
| } |
| |
| getWorkerById(workerId) { |
| return this._workers[workerId]; |
| } |
| |
| createWorker(_workerOptions) { |
| throw Error('Missing method createWorker in WorkerPool'); |
| } |
| |
| async end() { |
| // We do not cache the request object here. If so, it would only be only |
| // processed by one of the workers, and we want them all to close. |
| const workerExitPromises = this._workers.map(async worker => { |
| worker.send( |
| [_types().CHILD_MESSAGE_END, false], |
| emptyMethod, |
| emptyMethod, |
| emptyMethod |
| ); // Schedule a force exit in case worker fails to exit gracefully so |
| // await worker.waitForExit() never takes longer than FORCE_EXIT_DELAY |
| |
| let forceExited = false; |
| const forceExitTimeout = setTimeout(() => { |
| worker.forceExit(); |
| forceExited = true; |
| }, FORCE_EXIT_DELAY); |
| await worker.waitForExit(); // Worker ideally exited gracefully, don't send force exit then |
| |
| clearTimeout(forceExitTimeout); |
| return forceExited; |
| }); |
| |
| const workerExits = await Promise.all(workerExitPromises); |
| return workerExits.reduce( |
| (result, forceExited) => ({ |
| forceExited: result.forceExited || forceExited |
| }), |
| { |
| forceExited: false |
| } |
| ); |
| } |
| } |
| |
| exports.default = BaseWorkerPool; |