aboutsummaryrefslogtreecommitdiff
path: root/node_modules/jest-worker/build/workers/processChild.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/jest-worker/build/workers/processChild.js')
-rw-r--r--node_modules/jest-worker/build/workers/processChild.js148
1 files changed, 148 insertions, 0 deletions
diff --git a/node_modules/jest-worker/build/workers/processChild.js b/node_modules/jest-worker/build/workers/processChild.js
new file mode 100644
index 0000000..fdf766e
--- /dev/null
+++ b/node_modules/jest-worker/build/workers/processChild.js
@@ -0,0 +1,148 @@
+'use strict';
+
+var _types = require('../types');
+
+/**
+ * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+let file = null;
+let setupArgs = [];
+let initialized = false;
+/**
+ * This file is a small bootstrapper for workers. It sets up the communication
+ * between the worker and the parent process, interpreting parent messages and
+ * sending results back.
+ *
+ * The file loaded will be lazily initialized the first time any of the workers
+ * is called. This is done for optimal performance: if the farm is initialized,
+ * but no call is made to it, child Node processes will be consuming the least
+ * possible amount of memory.
+ *
+ * If an invalid message is detected, the child will exit (by throwing) with a
+ * non-zero exit code.
+ */
+
+const messageListener = request => {
+ switch (request[0]) {
+ case _types.CHILD_MESSAGE_INITIALIZE:
+ const init = request;
+ file = init[2];
+ setupArgs = request[3];
+ break;
+
+ case _types.CHILD_MESSAGE_CALL:
+ const call = request;
+ execMethod(call[2], call[3]);
+ break;
+
+ case _types.CHILD_MESSAGE_END:
+ end();
+ break;
+
+ default:
+ throw new TypeError(
+ 'Unexpected request from parent process: ' + request[0]
+ );
+ }
+};
+
+process.on('message', messageListener);
+
+function reportSuccess(result) {
+ if (!process || !process.send) {
+ throw new Error('Child can only be used on a forked process');
+ }
+
+ process.send([_types.PARENT_MESSAGE_OK, result]);
+}
+
+function reportClientError(error) {
+ return reportError(error, _types.PARENT_MESSAGE_CLIENT_ERROR);
+}
+
+function reportInitializeError(error) {
+ return reportError(error, _types.PARENT_MESSAGE_SETUP_ERROR);
+}
+
+function reportError(error, type) {
+ if (!process || !process.send) {
+ throw new Error('Child can only be used on a forked process');
+ }
+
+ if (error == null) {
+ error = new Error('"null" or "undefined" thrown');
+ }
+
+ process.send([
+ type,
+ error.constructor && error.constructor.name,
+ error.message,
+ error.stack,
+ typeof error === 'object' ? {...error} : error
+ ]);
+}
+
+function end() {
+ const main = require(file);
+
+ if (!main.teardown) {
+ exitProcess();
+ return;
+ }
+
+ execFunction(main.teardown, main, [], exitProcess, exitProcess);
+}
+
+function exitProcess() {
+ // Clean up open handles so the process ideally exits gracefully
+ process.removeListener('message', messageListener);
+}
+
+function execMethod(method, args) {
+ const main = require(file);
+
+ let fn;
+
+ if (method === 'default') {
+ fn = main.__esModule ? main['default'] : main;
+ } else {
+ fn = main[method];
+ }
+
+ function execHelper() {
+ execFunction(fn, main, args, reportSuccess, reportClientError);
+ }
+
+ if (initialized || !main.setup) {
+ execHelper();
+ return;
+ }
+
+ initialized = true;
+ execFunction(main.setup, main, setupArgs, execHelper, reportInitializeError);
+}
+
+const isPromise = obj =>
+ !!obj &&
+ (typeof obj === 'object' || typeof obj === 'function') &&
+ typeof obj.then === 'function';
+
+function execFunction(fn, ctx, args, onResult, onError) {
+ let result;
+
+ try {
+ result = fn.apply(ctx, args);
+ } catch (err) {
+ onError(err);
+ return;
+ }
+
+ if (isPromise(result)) {
+ result.then(onResult, onError);
+ } else {
+ onResult(result);
+ }
+}