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
			| 
											3 years ago
										 | '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; |