Skip to content

Commit 2e0ebbb

Browse files
committed
also mention daemon not running in error
1 parent 6a8def7 commit 2e0ebbb

File tree

15 files changed

+203
-102
lines changed

15 files changed

+203
-102
lines changed

apps/nxls/src/main.ts

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ import {
109109
import { URI } from 'vscode-uri';
110110
import { ensureOnlyJsonRpcStdout } from './ensureOnlyJsonRpcStdout';
111111
import { NativeWatcher } from '@nx-console/shared-watcher';
112+
import type { ProjectGraph } from 'nx/src/devkit-exports';
113+
import type { ConfigurationSourceMaps } from 'nx/src/project-graph/utils/project-configuration-utils';
112114

113115
process.on('unhandledRejection', (e: any) => {
114116
connection.console.error(formatError(`Unhandled exception`, e));
@@ -158,11 +160,18 @@ connection.onInitialize(async (params) => {
158160

159161
unregisterFileWatcher = await languageServerWatcher(
160162
WORKING_PATH,
161-
async () => {
163+
async (error, projectGraphAndSourceMaps) => {
162164
if (!WORKING_PATH) {
163165
return;
164166
}
165-
await reconfigureAndSendNotificationWithBackoff(WORKING_PATH);
167+
if (error) {
168+
lspLogger.log(error.toString());
169+
} else {
170+
await reconfigureAndSendNotificationWithBackoff(
171+
WORKING_PATH,
172+
projectGraphAndSourceMaps,
173+
);
174+
}
166175
},
167176
);
168177
} catch (e) {
@@ -674,11 +683,17 @@ connection.onNotification(NxChangeWorkspace, async (workspacePath) => {
674683
await reconfigureAndSendNotificationWithBackoff(WORKING_PATH);
675684
});
676685

677-
async function reconfigureAndSendNotificationWithBackoff(workingPath: string) {
686+
async function reconfigureAndSendNotificationWithBackoff(
687+
workingPath: string,
688+
projectGraphAndSourceMaps?: {
689+
projectGraph: ProjectGraph;
690+
sourceMaps: ConfigurationSourceMaps;
691+
} | null,
692+
) {
678693
if (reconfigureAttempts === 0) {
679694
connection.sendNotification(NxWorkspaceRefreshStartedNotification.method);
680695
}
681-
const workspace = await reconfigure(workingPath);
696+
const workspace = await reconfigure(workingPath, projectGraphAndSourceMaps);
682697
await connection.sendNotification(NxWorkspaceRefreshNotification.method);
683698

684699
if (
@@ -711,20 +726,27 @@ async function reconfigureAndSendNotificationWithBackoff(workingPath: string) {
711726

712727
async function reconfigure(
713728
workingPath: string,
729+
projectGraphAndSourceMaps?: {
730+
projectGraph: ProjectGraph;
731+
sourceMaps: ConfigurationSourceMaps;
732+
} | null,
714733
): Promise<NxWorkspace | undefined> {
715734
resetNxVersionCache();
716735
resetProjectPathCache();
717736
resetSourceMapFilesToProjectCache();
718737
resetInferencePluginsCompletionCache();
719738

720-
const workspace = await nxWorkspace(workingPath, lspLogger, true);
739+
const workspace = await nxWorkspace(
740+
workingPath,
741+
lspLogger,
742+
true,
743+
projectGraphAndSourceMaps,
744+
);
721745
await configureSchemas(workingPath, CLIENT_CAPABILITIES);
722746

723-
await unregisterFileWatcher();
724-
725-
unregisterFileWatcher = await languageServerWatcher(workingPath, async () => {
726-
reconfigureAndSendNotificationWithBackoff(workingPath);
727-
});
747+
// unregisterFileWatcher = await languageServerWatcher(workingPath, async () => {
748+
// reconfigureAndSendNotificationWithBackoff(workingPath);
749+
// });
728750

729751
return workspace;
730752
}

libs/language-server/watcher/src/lib/watcher.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import { lspLogger } from '@nx-console/language-server-utils';
22
import { getNxDaemonClient } from '@nx-console/shared-nx-workspace-info';
3-
import { PassiveDaemonWatcher } from '@nx-console/shared-watcher';
3+
import {
4+
DaemonWatcherCallback,
5+
PassiveDaemonWatcher,
6+
} from '@nx-console/shared-watcher';
47

58
let _daemonWatcher: PassiveDaemonWatcher | undefined;
69

@@ -23,7 +26,7 @@ export async function cleanupAllWatchers(): Promise<void> {
2326

2427
export async function languageServerWatcher(
2528
workspacePath: string,
26-
callback: () => unknown,
29+
callback: DaemonWatcherCallback,
2730
): Promise<() => Promise<void>> {
2831
const daemonClient = await getNxDaemonClient(workspacePath, lspLogger);
2932

@@ -35,8 +38,8 @@ export async function languageServerWatcher(
3538
}
3639
_daemonWatcher = new PassiveDaemonWatcher(workspacePath, lspLogger);
3740
await _daemonWatcher.start();
38-
_daemonWatcher.listen(() => {
39-
callback();
41+
_daemonWatcher.listen((error, projectGraphAndSourceMaps) => {
42+
callback(error, projectGraphAndSourceMaps);
4043
});
4144
return async () => {
4245
if (_daemonWatcher) {

libs/shared/nx-workspace-info/src/lib/get-nx-workspace-config.ts

Lines changed: 79 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ export async function getNxWorkspaceConfig(
2525
workspacePath: string,
2626
nxVersion: NxVersion,
2727
logger: Logger,
28+
projectGraphAndSourceMaps?: {
29+
projectGraph: ProjectGraph;
30+
sourceMaps: ConfigurationSourceMaps;
31+
} | null,
2832
): Promise<{
2933
projectGraph: ProjectGraph | undefined;
3034
sourceMaps: ConfigurationSourceMaps | undefined;
@@ -100,67 +104,88 @@ export async function getNxWorkspaceConfig(
100104
});
101105
}
102106

103-
try {
104-
_defaultProcessExit = process.exit;
105-
process.exit = function (code?: number) {
106-
console.warn('process.exit called with code', code);
107-
} as (code?: number) => never;
108-
109-
if (nxOutput !== undefined) {
110-
nxOutput.output.error = (output) => {
111-
// do nothing
112-
};
113-
nxOutput.output.log = (output) => {
114-
// do nothing
115-
};
116-
}
107+
if (!projectGraphAndSourceMaps) {
108+
try {
109+
_defaultProcessExit = process.exit;
110+
process.exit = function (code?: number) {
111+
console.warn('process.exit called with code', code);
112+
} as (code?: number) => never;
113+
114+
if (nxOutput !== undefined) {
115+
nxOutput.output.error = (output) => {
116+
// do nothing
117+
};
118+
nxOutput.output.log = (output) => {
119+
// do nothing
120+
};
121+
}
117122

118-
if (gte(nxVersion, '17.2.0')) {
119-
logger.log('createProjectGraphAndSourceMapsAsync');
120-
try {
121-
const projectGraphAndSourceMaps = await (
122-
nxProjectGraph as any
123-
).createProjectGraphAndSourceMapsAsync({
123+
if (gte(nxVersion, '17.2.0')) {
124+
logger.log('createProjectGraphAndSourceMapsAsync');
125+
try {
126+
const projectGraphAndSourceMaps = await (
127+
nxProjectGraph as any
128+
).createProjectGraphAndSourceMapsAsync({
129+
exitOnError: false,
130+
});
131+
projectGraph = projectGraphAndSourceMaps.projectGraph;
132+
133+
sourceMaps = projectGraphAndSourceMaps.sourceMaps;
134+
} catch (e) {
135+
if (isProjectGraphError(e)) {
136+
logger.log('caught ProjectGraphError, using partial graph');
137+
projectGraph = e.getPartialProjectGraph() ?? {
138+
nodes: {},
139+
dependencies: {},
140+
};
141+
sourceMaps = e.getPartialSourcemaps();
142+
errors = e.getErrors().map((error) => ({
143+
name: error.name,
144+
message: error.message,
145+
stack: error.stack,
146+
file:
147+
(error as any).file ??
148+
((error as any).cause as any)?.errors?.[0]?.location?.file,
149+
pluginName: (error as any).pluginName,
150+
cause: (error as any).cause,
151+
}));
152+
isPartial = true;
153+
} else {
154+
throw e;
155+
}
156+
}
157+
logger.log('createProjectGraphAndSourceMapsAsync successful');
158+
} else {
159+
logger.log('createProjectGraphAsync');
160+
projectGraph = await nxProjectGraph.createProjectGraphAsync({
124161
exitOnError: false,
125162
});
126-
projectGraph = projectGraphAndSourceMaps.projectGraph;
163+
logger.log('createProjectGraphAsync successful');
164+
}
165+
} catch (e) {
166+
logger.log('Unable to get project graph');
167+
logger.log(e.stack);
168+
errors = [{ stack: e.stack }];
169+
}
127170

128-
sourceMaps = projectGraphAndSourceMaps.sourceMaps;
171+
// reset the daemon client after getting all required information from the daemon
172+
if (
173+
nxDaemonClientModule &&
174+
nxDaemonClientModule.daemonClient?.enabled()
175+
) {
176+
try {
177+
logger.log('Resetting daemon client');
178+
nxDaemonClientModule.daemonClient?.reset();
129179
} catch (e) {
130-
if (isProjectGraphError(e)) {
131-
logger.log('caught ProjectGraphError, using partial graph');
132-
projectGraph = e.getPartialProjectGraph() ?? {
133-
nodes: {},
134-
dependencies: {},
135-
};
136-
sourceMaps = e.getPartialSourcemaps();
137-
errors = e.getErrors().map((error) => ({
138-
name: error.name,
139-
message: error.message,
140-
stack: error.stack,
141-
file:
142-
(error as any).file ??
143-
((error as any).cause as any)?.errors?.[0]?.location?.file,
144-
pluginName: (error as any).pluginName,
145-
cause: (error as any).cause,
146-
}));
147-
isPartial = true;
148-
} else {
149-
throw e;
150-
}
180+
logger.log(`Error while resetting daemon client, moving on...`);
151181
}
152-
logger.log('createProjectGraphAndSourceMapsAsync successful');
153-
} else {
154-
logger.log('createProjectGraphAsync');
155-
projectGraph = await nxProjectGraph.createProjectGraphAsync({
156-
exitOnError: false,
157-
});
158-
logger.log('createProjectGraphAsync successful');
159182
}
160-
} catch (e) {
161-
logger.log('Unable to get project graph');
162-
logger.log(e.stack);
163-
errors = [{ stack: e.stack }];
183+
} else {
184+
logger.log(
185+
'received project graph and source maps, skipping recomputation',
186+
);
187+
projectGraph = projectGraphAndSourceMaps.projectGraph;
188+
sourceMaps = projectGraphAndSourceMaps.sourceMaps;
164189
}
165190

166191
if (gte(nxVersion, '16.3.1') && projectGraph) {
@@ -176,16 +201,6 @@ export async function getNxWorkspaceConfig(
176201
});
177202
}
178203

179-
// reset the daemon client after getting all required information from the daemon
180-
if (nxDaemonClientModule && nxDaemonClientModule.daemonClient?.enabled()) {
181-
try {
182-
logger.log('Resetting daemon client');
183-
nxDaemonClientModule.daemonClient?.reset();
184-
} catch (e) {
185-
logger.log(`Error while resetting daemon client, moving on...`);
186-
}
187-
}
188-
189204
const end = performance.now();
190205
logger.log(`Retrieved workspace configuration in: ${end - start} ms`);
191206

libs/shared/nx-workspace-info/src/lib/workspace.ts

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ import {
1616
import { getNxVersion } from './get-nx-version';
1717
import { getNxWorkspaceConfig } from './get-nx-workspace-config';
1818
import { getNxDaemonClient } from './get-nx-workspace-package';
19+
import type { ProjectGraph } from 'nx/src/devkit-exports';
20+
import type { ConfigurationSourceMaps } from 'nx/src/project-graph/utils/project-configuration-utils';
21+
import { execSync } from 'child_process';
1922

2023
const enum Status {
2124
not_started,
@@ -35,8 +38,12 @@ export async function nxWorkspace(
3538
workspacePath: string,
3639
logger: Logger,
3740
reset?: boolean,
41+
projectGraphAndSourceMaps?: {
42+
projectGraph: ProjectGraph;
43+
sourceMaps: ConfigurationSourceMaps;
44+
} | null,
3845
): Promise<NxWorkspace> {
39-
if (reset) {
46+
if (reset || projectGraphAndSourceMaps) {
4047
resetStatus(workspacePath);
4148
}
4249

@@ -47,7 +54,9 @@ export async function nxWorkspace(
4754
tap(() => {
4855
status = Status.in_progress;
4956
}),
50-
switchMap(() => from(_workspace(workspacePath, logger))),
57+
switchMap(() =>
58+
from(_workspace(workspacePath, logger, projectGraphAndSourceMaps)),
59+
),
5160
tap((workspace) => {
5261
cachedReplay.next(workspace);
5362
status = Status.cached;
@@ -61,23 +70,40 @@ export async function nxWorkspace(
6170
async function _workspace(
6271
workspacePath: string,
6372
logger: Logger,
73+
projectGraphAndSourceMaps?: {
74+
projectGraph: ProjectGraph;
75+
sourceMaps: ConfigurationSourceMaps;
76+
} | null,
6477
): Promise<NxWorkspace> {
6578
try {
6679
const daemonClientModule = await getNxDaemonClient(workspacePath, logger);
6780
const nxVersion = await getNxVersion(workspacePath);
81+
6882
const {
6983
projectGraph,
7084
sourceMaps,
7185
nxJson,
7286
projectFileMap,
7387
errors,
7488
isPartial,
75-
} = await getNxWorkspaceConfig(workspacePath, nxVersion, logger);
89+
} = await getNxWorkspaceConfig(
90+
workspacePath,
91+
nxVersion,
92+
logger,
93+
projectGraphAndSourceMaps,
94+
);
7695

7796
const isLerna = await fileExists(join(workspacePath, 'lerna.json'));
7897

98+
const isAvailable =
99+
await daemonClientModule?.daemonClient.isServerAvailable();
100+
const isRunning = execSync(`npx nx daemon`);
101+
102+
logger.log(`isAvailable: ${isAvailable}, isRunning: ${isRunning}`);
79103
return {
80104
daemonEnabled: daemonClientModule?.isDaemonEnabled() ?? false,
105+
daemonRunning:
106+
(await daemonClientModule?.daemonClient.isServerAvailable()) ?? false,
81107
projectGraph: projectGraph ?? {
82108
nodes: {},
83109
dependencies: {},
@@ -103,6 +129,7 @@ async function _workspace(
103129
// Default to nx workspace
104130
return {
105131
daemonEnabled: false,
132+
daemonRunning: false,
106133
validWorkspaceJson: false,
107134
projectGraph: {
108135
nodes: {},

libs/shared/telemetry/src/lib/telemetry-types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ export type TelemetryEvents =
7777
| 'ai.configure-agents-check-start'
7878
| 'ai.configure-agents-check-end'
7979
| 'ai.configure-agents-check-error'
80+
| 'ai.configure-agents-check-finally'
8081
| 'ai.configure-agents-check-notification'
8182
| 'ai.configure-agents-action'
8283
| 'ai.configure-agents-dont-ask-again'

libs/shared/types/src/lib/nx-workspace.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export type NxProjectConfiguration = ProjectConfiguration & {
1313

1414
export interface NxWorkspace {
1515
daemonEnabled: boolean;
16+
daemonRunning: boolean;
1617
validWorkspaceJson: boolean;
1718
nxJson: NxJsonConfiguration;
1819
projectGraph: ProjectGraph;

0 commit comments

Comments
 (0)