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.
This commit is contained in:
parent
48a97abe1d
commit
1bd5eca73d
|
@ -1032,37 +1032,18 @@ index 7c3b6ae53e..18dec6effa 100644
|
||||||
|
|
||||||
get webviewResourceRoot(): string {
|
get webviewResourceRoot(): string {
|
||||||
diff --git a/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts b/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts
|
diff --git a/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts b/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts
|
||||||
index 6d31b177ac..a586ac7466 100644
|
index 6d31b177ac..d7c1705c57 100644
|
||||||
--- a/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts
|
--- a/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts
|
||||||
+++ b/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts
|
+++ b/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts
|
||||||
@@ -116,7 +116,7 @@ function _createExtHostProtocol(): Promise<IMessagePassingProtocol> {
|
@@ -128,7 +128,7 @@ function _createExtHostProtocol(): Promise<IMessagePassingProtocol> {
|
||||||
protocol.onClose(() => onTerminate());
|
} else {
|
||||||
resolve(protocol);
|
// Do not wait for web companion to reconnect
|
||||||
|
|
||||||
- if (msg.skipWebSocketFrames) {
|
|
||||||
+ // if (msg.skipWebSocketFrames) {
|
|
||||||
// Wait for rich client to reconnect
|
|
||||||
protocol.onSocketClose(() => {
|
protocol.onSocketClose(() => {
|
||||||
// The socket has closed, let's give the renderer a certain amount of time to reconnect
|
|
||||||
@@ -125,12 +125,12 @@ function _createExtHostProtocol(): Promise<IMessagePassingProtocol> {
|
|
||||||
onTerminate();
|
|
||||||
}, ProtocolConstants.ReconnectionGraceTime);
|
|
||||||
});
|
|
||||||
- } else {
|
|
||||||
- // Do not wait for web companion to reconnect
|
|
||||||
- protocol.onSocketClose(() => {
|
|
||||||
- onTerminate();
|
- onTerminate();
|
||||||
- });
|
+ process.send!('VSCODE_EXTHOST_DISCONNECTED'); // onTerminate();
|
||||||
- }
|
});
|
||||||
+ // } else {
|
}
|
||||||
+ // // Do not wait for web companion to reconnect
|
|
||||||
+ // protocol.onSocketClose(() => {
|
|
||||||
+ // onTerminate();
|
|
||||||
+ // });
|
|
||||||
+ // }
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
diff --git a/src/vs/workbench/workbench.web.main.ts b/src/vs/workbench/workbench.web.main.ts
|
diff --git a/src/vs/workbench/workbench.web.main.ts b/src/vs/workbench/workbench.web.main.ts
|
||||||
index 681fc606b6..e34ef5d4bc 100644
|
index 681fc606b6..e34ef5d4bc 100644
|
||||||
--- a/src/vs/workbench/workbench.web.main.ts
|
--- a/src/vs/workbench/workbench.web.main.ts
|
||||||
|
|
|
@ -17,10 +17,7 @@ export abstract class Connection {
|
||||||
private disposed = false;
|
private disposed = false;
|
||||||
private _offline: number | undefined;
|
private _offline: number | undefined;
|
||||||
|
|
||||||
public constructor(protected protocol: Protocol) {
|
public constructor(protected protocol: Protocol, public readonly token: string) {}
|
||||||
protocol.onClose(() => this.dispose()); // Explicit close.
|
|
||||||
protocol.onSocketClose(() => this._offline = Date.now()); // Might reconnect.
|
|
||||||
}
|
|
||||||
|
|
||||||
public get offline(): number | undefined {
|
public get offline(): number | undefined {
|
||||||
return this._offline;
|
return this._offline;
|
||||||
|
@ -39,6 +36,12 @@ export abstract class Connection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected setOffline(): void {
|
||||||
|
if (!this._offline) {
|
||||||
|
this._offline = Date.now();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set up the connection on a new socket.
|
* Set up the connection on a new socket.
|
||||||
*/
|
*/
|
||||||
|
@ -50,6 +53,12 @@ export abstract class Connection {
|
||||||
* Used for all the IPC channels.
|
* Used for all the IPC channels.
|
||||||
*/
|
*/
|
||||||
export class ManagementConnection extends Connection {
|
export class ManagementConnection extends Connection {
|
||||||
|
public constructor(protected protocol: Protocol, token: string) {
|
||||||
|
super(protocol, token);
|
||||||
|
protocol.onClose(() => this.dispose()); // Explicit close.
|
||||||
|
protocol.onSocketClose(() => this.setOffline()); // Might reconnect.
|
||||||
|
}
|
||||||
|
|
||||||
protected doDispose(): void {
|
protected doDispose(): void {
|
||||||
this.protocol.sendDisconnect();
|
this.protocol.sendDisconnect();
|
||||||
this.protocol.dispose();
|
this.protocol.dispose();
|
||||||
|
@ -66,11 +75,11 @@ export class ExtensionHostConnection extends Connection {
|
||||||
private process?: cp.ChildProcess;
|
private process?: cp.ChildProcess;
|
||||||
|
|
||||||
public constructor(
|
public constructor(
|
||||||
locale:string, protocol: Protocol, buffer: VSBuffer,
|
locale:string, protocol: Protocol, buffer: VSBuffer, token: string,
|
||||||
private readonly log: ILogService,
|
private readonly log: ILogService,
|
||||||
private readonly environment: IEnvironmentService,
|
private readonly environment: IEnvironmentService,
|
||||||
) {
|
) {
|
||||||
super(protocol);
|
super(protocol, token);
|
||||||
this.protocol.dispose();
|
this.protocol.dispose();
|
||||||
this.spawn(locale, buffer).then((p) => this.process = p);
|
this.spawn(locale, buffer).then((p) => this.process = p);
|
||||||
this.protocol.getUnderlyingSocket().pause();
|
this.protocol.getUnderlyingSocket().pause();
|
||||||
|
@ -129,6 +138,9 @@ export class ExtensionHostConnection extends Connection {
|
||||||
const severity = (<any>this.log)[event.severity] ? event.severity : "info";
|
const severity = (<any>this.log)[event.severity] ? event.severity : "info";
|
||||||
(<any>this.log)[severity]("Extension host", event.arguments);
|
(<any>this.log)[severity]("Extension host", event.arguments);
|
||||||
}
|
}
|
||||||
|
if (event && event.type === "VSCODE_EXTHOST_DISCONNECTED") {
|
||||||
|
this.setOffline();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const listen = (message: IExtHostReadyMessage) => {
|
const listen = (message: IExtHostReadyMessage) => {
|
||||||
|
|
|
@ -449,7 +449,7 @@ export class MainServer extends Server {
|
||||||
public readonly onDidClientConnect = this._onDidClientConnect.event;
|
public readonly onDidClientConnect = this._onDidClientConnect.event;
|
||||||
private readonly ipc = new IPCServer(this.onDidClientConnect);
|
private readonly ipc = new IPCServer(this.onDidClientConnect);
|
||||||
|
|
||||||
private readonly maxOfflineConnections = 5;
|
private readonly maxExtraOfflineConnections = 0;
|
||||||
private readonly connections = new Map<ConnectionType, Map<string, Connection>>();
|
private readonly connections = new Map<ConnectionType, Map<string, Connection>>();
|
||||||
|
|
||||||
private readonly services = new ServiceCollection();
|
private readonly services = new ServiceCollection();
|
||||||
|
@ -601,7 +601,7 @@ export class MainServer extends Server {
|
||||||
|
|
||||||
let connection: Connection;
|
let connection: Connection;
|
||||||
if (message.desiredConnectionType === ConnectionType.Management) {
|
if (message.desiredConnectionType === ConnectionType.Management) {
|
||||||
connection = new ManagementConnection(protocol);
|
connection = new ManagementConnection(protocol, token);
|
||||||
this._onDidClientConnect.fire({
|
this._onDidClientConnect.fire({
|
||||||
protocol, onDidClientDisconnect: connection.onClose,
|
protocol, onDidClientDisconnect: connection.onClose,
|
||||||
});
|
});
|
||||||
|
@ -609,28 +609,26 @@ export class MainServer extends Server {
|
||||||
const buffer = protocol.readEntireBuffer();
|
const buffer = protocol.readEntireBuffer();
|
||||||
connection = new ExtensionHostConnection(
|
connection = new ExtensionHostConnection(
|
||||||
message.args ? message.args.language : "en",
|
message.args ? message.args.language : "en",
|
||||||
protocol, buffer,
|
protocol, buffer, token,
|
||||||
this.services.get(ILogService) as ILogService,
|
this.services.get(ILogService) as ILogService,
|
||||||
this.services.get(IEnvironmentService) as IEnvironmentService,
|
this.services.get(IEnvironmentService) as IEnvironmentService,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
connections.set(token, connection);
|
connections.set(token, connection);
|
||||||
this.disposeOldOfflineConnections();
|
|
||||||
connection.onClose(() => connections.delete(token));
|
connection.onClose(() => connections.delete(token));
|
||||||
|
this.disposeOldOfflineConnections(connections);
|
||||||
break;
|
break;
|
||||||
case ConnectionType.Tunnel: return protocol.tunnel();
|
case ConnectionType.Tunnel: return protocol.tunnel();
|
||||||
default: throw new Error("Unrecognized connection type");
|
default: throw new Error("Unrecognized connection type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private disposeOldOfflineConnections(): void {
|
private disposeOldOfflineConnections(connections: Map<string, Connection>): void {
|
||||||
this.connections.forEach((connections) => {
|
const offline = Array.from(connections.values())
|
||||||
const offline = Array.from(connections.values())
|
.filter((connection) => typeof connection.offline !== "undefined");
|
||||||
.filter((connection) => typeof connection.offline !== "undefined");
|
for (let i = 0, max = offline.length - this.maxExtraOfflineConnections; i < max; ++i) {
|
||||||
for (let i = 0, max = offline.length - this.maxOfflineConnections; i < max; ++i) {
|
offline[i].dispose();
|
||||||
offline[i].dispose();
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async initializeServices(args: ParsedArgs): Promise<void> {
|
private async initializeServices(args: ParsedArgs): Promise<void> {
|
||||||
|
|
Loading…
Reference in New Issue