Restart a crashed language server per --restart never|always|N
The process is supervised: on exit after a successful initialize it is spawned again with exponential backoff (500ms to 30s), open documents are re-sent as didOpen before the new session is announced, and requests caught by the crash wait for it and retry. A crash more than a minute after the previous one starts a fresh streak; reaching the streak limit (default 3) ends restarting for good, after which every request fails with an LspError saying so. Restarts and give-ups are logged and forwarded to the MCP client. Writes to the child's stdin go through a PassThrough so a broken pipe ends the session instead of surfacing as an unhandled rejection.
This commit is contained in:
6 files changed
+441
-146
No files matched your search
Vendored
+6
-2
@@ -1,11 +1,14 @@
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { Effect, FileSystem, Layer, Path } from "effect";
|
||||
import { LanguageServer } from "../../src/lsp/LanguageServer.ts";
|
||||
import { LanguageServer, type Options } from "../../src/lsp/LanguageServer.ts";
|
||||
|
||||
const server = fileURLToPath(new URL("./server.ts", import.meta.url));
|
||||
|
||||
/** A temporary workspace with the given files, served by the fixture language server. */
|
||||
export const workspace = (files: Record<string, string>) =>
|
||||
export const workspace = (
|
||||
files: Record<string, string>,
|
||||
options?: Pick<Options, "restart">,
|
||||
) =>
|
||||
Layer.unwrap(
|
||||
Effect.gen(function* () {
|
||||
const fs = yield* FileSystem.FileSystem;
|
||||
@@ -18,6 +21,7 @@ export const workspace = (files: Record<string, string>) =>
|
||||
command: process.execPath,
|
||||
args: [server],
|
||||
root,
|
||||
...options,
|
||||
});
|
||||
}),
|
||||
);
|
||||
Reference in new issue
Block a user