Best JavaScript code snippet using jest
appverse-performance.js
Source:appverse-performance.js  
1(function() {2    'use strict';3    /**4     * @ngdoc module5     * @name appverse.performance6     *7     * @description8     * The AppPerformance provides services to handle usage of several performance elements:9     * 1. Webworkers. Multithreaded-parallelized execution of tasks separated of the main JavaScript thread.10     * 2. High Performance UI directives support.11     *12     * @requires appverse.configuration13     */14    run.$inject = ["$log"];15    angular.module('appverse.performance', ['appverse.configuration'])16        .run(run);17    function run ($log) {18        $log.info('appverse.performance run');19    }20})();21(function () {22    'use strict';23    angular.module('appverse.performance')24    /**25    * @ngdoc directive26    * @name webworker27    * @module appverse.performance28    * @restrict E29    *30    * @description31    * Establishes comm with messages to a selected web worker.32    * Allows send messages to the worker and receive results from.33    * Messages from the worker are displayed in a div.34    *35    * @example36    <example module="appverse.performance">37    <file name="index.html">38    <p>Web Worker test</p>39    <webworker  id="101" message="Hans Walter" template=""/>40    </file>41    </example>42    *43    * @param {string} id Id of the pre-configured worker or path to the worker's file44    * @param {string} message Message to be passed to the worker.45    *46    * @requires  https://docs.angularjs.org/api/ngMock/service/$log $log47    * @requires  WebWorkerFactory48    * @requires  PERFORMANCE_CONFIG49    */50    .directive('webworker', ['$log', 'WebWorkerFactory', 'PERFORMANCE_CONFIG',51        function ($log, WebWorkerFactory, PERFORMANCE_CONFIG) {52            return {53                restrict: 'E', //E = element, A = attribute, C = class, M = comment54                scope: {55                    //(required) set the worker id in configuration or the complete path56                    //if it is not included in config.57                    workerid: '@',58                    //(required) set the message to be passed to the worker59                    message: '@',60                    //(optional) custom template to render the received message from the worker61                    template: '@'62                },63                priority: 1000,64                terminal: true,65                compile: function () {},66                link: function postLink(scope, element, attrs) {67                    var workerid = attrs.id;68                    var template = attrs.template;69                    scope.$watch(function () {70                        return WebWorkerFactory._resultMessage;71                    }, function (newVal) {72                        $log.debug('Cache watch {' + name + '}:', newVal);73                        scope.messageFromWorker = WebWorkerFactory._resultMessage;74                    });75                    scope.$watch('message', function (value) {76                        init(value); // set defaults77                        compileTemplate(); // gets the template and compile the desired layout78                    });79                    /**80                     * @function81                     * @description82                     * Set defaults into the scope object83                     */84                    function init(message) {85                        scope.workerid = workerid;86                        scope.template = template || PERFORMANCE_CONFIG.webworker_Message_template;87                        initWorker(scope.workerid, message);88                    }89                    /**90                     * @function91                     * @description92                     * Gets the message from the worker.93                     */94                    function initWorker(workerid, message) {95                        WebWorkerFactory.runTask(workerid, message);96                        var messageFromWorker = WebWorkerFactory._resultMessage;97                        if (messageFromWorker) {98                            scope.messageFromWorker = messageFromWorker;99                        }100                    }101                    /**102                     * @function103                     * @description104                     * Gets the template and compile the desired layout.105                     * Based on $compile, it compiles a piece of HTML string or DOM into the retrieved106                     * template and produces a template function, which can then be used to link scope and107                     * the template together.108                     */109                    function compileTemplate($http, $templateCache, $compile) {110                        $http.get(scope.template, {111                                //This allows you can get the template again by consuming the112                                //$templateCache service directly.113                                cache: $templateCache114                            })115                            .success(function (html) {116                                element.html(html);117                                $compile(element.contents())(scope);118                            });119                    }120                }121            };122        }]);123})();124(function() {125    'use strict';126    WebWorkerPoolFactory.$inject = ["$log", "$q", "PERFORMANCE_CONFIG"];127    angular.module('appverse.performance')128        .factory('WebWorkerPoolFactory', WebWorkerPoolFactory);129    /**130     * @ngdoc service131     * @name WebWorkerFactory132     * @module appverse.performance133     *134     * @description135     * This factory starts a pooled multithreaded execution of a webworker:136     * <pre></code>                _______137     *                            |       |-> thread 1138     * USER -> message -> task -> | pool  |-> thread 2139     *                            |_______|-> thread N140     * </code></pre>141     *142     * @requires https://docs.angularjs.org/api/ngMock/service/$q $q143     * @requires https://docs.angularjs.org/api/ngMock/service/$log $log144     * @requires PERFORMANCE_CONFIG145     */146    function WebWorkerPoolFactory ($log, $q, PERFORMANCE_CONFIG) {147        var factory = {148            _poolSize: PERFORMANCE_CONFIG.webworker_pooled_threads,149            _authorizedWorkersOnly: PERFORMANCE_CONFIG.webworker_authorized_workers_only,150            _workersDir: PERFORMANCE_CONFIG.webworker_directory,151            _workersList: PERFORMANCE_CONFIG.webworker_authorized_workers,152            _resultMessage: ''153        };154        $log.debug("Initializated webworkers factory preconfigured values." );155        $log.debug("Default pool size: " + factory._poolSize);156        $log.debug("Are only authorized preconfigured workers? " + factory._authorizedWorkersOnly);157        $log.debug("The folder for webworkers in the app: " + factory._workersDir);158        $log.debug("Number of members in the workers list: " + factory._workersList.length);159        /**160         * @ngdoc method161         * @name WebWorkerFactory#runParallelTasksGroup162         *163         * @param {number} workerData WorkerData object with information of the task to be executed164         * @param {object} workerTasks Array with a group of WorkerTask objects for the same WorkerData165         *166         * @description167         * Runs a group of parallelized tasks168         * Run a set of workers according to the pre-defined data in configuration169         * (id, type, size in pool and worker file).170         * Pe-definition in configuration is mandatory.171         * The group of tasks are up to the caller.172         */173        factory.runParallelTasksGroup = function (workerData, workerTasks) {174            this.workerData = workerData;175            $log.debug("Started parallelized execution for worker: ");176            $log.debug(workerData.toString());177            //Initializes the pool with the indicated size for that worker group178            var pool = new factory.WorkerPool(this.workerData.poolSize);179            pool.init();180            //Create a worker task for181            if(workerTasks && workerTasks.length > 0){182                // iterate through all the parts of the image183                for (var x = 0; x < workerTasks.length; x++) {184                    var workerTask = workerTasks[x];185                    pool.addWorkerTask(workerTask);186                }187            }188            return factory._resultMessage;189        };190        /**191         * @ngdoc method192         * @name WebWorkerFactory#passMessage193         *194         * @param {number} id of the called worker195         * @param {object} function as callback196         * @param {string} message to be passed to the worker197         * @description198         * Execute a task in a worker.199         * The group of task is the same as the number indicated in the pool size for that pre-configured worker.200         */201        factory.runTask = function (workerId, message, callback) {202            var pool = new factory.WorkerPool(factory._poolSize);203            pool.init();204            /*205             If only workers in the configuration file are allowed.206             No fallback needed.207             */208            var workerData;209            var workerTask;210            if(factory._authorizedWorkersOnly){211                if(workerId){212                    //Get data from configuration for the worker from the provided ID213                    workerData = factory.getWorkerFromId(workerId);214                }else{215                    //NO VALID WORKER ID ERROR216                    $log.error("NO VALID WORKER ID ERROR");217                }218            }else{219                //If any provided worker is allowed the workerId arg is the complete path to the worker file220                //The ID is not important here221                if(workerId){222                    workerData = new WorkerData(1001, 'dedicated', workerId);223                }else{224                    //NO VALID WORKER ID ERROR225                    $log.error("NO VALID WORKER ID ERROR");226                }227            }228            if(workerData) {229                pool = new factory.WorkerPool(workerData.poolSize);230                /*231                 Create the worker task for the pool (only one task, passed N times):232                 workerName: File of the worker233                 callback: Register the supplied function as callback234                 message: The last argument will be used to send a message to the worker235                 */236                workerTask = new factory.WorkerTask(workerData, callback, message);237                // Pass the worker task object to the execution pool.238                // The default behavior is create one task for each thread in the pool.239                for(var i = 0; i < factory._poolSize; i++){240                    pool.addWorkerTask(workerTask);241                }242            }else{243                //NO WORKER DATA ERROR244                $log.error("NO WORKER DATA ERROR");245            }246            //return _resultMessage;247        };248        factory.WorkerPool = function(poolSize) {249            var _this = this;250            if(!poolSize) {251                this.size = factory._poolSize;252            }else{253                this.size = poolSize;254            }255            //Initialize some vars with default values256            this.taskQueue = [];257            this.workerQueue = [];258            //Start the thread pool. To be used by the caller.259            this.init = function() {260                //Create the 'size' number of worker threads261                for (var i = 0 ; i < _this.size ; i++) {262                    _this.workerQueue.push(new WorkerThread(_this));263                }264            };265            this.addWorkerTask = function(workerTask) {266                if (_this.workerQueue.length > 0) {267                    // get the worker from the front of the queue268                    var workerThread = _this.workerQueue.shift();269                    workerThread.run(workerTask);270                } else {271                    // If there are not free workers the task is put in queue272                    _this.taskQueue.push(workerTask);273                }274            };275            //Execute the queued task. If empty, put the task to the queue.276            this.freeWorkerThread = function(workerThread) {277                if (_this.taskQueue.length > 0) {278                    // It is not put back in the queue, but it is executed on the next task279                    var workerTask = _this.taskQueue.shift();280                    workerThread.run(workerTask);281                } else {282                    _this.taskQueue.push(workerThread);283                }284            };285        };286        //Runner work tasks in the pool287        function WorkerThread(parentPool) {288            var _this = this;289            this.parentPool = parentPool;290            this.workerTask = {};291            //Execute the task292            this.run = function(workerTask) {293                _this.workerTask = workerTask;294                //Create a new web worker295                if (_this.workerTask.script != null) {296                    /*297                     Creation of workers.298                     For both dedicated and shared workers, you can also attach to the299                     message event handler event type by using the addEventListener method.300                     */301                    var worker;302                    if(workerTask.type == PERFORMANCE_CONFIG.webworker_dedicated_literal){303                        worker = new Worker(_this.workerTask.script);304                        worker.addEventListener('message', _this.OnWorkerMessageHandler, false);305                        worker.postMessage(_this.workerTask.startMessage);306                    }else if(workerTask.type == PERFORMANCE_CONFIG.webworker_shared_literal){307                        worker = new SharedWorker(_this.workerTask.script);308                        worker.port.addEventListener('message', _this.OnWorkerMessageHandler, false);309                        worker.port.postMessage(_this.workerTask.startMessage);310                    }else{311                        //NO TYPE ERROR312                        $log.error("NO VALID WORKER TYPE");313                    }314                }315            };316            //We assume we only get a single callback from a worker as a handler317            //It also indicates the end of this worker.318            _this.OnWorkerMessageHandler = function (evt) {319                // pass to original callback320                _this.workerTask.callback(evt);321                // We should use a separate thread to add the worker322                _this.parentPool.freeWorkerThread(_this);323            };324        }325        //The task to run326        factory.WorkerTask = function (workerData, callback, msg) {327            this.script = workerData.file;328            if(callback){329                this.callback = callback;330            }else{331                this.callback = defaultEventHandler;332            }333            this.startMessage = msg;334            this.type = workerData.type;335        };336        /*337         Default event handler.338         */339        function defaultEventHandler(event){340            factory._resultMessage = event.data;341        }342        //Data object for a worker343        function WorkerData(workerId, type, poolSize, worker) {344            this.id = workerId;345            this.type = type;346            this.poolSize = poolSize;347            this.file = worker;348        }349        WorkerData.prototype.toString = function(){350            return "ID: " + this.id + "|TYPE: " + this.type + "|POOL SIZE: " + this.poolSize + "|FILE: " + this.file;351        };352        //Extract worker information from configuration353        factory.getWorkerFromId = function (workerId, poolSize){354            this.id = workerId;355            this.type = '';356            this.poolSize = poolSize;357            this.file = '';358            for(var i = 0; i < factory._workersList.length; i++) {359                if(factory._workersList[i].id === workerId){360                    this.type = factory._workersList[i].type;361                    if(!this.poolSize || this.poolSize == 0){362                        this.poolSize = factory._workersList[i].poolSize;363                    }else{364                        this.poolSize = poolSize;365                    }366                    this.file = factory._workersDir + factory._workersList[i].file;367                    break;368                }369            }370            var workerData = new WorkerData(this.id, this.type, this.poolSize, this.file);371            return workerData;372        };373        return factory;374    }...WorkerExecutionSupport.js
Source:WorkerExecutionSupport.js  
1/**2 * Development repository: https://github.com/kaisalmen/WWOBJLoader3 */4/**5 * These instructions are used by {WorkerExecutionSupport} to build code for the web worker or to assign code6 *7 * @param {boolean} supportsStandardWorker8 * @param {boolean} supportsJsmWorker9 * @constructor10 */11const CodeBuilderInstructions = function ( supportsStandardWorker, supportsJsmWorker, preferJsmWorker ) {12	this.supportsStandardWorker = supportsStandardWorker;13	this.supportsJsmWorker = supportsJsmWorker;14	this.preferJsmWorker = preferJsmWorker;15	this.startCode = '';16	this.codeFragments = [];17	this.importStatements = [];18	this.jsmWorkerUrl = null;19	this.defaultGeometryType = 0;20};21CodeBuilderInstructions.prototype = {22	constructor: CodeBuilderInstructions,23	isSupportsStandardWorker: function () {24		return this.supportsStandardWorker;25	},26	isSupportsJsmWorker: function () {27		return this.supportsJsmWorker;28	},29	isPreferJsmWorker: function () {30		return this.preferJsmWorker;31	},32	/**33	 * Set the full path to the module that contains the worker code.34	 *35	 * @param {String} jsmWorkerUrl36	 */37	setJsmWorkerUrl: function ( jsmWorkerUrl ) {38		if ( jsmWorkerUrl !== undefined && jsmWorkerUrl !== null ) {39			this.jsmWorkerUrl = jsmWorkerUrl;40		}41	},42	/**43	 * Add code that is contained in addition to fragments and libraries44	 * @param {String} startCode45	 */46	addStartCode: function ( startCode ) {47		this.startCode = startCode;48	},49	/**50	 * Add code fragment that is included in the provided order51	 * @param {String} code52	 */53	addCodeFragment: function ( code ) {54		this.codeFragments.push( code );55	},56	/**57	 * Add full path to a library that is contained at the start of the worker via "importScripts"58	 * @param {String} libraryPath59	 */60	addLibraryImport: function ( libraryPath ) {61		let libraryUrl = new URL( libraryPath, window.location.href ).href;62		let code = 'importScripts( "' + libraryUrl + '" );';63		this.importStatements.push(	code );64	},65	getImportStatements: function () {66		return this.importStatements;67	},68	getCodeFragments: function () {69		return this.codeFragments;70	},71	getStartCode: function () {72		return this.startCode;73	}74};75/**76 * This class provides means to transform existing parser code into a web worker. It defines a simple communication protocol77 * which allows to configure the worker and receive raw mesh data during execution.78 * @class79 */80const WorkerExecutionSupport = function () {81	// check worker support first82	if ( window.Worker === undefined ) throw "This browser does not support web workers!";83	if ( window.Blob === undefined ) throw "This browser does not support Blob!";84	if ( typeof window.URL.createObjectURL !== 'function' ) throw "This browser does not support Object creation from URL!";85	this._reset();86};87WorkerExecutionSupport.WORKER_SUPPORT_VERSION = '3.2.0';88console.info( 'Using WorkerSupport version: ' + WorkerExecutionSupport.WORKER_SUPPORT_VERSION );89WorkerExecutionSupport.prototype = {90	constructor: WorkerExecutionSupport,91	_reset: function () {92		this.logging = {93			enabled: false,94			debug: false95		};96		let scope = this;97		let scopeTerminate = function ( ) {98			scope._terminate();99		};100		this.worker = {101			native: null,102			jsmWorker: false,103			logging: true,104			workerRunner: {105				name: 'WorkerRunner',106				usesMeshDisassembler: false,107				defaultGeometryType: 0108			},109			terminateWorkerOnLoad: true,110			forceWorkerDataCopy: false,111			started: false,112			queuedMessage: null,113			callbacks: {114				onAssetAvailable: null,115				onLoad: null,116				terminate: scopeTerminate117			}118		};119	},120	/**121	 * Enable or disable logging in general (except warn and error), plus enable or disable debug logging.122	 *123	 * @param {boolean} enabled True or false.124	 * @param {boolean} debug True or false.125	 */126	setLogging: function ( enabled, debug ) {127		this.logging.enabled = enabled === true;128		this.logging.debug = debug === true;129		this.worker.logging = enabled === true;130		return this;131	},132	/**133	 * Forces all ArrayBuffers to be transferred to worker to be copied.134	 *135	 * @param {boolean} forceWorkerDataCopy True or false.136	 */137	setForceWorkerDataCopy: function ( forceWorkerDataCopy ) {138		this.worker.forceWorkerDataCopy = forceWorkerDataCopy === true;139		return this;140	},141	/**142	 * Request termination of worker once parser is finished.143	 *144	 * @param {boolean} terminateWorkerOnLoad True or false.145	 */146	setTerminateWorkerOnLoad: function ( terminateWorkerOnLoad ) {147		this.worker.terminateWorkerOnLoad = terminateWorkerOnLoad === true;148		if ( this.worker.terminateWorkerOnLoad && this.isWorkerLoaded( this.worker.jsmWorker ) &&149				this.worker.queuedMessage === null && this.worker.started ) {150			if ( this.logging.enabled ) {151				console.info( 'Worker is terminated immediately as it is not running!' );152			}153			this._terminate();154		}155		return this;156	},157	/**158	 * Update all callbacks.159	 *160	 * @param {Function} onAssetAvailable The function for processing the data, e.g. {@link MeshReceiver}.161	 * @param {Function} [onLoad] The function that is called when parsing is complete.162	 */163	updateCallbacks: function ( onAssetAvailable, onLoad ) {164		if ( onAssetAvailable !== undefined && onAssetAvailable !== null ) {165			this.worker.callbacks.onAssetAvailable = onAssetAvailable;166		}167		if ( onLoad !== undefined && onLoad !== null ) {168			this.worker.callbacks.onLoad = onLoad;169		}170		this._verifyCallbacks();171	},172	_verifyCallbacks: function () {173		if ( this.worker.callbacks.onAssetAvailable === undefined || this.worker.callbacks.onAssetAvailable === null ) {174			throw 'Unable to run as no "onAssetAvailable" callback is set.';175		}176	},177	/**178	 * Builds the worker code according the provided Instructions.179	 * If jsm worker code shall be built, then function may fall back to standard if lag is set180	 *181 	 * @param {CodeBuilderInstructions} codeBuilderInstructions182	 */183	buildWorker: function ( codeBuilderInstructions ) {184		let jsmSuccess = false;185		if ( codeBuilderInstructions.isSupportsJsmWorker() && codeBuilderInstructions.isPreferJsmWorker() ) {186			jsmSuccess = this._buildWorkerJsm( codeBuilderInstructions );187		}188		if ( ! jsmSuccess && codeBuilderInstructions.isSupportsStandardWorker() ) {189			this._buildWorkerStandard( codeBuilderInstructions );190		}191	},192	/**193	 *194	 * @param {CodeBuilderInstructions} codeBuilderInstructions195	 * @return {boolean} Whether loading of jsm worker was successful196	 * @private197	 */198	_buildWorkerJsm: function ( codeBuilderInstructions ) {199		let jsmSuccess = true;200		let timeLabel = 'buildWorkerJsm';201		let workerAvailable = this._buildWorkerCheckPreconditions( true, timeLabel );202		if ( ! workerAvailable ) {203			try {204				let worker = new Worker( codeBuilderInstructions.jsmWorkerUrl.href, { type: "module" } );205				this._configureWorkerCommunication( worker, true, codeBuilderInstructions.defaultGeometryType, timeLabel );206			} catch ( e ) {207				jsmSuccess = false;208				// Chrome throws this exception, but Firefox currently does not complain, but can't execute the worker afterwards209				if ( e instanceof TypeError || e instanceof SyntaxError ) {210					console.error( "Modules are not supported in workers." );211				}212			}213		}214		return jsmSuccess;215	},216	/**217	 * Validate the status of worker code and the derived worker and specify functions that should be build when new raw mesh data becomes available and when the parser is finished.218	 *219	 * @param {CodeBuilderIns} buildWorkerCode The function that is invoked to create the worker code of the parser.220	 */221	/**222	 *223	 * @param {CodeBuilderInstructions} codeBuilderInstructions224	 * @private225	 */226	_buildWorkerStandard: function ( codeBuilderInstructions ) {227		let timeLabel = 'buildWorkerStandard';228		let workerAvailable = this._buildWorkerCheckPreconditions( false, timeLabel );229		if ( ! workerAvailable ) {230			let concatenateCode = '';231			codeBuilderInstructions.getImportStatements().forEach( function ( element ) {232				concatenateCode += element + '\n';233			} );234			concatenateCode += '\n';235			codeBuilderInstructions.getCodeFragments().forEach( function ( element ) {236				concatenateCode += element + '\n';237			} );238			concatenateCode += '\n';239			concatenateCode += codeBuilderInstructions.getStartCode();240			let blob = new Blob( [ concatenateCode ], { type: 'application/javascript' } );241			let worker = new Worker( window.URL.createObjectURL( blob ) );242			this._configureWorkerCommunication( worker, false, codeBuilderInstructions.defaultGeometryType, timeLabel );243		}244	},245	_buildWorkerCheckPreconditions: function ( requireJsmWorker, timeLabel ) {246		let workerAvailable = false;247		if ( this.isWorkerLoaded( requireJsmWorker ) ) {248			workerAvailable = true;249		} else {250			if ( this.logging.enabled ) {251				console.info( 'WorkerExecutionSupport: Building ' + ( requireJsmWorker ? 'jsm' : 'standard' ) + ' worker code...' );252				console.time( timeLabel );253			}254		}255		return workerAvailable;256	},257	_configureWorkerCommunication: function ( worker, haveJsmWorker, defaultGeometryType, timeLabel ) {258		this.worker.native = worker;259		this.worker.jsmWorker = haveJsmWorker;260		let scope = this;261		let scopedReceiveWorkerMessage = function ( event ) {262			scope._receiveWorkerMessage( event );263		};264		this.worker.native.onmessage = scopedReceiveWorkerMessage;265		this.worker.native.onerror = scopedReceiveWorkerMessage;266		if ( defaultGeometryType !== undefined && defaultGeometryType !== null ) {267			this.worker.workerRunner.defaultGeometryType = defaultGeometryType;268		}269		if ( this.logging.enabled ) {270			console.timeEnd( timeLabel );271		}272	},273	/**274	 * Returns if Worker code is available and complies with expectation.275	 * @param {boolean} requireJsmWorker276	 * @return {boolean|*}277	 */278	isWorkerLoaded: function ( requireJsmWorker ) {279		return this.worker.native !== null &&280			( ( requireJsmWorker && this.worker.jsmWorker ) || ( ! requireJsmWorker && ! this.worker.jsmWorker ) );281	},282	/**283	 * Executed in worker scope284	 */285	_receiveWorkerMessage: function ( event ) {286		// fast-fail in case of error287		if ( event.type === "error" ) {288			console.error( event );289			return;290		}291		let payload = event.data;292		let workerRunnerName = this.worker.workerRunner.name;293		switch ( payload.cmd ) {294			case 'assetAvailable':295				this.worker.callbacks.onAssetAvailable( payload );296				break;297			case 'completeOverall':298				this.worker.queuedMessage = null;299				this.worker.started = false;300				if ( this.worker.callbacks.onLoad !== null ) {301					this.worker.callbacks.onLoad( payload.msg );302				}303				if ( this.worker.terminateWorkerOnLoad ) {304					if ( this.worker.logging.enabled ) {305						console.info( 'WorkerSupport [' + workerRunnerName + ']: Run is complete. Terminating application on request!' );306					}307					this.worker.callbacks.terminate();308				}309				break;310			case 'error':311				console.error( 'WorkerSupport [' + workerRunnerName + ']: Reported error: ' + payload.msg );312				this.worker.queuedMessage = null;313				this.worker.started = false;314				if ( this.worker.callbacks.onLoad !== null ) {315					this.worker.callbacks.onLoad( payload.msg );316				}317				if ( this.worker.terminateWorkerOnLoad ) {318					if ( this.worker.logging.enabled ) {319						console.info( 'WorkerSupport [' + workerRunnerName + ']: Run reported error. Terminating application on request!' );320					}321					this.worker.callbacks.terminate();322				}323				break;324			default:325				console.error( 'WorkerSupport [' + workerRunnerName + ']: Received unknown command: ' + payload.cmd );326				break;327		}328	},329	/**330	 * Runs the parser with the provided configuration.331	 *332	 * @param {Object} payload Raw mesh description (buffers, params, materials) used to build one to many meshes.333	 */334	executeParallel: function ( payload, transferables ) {335		payload.cmd = 'parse';336		payload.usesMeshDisassembler = this.worker.workerRunner.usesMeshDisassembler;337		payload.defaultGeometryType = this.worker.workerRunner.defaultGeometryType;338		if ( ! this._verifyWorkerIsAvailable( payload, transferables ) ) return;339		this._postMessage();340	},341	_verifyWorkerIsAvailable: function ( payload, transferables ) {342		this._verifyCallbacks();343		let ready = true;344		if ( this.worker.queuedMessage !== null ) {345			console.warn( 'Already processing message. Rejecting new run instruction' );346			ready = false;347		} else {348			this.worker.queuedMessage = {349				payload: payload,350				transferables: ( transferables === undefined || transferables === null ) ? [] : transferables351			};352			this.worker.started = true;353		}354		return ready;355	},356	_postMessage: function () {357		if ( this.worker.queuedMessage !== null ) {358			if ( this.worker.queuedMessage.payload.data.input instanceof ArrayBuffer ) {359				let transferables = [];360				if ( this.worker.forceWorkerDataCopy ) {361					transferables.push( this.worker.queuedMessage.payload.data.input.slice( 0 ) );362				} else {363					transferables.push( this.worker.queuedMessage.payload.data.input );364				}365				if ( this.worker.queuedMessage.transferables.length > 0 ) {366					transferables = transferables.concat( this.worker.queuedMessage.transferables );367				}368				this.worker.native.postMessage( this.worker.queuedMessage.payload, transferables );369			} else {370				this.worker.native.postMessage( this.worker.queuedMessage.payload );371			}372		}373	},374	_terminate: function () {375		this.worker.native.terminate();376		this._reset();377	}378};379export {380	CodeBuilderInstructions,381	WorkerExecutionSupport...miner_stats.js
Source:miner_stats.js  
1var workerHashrateData;2var workerHashrateChart;3var workerHistoryMax = 160;4var statData;5var totalHash;6var totalImmature;7var totalBal;8var totalPaid;9var totalShares;10function getReadableHashRateString(hashrate){11	hashrate = (hashrate * 2);12	if (hashrate < 1000000) {13		return (Math.round(hashrate / 1000) / 1000 ).toFixed(2)+' Sol/s';14	}15	var byteUnits = [ ' Sol/s', ' KSol/s', ' MSol/s', ' GSol/s', ' TSol/s', ' PSol/s' ];16	var i = Math.floor((Math.log(hashrate/1000) / Math.log(1000)) - 1);17	hashrate = (hashrate/1000) / Math.pow(1000, i + 1);18	return hashrate.toFixed(2) + byteUnits[i];19}20function timeOfDayFormat(timestamp){21    var dStr = d3.time.format('%I:%M %p')(new Date(timestamp));22    if (dStr.indexOf('0') === 0) dStr = dStr.slice(1);23    return dStr;24}25function getWorkerNameFromAddress(w) {26	var worker = w;27	if (w.split(".").length > 1) {28		worker = w.split(".")[1];29		if (worker == null || worker.length < 1) {30			worker = "noname";31		}32	} else {33		worker = "noname";34	}35	return worker;36}37function buildChartData(){38    var workers = {};39	for (var w in statData.history) {40		var worker = getWorkerNameFromAddress(w);41		var a = workers[worker] = (workers[worker] || {42			hashrate: []43		});44		for (var wh in statData.history[w]) {45			a.hashrate.push([statData.history[w][wh].time * 1000, statData.history[w][wh].hashrate]);46		}47		if (a.hashrate.length > workerHistoryMax) {48			workerHistoryMax = a.hashrate.length;49		}50	}51	52	var i=0;53    workerHashrateData = [];54    for (var worker in workers){55        workerHashrateData.push({56            key: worker,57			disabled: (i > Math.min((_workerCount-1), 3)),58            values: workers[worker].hashrate59        });60		i++;61    }62}63function updateChartData(){64    var workers = {};65	for (var w in statData.history) {66		var worker = getWorkerNameFromAddress(w);67		// get a reference to lastest workerhistory68		for (var wh in statData.history[w]) { }69		//var wh = statData.history[w][statData.history[w].length - 1];70		var foundWorker = false;71		for (var i = 0; i < workerHashrateData.length; i++) {72			if (workerHashrateData[i].key === worker) {73				foundWorker = true;74				if (workerHashrateData[i].values.length >= workerHistoryMax) {75					workerHashrateData[i].values.shift();76				}77				workerHashrateData[i].values.push([statData.history[w][wh].time * 1000, statData.history[w][wh].hashrate]);78				break;79			}80		}81		if (!foundWorker) {82			var hashrate = [];83			hashrate.push([statData.history[w][wh].time * 1000, statData.history[w][wh].hashrate]);84			workerHashrateData.push({85				key: worker,86				values: hashrate87			});88			rebuildWorkerDisplay();89			return true;90		}91	}92	triggerChartUpdates();93	return false;94}95function calculateAverageHashrate(worker) {96	var count = 0;97	var total = 1;98	var avg = 0;99	for (var i = 0; i < workerHashrateData.length; i++) {100		count = 0;101		for (var ii = 0; ii < workerHashrateData[i].values.length; ii++) {102			if (worker == null || workerHashrateData[i].key === worker) {103				count++;104				avg += parseFloat(workerHashrateData[i].values[ii][1]);105			}106		}107		if (count > total)108			total = count;109	}110	avg = avg / total;111	return avg;112}113function triggerChartUpdates(){114    workerHashrateChart.update();115}116function displayCharts() {117    nv.addGraph(function() {118        workerHashrateChart = nv.models.lineChart()119            .margin({left: 80, right: 30})120            .x(function(d){ return d[0] })121            .y(function(d){ return d[1] })122            .useInteractiveGuideline(true);123        workerHashrateChart.xAxis.tickFormat(timeOfDayFormat);124        workerHashrateChart.yAxis.tickFormat(function(d){125            return getReadableHashRateString(d);126        });127        d3.select('#workerHashrate').datum(workerHashrateData).call(workerHashrateChart);128        return workerHashrateChart;129    });130}131function updateStats() {132	totalHash = statData.totalHash;133	totalPaid = statData.paid;134	totalBal = statData.balance;135	totalImmature = statData.immature;136	totalShares = statData.totalShares;137	// do some calculations138	var _blocktime = 250;139	var _networkHashRate = parseFloat(statData.networkSols) * 1.2;140	var _myHashRate = (totalHash / 1000000) * 2;141	var luckDays =  ((_networkHashRate / _myHashRate * _blocktime) / (24 * 60 * 60)).toFixed(3);142	// update miner stats143	$("#statsHashrate").text(getReadableHashRateString(totalHash));144	$("#statsHashrateAvg").text(getReadableHashRateString(calculateAverageHashrate(null)));145	$("#statsLuckDays").text(luckDays);146	$("#statsTotalImmature").text(totalImmature);147	$("#statsTotalBal").text(totalBal);148	$("#statsTotalPaid").text(totalPaid);149	$("#statsTotalShares").text(totalShares.toFixed(2));150}151function updateWorkerStats() {152	// update worker stats153	var i=0;154	for (var w in statData.workers) { i++;155		var htmlSafeWorkerName = w.split('.').join('_').replace(/[^\w\s]/gi, '');156		var saneWorkerName = getWorkerNameFromAddress(w);157		$("#statsHashrate"+htmlSafeWorkerName).text(getReadableHashRateString(statData.workers[w].hashrate));158		$("#statsHashrateAvg"+htmlSafeWorkerName).text(getReadableHashRateString(calculateAverageHashrate(saneWorkerName)));159		$("#statsLuckDays"+htmlSafeWorkerName).text(statData.workers[w].luckDays);160		$("#statsPaid"+htmlSafeWorkerName).text(statData.workers[w].paid);161		$("#statsBalance"+htmlSafeWorkerName).text(statData.workers[w].balance);162		$("#statsShares"+htmlSafeWorkerName).text(Math.round(statData.workers[w].currRoundShares * 100) / 100);163		$("#statsDiff"+htmlSafeWorkerName).text(statData.workers[w].diff);164	}165}166function addWorkerToDisplay(name, htmlSafeName, workerObj) {167	var htmlToAdd = "";168	htmlToAdd = '<div class="boxStats" id="boxStatsLeft" style="float:left; margin: 9px; min-width: 260px;"><div class="boxStatsList">';169	if (htmlSafeName.indexOf("_") >= 0) {170		htmlToAdd+= '<div class="boxLowerHeader">'+htmlSafeName.substr(htmlSafeName.indexOf("_")+1,htmlSafeName.length)+'</div>';171	} else {172		htmlToAdd+= '<div class="boxLowerHeader">noname</div>';173	}174	htmlToAdd+='<div><i class="fa fa-tachometer"></i> <span id="statsHashrate'+htmlSafeName+'">'+getReadableHashRateString(workerObj.hashrate)+'</span> (Now)</div>';175	htmlToAdd+='<div><i class="fa fa-tachometer"></i> <span id="statsHashrateAvg'+htmlSafeName+'">'+getReadableHashRateString(calculateAverageHashrate(name))+'</span> (Avg)</div>';176	htmlToAdd+='<div><i class="fa fa-shield"></i> <small>Diff:</small> <span id="statsDiff'+htmlSafeName+'">'+workerObj.diff+'</span></div>';177	htmlToAdd+='<div><i class="fa fa-cog"></i> <small>Shares:</small> <span id="statsShares'+htmlSafeName+'">'+(Math.round(workerObj.currRoundShares * 100) / 100)+'</span></div>';178	htmlToAdd+='<div><i class="fa fa-gavel"></i> <small>Luck <span id="statsLuckDays'+htmlSafeName+'">'+workerObj.luckDays+'</span> Days</small></div>';179	htmlToAdd+='<div><i class="fa fa-money"></i> <small>Bal: <span id="statsBalance'+htmlSafeName+'">'+workerObj.balance+'</span></small></div>';180	htmlToAdd+='<div><i class="fa fa-money"></i> <small>Paid: <span id="statsPaid'+htmlSafeName+'">'+workerObj.paid+'</span></small></div>';181	htmlToAdd+='</div></div></div>';182	$("#boxesWorkers").html($("#boxesWorkers").html()+htmlToAdd);183}184function rebuildWorkerDisplay() {185	$("#boxesWorkers").html("");186	var i=0;187	for (var w in statData.workers) { i++;188		var htmlSafeWorkerName = w.split('.').join('_').replace(/[^\w\s]/gi, '');189		var saneWorkerName = getWorkerNameFromAddress(w);190		addWorkerToDisplay(saneWorkerName, htmlSafeWorkerName, statData.workers[w]);191	}192}193// resize chart on window resize194nv.utils.windowResize(triggerChartUpdates);195// grab initial stats196$.getJSON('/api/worker_stats?'+_miner, function(data){197    statData = data;198	for (var w in statData.workers) { _workerCount++; }199	buildChartData();200	displayCharts();201	rebuildWorkerDisplay();	202    updateStats();203});204// live stat updates205statsSource.addEventListener('message', function(e){206	// TODO, create miner_live_stats...207	// miner_live_stats will return the same josn except without the worker history208	// FOR NOW, use this to grab updated stats209	$.getJSON('/api/worker_stats?'+_miner, function(data){210		statData = data;211		// check for missing workers212		var wc = 0;213		var rebuilt = false;214		// update worker stats215		for (var w in statData.workers) { wc++; }216		// TODO, this isn't 100% fool proof!217		if (_workerCount != wc) {218			if (_workerCount > wc) {219				rebuildWorkerDisplay();220				rebuilt = true;221			}222			_workerCount = wc;223		}224		rebuilt = (rebuilt || updateChartData());225		updateStats();226		if (!rebuilt) {227			updateWorkerStats();228		}229	});...WorkerManager.js
Source:WorkerManager.js  
1/*2 * Copyright (C) 2011 Google Inc. All rights reserved.3 *4 * Redistribution and use in source and binary forms, with or without5 * modification, are permitted provided that the following conditions are6 * met:7 *8 *     * Redistributions of source code must retain the above copyright9 * notice, this list of conditions and the following disclaimer.10 *     * Redistributions in binary form must reproduce the above11 * copyright notice, this list of conditions and the following disclaimer12 * in the documentation and/or other materials provided with the13 * distribution.14 *     * Neither the name of Google Inc. nor the names of its15 * contributors may be used to endorse or promote products derived from16 * this software without specific prior written permission.17 *18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.29 */30/**31 * @constructor32 * @extends {WebInspector.Object}33 */34WebInspector.WorkerManager = function()35{36    this._workerIdToWindow = {};37    InspectorBackend.registerWorkerDispatcher(new WebInspector.DedicatedWorkerMessageForwarder(this));38}39WebInspector.WorkerManager.isWorkerFrontend = function()40{41    return !!WebInspector.queryParamsObject["dedicatedWorkerId"] ||42           !!WebInspector.queryParamsObject["isSharedWorker"];43}44WebInspector.WorkerManager.loaded = function()45{46    var workerId = WebInspector.queryParamsObject["dedicatedWorkerId"];47    if (workerId)48        WebInspector.WorkerManager._initializeDedicatedWorkerFrontend(workerId);49    else50        WebInspector.workerManager = new WebInspector.WorkerManager();51    if (WebInspector.WorkerManager.isWorkerFrontend())52        WebInspector.WorkerManager._calculateWorkerInspectorTitle();53}54WebInspector.WorkerManager._initializeDedicatedWorkerFrontend = function(workerId)55{56    function receiveMessage(event)57    {58        var message = event.data;59        InspectorBackend.dispatch(message);60    }61    window.addEventListener("message", receiveMessage, true);62    InspectorBackend.sendMessageObjectToBackend = function(message)63    {64        window.opener.postMessage({workerId: workerId, command: "sendMessageToBackend", message: message}, "*");65    }66    InspectorFrontendHost.loaded = function()67    {68        window.opener.postMessage({workerId: workerId, command: "loaded"}, "*");69    }70}71WebInspector.WorkerManager._calculateWorkerInspectorTitle = function()72{73    var expression = "location.href";74    if (WebInspector.queryParamsObject["isSharedWorker"])75        expression += " + (this.name ? ' (' + this.name + ')' : '')";76    RuntimeAgent.evaluate.invoke({expression:expression, doNotPauseOnExceptions:true, returnByValue: true}, evalCallback.bind(this));77    function evalCallback(error, result, wasThrown)78    {79        if (error || wasThrown) {80            console.error(error);81            return;82        }83        InspectorFrontendHost.inspectedURLChanged(result.value);84    }85}86WebInspector.WorkerManager.Events = {87    WorkerAdded: "worker-added",88    WorkerRemoved: "worker-removed",89    WorkersCleared: "workers-cleared",90    WorkerInspectorClosed: "worker-inspector-closed"91}92WebInspector.WorkerManager.prototype = {93    _workerCreated: function(workerId, url, inspectorConnected)94     {95        if (inspectorConnected)96            this._openInspectorWindow(workerId);97        this.dispatchEventToListeners(WebInspector.WorkerManager.Events.WorkerAdded, {workerId: workerId, url: url, inspectorConnected: inspectorConnected});98     },99    _workerTerminated: function(workerId)100     {101        this.closeWorkerInspector(workerId);102        this.dispatchEventToListeners(WebInspector.WorkerManager.Events.WorkerRemoved, workerId);103     },104    _sendMessageToWorkerInspector: function(workerId, message)105    {106        var workerInspectorWindow = this._workerIdToWindow[workerId];107        if (workerInspectorWindow)108            workerInspectorWindow.postMessage(message, "*");109    },110    openWorkerInspector: function(workerId)111    {112        this._openInspectorWindow(workerId);113        WorkerAgent.connectToWorker(workerId);114    },115    _openInspectorWindow: function(workerId)116    {117        var url = window.location.href + "&dedicatedWorkerId=" + workerId;118        url = url.replace("docked=true&", "");119        // Set location=0 just to make sure the front-end will be opened in a separate window, not in new tab.120        var workerInspectorWindow = window.open(url, undefined, "location=0");121        this._workerIdToWindow[workerId] = workerInspectorWindow;122        workerInspectorWindow.addEventListener("beforeunload", this._workerInspectorClosing.bind(this, workerId), true);123        // Listen to beforeunload in detached state and to the InspectorClosing event in case of attached inspector.124        window.addEventListener("beforeunload", this._pageInspectorClosing.bind(this), true);125        WebInspector.notifications.addEventListener(WebInspector.Events.InspectorClosing, this._pageInspectorClosing, this);126    },127    closeWorkerInspector: function(workerId)128    {129        var workerInspectorWindow = this._workerIdToWindow[workerId];130        if (workerInspectorWindow)131            workerInspectorWindow.close();132    },133    reset: function()134    {135        for (var workerId in this._workerIdToWindow)136            this.closeWorkerInspector(workerId);137        this.dispatchEventToListeners(WebInspector.WorkerManager.Events.WorkersCleared);138    },139    _pageInspectorClosing: function()140    {141        this._ignoreWorkerInspectorClosing = true;142        for (var workerId in this._workerIdToWindow) {143            this._workerIdToWindow[workerId].close();144            WorkerAgent.disconnectFromWorker(parseInt(workerId, 10));145        }146    },147    _workerInspectorClosing: function(workerId, event)148    {149        if (this._ignoreWorkerInspectorClosing)150            return;151        delete this._workerIdToWindow[workerId];152        WorkerAgent.disconnectFromWorker(workerId);153        this.dispatchEventToListeners(WebInspector.WorkerManager.Events.WorkerInspectorClosed, workerId);154    }155}156WebInspector.WorkerManager.prototype.__proto__ = WebInspector.Object.prototype;157/**158 * @constructor159 * @implements {WorkerAgent.Dispatcher}160 */161WebInspector.DedicatedWorkerMessageForwarder = function(workerManager)162{163    this._workerManager = workerManager;164    window.addEventListener("message", this._receiveMessage.bind(this), true);165}166WebInspector.DedicatedWorkerMessageForwarder.prototype = {167    _receiveMessage: function(event)168    {169        var workerId = event.data["workerId"];170        workerId = parseInt(workerId, 10);171        var command = event.data.command;172        var message = event.data.message;173        if (command == "sendMessageToBackend")174            WorkerAgent.sendMessageToWorker(workerId, message);175    },176    workerCreated: function(workerId, url, inspectorConnected)177    {178        this._workerManager._workerCreated(workerId, url, inspectorConnected);179    },180    workerTerminated: function(workerId)181    {182        this._workerManager._workerTerminated(workerId);183    },184    dispatchMessageFromWorker: function(workerId, message)185    {186        this._workerManager._sendMessageToWorkerInspector(workerId, message);187    }...WorkersSidebarPane.js
Source:WorkersSidebarPane.js  
1/*2 * Copyright (C) 2010 Google Inc. All rights reserved.3 *4 * Redistribution and use in source and binary forms, with or without5 * modification, are permitted provided that the following conditions are6 * met:7 *8 *     * Redistributions of source code must retain the above copyright9 * notice, this list of conditions and the following disclaimer.10 *     * Redistributions in binary form must reproduce the above11 * copyright notice, this list of conditions and the following disclaimer12 * in the documentation and/or other materials provided with the13 * distribution.14 *     * Neither the name of Google Inc. nor the names of its15 * contributors may be used to endorse or promote products derived from16 * this software without specific prior written permission.17 *18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.29 */30/**31 * @constructor32 * @extends {WebInspector.SidebarPane}33 */34WebInspector.WorkersSidebarPane = function()35{36    WebInspector.SidebarPane.call(this, WebInspector.UIString("Workers"));37    this._workers = {};38    this._enableWorkersCheckbox = new WebInspector.Checkbox(39        WebInspector.UIString("Debug"),40        "sidebar-pane-subtitle",41        WebInspector.UIString("Allow debugging workers. Enabling this option will replace native workers with the iframe-based JavaScript implementation"));42    this.titleElement.insertBefore(this._enableWorkersCheckbox.element, this.titleElement.firstChild);43    this._enableWorkersCheckbox.addEventListener(this._onTriggerInstrument.bind(this));44    this._enableWorkersCheckbox.checked = false;45    this._listElement = document.createElement("ol");46    this._listElement.className = "workers-list";47    this.bodyElement.appendChild(this._listElement);48    this._treeOutline = new TreeOutline(this._listElement);49}50WebInspector.WorkersSidebarPane.prototype = {51    addWorker: function(id, url, isShared)52    {53        if (id in this._workers)54            return;55        var worker = new WebInspector.Worker(id, url, isShared);56        this._workers[id] = worker;57        var title = WebInspector.linkifyURL(url, WebInspector.displayNameForURL(url), "worker-item", true, url);58        var treeElement = new TreeElement(null, worker, false);59        treeElement.titleHTML = title;60        this._treeOutline.appendChild(treeElement);61    },62    removeWorker: function(id)63    {64        if (id in this._workers) {65            this._treeOutline.removeChild(this._treeOutline.getCachedTreeElement(this._workers[id]));66            delete this._workers[id];67        }68    },69    setInstrumentation: function(enabled)70    {71        PageAgent.removeAllScriptsToEvaluateOnLoad();72        if (enabled)73            PageAgent.addScriptToEvaluateOnLoad("(" + InjectedFakeWorker + ")");74    },75    reset: function()76    {77        this.setInstrumentation(this._enableWorkersCheckbox.checked);78        this._treeOutline.removeChildren();79        this._workers = {};80    },81    _onTriggerInstrument: function(event)82    {83        this.setInstrumentation(this._enableWorkersCheckbox.checked);84    }85};86WebInspector.WorkersSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype;87/**88 * @constructor89 */90WebInspector.Worker = function(id, url, shared)91{92    this.id = id;93    this.url = url;94    this.shared = shared;95}96/**97 * @constructor98 * @extends {WebInspector.SidebarPane}99 */100WebInspector.WorkerListSidebarPane = function(workerManager)101{102    WebInspector.SidebarPane.call(this, WebInspector.UIString("Worker inspectors"));103    this._enableWorkersCheckbox = new WebInspector.Checkbox(104        WebInspector.UIString("Debug"),105        "sidebar-pane-subtitle",106        WebInspector.UIString("Automatically attach to new workers. Enabling this option will force opening inspector for all new workers."));107    this.titleElement.insertBefore(this._enableWorkersCheckbox.element, this.titleElement.firstChild);108    this._enableWorkersCheckbox.addEventListener(this._autoattachToWorkersClicked.bind(this));109    this._enableWorkersCheckbox.checked = false;110    this._workerListElement = document.createElement("ol");111    this._workerListElement.tabIndex = 0;112    this._workerListElement.addStyleClass("properties-tree");113    this._workerListTreeOutline = new TreeOutline(this._workerListElement);114    this.bodyElement.appendChild(this._workerListElement);115    this._idToWorkerItem = {};116    this._workerManager = workerManager;117    workerManager.addEventListener(WebInspector.WorkerManager.Events.WorkerAdded, this._workerAdded, this);118    workerManager.addEventListener(WebInspector.WorkerManager.Events.WorkerRemoved, this._workerRemoved, this);119    workerManager.addEventListener(WebInspector.WorkerManager.Events.WorkersCleared, this._workersCleared, this);120    workerManager.addEventListener(WebInspector.WorkerManager.Events.WorkerInspectorClosed, this._workerInspectorClosed, this);121}122WebInspector.WorkerListSidebarPane.prototype = {123    _workerAdded: function(event)124    {125        this._addWorker(event.data.workerId, event.data.url, event.data.inspectorConnected);126    },127    _workerRemoved: function(event)128    {129        var workerItem = this._idToWorkerItem[event.data];130        delete this._idToWorkerItem[event.data];131        workerItem.element.parent.removeChild(workerItem.element);132    },133    _workerInspectorClosed: function(event)134    {135        var workerItem = this._idToWorkerItem[event.data];136        workerItem.checkbox.checked = false;137    },138    _workersCleared: function(event)139    {140        this._idToWorkerItem = {};141        this._workerListTreeOutline.removeChildren();142    },143    _addWorker: function(workerId, url, inspectorConnected)144    {145        var workerItem = {};146        workerItem.workerId = workerId;147        workerItem.element = new TreeElement(url);148        this._workerListTreeOutline.appendChild(workerItem.element);149        workerItem.element.selectable = true;150        workerItem.checkbox = this._createCheckbox(workerItem.element);151        workerItem.checkbox.checked = inspectorConnected;152        workerItem.checkbox.addEventListener("click", this._workerItemClicked.bind(this, workerItem), true);153        this._idToWorkerItem[workerId] = workerItem;154    },155    _createCheckbox: function(treeElement)156    {157        var checkbox = document.createElement("input");158        checkbox.className = "checkbox-elem";159        checkbox.type = "checkbox";160        treeElement.listItemElement.insertBefore(checkbox, treeElement.listItemElement.firstChild);161        return checkbox;162    },163    _workerItemClicked: function(workerItem, event)164    {165        if (event.target.checked)166            this._workerManager.openWorkerInspector(workerItem.workerId);167        else168            this._workerManager.closeWorkerInspector(workerItem.workerId);169    },170    _autoattachToWorkersClicked: function(event)171    {172        WorkerAgent.setAutoconnectToWorkers(event.target.checked);173    }174}...NodeThreadsWorker.test.js
Source:NodeThreadsWorker.test.js  
1/**2 * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.3 *4 * This source code is licensed under the MIT license found in the5 * LICENSE file in the root directory of this source tree.6 */7'use strict';8/* eslint-disable no-new */9import {10  CHILD_MESSAGE_CALL,11  CHILD_MESSAGE_INITIALIZE,12  PARENT_MESSAGE_OK,13  PARENT_MESSAGE_CLIENT_ERROR,14} from '../../types';15let Worker;16let childProcess;17let originalExecArgv;18beforeEach(() => {19  jest.mock('worker_threads', () => {20    const fakeClass = jest.fn(() => {21      const EventEmitter = require('events');22      const thread = new EventEmitter();23      thread.postMessage = jest.fn();24      thread.stdout = 'stdout';25      thread.stderr = 'stderr';26      return thread;27    });28    return {29      Worker: fakeClass,30    };31  });32  originalExecArgv = process.execArgv;33  childProcess = require('worker_threads').Worker;34  childProcess.postMessage = jest.fn();35  Worker = require('../NodeThreadsWorker').default;36});37afterEach(() => {38  jest.resetModules();39  process.execArgv = originalExecArgv;40});41it('passes fork options down to child_process.fork, adding the defaults', () => {42  const child = require.resolve('../threadChild');43  process.execArgv = ['--inspect', '-p'];44  new Worker({45    forkOptions: {46      cwd: '/tmp',47      execPath: 'hello',48    },49    maxRetries: 3,50    workerId: process.env.JEST_WORKER_ID,51    workerPath: '/tmp/foo/bar/baz.js',52  });53  expect(childProcess.mock.calls[0][0]).toBe(child);54  expect(childProcess.mock.calls[0][1]).toEqual({55    eval: false,56    stderr: true,57    stdout: true,58    workerData: {59      cwd: '/tmp', // Overridden default option.60      env: process.env, // Default option.61      execArgv: ['-p'], // Filtered option.62      execPath: 'hello', // Added option.63      silent: true, // Default option.64    },65  });66});67it('passes workerId to the child process and assign it to env.JEST_WORKER_ID', () => {68  new Worker({69    forkOptions: {},70    maxRetries: 3,71    workerId: 2,72    workerPath: '/tmp/foo',73  });74  expect(childProcess.mock.calls[0][1].workerData.env.JEST_WORKER_ID).toEqual(75    2,76  );77});78it('initializes the child process with the given workerPath', () => {79  const worker = new Worker({80    forkOptions: {},81    maxRetries: 3,82    setupArgs: ['foo', 'bar'],83    workerPath: '/tmp/foo/bar/baz.js',84  });85  expect(worker._worker.postMessage.mock.calls[0][0]).toEqual([86    CHILD_MESSAGE_INITIALIZE,87    false,88    '/tmp/foo/bar/baz.js',89    ['foo', 'bar'],90  ]);91});92it('stops initializing the worker after the amount of retries is exceeded', () => {93  const worker = new Worker({94    forkOptions: {},95    maxRetries: 3,96    workerPath: '/tmp/foo/bar/baz.js',97  });98  const request = [CHILD_MESSAGE_CALL, false, 'foo', []];99  const onProcessStart = jest.fn();100  const onProcessEnd = jest.fn();101  worker.send(request, onProcessStart, onProcessEnd);102  // We fail four times (initial + three retries).103  worker._worker.emit('exit');104  worker._worker.emit('exit');105  worker._worker.emit('exit');106  worker._worker.emit('exit');107  expect(childProcess).toHaveBeenCalledTimes(5);108  expect(onProcessStart).toBeCalledWith(worker);109  expect(onProcessEnd).toHaveBeenCalledTimes(1);110  expect(onProcessEnd.mock.calls[0][0]).toBeInstanceOf(Error);111  expect(onProcessEnd.mock.calls[0][0].type).toBe('WorkerError');112  expect(onProcessEnd.mock.calls[0][1]).toBe(null);113});114it('provides stdout and stderr fields from the child process', () => {115  const worker = new Worker({116    forkOptions: {},117    maxRetries: 3,118    workerPath: '/tmp/foo',119  });120  expect(worker.getStdout()).toBe('stdout');121  expect(worker.getStderr()).toBe('stderr');122});123it('sends the task to the child process', () => {124  const worker = new Worker({125    forkOptions: {},126    maxRetries: 3,127    workerPath: '/tmp/foo',128  });129  const request = [CHILD_MESSAGE_CALL, false, 'foo', []];130  worker.send(request, () => {}, () => {});131  // Skipping call "0" because it corresponds to the "initialize" one.132  expect(worker._worker.postMessage.mock.calls[1][0]).toEqual(request);133});134it('calls the onProcessStart method synchronously if the queue is empty', () => {135  const worker = new Worker({136    forkOptions: {},137    maxRetries: 3,138    workerPath: '/tmp/foo',139  });140  const onProcessStart = jest.fn();141  const onProcessEnd = jest.fn();142  worker.send(143    [CHILD_MESSAGE_CALL, false, 'foo', []],144    onProcessStart,145    onProcessEnd,146  );147  // Only onProcessStart has been called148  expect(onProcessStart).toHaveBeenCalledTimes(1);149  expect(onProcessEnd).not.toHaveBeenCalled();150  // then first call replies...151  worker._worker.emit('message', [PARENT_MESSAGE_OK]);152  expect(onProcessEnd).toHaveBeenCalledTimes(1);153});154it('creates error instances for known errors', () => {155  const worker = new Worker({156    forkOptions: {},157    maxRetries: 3,158    workerPath: '/tmp/foo',159  });160  const callback1 = jest.fn();161  const callback2 = jest.fn();162  const callback3 = jest.fn();163  // Testing a generic ECMAScript error.164  worker.send([CHILD_MESSAGE_CALL, false, 'method', []], () => {}, callback1);165  worker._worker.emit('message', [166    PARENT_MESSAGE_CLIENT_ERROR,167    'TypeError',168    'bar',169    'TypeError: bar',170    {},171  ]);172  expect(callback1.mock.calls[0][0]).toBeInstanceOf(TypeError);173  expect(callback1.mock.calls[0][0].message).toBe('bar');174  expect(callback1.mock.calls[0][0].type).toBe('TypeError');175  expect(callback1.mock.calls[0][0].stack).toBe('TypeError: bar');176  // Testing a custom error.177  worker.send([CHILD_MESSAGE_CALL, false, 'method', []], () => {}, callback2);178  worker._worker.emit('message', [179    PARENT_MESSAGE_CLIENT_ERROR,180    'RandomCustomError',181    'bar',182    'RandomCustomError: bar',183    {qux: 'extra property'},184  ]);185  expect(callback2.mock.calls[0][0]).toBeInstanceOf(Error);186  expect(callback2.mock.calls[0][0].message).toBe('bar');187  expect(callback2.mock.calls[0][0].type).toBe('RandomCustomError');188  expect(callback2.mock.calls[0][0].stack).toBe('RandomCustomError: bar');189  expect(callback2.mock.calls[0][0].qux).toBe('extra property');190  // Testing a non-object throw.191  worker.send([CHILD_MESSAGE_CALL, false, 'method', []], () => {}, callback3);192  worker._worker.emit('message', [193    PARENT_MESSAGE_CLIENT_ERROR,194    'Number',195    null,196    null,197    412,198  ]);199  expect(callback3.mock.calls[0][0]).toBe(412);200});201it('throws when the child process returns a strange message', () => {202  const worker = new Worker({203    forkOptions: {},204    maxRetries: 3,205    workerPath: '/tmp/foo',206  });207  worker.send([CHILD_MESSAGE_CALL, false, 'method', []], () => {}, () => {});208  // Type 27 does not exist.209  expect(() => {210    worker._worker.emit('message', [27]);211  }).toThrow(TypeError);212});213it('does not restart the child if it cleanly exited', () => {214  const worker = new Worker({215    forkOptions: {},216    maxRetries: 3,217    workerPath: '/tmp/foo',218  });219  expect(childProcess).toHaveBeenCalledTimes(1);220  worker._worker.emit('exit', 0);221  expect(childProcess).toHaveBeenCalledTimes(1);222});223it('restarts the child when the child process dies', () => {224  const worker = new Worker({225    workerPath: '/tmp/foo',226  });227  expect(childProcess).toHaveBeenCalledTimes(1);228  worker._worker.emit('exit', 1);229  expect(childProcess).toHaveBeenCalledTimes(2);...test-Worker.js
Source:test-Worker.js  
1const os = require('os');2const process = require('process');3const path = require('path');4const { toBeType } = require('jest-tobetype');5const mediasoup = require('../lib/');6const { createWorker, observer } = mediasoup;7const { InvalidStateError } = require('../lib/errors');8expect.extend({ toBeType });9let worker;10beforeEach(() => worker && !worker.closed && worker.close());11afterEach(() => worker && !worker.closed && worker.close());12test('createWorker() succeeds', async () =>13{14	const onObserverNewWorker = jest.fn();15	observer.once('newworker', onObserverNewWorker);16	worker = await createWorker();17	expect(onObserverNewWorker).toHaveBeenCalledTimes(1);18	expect(onObserverNewWorker).toHaveBeenCalledWith(worker);19	expect(worker).toBeType('object');20	expect(worker.pid).toBeType('number');21	expect(worker.closed).toBe(false);22	expect(worker.died).toBe(false);23	worker.close();24	expect(worker.closed).toBe(true);25	expect(worker.died).toBe(false);26	// eslint-disable-next-line require-atomic-updates27	worker = await createWorker(28		{29			logLevel            : 'debug',30			logTags             : [ 'info' ],31			rtcMinPort          : 0,32			rtcMaxPort          : 9999,33			dtlsCertificateFile : path.join(__dirname, 'data', 'dtls-cert.pem'),34			dtlsPrivateKeyFile  : path.join(__dirname, 'data', 'dtls-key.pem'),35			appData             : { bar: 456 }36		});37	expect(worker).toBeType('object');38	expect(worker.pid).toBeType('number');39	expect(worker.closed).toBe(false);40	expect(worker.died).toBe(false);41	expect(worker.appData).toEqual({ bar: 456 });42	worker.close();43	expect(worker.closed).toBe(true);44	expect(worker.died).toBe(false);45}, 2000);46test('createWorker() with wrong settings rejects with TypeError', async () =>47{48	await expect(createWorker({ logLevel: 'chicken' }))49		.rejects50		.toThrow(TypeError);51	await expect(createWorker({ rtcMinPort: 1000, rtcMaxPort: 999 }))52		.rejects53		.toThrow(TypeError);54	// Port is from 0 to 65535.55	await expect(createWorker({ rtcMinPort: 1000, rtcMaxPort: 65536 }))56		.rejects57		.toThrow(TypeError);58	await expect(createWorker({ dtlsCertificateFile: '/notfound/cert.pem' }))59		.rejects60		.toThrow(TypeError);61	await expect(createWorker({ dtlsPrivateKeyFile: '/notfound/priv.pem' }))62		.rejects63		.toThrow(TypeError);64	await expect(createWorker({ appData: 'NOT-AN-OBJECT' }))65		.rejects66		.toThrow(TypeError);67}, 2000);68test('worker.updateSettings() succeeds', async () =>69{70	worker = await createWorker();71	await expect(worker.updateSettings({ logLevel: 'debug', logTags: [ 'ice' ] }))72		.resolves73		.toBeUndefined();74	worker.close();75}, 2000);76test('worker.updateSettings() with wrong settings rejects with TypeError', async () =>77{78	worker = await createWorker();79	await expect(worker.updateSettings({ logLevel: 'chicken' }))80		.rejects81		.toThrow(TypeError);82	worker.close();83}, 2000);84test('worker.updateSettings() rejects with InvalidStateError if closed', async () =>85{86	worker = await createWorker();87	worker.close();88	await expect(worker.updateSettings({ logLevel: 'error' }))89		.rejects90		.toThrow(InvalidStateError);91	worker.close();92}, 2000);93test('worker.dump() succeeds', async () =>94{95	worker = await createWorker();96	await expect(worker.dump())97		.resolves98		.toEqual({ pid: worker.pid, routerIds: [] });99	worker.close();100}, 2000);101test('worker.dump() rejects with InvalidStateError if closed', async () =>102{103	worker = await createWorker();104	worker.close();105	await expect(worker.dump())106		.rejects107		.toThrow(InvalidStateError);108	worker.close();109}, 2000);110test('worker.getResourceUsage() succeeds', async () =>111{112	worker = await createWorker();113	await expect(worker.getResourceUsage())114		.resolves115		.toMatchObject({});116	worker.close();117}, 2000);118test('worker.close() succeeds', async () =>119{120	worker = await createWorker({ logLevel: 'warn' });121	const onObserverClose = jest.fn();122	worker.observer.once('close', onObserverClose);123	worker.close();124	expect(onObserverClose).toHaveBeenCalledTimes(1);125	expect(worker.closed).toBe(true);126	expect(worker.died).toBe(false);127}, 2000);128test('Worker emits "died" if worker process died unexpectedly', async () =>129{130	let onDied;131	let onObserverClose;132	worker = await createWorker({ logLevel: 'warn' });133	onDied = jest.fn();134	onObserverClose = jest.fn();135	worker.observer.once('close', onObserverClose);136	await new Promise((resolve, reject) =>137	{138		worker.on('died', () =>139		{140			onDied();141			if (onObserverClose.mock.calls.length > 0)142			{143				reject(144					new Error('observer "close" event emitted before worker "died" event'));145			}146			else if (worker.closed)147			{148				resolve();149			}150			else151			{152				reject(new Error('worker.closed is false'));153			}154		});155		process.kill(worker.pid, 'SIGINT');156	});157	expect(onDied).toHaveBeenCalledTimes(1);158	expect(onObserverClose).toHaveBeenCalledTimes(1);159	expect(worker.closed).toBe(true);160	expect(worker.died).toBe(true);161	// eslint-disable-next-line require-atomic-updates162	worker = await createWorker({ logLevel: 'warn' });163	onDied = jest.fn();164	onObserverClose = jest.fn();165	worker.observer.once('close', onObserverClose);166	await new Promise((resolve, reject) =>167	{168		worker.on('died', () =>169		{170			onDied();171			if (onObserverClose.mock.calls.length > 0)172			{173				reject(174					new Error('observer "close" event emitted before worker "died" event'));175			}176			else if (worker.closed)177			{178				resolve();179			}180			else181			{182				reject(new Error('worker.closed is false'));183			}184		});185		process.kill(worker.pid, 'SIGTERM');186	});187	expect(onDied).toHaveBeenCalledTimes(1);188	expect(onObserverClose).toHaveBeenCalledTimes(1);189	expect(worker.closed).toBe(true);190	expect(worker.died).toBe(true);191	// eslint-disable-next-line require-atomic-updates192	worker = await createWorker({ logLevel: 'warn' });193	onDied = jest.fn();194	onObserverClose = jest.fn();195	worker.observer.once('close', onObserverClose);196	await new Promise((resolve, reject) =>197	{198		worker.on('died', () =>199		{200			onDied();201			if (onObserverClose.mock.calls.length > 0)202			{203				reject(204					new Error('observer "close" event emitted before worker "died" event'));205			}206			else if (worker.closed)207			{208				resolve();209			}210			else211			{212				reject(new Error('worker.closed is false'));213			}214		});215		process.kill(worker.pid, 'SIGKILL');216	});217	expect(onDied).toHaveBeenCalledTimes(1);218	expect(onObserverClose).toHaveBeenCalledTimes(1);219	expect(worker.closed).toBe(true);220	expect(worker.died).toBe(true);221}, 5000);222test('worker process ignores PIPE, HUP, ALRM, USR1 and USR2 signals', async () =>223{224	// Windows doesn't have some signals such as SIGPIPE, SIGALRM, SIGUSR1, SIGUSR2225	// so we just skip this test in Windows.226	if (os.platform() === 'win32')227		return;228	worker = await createWorker({ logLevel: 'warn' });229	await new Promise((resolve, reject) =>230	{231		worker.on('died', reject);232		process.kill(worker.pid, 'SIGPIPE');233		process.kill(worker.pid, 'SIGHUP');234		process.kill(worker.pid, 'SIGALRM');235		process.kill(worker.pid, 'SIGUSR1');236		process.kill(worker.pid, 'SIGUSR2');237		setTimeout(() =>238		{239			expect(worker.closed).toBe(false);240			worker.close();241			resolve();242		}, 2000);243	});...workerpool.js
Source:workerpool.js  
1// Copyright 2007 The Closure Library Authors. All Rights Reserved.2//3// Licensed under the Apache License, Version 2.0 (the "License");4// you may not use this file except in compliance with the License.5// You may obtain a copy of the License at6//7//      http://www.apache.org/licenses/LICENSE-2.08//9// Unless required by applicable law or agreed to in writing, software10// distributed under the License is distributed on an "AS-IS" BASIS,11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12// See the License for the specific language governing permissions and13// limitations under the License.14/**15 * @fileoverview This file implements a wrapper around the Gears WorkerPool16 * with some extra features.17 *18 * @author arv@google.com (Erik Arvidsson)19 */20goog.provide('goog.gears.WorkerPool');21goog.provide('goog.gears.WorkerPool.Event');22goog.provide('goog.gears.WorkerPool.EventType');23goog.require('goog.events.Event');24goog.require('goog.events.EventTarget');25goog.require('goog.gears');26goog.require('goog.gears.Worker');27/**28 * This class implements a wrapper around the Gears Worker Pool.29 *30 * @constructor31 * @extends {goog.events.EventTarget}32 */33goog.gears.WorkerPool = function() {34  goog.events.EventTarget.call(this);35  /**36   * Map from thread id to worker object37   * @type {Object}38   * @private39   */40  this.workers_ = {};41  // If we are in a worker thread we get the global google.gears.workerPool,42  // otherwise we create a new Gears WorkerPool using the factory43  var workerPool = /** @type {GearsWorkerPool} */44      (goog.getObjectByName('google.gears.workerPool'));45  if (workerPool) {46    this.workerPool_ = workerPool;47  } else {48    // use a protected method to let the sub class override49    this.workerPool_ = this.getGearsWorkerPool();50  }51  this.workerPool_.onmessage = goog.bind(this.handleMessage_, this);52};53goog.inherits(goog.gears.WorkerPool, goog.events.EventTarget);54/**55 * Enum for event types fired by the WorkerPool.56 * @enum {string}57 */58goog.gears.WorkerPool.EventType = {59  UNKNOWN_WORKER: 'uknown_worker'60};61/**62 * The Gears WorkerPool object.63 * @type {GearsWorkerPool}64 * @private65 */66goog.gears.WorkerPool.prototype.workerPool_ = null;67/**68 * @return {GearsWorkerPool} A Gears WorkerPool object.69 * @protected70 */71goog.gears.WorkerPool.prototype.getGearsWorkerPool = function() {72  var factory = goog.gears.getFactory();73  return factory.create('beta.workerpool');74};75/**76 * Sets a last-chance error handler for a worker pool.77 * WARNING: This will only succeed from inside a worker thread. In main thread,78 * use window.onerror handler.79 * @param {function(!GearsErrorObject):boolean} fn An error handler function80 *     that gets passed an error object with message and line number attributes.81 *     Returns whether the error was handled. If true stops propagation.82 * @param {Object=} opt_handler This object for the function.83 */84goog.gears.WorkerPool.prototype.setErrorHandler = function(fn, opt_handler) {85  this.workerPool_.onerror = goog.bind(fn, opt_handler);86};87/**88 * Creates a new worker.89 * @param {string} code  The code to execute inside the worker.90 * @return {goog.gears.Worker} The worker that was just created.91 */92goog.gears.WorkerPool.prototype.createWorker = function(code) {93  var workerId = this.workerPool_.createWorker(code);94  var worker = new goog.gears.Worker(this, workerId);95  this.registerWorker(worker);96  return worker;97};98/**99 * Creates a new worker from a URL.100 * @param {string} url  URL from which to get the code to execute inside the101 *     worker.102 * @return {goog.gears.Worker} The worker that was just created.103 */104goog.gears.WorkerPool.prototype.createWorkerFromUrl = function(url) {105  var workerId = this.workerPool_.createWorkerFromUrl(url);106  var worker = new goog.gears.Worker(this, workerId);107  this.registerWorker(worker);108  return worker;109};110/**111 * Allows the worker who calls this to be used cross origin.112 */113goog.gears.WorkerPool.prototype.allowCrossOrigin = function() {114  this.workerPool_.allowCrossOrigin();115};116/**117 * Sends a message to a given worker.118 * @param {*} message The message to send to the worker.119 * @param {goog.gears.Worker} worker The worker to send the message to.120 */121goog.gears.WorkerPool.prototype.sendMessage = function(message, worker) {122  this.workerPool_.sendMessage(message, worker.getId());123};124/**125 * Callback when this worker recieves a message.126 * @param {string} message  The message that was sent.127 * @param {number} senderId  The ID of the worker that sent the message.128 * @param {GearsMessageObject} messageObject An object containing all129 *     information about the message.130 * @private131 */132goog.gears.WorkerPool.prototype.handleMessage_ = function(message,133                                                          senderId,134                                                          messageObject) {135  if (!this.isDisposed()) {136    var workers = this.workers_;137    if (!workers[senderId]) {138      // If the worker is unknown, dispatch an event giving users of the class139      // the change to register the worker.140      this.dispatchEvent(new goog.gears.WorkerPool.Event(141          goog.gears.WorkerPool.EventType.UNKNOWN_WORKER,142          senderId,143          messageObject));144    }145    var worker = workers[senderId];146    if (worker) {147      worker.handleMessage(messageObject);148    }149  }150};151/**152 * Registers a worker object.153 * @param {goog.gears.Worker} worker  The worker to register.154 */155goog.gears.WorkerPool.prototype.registerWorker = function(worker) {156  this.workers_[worker.getId()] = worker;157};158/**159 * Unregisters a worker object.160 * @param {goog.gears.Worker} worker  The worker to unregister.161 */162goog.gears.WorkerPool.prototype.unregisterWorker = function(worker) {163  delete this.workers_[worker.getId()];164};165/** @override */166goog.gears.WorkerPool.prototype.disposeInternal = function() {167  goog.gears.WorkerPool.superClass_.disposeInternal.call(this);168  this.workerPool_ = null;169  delete this.workers_;170};171/**172 * Event used when the workerpool recieves a message173 * @param {string} type  The type of event.174 * @param {number} senderId  The id of the sender of the message.175 * @param {GearsMessageObject} messageObject  The message object.176 *177 * @constructor178 * @extends {goog.events.Event}179 */180goog.gears.WorkerPool.Event = function(181    type, senderId, messageObject) {182  goog.events.Event.call(this, type);183  /**184   * The id of the sender of the message.185   * @type {number}186   */187  this.senderId = senderId;188  /**189   * The message sent from the worker. This is the same as the190   * messageObject.body field and is here for convenience.191   * @type {*}192   */193  this.message = messageObject.body;194  /**195   * The object containing all information about the message.196   * @type {GearsMessageObject}197   */198  this.messageObject = messageObject;199};...LambdaTest’s Jest Testing Tutorial covers step-by-step guides around Jest with code examples to help you be proficient with the Jest framework. The Jest tutorial has chapters to help you learn right from the basics of Jest framework to code-based tutorials around testing react apps with Jest, perform snapshot testing, import ES modules and more.
|<p>it('check_object_of_Car', () => {</p><p>    expect(newCar()).toBeInstanceOf(Car);</p><p> });</p>|
| :- |
Get 100 minutes of automation test minutes FREE!!
