microsoft / microsoft/vscode-languageserver-node

`detached` not working as expected

Open
#1,595 5 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

feature-request
Dominant language
TypeScript
Stars
1.8k
Forks
404
Avg merge
2d 8h
Merged PRs (30d)
14

Description

My original task is that if the LS client (Extension Host) terminates gracefully or non gracefully, I don't want my Language Server to terminate. I want the LS to decide for itself when to terminate.

  • It looks like the detached flag should have been the solution but I am not able to get it to working.
  • I've also tried:
// based on this comment: https://github.com/microsoft/vscode-languageserver-node/issues/857#issuecomment-980003467
{ initializationOptions: { processId: '' }, }
Minimal Repro

These are the following steps to setup for repro.

import {
	createConnection,
	NotificationType,
	ProposedFeatures} from 'vscode-languageserver/node';

const Heartbeat: NotificationType<undefined> = new NotificationType<undefined>('heartbeat');

const connection = createConnection(ProposedFeatures.all);

connection.onInitialize(() => {
	connection.console.log(`PPID ${process.ppid}`);
        // I would expect this PID to stay alive after the PPID above is terminated, but it does not
	connection.console.log(`PID ${process.pid}`);
	return {
		capabilities: {}
	};
});

connection.onNotification(Heartbeat, () => {
	connection.console.log('heartbeat');
});

connection.listen();

  • Replace client/src/extension.ts
import * as path from 'path';
import { ExtensionContext } from 'vscode';

import {
	Executable,
	LanguageClient,
	NotificationType,
	TransportKind
} from 'vscode-languageclient/node';

let client: LanguageClient;
const Heartbeat: NotificationType<undefined> = new NotificationType<undefined>('heartbeat');

export async function activate(context: ExtensionContext) {
	const serverModule = context.asAbsolutePath(
		path.join('server', 'out', 'server.js')
	);

	// `detached` is not available in ForkOptions, so I must do it this way
	const serverOptions: Executable = {
		command: 'node', args: [serverModule], transport: TransportKind.stdio, options: { detached: true }
	};

	// Create the language client and start the client.
	client = new LanguageClient(
		'languageServerExample',
		'Language Server Example',
		serverOptions,
		// Tried this based on this comment: https://github.com/microsoft/vscode-languageserver-node/issues/857#issuecomment-980003467
		{ initializationOptions: { processId: '' }, }
	);

	await client.start();


	// Send a heartbeat every interval to show we are connected to LSP
	setInterval(async () => {
		await client.sendNotification(Heartbeat);
	}, 5000);
}

export function deactivate(): Thenable<void> | undefined {
	return undefined;
}

  • Run the extension in Debug Mode
  • Note the PPID+PID in the logs of the Language Server Example Output logs
  • Kill the PPID (Ext host)
  • The PID unexpectedly terminates shortly after.
Expected

I would expect that with detached: true killing the Ext Host would not impact the Language Server.

Is there any configuration that I am missing? Maybe something that needs to be configured on the LS side?

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the lsp-sample files server/src/server.ts and client/src/extension.ts, then reproduce the behavior by running the extension in Debug Mode and terminating the extension-host PPID. Trace how Executable options, detached, and initializationOptions.processId are handled. Done means the language-server PID remains alive after the extension host terminates, with the expected behavior covered by a relevant test or documented configuration.

Written by the indexing model from the issue text.

Assessment

Tech stack
node.js, typescript
Domain
developer-experience, tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.