Skip to content

Commit 6ef01d7

Browse files
committed
fix(core): daemon command should exit at end
1 parent aa38b25 commit 6ef01d7

File tree

4 files changed

+96
-62
lines changed

4 files changed

+96
-62
lines changed

packages/nx/src/command-line/daemon/command-object.ts

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,24 @@
11
import { CommandModule, Argv } from 'yargs';
22
import { linkToNxDevAndExamples } from '../yargs-utils/documentation';
3+
import { handleErrors } from '../../utils/handle-errors';
4+
import { withVerbose } from '../yargs-utils/shared-options';
5+
import { makeCommandModule } from '../yargs-utils/arguments-of';
36

4-
export const yargsDaemonCommand: CommandModule = {
7+
const builder = (yargs: Argv) =>
8+
linkToNxDevAndExamples(withVerbose(withDaemonOptions(yargs)), 'daemon');
9+
10+
export const yargsDaemonCommand = makeCommandModule({
511
command: 'daemon',
612
describe:
713
'Prints information about the Nx Daemon process or starts a daemon process.',
8-
builder: (yargs) =>
9-
linkToNxDevAndExamples(withDaemonOptions(yargs), 'daemon'),
10-
handler: async (args) => (await import('./daemon')).daemonHandler(args),
11-
};
14+
builder,
15+
handler: async (args) => {
16+
const exitCode = await handleErrors(args.verbose, async () =>
17+
(await import('./daemon')).daemonHandler(args)
18+
);
19+
process.exit(exitCode);
20+
},
21+
});
1222

