Skip to content

Commit 6966209

Browse files
authored
Use node ipc for TS Server (#46418)
* Use node ipc for TS Server For #46417 This lets us use Node's built-in ipc for passing messages to/from the typescript server instead of using stdio * Remove extra parse * Add extra logging when using node IPC * Split out to subclass * Extract common writeMessage method * Baseline accept
1 parent e10c912 commit 6966209

File tree

3 files changed

+35
-2
lines changed

3 files changed

+35
-2
lines changed

src/server/session.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -940,6 +940,10 @@ namespace ts.server {
940940
}
941941
return;
942942
}
943+
this.writeMessage(msg);
944+
}
945+
946+
protected writeMessage(msg: protocol.Message) {
943947
const msgText = formatMessage(msg, this.logger, this.byteLength, this.host.newLine);
944948
perfLogger.logEvent(`Response message size: ${msgText.length}`);
945949
this.host.write(msgText);

src/tsserver/nodeServer.ts

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ namespace ts.server {
233233

234234
// Override sys.write because fs.writeSync is not reliable on Node 4
235235
sys.write = (s: string) => writeMessage(sys.bufferFrom!(s, "utf8") as globalThis.Buffer);
236-
// REVIEW: for now this implementation uses polling.
236+
// REVIEW: for now this implementation uses polling.
237237
// The advantage of polling is that it works reliably
238238
// on all os and with network mounted files.
239239
// For 90 referenced files, the average time to detect
@@ -759,12 +759,40 @@ namespace ts.server {
759759
}
760760
}
761761

762+
class IpcIOSession extends IOSession {
763+
764+
protected writeMessage(msg: protocol.Message): void {
765+
const verboseLogging = logger.hasLevel(LogLevel.verbose);
766+
if (verboseLogging) {
767+
const json = JSON.stringify(msg);
768+
logger.info(`${msg.type}:${indent(json)}`);
769+
}
770+
771+
process.send!(msg);
772+
}
773+
774+
protected parseMessage(message: any): protocol.Request {
775+
return message as protocol.Request;
776+
}
777+
778+
protected toStringMessage(message: any) {
779+
return JSON.stringify(message, undefined, 2);
780+
}
781+
782+
public listen() {
783+
process.on("message", (e: any) => {
784+
this.onMessage(e);
785+
});
786+
}
787+
}
788+
762789
const eventPort: number | undefined = parseEventPort(findArgument("--eventPort"));
763790
const typingSafeListLocation = findArgument(Arguments.TypingSafeListLocation)!; // TODO: GH#18217
764791
const typesMapLocation = findArgument(Arguments.TypesMapLocation) || combinePaths(getDirectoryPath(sys.getExecutingFilePath()), "typesMap.json");
765792
const npmLocation = findArgument(Arguments.NpmLocation);
766793
const validateDefaultNpmLocation = hasArgument(Arguments.ValidateDefaultNpmLocation);
767794
const disableAutomaticTypingAcquisition = hasArgument("--disableAutomaticTypingAcquisition");
795+
const useNodeIpc = hasArgument("--useNodeIpc");
768796
const telemetryEnabled = hasArgument(Arguments.EnableTelemetry);
769797
const commandLineTraceDir = findArgument("--traceDirectory");
770798
const traceDir = commandLineTraceDir
@@ -774,7 +802,7 @@ namespace ts.server {
774802
startTracing("server", traceDir);
775803
}
776804

777-
const ioSession = new IOSession();
805+
const ioSession = useNodeIpc ? new IpcIOSession() : new IOSession();
778806
process.on("uncaughtException", err => {
779807
ioSession.logError(err, "unknown");
780808
});

tests/baselines/reference/api/tsserverlibrary.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10487,6 +10487,7 @@ declare namespace ts.server {
1048710487
logError(err: Error, cmd: string): void;
1048810488
private logErrorWorker;
1048910489
send(msg: protocol.Message): void;
10490+
protected writeMessage(msg: protocol.Message): void;
1049010491
event<T extends object>(body: T, eventName: string): void;
1049110492
/** @deprecated */
1049210493
output(info: any, cmdName: string, reqSeq?: number, errorMsg?: string): void;

0 commit comments

Comments
 (0)