Skip to content

Commit 6adb005

Browse files
client: setting to indicate detached server max lifetime
- Allows the client to configure a ServerOptions setting that sets the max lifetime of the detached language server after the parent/client has terminated. - Additionally, this exposes some utils from the language server so that they can be reused in tests. Otherwise we'd have to duplicate code and reduce code coverage Signed-off-by: nkomonen-amazon <[email protected]>
1 parent bb822ef commit 6adb005

File tree

6 files changed

+43
-11
lines changed

6 files changed

+43
-11
lines changed

client-node-tests/src/integration.test.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1979,7 +1979,7 @@ suite('Server tests', () => {
19791979
};
19801980
const client = new lsclient.LanguageClient('test svr', serverOptions, {});
19811981
const res = await client.sendRequest(IsDetachedRequest);
1982-
assert.strictEqual(res, false);
1982+
assert.deepStrictEqual(res, { detached: false });
19831983
});
19841984

19851985
[lsclient.TransportKind.stdio, lsclient.TransportKind.ipc, lsclient.TransportKind.pipe].forEach((transport) => {
@@ -1988,12 +1988,13 @@ suite('Server tests', () => {
19881988
module: detachedServerModule,
19891989
transport,
19901990
options: {
1991-
detached: true
1991+
detached: true,
1992+
detachedTimeout: 1000
19921993
}
19931994
};
19941995
const client = new lsclient.LanguageClient('test svr', serverOptions, {});
19951996
const res = await client.sendRequest(IsDetachedRequest);
1996-
assert.strictEqual(res, true);
1997+
assert.deepStrictEqual(res, { detached: true, timeout: 1000 });
19971998
});
19981999
});
19992000

@@ -2004,12 +2005,13 @@ suite('Server tests', () => {
20042005
args: [detachedServerModule],
20052006
transport,
20062007
options: {
2007-
detached: true
2008+
detached: true,
2009+
detachedTimeout: 1001
20082010
}
20092011
};
20102012
const client = new lsclient.LanguageClient('test svr', serverOptions, {});
20112013
const res = await client.sendRequest(IsDetachedRequest);
2012-
assert.strictEqual(res, true);
2014+
assert.deepStrictEqual(res, { detached: true, timeout: 1001 });
20132015
});
20142016
});
20152017

client-node-tests/src/servers/detachedServer.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,15 @@
99

1010
import { createConnection, ProposedFeatures } from 'vscode-languageserver/node';
1111
import { IsDetachedRequest } from './types';
12+
import { parseCliOpts } from 'vscode-languageserver/utils';
1213

1314
const connection = createConnection(ProposedFeatures.all);
1415

1516
connection.onRequest(IsDetachedRequest, () => {
16-
return process.argv.includes('--detached');
17+
const args = parseCliOpts(process.argv);
18+
const detached = Object.keys(args).includes('detached');
19+
const timeout = args['detached'];
20+
return { detached, timeout };
1721
});
1822

1923
// Initialize the language server connection

client-node-tests/src/servers/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@
55

66
import { RequestType0 } from 'vscode-languageserver';
77

8-
export const IsDetachedRequest = new RequestType0('isDetached');
8+
export const IsDetachedRequest = new RequestType0<{detached: boolean; timeout: number }, void>('isDetached');

client/src/node/main.ts

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,18 @@ namespace Transport {
5757
}
5858
}
5959

60-
export interface ExecutableOptions {
60+
export interface DetachedOptions {
61+
detached?: boolean;
62+
/**
63+
* Maximum milliseconds to keep the server alive after the parent/client terminates.
64+
* If undefined it will never terminate.
65+
*/
66+
detachedTimeout?: number;
67+
}
68+
69+
export interface ExecutableOptions extends DetachedOptions {
6170
cwd?: string;
6271
env?: any;
63-
detached?: boolean;
6472
shell?: boolean;
6573
}
6674

@@ -77,12 +85,11 @@ namespace Executable {
7785
}
7886
}
7987

80-
export interface ForkOptions {
88+
export interface ForkOptions extends DetachedOptions {
8189
cwd?: string;
8290
env?: any;
8391
encoding?: string;
8492
execArgv?: string[];
85-
detached?: boolean;
8693
}
8794

8895
export interface NodeModule {
@@ -354,6 +361,9 @@ export class LanguageClient extends BaseLanguageClient {
354361
}
355362
if (node.options?.detached) {
356363
args.push('--detached');
364+
if (node.options.detachedTimeout) {
365+
args.push(node.options.detachedTimeout.toString());
366+
}
357367
}
358368
args.push(`--clientProcessId=${process.pid.toString()}`);
359369
if (transport === TransportKind.ipc || transport === TransportKind.stdio) {
@@ -416,6 +426,9 @@ export class LanguageClient extends BaseLanguageClient {
416426
args.push(`--clientProcessId=${process.pid.toString()}`);
417427
if (node.options?.detached) {
418428
args.push('--detached');
429+
if (node.options.detachedTimeout) {
430+
args.push(node.options.detachedTimeout.toString());
431+
}
419432
}
420433
const options: cp.ForkOptions = node.options ?? Object.create(null);
421434
options.env = getEnvironment(options.env, true);
@@ -478,6 +491,9 @@ export class LanguageClient extends BaseLanguageClient {
478491
}
479492
if (command.options?.detached) {
480493
args.push('--detached');
494+
if (command.options.detachedTimeout) {
495+
args.push(command.options.detachedTimeout.toString());
496+
}
481497
}
482498
const options = Object.assign({}, command.options);
483499
options.cwd = options.cwd || serverWorkingDir;

server/package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@
2424
"./browser": {
2525
"types": "./lib/browser/main.d.ts",
2626
"browser": "./lib/browser/main.js"
27+
},
28+
"./utils": {
29+
"types": "./lib/common/utils/main.d.ts",
30+
"default": "./lib/common/utils/main.js"
2731
}
2832
},
2933
"bin": {

server/src/common/utils/main.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/* --------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
* ------------------------------------------------------------------------------------------ */
5+
6+
export * from './process';

0 commit comments

Comments
 (0)