From 5382c8af651d900381ac598a4b7cd49e8b386d08 Mon Sep 17 00:00:00 2001 From: Craigory Coppola Date: Fri, 28 Feb 2025 12:13:19 -0500 Subject: [PATCH] fix(core): ensure daemon enabled check is unchanged (#30228) --- docs/generated/devkit/isDaemonEnabled.md | 8 +- packages/nx/src/daemon/client/client.ts | 66 +++++++++++++++- packages/nx/src/daemon/client/enabled.ts | 79 ------------------- packages/nx/src/devkit-exports.ts | 2 +- .../project-graph/plugins/loaded-nx-plugin.ts | 7 +- .../plugins/tasks-execution-hooks.ts | 9 +-- .../rspack-nx-build-coordination-plugin.ts | 3 +- .../webpack-nx-build-coordination-plugin.ts | 3 +- 8 files changed, 74 insertions(+), 103 deletions(-) delete mode 100644 packages/nx/src/daemon/client/enabled.ts diff --git a/docs/generated/devkit/isDaemonEnabled.md b/docs/generated/devkit/isDaemonEnabled.md index b53aacae7c..9eb4dddd3c 100644 --- a/docs/generated/devkit/isDaemonEnabled.md +++ b/docs/generated/devkit/isDaemonEnabled.md @@ -1,12 +1,6 @@ # Function: isDaemonEnabled -▸ **isDaemonEnabled**(`nxJson?`): `boolean` - -#### Parameters - -| Name | Type | -| :------- | :----------------------------------------------------------------------------------------- | -| `nxJson` | [`NxJsonConfiguration`](../../devkit/documents/NxJsonConfiguration)\<`string`[] \| `"*"`\> | +▸ **isDaemonEnabled**(): `boolean` #### Returns diff --git a/packages/nx/src/daemon/client/client.ts b/packages/nx/src/daemon/client/client.ts index 345c46890e..264fed0451 100644 --- a/packages/nx/src/daemon/client/client.ts +++ b/packages/nx/src/daemon/client/client.ts @@ -16,6 +16,7 @@ import { getFullOsSocketPath, killSocketOrPath } from '../socket-utils'; import { DAEMON_DIR_FOR_CURRENT_WORKSPACE, DAEMON_OUTPUT_LOG_FILE, + isDaemonDisabled, removeSocketDir, } from '../tmp-dir'; import { FileData, ProjectGraph } from '../../config/project-graph'; @@ -95,7 +96,6 @@ import { POST_TASKS_EXECUTION, PRE_TASKS_EXECUTION, } from '../message-types/run-tasks-execution-hooks'; -import { isDaemonEnabled } from './enabled'; const DAEMON_ENV_SETTINGS = { NX_PROJECT_GLOB_CACHE: 'false', @@ -141,7 +141,48 @@ export class DaemonClient { private _err: FileHandle = null; enabled() { - return isDaemonEnabled(this.nxJson); + if (this._enabled === undefined) { + const useDaemonProcessOption = this.nxJson?.useDaemonProcess; + const env = process.env.NX_DAEMON; + + // env takes precedence + // option=true,env=false => no daemon + // option=false,env=undefined => no daemon + // option=false,env=false => no daemon + + // option=undefined,env=undefined => daemon + // option=true,env=true => daemon + // option=false,env=true => daemon + + // CI=true,env=undefined => no daemon + // CI=true,env=false => no daemon + // CI=true,env=true => daemon + + // docker=true,env=undefined => no daemon + // docker=true,env=false => no daemon + // docker=true,env=true => daemon + // WASM => no daemon because file watching does not work + if ( + ((isCI() || isDocker()) && env !== 'true') || + isDaemonDisabled() || + nxJsonIsNotPresent() || + (useDaemonProcessOption === undefined && env === 'false') || + (useDaemonProcessOption === true && env === 'false') || + (useDaemonProcessOption === false && env === undefined) || + (useDaemonProcessOption === false && env === 'false') + ) { + this._enabled = false; + } else if (IS_WASM) { + output.warn({ + title: + 'The Nx Daemon is unsupported in WebAssembly environments. Some things may be slower than or not function as expected.', + }); + this._enabled = false; + } else { + this._enabled = true; + } + } + return this._enabled; } reset() { @@ -677,6 +718,27 @@ export class DaemonClient { export const daemonClient = new DaemonClient(); +export function isDaemonEnabled() { + return daemonClient.enabled(); +} + +function isDocker() { + try { + statSync('/.dockerenv'); + return true; + } catch { + try { + return readFileSync('/proc/self/cgroup', 'utf8')?.includes('docker'); + } catch {} + + return false; + } +} + +function nxJsonIsNotPresent() { + return !hasNxJson(workspaceRoot); +} + function daemonProcessException(message: string) { try { let log = readFileSync(DAEMON_OUTPUT_LOG_FILE).toString().split('\n'); diff --git a/packages/nx/src/daemon/client/enabled.ts b/packages/nx/src/daemon/client/enabled.ts deleted file mode 100644 index 05084cc866..0000000000 --- a/packages/nx/src/daemon/client/enabled.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { - hasNxJson, - readNxJson, - type NxJsonConfiguration, -} from '../../config/nx-json'; - -import { readFileSync, statSync } from 'node:fs'; - -import { isCI } from '../../utils/is-ci'; -import { workspaceRoot } from '../../utils/workspace-root'; -import { isDaemonDisabled } from '../tmp-dir'; - -let _enabled: boolean | undefined; - -export function isDaemonEnabled(nxJson: NxJsonConfiguration = readNxJson()) { - if (_enabled === undefined) { - const useDaemonProcessOption = nxJson?.useDaemonProcess; - const env = process.env.NX_DAEMON; - - // env takes precedence - // option=true,env=false => no daemon - // option=false,env=undefined => no daemon - // option=false,env=false => no daemon - - // option=undefined,env=undefined => daemon - // option=true,env=true => daemon - // option=false,env=true => daemon - - // CI=true,env=undefined => no daemon - // CI=true,env=false => no daemon - // CI=true,env=true => daemon - - // docker=true,env=undefined => no daemon - // docker=true,env=false => no daemon - // docker=true,env=true => daemon - // WASM => no daemon because file watching does not work - if ( - ((isCI() || isDocker()) && env !== 'true') || - isDaemonDisabled() || - nxJsonIsNotPresent() || - (useDaemonProcessOption === undefined && env === 'false') || - (useDaemonProcessOption === true && env === 'false') || - (useDaemonProcessOption === false && env === undefined) || - (useDaemonProcessOption === false && env === 'false') - ) { - _enabled = false; - } else if ( - (require('../../native') as typeof import('../../native')).IS_WASM - ) { - ( - require('../../utils/output') as typeof import('../../utils/output') - ).output.warn({ - title: - 'The Nx Daemon is unsupported in WebAssembly environments. Some things may be slower than or not function as expected.', - }); - _enabled = false; - } else { - _enabled = true; - } - } - return _enabled; -} - -function isDocker() { - try { - statSync('/.dockerenv'); - return true; - } catch { - try { - return readFileSync('/proc/self/cgroup', 'utf8')?.includes('docker'); - } catch {} - - return false; - } -} - -function nxJsonIsNotPresent() { - return !hasNxJson(workspaceRoot); -} diff --git a/packages/nx/src/devkit-exports.ts b/packages/nx/src/devkit-exports.ts index 082bcbe03d..44151f6d88 100644 --- a/packages/nx/src/devkit-exports.ts +++ b/packages/nx/src/devkit-exports.ts @@ -260,4 +260,4 @@ export { cacheDir } from './utils/cache-directory'; */ export { createProjectFileMapUsingProjectGraph } from './project-graph/file-map-utils'; -export { isDaemonEnabled } from './daemon/client/enabled'; +export { isDaemonEnabled } from './daemon/client/client'; diff --git a/packages/nx/src/project-graph/plugins/loaded-nx-plugin.ts b/packages/nx/src/project-graph/plugins/loaded-nx-plugin.ts index 7cd83846e6..26d4e7e6db 100644 --- a/packages/nx/src/project-graph/plugins/loaded-nx-plugin.ts +++ b/packages/nx/src/project-graph/plugins/loaded-nx-plugin.ts @@ -17,7 +17,7 @@ import type { } from './public-api'; import { createNodesFromFiles } from './utils'; import { isIsolationEnabled } from './isolation/enabled'; -import { isDaemonEnabled } from '../../daemon/client/enabled'; +import { isDaemonEnabled } from '../../daemon/client/client'; export class LoadedNxPlugin { index?: number; @@ -123,10 +123,7 @@ export class LoadedNxPlugin { this.preTasksExecution = async (context: PreTasksExecutionContext) => { const updates = {}; let originalEnv = process.env; - if ( - isIsolationEnabled() || - isDaemonEnabled(context.nxJsonConfiguration) - ) { + if (isIsolationEnabled() || isDaemonEnabled()) { process.env = new Proxy(originalEnv, { set: (target, key: string, value) => { target[key] = value; diff --git a/packages/nx/src/project-graph/plugins/tasks-execution-hooks.ts b/packages/nx/src/project-graph/plugins/tasks-execution-hooks.ts index 9a2e68adfd..261baeb3a6 100644 --- a/packages/nx/src/project-graph/plugins/tasks-execution-hooks.ts +++ b/packages/nx/src/project-graph/plugins/tasks-execution-hooks.ts @@ -4,13 +4,12 @@ import type { } from './public-api'; import { getPlugins } from './get-plugins'; import { isOnDaemon } from '../../daemon/is-on-daemon'; -import { daemonClient } from '../../daemon/client/client'; -import { isDaemonEnabled } from '../../daemon/client/enabled'; +import { daemonClient, isDaemonEnabled } from '../../daemon/client/client'; export async function runPreTasksExecution( pluginContext: PreTasksExecutionContext ) { - if (isOnDaemon() || !isDaemonEnabled(pluginContext.nxJsonConfiguration)) { + if (isOnDaemon() || !isDaemonEnabled()) { performance.mark(`preTasksExecution:start`); const plugins = await getPlugins(pluginContext.workspaceRoot); const envs = await Promise.all( @@ -31,7 +30,7 @@ export async function runPreTasksExecution( }) ); - if (!isDaemonEnabled(pluginContext.nxJsonConfiguration)) { + if (!isDaemonEnabled()) { applyProcessEnvs(envs); } performance.mark(`preTasksExecution:end`); @@ -58,7 +57,7 @@ function applyProcessEnvs(envs: NodeJS.ProcessEnv[]) { export async function runPostTasksExecution( context: PostTasksExecutionContext ) { - if (isOnDaemon() || !isDaemonEnabled(context.nxJsonConfiguration)) { + if (isOnDaemon() || !isDaemonEnabled()) { performance.mark(`postTasksExecution:start`); const plugins = await getPlugins(); await Promise.all( diff --git a/packages/rspack/src/plugins/utils/plugins/rspack-nx-build-coordination-plugin.ts b/packages/rspack/src/plugins/utils/plugins/rspack-nx-build-coordination-plugin.ts index 4b73808d01..fb13e7589f 100644 --- a/packages/rspack/src/plugins/utils/plugins/rspack-nx-build-coordination-plugin.ts +++ b/packages/rspack/src/plugins/utils/plugins/rspack-nx-build-coordination-plugin.ts @@ -1,7 +1,6 @@ import { exec } from 'child_process'; import type { Compiler } from '@rspack/core'; -import { daemonClient } from 'nx/src/daemon/client/client'; -import { isDaemonEnabled } from 'nx/src/daemon/client/enabled'; +import { daemonClient, isDaemonEnabled } from 'nx/src/daemon/client/client'; import { BatchFunctionRunner } from 'nx/src/command-line/watch/watch'; import { output } from 'nx/src/utils/output'; diff --git a/packages/webpack/src/plugins/webpack-nx-build-coordination-plugin.ts b/packages/webpack/src/plugins/webpack-nx-build-coordination-plugin.ts index ab799a771d..1fe05acfe2 100644 --- a/packages/webpack/src/plugins/webpack-nx-build-coordination-plugin.ts +++ b/packages/webpack/src/plugins/webpack-nx-build-coordination-plugin.ts @@ -1,9 +1,8 @@ import { exec } from 'child_process'; import type { Compiler } from 'webpack'; -import { daemonClient } from 'nx/src/daemon/client/client'; +import { daemonClient, isDaemonEnabled } from 'nx/src/daemon/client/client'; import { BatchFunctionRunner } from 'nx/src/command-line/watch/watch'; import { output } from 'nx/src/utils/output'; -import { isDaemonEnabled } from 'nx/src/daemon/client/enabled'; type PluginOptions = { skipInitialBuild?: boolean;