You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							204 lines
						
					
					
						
							5.8 KiB
						
					
					
				
			
		
		
	
	
							204 lines
						
					
					
						
							5.8 KiB
						
					
					
				'use strict';
 | 
						|
 | 
						|
Object.defineProperty(exports, '__esModule', {
 | 
						|
  value: true
 | 
						|
});
 | 
						|
Object.defineProperty(exports, 'messageParent', {
 | 
						|
  enumerable: true,
 | 
						|
  get: function () {
 | 
						|
    return _messageParent.default;
 | 
						|
  }
 | 
						|
});
 | 
						|
exports.default = void 0;
 | 
						|
 | 
						|
function _os() {
 | 
						|
  const data = require('os');
 | 
						|
 | 
						|
  _os = function () {
 | 
						|
    return data;
 | 
						|
  };
 | 
						|
 | 
						|
  return data;
 | 
						|
}
 | 
						|
 | 
						|
var _Farm = _interopRequireDefault(require('./Farm'));
 | 
						|
 | 
						|
var _WorkerPool = _interopRequireDefault(require('./WorkerPool'));
 | 
						|
 | 
						|
var _messageParent = _interopRequireDefault(require('./workers/messageParent'));
 | 
						|
 | 
						|
function _interopRequireDefault(obj) {
 | 
						|
  return obj && obj.__esModule ? obj : {default: obj};
 | 
						|
}
 | 
						|
 | 
						|
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;
 | 
						|
}
 | 
						|
 | 
						|
