mirror of
https://github.com/nodejs/node.git
synced 2025-05-03 13:28:42 +00:00

`debuglog()` depends on `process.pid` and `process.env.NODE_DEBUG`, so it needs to be called lazily in top scopes of internal modules that may be loaded before these run time states are allowed to be accessed. This patch makes its implementation lazy by default, the process states are only accessed when the returned debug function is called for the first time. PR-URL: https://github.com/nodejs/node/pull/27281 Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Richard Lau <riclau@uk.ibm.com> Reviewed-By: Yongsheng Zhang <zyszys98@gmail.com>
175 lines
4.5 KiB
JavaScript
175 lines
4.5 KiB
JavaScript
'use strict';
|
|
|
|
// In worker threads, execute the script sent through the
|
|
// message port.
|
|
|
|
const { Object } = primordials;
|
|
|
|
const {
|
|
patchProcessObject,
|
|
setupCoverageHooks,
|
|
setupInspectorHooks,
|
|
setupWarningHandler,
|
|
setupDebugEnv,
|
|
initializeDeprecations,
|
|
initializeESMLoader,
|
|
initializeFrozenIntrinsics,
|
|
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('internal/util/debuglog').debuglog('worker');
|
|
|
|
const assert = require('internal/assert');
|
|
|
|
patchProcessObject();
|
|
setupInspectorHooks();
|
|
setupDebugEnv();
|
|
|
|
setupWarningHandler();
|
|
|
|
// Since worker threads cannot switch cwd, we do not need to
|
|
// overwrite the process.env.NODE_V8_COVERAGE variable.
|
|
if (process.env.NODE_V8_COVERAGE) {
|
|
setupCoverageHooks(process.env.NODE_V8_COVERAGE);
|
|
}
|
|
|
|
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();
|
|
initializeFrozenIntrinsics();
|
|
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();
|
|
}
|
|
} else if (message.type === STDIO_PAYLOAD) {
|
|
const { stream, chunk, encoding } = message;
|
|
process[stream].push(chunk, encoding);
|
|
} else {
|
|
assert(
|
|
message.type === STDIO_WANTS_MORE_DATA,
|
|
`Unknown worker message type ${message.type}`
|
|
);
|
|
const { stream } = message;
|
|
process[stream][kStdioWantsMoreDataCallback]();
|
|
}
|
|
});
|
|
|
|
// Overwrite fatalException
|
|
process._fatalException = (error, fromPromise) => {
|
|
debug(`[${threadId}] gets fatal exception`);
|
|
let caught = false;
|
|
try {
|
|
caught = originalFatalException.call(this, error, fromPromise);
|
|
} 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();
|