Skip to content

Commit 0202522

Browse files
committed
Fix server lifecycle bugs and replace hard-coded startup delays
- Fix duplicate --tuple-counting flag when both debug and tupleCounting are set in buildQueryServerArgs - Fix non-awaited force-kill timers in query-server and language-server shutdown methods (process could outlive caller) - Remove redundant process.on SIGINT/SIGTERM handlers from lsp-diagnostics (already handled by shutdownServerManager) - Replace hard-coded setTimeout delays (1.5-2s) in server start() methods with waitForProcessReady utility that resolves on first stderr/stdout output or rejects on spawn failure - Add comprehensive tests for process-ready utility
1 parent 76a139b commit 0202522

14 files changed

+453
-60
lines changed

server/dist/codeql-development-mcp-server.js

Lines changed: 106 additions & 34 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

server/dist/codeql-development-mcp-server.js.map

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

server/src/lib/cli-server.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { clearTimeout, setTimeout } from 'timers';
1515
import { buildCLIServerArgs, CLIServerConfig } from './server-config';
1616
import { getResolvedCodeQLDir } from './cli-executor';
1717
import { logger } from '../utils/logger';
18+
import { waitForProcessReady } from '../utils/process-ready';
1819

1920
/**
2021
* A queued command waiting to be sent to the CLI server.
@@ -102,8 +103,8 @@ export class CodeQLCLIServer extends EventEmitter {
102103
this.emit('exit', code);
103104
});
104105

105-
// Brief startup delay for JVM init
106-
await new Promise((resolve) => setTimeout(resolve, 1500));
106+
// Wait for the JVM to initialise (resolves on first stderr/stdout output)
107+
await waitForProcessReady(this.process, 'CodeQL CLI Server');
107108
logger.info('CodeQL CLI Server started');
108109
}
109110

server/src/lib/language-server.ts

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { logger } from '../utils/logger';
1212
import { getPackageVersion } from '../utils/package-paths';
1313
import { getProjectTmpDir } from '../utils/temp-dir';
1414
import { getResolvedCodeQLDir } from './cli-executor';
15+
import { waitForProcessReady } from '../utils/process-ready';
1516

1617
export interface LSPMessage {
1718
jsonrpc: '2.0';
@@ -177,8 +178,8 @@ export class CodeQLLanguageServer extends EventEmitter {
177178
this.emit('exit', code);
178179
});
179180

180-
// Wait for server to be ready
181-
await new Promise((resolve) => setTimeout(resolve, 2000));
181+
// Wait for the JVM to initialise (resolves on first stderr/stdout output)
182+
await waitForProcessReady(this.server, 'CodeQL Language Server');
182183
}
183184

184185
private handleStdout(data: Buffer): void {
@@ -520,11 +521,25 @@ export class CodeQLLanguageServer extends EventEmitter {
520521
}
521522

522523
// Force kill if needed
523-
setTimeout(() => {
524+
await new Promise<void>((resolve) => {
525+
const timer = setTimeout(() => {
526+
if (this.server) {
527+
this.server.kill('SIGTERM');
528+
}
529+
resolve();
530+
}, 1000);
531+
524532
if (this.server) {
525-
this.server.kill('SIGTERM');
533+
this.server.once('exit', () => {
534+
clearTimeout(timer);
535+
this.server = null;
536+
resolve();
537+
});
538+
} else {
539+
clearTimeout(timer);
540+
resolve();
526541
}
527-
}, 1000);
542+
});
528543

529544
this.isInitialized = false;
530545
}

0 commit comments

Comments
 (0)