function getExposedMethods(workerPath, options) {
 | 
						|
  let exposedMethods = options.exposedMethods; // If no methods list is given, try getting it by auto-requiring the module.
 | 
						|
 | 
						|
  if (!exposedMethods) {
 | 
						|
    const module = require(workerPath);
 | 
						|
 | 
						|
    exposedMethods = Object.keys(module).filter(
 | 
						|
      // @ts-expect-error: no index
 | 
						|
      name => typeof module[name] === 'function'
 | 
						|
    );
 | 
						|
 | 
						|
    if (typeof module === 'function') {
 | 
						|
      exposedMethods = [...exposedMethods, 'default'];
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return exposedMethods;
 | 
						|
}
 | 
						|
/**
 | 
						|
 * The Jest farm (publicly called "Worker") is a class that allows you to queue
 | 
						|
 * methods across multiple child processes, in order to parallelize work. This
 | 
						|
 * is done by providing an absolute path to a module that will be loaded on each
 | 
						|
 * of the child processes, and bridged to the main process.
 | 
						|
 *
 | 
						|
 * Bridged methods are specified by using the "exposedMethods" property of the
 | 
						|
 * "options" object. This is an array of strings, where each of them corresponds
 | 
						|
 * to the exported name in the loaded module.
 | 
						|
 *
 | 
						|
 * You can also control the amount of workers by using the "numWorkers" property
 | 
						|
 * of the "options" object, and the settings passed to fork the process through
 | 
						|
 * the "forkOptions" property. The amount of workers defaults to the amount of
 | 
						|
 * CPUS minus one.
 | 
						|
 *
 | 
						|
 * Queueing calls can be done in two ways:
 | 
						|
 *   - Standard method: calls will be redirected to the first available worker,
 | 
						|
 *     so they will get executed as soon as they can.
 | 
						|
 *
 | 
						|
 *   - Sticky method: if a "computeWorkerKey" method is provided within the
 | 
						|
 *     config, the resulting string of this method will be used as a key.
 | 
						|
 *     Every time this key is returned, it is guaranteed that your job will be
 | 
						|
 *     processed by the same worker. This is specially useful if your workers
 | 
						|
 *     are caching results.
 | 
						|
 */
 | 
						|
 | 
						|
class JestWorker {
 | 
						|
  constructor(workerPath, options) {
 | 
						|
    var _this$_options$enable,
 | 
						|
      _this$_options$forkOp,
 | 
						|
      _this$_options$maxRet,
 | 
						|
      _this$_options$numWor,
 | 
						|
      _this$_options$resour,
 | 
						|
      _this$_options$setupA;
 | 
						|
 | 
						|
    _defineProperty(this, '_ending', void 0);
 | 
						|
 | 
						|
    _defineProperty(this, '_farm', void 0);
 | 
						|
 | 
						|
    _defineProperty(this, '_options', void 0);
 | 
						|
 | 
						|
    _defineProperty(this, '_workerPool', void 0);
 | 
						|
 | 
						|
    this._options = {...options};
 | 
						|
    this._ending = false;
 | 
						|
    const workerPoolOptions = {
 | 
						|
      enableWorkerThreads:
 | 
						|
        (_this$_options$enable = this._options.enableWorkerThreads) !== null &&
 | 
						|
        _this$_options$enable !== void 0
 | 
						|
          ? _this$_options$enable
 | 
						|
          : false,
 | 
						|
      forkOptions:
 | 
						|
        (_this$_options$forkOp = this._options.forkOptions) !== null &&
 | 
						|
        _this$_options$forkOp !== void 0
 | 
						|
          ? _this$_options$forkOp
 | 
						|
          : {},
 | 
						|
      maxRetries:
 | 
						|
        (_this$_options$maxRet = this._options.maxRetries) !== null &&
 | 
						|
        _this$_options$maxRet !== void 0
 | 
						|
          ? _this$_options$maxRet
 | 
						|
          : 3,
 | 
						|
      numWorkers:
 | 
						|
        (_this$_options$numWor = this._options.numWorkers) !== null &&
 | 
						|
        _this$_options$numWor !== void 0
 | 
						|
          ? _this$_options$numWor
 | 
						|
          : Math.max((0, _os().cpus)().length - 1, 1),
 | 
						|
      resourceLimits:
 | 
						|
        (_this$_options$resour = this._options.resourceLimits) !== null &&
 | 
						|
        _this$_options$resour !== void 0
 | 
						|
          ? _this$_options$resour
 | 
						|
          : {},
 | 
						|
      setupArgs:
 | 
						|
        (_this$_options$setupA = this._options.setupArgs) !== null &&
 | 
						|
        _this$_options$setupA !== void 0
 | 
						|
          ? _this$_options$setupA
 | 
						|
          : []
 | 
						|
    };
 | 
						|
 | 
						|
    if (this._options.WorkerPool) {
 | 
						|
      // @ts-expect-error: constructor target any?
 | 
						|
      this._workerPool = new this._options.WorkerPool(
 | 
						|
        workerPath,
 | 
						|
        workerPoolOptions
 | 
						|
      );
 | 
						|
    } else {
 | 
						|
      this._workerPool = new _WorkerPool.default(workerPath, workerPoolOptions);
 | 
						|
    }
 | 
						|
 | 
						|
    this._farm = new _Farm.default(
 | 
						|
      workerPoolOptions.numWorkers,
 | 
						|
      this._workerPool.send.bind(this._workerPool),
 | 
						|
      this._options.computeWorkerKey
 | 
						|
    );
 | 
						|
 | 
						|
    this._bindExposedWorkerMethods(workerPath, this._options);
 | 
						|
  }
 | 
						|
 | 
						|
  _bindExposedWorkerMethods(workerPath, options) {
 | 
						|
    getExposedMethods(workerPath, options).forEach(name => {
 | 
						|
      if (name.startsWith('_')) {
 | 
						|
        return;
 | 
						|
      }
 | 
						|
 | 
						|
      if (this.constructor.prototype.hasOwnProperty(name)) {
 | 
						|
        throw new TypeError('Cannot define a method called ' + name);
 | 
						|
      } // @ts-expect-error: dynamic extension of the class instance is expected.
 | 
						|
 | 
						|
      this[name] = this._callFunctionWithArgs.bind(this, name);
 | 
						|
    });
 | 
						|
  }
 | 
						|
 | 
						|
  _callFunctionWithArgs(method, ...args) {
 | 
						|
    if (this._ending) {
 | 
						|
      throw new Error('Farm is ended, no more calls can be done to it');
 | 
						|
    }
 | 
						|
 | 
						|
    return this._farm.doWork(method, ...args);
 | 
						|
  }
 | 
						|
 | 
						|
  getStderr() {
 | 
						|
    return this._workerPool.getStderr();
 | 
						|
  }
 | 
						|
 | 
						|
  getStdout() {
 | 
						|
    return this._workerPool.getStdout();
 | 
						|
  }
 | 
						|
 | 
						|
  async end() {
 | 
						|
    if (this._ending) {
 | 
						|
      throw new Error('Farm is ended, no more calls can be done to it');
 | 
						|
    }
 | 
						|
 | 
						|
    this._ending = true;
 | 
						|
    return this._workerPool.end();
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
exports.default = JestWorker;
 |