fix(core): handle self shutdown for plugin workers is orphaned before connections and loading
This commit is contained in:
parent
0ae87f191c
commit
1bf0e67e1b
@ -579,6 +579,12 @@ export class DaemonClient {
|
||||
}
|
||||
|
||||
async startInBackground(): Promise<ChildProcess['pid']> {
|
||||
if (global.NX_PLUGIN_WORKER) {
|
||||
throw new Error(
|
||||
'Fatal Error: Something unexpected has occurred. Plugin Workers should not start a new daemon process. Please report this issue.'
|
||||
);
|
||||
}
|
||||
|
||||
mkdirSync(DAEMON_DIR_FOR_CURRENT_WORKSPACE, { recursive: true });
|
||||
if (!existsSync(DAEMON_OUTPUT_LOG_FILE)) {
|
||||
writeFileSync(DAEMON_OUTPUT_LOG_FILE, '');
|
||||
|
||||
@ -10,7 +10,7 @@ import { PackageJson } from '../../utils/package-json';
|
||||
import { nxVersion } from '../../utils/versions';
|
||||
import { setupWorkspaceContext } from '../../utils/workspace-context';
|
||||
import { workspaceRoot } from '../../utils/workspace-root';
|
||||
import { writeDaemonJsonProcessCache } from '../cache';
|
||||
import { getDaemonProcessIdSync, writeDaemonJsonProcessCache } from '../cache';
|
||||
import {
|
||||
getFullOsSocketPath,
|
||||
isWindows,
|
||||
@ -518,6 +518,17 @@ export async function startServer(): Promise<Server> {
|
||||
server.listen(getFullOsSocketPath(), async () => {
|
||||
try {
|
||||
serverLogger.log(`Started listening on: ${getFullOsSocketPath()}`);
|
||||
|
||||
setInterval(() => {
|
||||
if (getDaemonProcessIdSync() !== process.pid) {
|
||||
return handleServerProcessTermination({
|
||||
server,
|
||||
reason: 'this process is no longer the current daemon (native)',
|
||||
sockets: openSockets,
|
||||
});
|
||||
}
|
||||
}).unref();
|
||||
|
||||
// this triggers the storage of the lock file hash
|
||||
daemonIsOutdated();
|
||||
|
||||
|
||||
@ -12,12 +12,23 @@ if (process.env.NX_PERF_LOGGING === 'true') {
|
||||
}
|
||||
|
||||
global.NX_GRAPH_CREATION = true;
|
||||
|
||||
global.NX_PLUGIN_WORKER = true;
|
||||
let connected = false;
|
||||
let plugin: LoadedNxPlugin;
|
||||
|
||||
const socketPath = process.argv[2];
|
||||
|
||||
const server = createServer((socket) => {
|
||||
connected = true;
|
||||
// This handles cases where the host process was killed
|
||||
// after the worker connected but before the worker was
|
||||
// instructed to load the plugin.
|
||||
const loadTimeout = setTimeout(() => {
|
||||
console.error(
|
||||
`Plugin Worker exited because no plugin was loaded within 10 seconds of starting up.`
|
||||
);
|
||||
process.exit(1);
|
||||
}, 10000).unref();
|
||||
socket.on(
|
||||
'data',
|
||||
consumeMessagesFromSocket((raw) => {
|
||||
@ -27,6 +38,7 @@ const server = createServer((socket) => {
|
||||
}
|
||||
return consumeMessage(socket, message, {
|
||||
load: async ({ plugin: pluginConfiguration, root }) => {
|
||||
if (loadTimeout) clearTimeout(loadTimeout);
|
||||
process.chdir(root);
|
||||
try {
|
||||
const [promise] = loadNxPlugin(pluginConfiguration, root);
|
||||
@ -120,6 +132,8 @@ const server = createServer((socket) => {
|
||||
// since the worker is spawned per host process. As such,
|
||||
// we can safely close the worker when the host disconnects.
|
||||
socket.on('end', () => {
|
||||
// Destroys the socket once it's fully closed.
|
||||
socket.destroySoon();
|
||||
// Stops accepting new connections, but existing connections are
|
||||
// not closed immediately.
|
||||
server.close(() => {
|
||||
@ -128,13 +142,20 @@ const server = createServer((socket) => {
|
||||
} catch (e) {}
|
||||
process.exit(0);
|
||||
});
|
||||
// Destroys the socket once it's fully closed.
|
||||
socket.destroySoon();
|
||||
});
|
||||
});
|
||||
|
||||
server.listen(socketPath);
|
||||
|
||||
setTimeout(() => {
|
||||
if (!connected) {
|
||||
console.error(
|
||||
'The plugin worker is exiting as it was not connected to within 5 seconds.'
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
}, 5000).unref();
|
||||
|
||||
const exitHandler = (exitCode: number) => () => {
|
||||
server.close();
|
||||
try {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user