0
0
mirror of https://github.com/nodejs/node.git synced 2024-11-30 23:43:09 +01:00
nodejs/lib/internal/main/worker_thread.js
Joyee Cheung b0869c64d1
process: move initialization of node-report into pre_execution.js
- Splits signal handler setup code into two functions: one sets up
  `process.on('SIGNAL_NAME')`, another takes care of the signal
  triggers of node-report. Both should only happen on the main thread.
  The latter needs to happen after the node-report configurations
  are read into the process.
- Move the initialization of node-report into pre_execution.js
  because it depends on CLI/environment settings.

PR-URL: https://github.com/nodejs/node/pull/26227
Reviewed-By: Richard Lau <riclau@uk.ibm.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
2019-02-24 23:41:27 +01:00

153 lines
4.0 KiB
JavaScript

'use strict';
// In worker threads, execute the script sent through the
// message port.
const {
initializeDeprecations,
initializeESMLoader,
initializeReport,
loadPreloadModules,
setupTraceCategoryState
} = require('internal/bootstrap/pre_execution');
const {
threadId,
getEnvMessagePort
} = internalBinding('worker');
const {
messageTypes: {
// Messages that may be received by workers
LOAD_SCRIPT,
// Messages that may be posted from workers
UP_AND_RUNNING,
ERROR_MESSAGE,
COULD_NOT_SERIALIZE_ERROR,
// Messages that may be either received or posted
STDIO_PAYLOAD,
STDIO_WANTS_MORE_DATA,
},
kStdioWantsMoreDataCallback
} = require('internal/worker/io');
const {
fatalException: originalFatalException
} = require('internal/process/execution');
const publicWorker = require('worker_threads');
const debug = require('util').debuglog('worker');
debug(`[${threadId}] is setting up worker child environment`);
// Set up the message port and start listening
const port = getEnvMessagePort();
// If the main thread is spawned with env NODE_CHANNEL_FD, it's probably
// spawned by our child_process module. In the work threads, mark the
// related IPC properties as unavailable.
if (process.env.NODE_CHANNEL_FD) {
const workerThreadSetup = require('internal/process/worker_thread_only');
Object.defineProperty(process, 'channel', {
enumerable: false,
get: workerThreadSetup.unavailable('process.channel')
});
Object.defineProperty(process, 'connected', {
enumerable: false,
get: workerThreadSetup.unavailable('process.connected')
});
process.send = workerThreadSetup.unavailable('process.send()');
process.disconnect =
workerThreadSetup.unavailable('process.disconnect()');
}
port.on('message', (message) => {
if (message.type === LOAD_SCRIPT) {
const {
filename,
doEval,
workerData,
publicPort,
manifestSrc,
manifestURL,
hasStdin
} = message;
setupTraceCategoryState();
initializeReport();
if (manifestSrc) {
require('internal/process/policy').setup(manifestSrc, manifestURL);
}
initializeDeprecations();
initializeESMLoader();
loadPreloadModules();
publicWorker.parentPort = publicPort;
publicWorker.workerData = workerData;
if (!hasStdin)
process.stdin.push(null);
debug(`[${threadId}] starts worker script ${filename} ` +
`(eval = ${eval}) at cwd = ${process.cwd()}`);
port.unref();
port.postMessage({ type: UP_AND_RUNNING });
if (doEval) {
const { evalScript } = require('internal/process/execution');
evalScript('[worker eval]', filename);
} else {
process.argv[1] = filename; // script filename
require('module').runMain();
}
return;
} else if (message.type === STDIO_PAYLOAD) {
const { stream, chunk, encoding } = message;
process[stream].push(chunk, encoding);
return;
} else if (message.type === STDIO_WANTS_MORE_DATA) {
const { stream } = message;
process[stream][kStdioWantsMoreDataCallback]();
return;
}
require('assert').fail(`Unknown worker message type ${message.type}`);
});
// Overwrite fatalException
process._fatalException = (error) => {
debug(`[${threadId}] gets fatal exception`);
let caught = false;
try {
caught = originalFatalException.call(this, error);
} catch (e) {
error = e;
}
debug(`[${threadId}] fatal exception caught = ${caught}`);
if (!caught) {
let serialized;
try {
const { serializeError } = require('internal/error-serdes');
serialized = serializeError(error);
} catch {}
debug(`[${threadId}] fatal exception serialized = ${!!serialized}`);
if (serialized)
port.postMessage({
type: ERROR_MESSAGE,
error: serialized
});
else
port.postMessage({ type: COULD_NOT_SERIALIZE_ERROR });
const { clearAsyncIdStack } = require('internal/async_hooks');
clearAsyncIdStack();
process.exit();
}
};
markBootstrapComplete();
port.start();