Skip to content

Commit

Permalink
chore(core): reduce code loading time for plugin worker
Browse files Browse the repository at this point in the history
  • Loading branch information
AgentEnder committed Feb 12, 2025
1 parent b2f66f9 commit eb23e4b
Show file tree
Hide file tree
Showing 11 changed files with 120 additions and 116 deletions.
8 changes: 7 additions & 1 deletion docs/generated/devkit/isDaemonEnabled.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
# Function: isDaemonEnabled

**isDaemonEnabled**(): `boolean`
**isDaemonEnabled**(`nxJson?`): `boolean`

#### Parameters

| Name | Type |
| :------- | :----------------------------------------------------------------------------------------- |
| `nxJson` | [`NxJsonConfiguration`](../../devkit/documents/NxJsonConfiguration)\<`string`[] \| `"*"`\> |

#### Returns

Expand Down
9 changes: 5 additions & 4 deletions packages/nx/src/config/nx-json.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@ import { existsSync } from 'fs';
import { dirname, join } from 'path';

import type { ChangelogRenderOptions } from '../../release/changelog-renderer';
import { readJsonFile } from '../utils/fileutils';
import { PackageManager } from '../utils/package-manager';
import { workspaceRoot } from '../utils/workspace-root';
import {
import type { PackageManager } from '../utils/package-manager';
import type {
InputDefinition,
TargetConfiguration,
TargetDependencyConfig,
} from './workspace-json-project-json';

import { readJsonFile } from '../utils/fileutils';
import { workspaceRoot } from '../utils/workspace-root';

export type ImplicitDependencyEntry<T = '*' | string[]> = {
[key: string]: T | ImplicitJsonSubsetDependency<T>;
};
Expand Down
66 changes: 2 additions & 64 deletions packages/nx/src/daemon/client/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ 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';
Expand Down Expand Up @@ -96,6 +95,7 @@ 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',
Expand Down Expand Up @@ -141,48 +141,7 @@ export class DaemonClient {
private _err: FileHandle = null;

enabled() {
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;
return isDaemonEnabled(this.nxJson);
}

reset() {
Expand Down Expand Up @@ -718,27 +677,6 @@ 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');
Expand Down
79 changes: 79 additions & 0 deletions packages/nx/src/daemon/client/enabled.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
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);
}
2 changes: 1 addition & 1 deletion packages/nx/src/devkit-exports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -260,4 +260,4 @@ export { cacheDir } from './utils/cache-directory';
*/
export { createProjectFileMapUsingProjectGraph } from './project-graph/file-map-utils';

export { isDaemonEnabled } from './daemon/client/client';
export { isDaemonEnabled } from './daemon/client/enabled';
11 changes: 11 additions & 0 deletions packages/nx/src/project-graph/plugins/isolation/plugin-worker.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
import { performance } from 'node:perf_hooks';

performance.mark(`plugin worker ${process.pid} code loading -- start`);

import { consumeMessage, isPluginWorkerMessage } from './messaging';
import { createSerializableError } from '../../../utils/serializable-error';
import { consumeMessagesFromSocket } from '../../../utils/consume-messages-from-socket';
Expand All @@ -10,6 +14,13 @@ if (process.env.NX_PERF_LOGGING === 'true') {
require('../../../utils/perf-logging');
}

performance.mark(`plugin worker ${process.pid} code loading -- end`);
performance.measure(
`plugin worker ${process.pid} code loading`,
`plugin worker ${process.pid} code loading -- start`,
`plugin worker ${process.pid} code loading -- end`
);

global.NX_GRAPH_CREATION = true;
global.NX_PLUGIN_WORKER = true;
let connected = false;
Expand Down
6 changes: 3 additions & 3 deletions packages/nx/src/project-graph/plugins/loaded-nx-plugin.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { ProjectGraph } from '../../config/project-graph';
import type { PluginConfiguration } from '../../config/nx-json';
import { readNxJson, type PluginConfiguration } from '../../config/nx-json';
import {
AggregateCreateNodesError,
isAggregateCreateNodesError,
Expand All @@ -17,7 +17,7 @@ import type {
} from './public-api';
import { createNodesFromFiles } from './utils';
import { isIsolationEnabled } from './isolation/enabled';
import { isDaemonEnabled } from '../../daemon/client/client';
import { isDaemonEnabled } from '../../daemon/client/enabled';

export class LoadedNxPlugin {
index?: number;
Expand Down Expand Up @@ -123,7 +123,7 @@ export class LoadedNxPlugin {
this.preTasksExecution = async (context: PreTasksExecutionContext) => {
const updates = {};
let originalEnv = process.env;
if (isIsolationEnabled() || isDaemonEnabled()) {
if (isIsolationEnabled() || isDaemonEnabled(readNxJson())) {
process.env = new Proxy<NodeJS.ProcessEnv>(originalEnv, {
set: (target, key: string, value) => {
target[key] = value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ import type {
} from './public-api';
import { getPlugins } from './get-plugins';
import { isOnDaemon } from '../../daemon/is-on-daemon';
import { daemonClient, isDaemonEnabled } from '../../daemon/client/client';
import { daemonClient } from '../../daemon/client/client';
import { isDaemonEnabled } from '../../daemon/client/enabled';

export async function runPreTasksExecution(
pluginContext: PreTasksExecutionContext
) {
if (isOnDaemon() || !isDaemonEnabled()) {
if (isOnDaemon() || !isDaemonEnabled(pluginContext.nxJsonConfiguration)) {
performance.mark(`preTasksExecution:start`);
const plugins = await getPlugins(pluginContext.workspaceRoot);
const envs = await Promise.all(
Expand All @@ -30,7 +31,7 @@ export async function runPreTasksExecution(
})
);

if (!isDaemonEnabled()) {
if (!isDaemonEnabled(pluginContext.nxJsonConfiguration)) {
applyProcessEnvs(envs);
}
performance.mark(`preTasksExecution:end`);
Expand All @@ -57,7 +58,7 @@ function applyProcessEnvs(envs: NodeJS.ProcessEnv[]) {
export async function runPostTasksExecution(
context: PostTasksExecutionContext
) {
if (isOnDaemon() || !isDaemonEnabled()) {
if (isOnDaemon() || !isDaemonEnabled(context.nxJsonConfiguration)) {
performance.mark(`postTasksExecution:start`);
const plugins = await getPlugins();
await Promise.all(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { exec } from 'child_process';
import type { Compiler } from '@rspack/core';
import { daemonClient, isDaemonEnabled } from 'nx/src/daemon/client/client';
import { daemonClient } from 'nx/src/daemon/client/client';
import { isDaemonEnabled } from 'nx/src/daemon/client/enabled';
import { BatchFunctionRunner } from 'nx/src/command-line/watch/watch';
import { output } from 'nx/src/utils/output';

Expand Down
Loading

0 comments on commit eb23e4b

Please sign in to comment.