1323
function withDaemonOptions(yargs: Argv): Argv {
1424
return yargs
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import type { Argv, CommandModule as YargsCommandModule } from 'yargs';
2+
3+
export type Builder<InitialArgs, FinalArgs> = (
4+
yargs: Argv<InitialArgs>
5+
) => Argv<FinalArgs>;
6+
7+
export type Handler<B extends Builder<any, any>> = (
8+
args: Awaited<ReturnType<B>['argv']>
9+
) => void | Promise<void>;
10+
11+
export interface CommandModule<T, U>
12+
extends Omit<YargsCommandModule<T, U>, 'handler'> {
13+
builder: Builder<T, U>;
14+
handler: Handler<Builder<T, U>>;
15+
}
16+
17+
/**
18+
* Helper function to define a Yargs CommandModule with proper typing and not sacrifice inference.
19+
*/
20+
export function makeCommandModule<T, U>(
21+
module: CommandModule<T, U>
22+
): CommandModule<T, U> {
23+
return module;
24+
}

packages/nx/src/project-graph/plugins/get-plugins.ts

Lines changed: 54 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,7 @@ import { isIsolationEnabled } from './isolation/enabled';
2020
*/
2121
let currentPluginsConfigurationHash: string;
2222
let loadedPlugins: LoadedNxPlugin[];
23-
let pendingPluginsPromise:
24-
| Promise<readonly [LoadedNxPlugin[], () => void]>
25-
| undefined;
23+
let pendingPluginsPromise: Promise<LoadedNxPlugin[]> | undefined;
2624
let cleanupSpecifiedPlugins: () => void | undefined;
2725

2826
const loadingMethod = (
@@ -48,24 +46,16 @@ export async function getPlugins(
4846
return loadedPlugins;
4947
}
5048

51-
// Cleanup current plugins before loading new ones
52-
cleanupSpecifiedPlugins?.();
53-
54-
pendingPluginsPromise ??= loadSpecifiedNxPlugins(pluginsConfiguration, root);
55-
5649
currentPluginsConfigurationHash = pluginsConfigurationHash;
57-
const [[result, cleanupFn], defaultPlugins] = await Promise.all([
58-
pendingPluginsPromise,
50+
const [defaultPlugins, specifiedPlugins] = await Promise.all([
5951
getOnlyDefaultPlugins(root),
52+
(pendingPluginsPromise ??= loadSpecifiedNxPlugins(
53+
pluginsConfiguration,
54+
root
55+
)),
6056
]);
6157

62-
cleanupSpecifiedPlugins = () => {
63-
loadedPlugins = undefined;
64-
pendingPluginsPromise = undefined;
65-
cleanupFn();
66-
};
67-
68-
loadedPlugins = result.concat(defaultPlugins);
58+
loadedPlugins = specifiedPlugins.concat(defaultPlugins);
6959

7060
return loadedPlugins;
7161
}
@@ -111,6 +101,8 @@ export async function getOnlyDefaultPlugins(root = workspaceRoot) {
111101
export function cleanupPlugins() {
112102
cleanupSpecifiedPlugins?.();
113103
cleanupDefaultPlugins?.();
104+
pendingPluginsPromise = undefined;
105+
pendingDefaultPluginPromise = undefined;
114106
}
115107

116108
/**
@@ -164,55 +156,62 @@ async function loadDefaultNxPlugins(root = workspaceRoot) {
164156
}
165157

166158
async function loadSpecifiedNxPlugins(
167-
plugins: PluginConfiguration[],
159+
pluginsConfigurations: PluginConfiguration[],
168160
root = workspaceRoot
169-
): Promise<readonly [LoadedNxPlugin[], () => void]> {
161+
): Promise<LoadedNxPlugin[]> {
162+
// Returning existing plugins is handled by getPlugins,
163+
// so, if we are here and there are existing plugins, they are stale
164+
if (cleanupSpecifiedPlugins) {
165+
cleanupSpecifiedPlugins();
166+
}
167+
170168
performance.mark('loadSpecifiedNxPlugins:start');
171169

172-
plugins ??= [];
170+
pluginsConfigurations ??= [];
173171

174172
const cleanupFunctions: Array<() => void> = [];
175-
const ret = [
176-
await Promise.all(
177-
plugins.map(async (plugin, index) => {
178-
const pluginPath = typeof plugin === 'string' ? plugin : plugin.plugin;
179-
performance.mark(`Load Nx Plugin: ${pluginPath} - start`);
180-
181-
const [loadedPluginPromise, cleanup] = await loadingMethod(
182-
plugin,
183-
root,
184-
index
185-
);
186-
187-
cleanupFunctions.push(cleanup);
188-
const res = await loadedPluginPromise;
189-
res.index = index;
190-
performance.mark(`Load Nx Plugin: ${pluginPath} - end`);
191-
performance.measure(
192-
`Load Nx Plugin: ${pluginPath}`,
193-
`Load Nx Plugin: ${pluginPath} - start`,
194-
`Load Nx Plugin: ${pluginPath} - end`
195-
);
196-
197-
return res;
198-
})
199-
),
200-
() => {
201-
for (const fn of cleanupFunctions) {
202-
fn();
203-
}
204-
if (pluginTranspilerIsRegistered()) {
205-
cleanupPluginTSTranspiler();
206-
}
207-
},
208-
] as const;
173+
const plugins = await Promise.all(
174+
pluginsConfigurations.map(async (plugin, index) => {
175+
const pluginPath = typeof plugin === 'string' ? plugin : plugin.plugin;
176+
performance.mark(`Load Nx Plugin: ${pluginPath} - start`);
177+
178+
const [loadedPluginPromise, cleanup] = await loadingMethod(
179+
plugin,
180+
root,
181+
index
182+
);
183+
184+
cleanupFunctions.push(cleanup);
185+
const res = await loadedPluginPromise;
186+
res.index = index;
187+
performance.mark(`Load Nx Plugin: ${pluginPath} - end`);
188+
performance.measure(
189+
`Load Nx Plugin: ${pluginPath}`,
190+
`Load Nx Plugin: ${pluginPath} - start`,
191+
`Load Nx Plugin: ${pluginPath} - end`
192+
);
193+
194+
return res;
195+
})
196+
);
209197
performance.mark('loadSpecifiedNxPlugins:end');
210198
performance.measure(
211199
'loadSpecifiedNxPlugins',
212200
'loadSpecifiedNxPlugins:start',
213201
'loadSpecifiedNxPlugins:end'
214202
);
215-
return ret;
203+
204+
cleanupSpecifiedPlugins = () => {
205+
for (const fn of cleanupFunctions) {
206+
fn();
207+
}
208+
if (pluginTranspilerIsRegistered()) {
209+
cleanupPluginTSTranspiler();
210+
}
211+
pendingPluginsPromise = undefined;
212+
};
213+
214+
return plugins;
216215
}
217216

218217
function getDefaultPlugins(root: string) {

packages/nx/src/project-graph/plugins/isolation/plugin-pool.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ export async function loadRemoteNxPlugin(
6767
const { name, pluginPath, shouldRegisterTSTranspiler } =
6868
await resolveNxPlugin(moduleName, root, getNxRequirePaths(root));
6969

70-
const { worker, socket } = await startPluginWorker();
70+
const { worker, socket } = await startPluginWorker(name);
7171

7272
// Register plugin worker as a subprocess of the main CLI
7373
// This allows metrics collection when the daemon is not used
@@ -411,7 +411,7 @@ function registerPendingPromise(
411411

412412
global.nxPluginWorkerCount ??= 0;
413413

414-
async function startPluginWorker() {
414+
async function startPluginWorker(name: string) {
415415
// this should only really be true when running unit tests within
416416
// the Nx repo. We still need to start the worker in this case,
417417
// but its typescript.
@@ -441,6 +441,7 @@ async function startPluginWorker() {
441441
...(isWorkerTypescript ? ['--require', 'ts-node/register'] : []),
442442
workerPath,
443443
ipcPath,
444+
name,
444445
],
445446
{
446447
stdio: 'inherit',

0 commit comments

Comments
 (0)