diff --git a/packages/nx/src/daemon/client/client.ts b/packages/nx/src/daemon/client/client.ts index 4d2d0d09df..fd700dc6f2 100644 --- a/packages/nx/src/daemon/client/client.ts +++ b/packages/nx/src/daemon/client/client.ts @@ -93,6 +93,10 @@ export class DaemonClient { this._connected = false; } + async requestShutdown(): Promise { + return this.sendToDaemonViaQueue({ type: 'REQUEST_SHUTDOWN' }); + } + async getProjectGraph(): Promise { return (await this.sendToDaemonViaQueue({ type: 'REQUEST_PROJECT_GRAPH' })) .projectGraph; diff --git a/packages/nx/src/daemon/server/handle-request-shutdown.ts b/packages/nx/src/daemon/server/handle-request-shutdown.ts new file mode 100644 index 0000000000..a5506d87d2 --- /dev/null +++ b/packages/nx/src/daemon/server/handle-request-shutdown.ts @@ -0,0 +1,26 @@ +import { Server } from 'net'; +import { handleServerProcessTermination } from './shutdown-utils'; + +export async function handleRequestShutdown( + server: Server, + numberOfConnections: number +) { + // 1 connection is the client asking to shut down + if (numberOfConnections > 1) { + return { + description: `Unable to shutdown the daemon. ${numberOfConnections} connections are open.`, + response: '{}', + }; + } else { + setTimeout(async () => { + await handleServerProcessTermination({ + server, + reason: 'Request to shutdown', + }); + }, 0); + return { + description: 'Shutdown initiated', + response: '{}', + }; + } +} diff --git a/packages/nx/src/daemon/server/server.ts b/packages/nx/src/daemon/server/server.ts index 28ba7e5d06..e64fa7e3f8 100644 --- a/packages/nx/src/daemon/server/server.ts +++ b/packages/nx/src/daemon/server/server.ts @@ -40,6 +40,7 @@ import { disableOutputsTracking, processFileChangesInOutputs, } from './outputs-tracking'; +import { handleRequestShutdown } from './handle-request-shutdown'; let performanceObserver: PerformanceObserver | undefined; let workspaceWatcherError: Error | undefined; @@ -130,6 +131,11 @@ async function handleMessage(socket, data: string) { await handleResult(socket, await handleRecordOutputsHash(payload)); } else if (payload.type === 'OUTPUTS_HASHES_MATCH') { await handleResult(socket, await handleOutputsHashesMatch(payload)); + } else if (payload.type === 'REQUEST_SHUTDOWN') { + await handleResult( + socket, + await handleRequestShutdown(server, numberOfOpenConnections) + ); } else { await respondWithErrorAndExit( socket,