Skip to content

Commit 1bd5eca

Browse files
committed
Don't terminate extension host on a timeout
We will clean it up on our end if necessary. This allows reconnections after any length of time.
1 parent 48a97ab commit 1bd5eca

File tree

3 files changed

+35
-44
lines changed

3 files changed

+35
-44
lines changed

scripts/vscode.patch

+7-26
Original file line numberDiff line numberDiff line change
@@ -1032,37 +1032,18 @@ index 7c3b6ae53e..18dec6effa 100644
10321032

10331033
get webviewResourceRoot(): string {
10341034
diff --git a/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts b/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts
1035-
index 6d31b177ac..a586ac7466 100644
1035+
index 6d31b177ac..d7c1705c57 100644
10361036
--- a/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts
10371037
+++ b/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts
1038-
@@ -116,7 +116,7 @@ function _createExtHostProtocol(): Promise<IMessagePassingProtocol> {
1039-
protocol.onClose(() => onTerminate());
1040-
resolve(protocol);
1041-
1042-
- if (msg.skipWebSocketFrames) {
1043-
+ // if (msg.skipWebSocketFrames) {
1044-
// Wait for rich client to reconnect
1038+
@@ -128,7 +128,7 @@ function _createExtHostProtocol(): Promise<IMessagePassingProtocol> {
1039+
} else {
1040+
// Do not wait for web companion to reconnect
10451041
protocol.onSocketClose(() => {
1046-
// The socket has closed, let's give the renderer a certain amount of time to reconnect
1047-
@@ -125,12 +125,12 @@ function _createExtHostProtocol(): Promise<IMessagePassingProtocol> {
1048-
onTerminate();
1049-
}, ProtocolConstants.ReconnectionGraceTime);
1050-
});
1051-
- } else {
1052-
- // Do not wait for web companion to reconnect
1053-
- protocol.onSocketClose(() => {
10541042
- onTerminate();
1055-
- });
1056-
- }
1057-
+ // } else {
1058-
+ // // Do not wait for web companion to reconnect
1059-
+ // protocol.onSocketClose(() => {
1060-
+ // onTerminate();
1061-
+ // });
1062-
+ // }
1043+
+ process.send!('VSCODE_EXTHOST_DISCONNECTED'); // onTerminate();
1044+
});
1045+
}
10631046
}
1064-
}
1065-
});
10661047
diff --git a/src/vs/workbench/workbench.web.main.ts b/src/vs/workbench/workbench.web.main.ts
10671048
index 681fc606b6..e34ef5d4bc 100644
10681049
--- a/src/vs/workbench/workbench.web.main.ts

src/connection.ts

+18-6
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,7 @@ export abstract class Connection {
1717
private disposed = false;
1818
private _offline: number | undefined;
1919

20-
public constructor(protected protocol: Protocol) {
21-
protocol.onClose(() => this.dispose()); // Explicit close.
22-
protocol.onSocketClose(() => this._offline = Date.now()); // Might reconnect.
23-
}
20+
public constructor(protected protocol: Protocol, public readonly token: string) {}
2421

2522
public get offline(): number | undefined {
2623
return this._offline;
@@ -39,6 +36,12 @@ export abstract class Connection {
3936
}
4037
}
4138

39+
protected setOffline(): void {
40+
if (!this._offline) {
41+
this._offline = Date.now();
42+
}
43+
}
44+
4245
/**
4346
* Set up the connection on a new socket.
4447
*/
@@ -50,6 +53,12 @@ export abstract class Connection {
5053
* Used for all the IPC channels.
5154
*/
5255
export class ManagementConnection extends Connection {
56+
public constructor(protected protocol: Protocol, token: string) {
57+
super(protocol, token);
58+
protocol.onClose(() => this.dispose()); // Explicit close.
59+
protocol.onSocketClose(() => this.setOffline()); // Might reconnect.
60+
}
61+
5362
protected doDispose(): void {
5463
this.protocol.sendDisconnect();
5564
this.protocol.dispose();
@@ -66,11 +75,11 @@ export class ExtensionHostConnection extends Connection {
6675
private process?: cp.ChildProcess;
6776

6877
public constructor(
69-
locale:string, protocol: Protocol, buffer: VSBuffer,
78+
locale:string, protocol: Protocol, buffer: VSBuffer, token: string,
7079
private readonly log: ILogService,
7180
private readonly environment: IEnvironmentService,
7281
) {
73-
super(protocol);
82+
super(protocol, token);
7483
this.protocol.dispose();
7584
this.spawn(locale, buffer).then((p) => this.process = p);
7685
this.protocol.getUnderlyingSocket().pause();
@@ -129,6 +138,9 @@ export class ExtensionHostConnection extends Connection {
129138
const severity = (<any>this.log)[event.severity] ? event.severity : "info";
130139
(<any>this.log)[severity]("Extension host", event.arguments);
131140
}
141+
if (event && event.type === "VSCODE_EXTHOST_DISCONNECTED") {
142+
this.setOffline();
143+
}
132144
});
133145

134146
const listen = (message: IExtHostReadyMessage) => {

src/server.ts

+10-12
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,7 @@ export class MainServer extends Server {
449449
public readonly onDidClientConnect = this._onDidClientConnect.event;
450450
private readonly ipc = new IPCServer(this.onDidClientConnect);
451451

452-
private readonly maxOfflineConnections = 5;
452+
private readonly maxExtraOfflineConnections = 0;
453453
private readonly connections = new Map<ConnectionType, Map<string, Connection>>();
454454

455455
private readonly services = new ServiceCollection();
@@ -601,36 +601,34 @@ export class MainServer extends Server {
601601

602602
let connection: Connection;
603603
if (message.desiredConnectionType === ConnectionType.Management) {
604-
connection = new ManagementConnection(protocol);
604+
connection = new ManagementConnection(protocol, token);
605605
this._onDidClientConnect.fire({
606606
protocol, onDidClientDisconnect: connection.onClose,
607607
});
608608
} else {
609609
const buffer = protocol.readEntireBuffer();
610610
connection = new ExtensionHostConnection(
611611
message.args ? message.args.language : "en",
612-
protocol, buffer,
612+
protocol, buffer, token,
613613
this.services.get(ILogService) as ILogService,
614614
this.services.get(IEnvironmentService) as IEnvironmentService,
615615
);
616616
}
617617
connections.set(token, connection);
618-
this.disposeOldOfflineConnections();
619618
connection.onClose(() => connections.delete(token));
619+
this.disposeOldOfflineConnections(connections);
620620
break;
621621
case ConnectionType.Tunnel: return protocol.tunnel();
622622
default: throw new Error("Unrecognized connection type");
623623
}
624624
}
625625

626-
private disposeOldOfflineConnections(): void {
627-
this.connections.forEach((connections) => {
628-
const offline = Array.from(connections.values())
629-
.filter((connection) => typeof connection.offline !== "undefined");
630-
for (let i = 0, max = offline.length - this.maxOfflineConnections; i < max; ++i) {
631-
offline[i].dispose();
632-
}
633-
});
626+
private disposeOldOfflineConnections(connections: Map<string, Connection>): void {
627+
const offline = Array.from(connections.values())
628+
.filter((connection) => typeof connection.offline !== "undefined");
629+
for (let i = 0, max = offline.length - this.maxExtraOfflineConnections; i < max; ++i) {
630+
offline[i].dispose();
631+
}
634632
}
635633

636634
private async initializeServices(args: ParsedArgs): Promise<void> {

0 commit comments

Comments
 (0)