Skip to content

Commit 0a7fe80

Browse files
committed
fix(core): daemon command should exit at end
1 parent 26df170 commit 0a7fe80

File tree

4 files changed

+90
-62
lines changed

4 files changed

+90
-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: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
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+
export function makeCommandModule<T, U>(
18+
module: CommandModule<T, U>
19+
): CommandModule<T, U> {
20+
return module;
21+
}

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

Lines changed: 51 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
}
@@ -164,55 +154,61 @@ async function loadDefaultNxPlugins(root = workspaceRoot) {
164154
}
165155

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

172-
plugins ??= [];
168+
pluginsConfigurations ??= [];
173169

174170
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;
171+
const plugins = await Promise.all(
172+
pluginsConfigurations.map(async (plugin, index) => {
173+
const pluginPath = typeof plugin === 'string' ? plugin : plugin.plugin;
174+
performance.mark(`Load Nx Plugin: ${pluginPath} - start`);
175+
176+
const [loadedPluginPromise, cleanup] = await loadingMethod(
177+
plugin,
178+
root,
179+
index
180+
);
181+
182+
cleanupFunctions.push(cleanup);
183+
const res = await loadedPluginPromise;
184+
res.index = index;
185+
performance.mark(`Load Nx Plugin: ${pluginPath} - end`);
186+
performance.measure(
187+
`Load Nx Plugin: ${pluginPath}`,
188+
`Load Nx Plugin: ${pluginPath} - start`,
189+
`Load Nx Plugin: ${pluginPath} - end`
190+
);
191+
192+
return res;
193+
})
194+
);
209195
performance.mark('loadSpecifiedNxPlugins:end');
210196
performance.measure(
211197
'loadSpecifiedNxPlugins',
212198
'loadSpecifiedNxPlugins:start',
213199
'loadSpecifiedNxPlugins:end'
214200
);
215-
return ret;
201+
202+
cleanupSpecifiedPlugins = () => {
203+
for (const fn of cleanupFunctions) {
204+
fn();
205+
}
206+
if (pluginTranspilerIsRegistered()) {
207+
cleanupPluginTSTranspiler();
208+
}
209+
};
210+
211+
return plugins;
216212
}
217213

218214
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)