Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 0025812

Browse files
code-asherkylecarbs
authored andcommittedMar 28, 2019
Handle disconnects (#363)
* Make proxies decide how to handle disconnects * Connect to a new terminal instance on disconnect * Use our retry for the watcher * Specify method when proxy doesn't exist * Don't error when closing/killing disconnected proxy * Specify proxy ID when a method doesn't exist * Use our retry for the searcher Also dispose some things for the watcher because it doesn't seem that was done properly. The searcher also now starts immediately so there won't be lag when you perform your first search. * Use our retry for the extension host * Emit error in parent proxy class Reduces duplicate code. Not all items are "supposed" to have an error event according to the original implementation we are filling, but there is no reason why we can't emit our own events (and are already doing so for the "disconnected" event anyway). * Reconnect spdlog * Add error message when shared process disconnects * Pass method resolve to parse * Don't pass method to getProxy It doesn't tell you anything that trace logging wouldn't and has no relation to what the function actually does. * Fix infinite recursion when disposing protocol client in tests
1 parent 4983d71 commit 0025812

File tree

11 files changed

+219
-30
lines changed

11 files changed

+219
-30
lines changed
 

‎packages/protocol/src/browser/client.ts

+24-15
Original file line numberDiff line numberDiff line change
@@ -134,21 +134,21 @@ export class Client {
134134
message.setResponse(stringify(error));
135135
this.failEmitter.emit(message);
136136

137-
this.eventEmitter.emit({ event: "exit", args: [1] });
138-
this.eventEmitter.emit({ event: "close", args: [] });
139-
try {
140-
this.eventEmitter.emit({ event: "error", args: [error] });
141-
} catch (error) {
142-
// If nothing is listening, EventEmitter will throw an error.
143-
}
144-
this.eventEmitter.emit({ event: "done", args: [true] });
137+
this.eventEmitter.emit({ event: "disconnected", args: [error] });
138+
this.eventEmitter.emit({ event: "done", args: [] });
145139
};
146140

147141
connection.onDown(() => handleDisconnect());
148142
connection.onClose(() => {
149143
clearTimeout(this.pingTimeout as any);
150144
this.pingTimeout = undefined;
151145
handleDisconnect();
146+
this.proxies.clear();
147+
this.successEmitter.dispose();
148+
this.failEmitter.dispose();
149+
this.eventEmitter.dispose();
150+
this.initDataEmitter.dispose();
151+
this.sharedProcessActiveEmitter.dispose();
152152
});
153153
connection.onUp(() => this.disconnected = false);
154154

@@ -174,8 +174,17 @@ export class Client {
174174
* Make a remote call for a proxy's method using proto.
175175
*/
176176
private remoteCall(proxyId: number | Module, method: string, args: any[]): Promise<any> {
177-
if (this.disconnected) {
178-
return Promise.reject(new Error("disconnected"));
177+
if (this.disconnected && typeof proxyId === "number") {
178+
// Can assume killing or closing works because a disconnected proxy
179+
// is disposed on the server's side.
180+
switch (method) {
181+
case "close":
182+
case "kill":
183+
return Promise.resolve();
184+
}
185+
return Promise.reject(
186+
new Error(`Unable to call "${method}" on proxy ${proxyId}: disconnected`),
187+
);
179188
}
180189

181190
const message = new MethodMessage();
@@ -223,7 +232,7 @@ export class Client {
223232

224233
// The server will send back a fail or success message when the method
225234
// has completed, so we listen for that based on the message's unique ID.
226-
const promise = new Promise((resolve, reject): void => {
235+
const promise = new Promise((resolve, reject): void => {
227236
const dispose = (): void => {
228237
d1.dispose();
229238
d2.dispose();
@@ -237,7 +246,7 @@ export class Client {
237246

238247
const d1 = this.successEmitter.event(id, (message) => {
239248
dispose();
240-
resolve(this.parse(message.getResponse()));
249+
resolve(this.parse(message.getResponse(), promise));
241250
});
242251

243252
const d2 = this.failEmitter.event(id, (message) => {
@@ -450,12 +459,12 @@ export class Client {
450459
callbacks: new Map(),
451460
});
452461

453-
instance.onDone((disconnected: boolean) => {
462+
instance.onDone(() => {
454463
const log = (): void => {
455464
logger.trace(() => [
456465
typeof proxyId === "number" ? "disposed proxy" : "disposed proxy callbacks",
457466
field("proxyId", proxyId),
458-
field("disconnected", disconnected),
467+
field("disconnected", this.disconnected),
459468
field("callbacks", Array.from(this.proxies.values()).reduce((count, proxy) => count + proxy.callbacks.size, 0)),
460469
field("success listeners", this.successEmitter.counts),
461470
field("fail listeners", this.failEmitter.counts),
@@ -471,7 +480,7 @@ export class Client {
471480
this.eventEmitter.dispose(proxyId);
472481
log();
473482
};
474-
if (!disconnected) {
483+
if (!this.disconnected) {
475484
instance.dispose().then(dispose).catch(dispose);
476485
} else {
477486
dispose();

‎packages/protocol/src/browser/modules/child_process.ts

+5
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,11 @@ export class ChildProcess extends ClientProxy<ChildProcessProxy> implements cp.C
8787

8888
return true; // Always true since we can't get this synchronously.
8989
}
90+
91+
protected handleDisconnect(): void {
92+
this.emit("exit", 1);
93+
this.emit("close");
94+
}
9095
}
9196

9297
export class ChildProcessModule {

‎packages/protocol/src/browser/modules/fs.ts

+4
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ class Watcher extends ClientProxy<WatcherProxy> implements fs.FSWatcher {
4141
public close(): void {
4242
this.proxy.close();
4343
}
44+
45+
protected handleDisconnect(): void {
46+
this.emit("close");
47+
}
4448
}
4549

4650
class WriteStream extends Writable<WriteStreamProxy> implements fs.WriteStream {

‎packages/protocol/src/browser/modules/net.ts

+11-1
Original file line numberDiff line numberDiff line change
@@ -126,14 +126,20 @@ export class Socket extends Duplex<NetSocketProxy> implements net.Socket {
126126
}
127127

128128
export class Server extends ClientProxy<NetServerProxy> implements net.Server {
129+
private socketId = 0;
129130
private readonly sockets = new Map<number, net.Socket>();
130131
private _listening: boolean = false;
131132

132133
public constructor(proxyPromise: Promise<NetServerProxy> | NetServerProxy) {
133134
super(proxyPromise);
134135

135136
this.proxy.onConnection((socketProxy) => {
136-
this.emit("connection", new Socket(socketProxy));
137+
const socket = new Socket(socketProxy);
138+
const socketId = this.socketId++;
139+
this.sockets.set(socketId, socket);
140+
socket.on("error", () => this.sockets.delete(socketId))
141+
socket.on("close", () => this.sockets.delete(socketId))
142+
this.emit("connection", socket);
137143
});
138144

139145
this.on("listening", () => this._listening = true);
@@ -200,6 +206,10 @@ export class Server extends ClientProxy<NetServerProxy> implements net.Server {
200206
public getConnections(cb: (error: Error | null, count: number) => void): void {
201207
cb(null, this.sockets.size);
202208
}
209+
210+
protected handleDisconnect(): void {
211+
this.emit("close");
212+
}
203213
}
204214

205215
type NodeNet = typeof net;

‎packages/protocol/src/browser/modules/node-pty.ts

+19-4
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,20 @@ export class NodePtyProcess extends ClientProxy<NodePtyProcessProxy> implements
66
private _pid = -1;
77
private _process = "";
88

9-
public constructor(proxyPromise: Promise<NodePtyProcessProxy>) {
10-
super(proxyPromise);
9+
public constructor(
10+
private readonly moduleProxy: NodePtyModuleProxy,
11+
private readonly file: string,
12+
private readonly args: string[] | string,
13+
private readonly options: pty.IPtyForkOptions,
14+
) {
15+
super(moduleProxy.spawn(file, args, options));
16+
this.on("process", (process) => this._process = process);
17+
}
18+
19+
protected initialize(proxyPromise: Promise<NodePtyProcessProxy>) {
20+
super.initialize(proxyPromise);
1121
this.proxy.getPid().then((pid) => this._pid = pid);
1222
this.proxy.getProcess().then((process) => this._process = process);
13-
this.on("process", (process) => this._process = process);
1423
}
1524

1625
public get pid(): number {
@@ -32,6 +41,12 @@ export class NodePtyProcess extends ClientProxy<NodePtyProcessProxy> implements
3241
public kill(signal?: string): void {
3342
this.proxy.kill(signal);
3443
}
44+
45+
protected handleDisconnect(): void {
46+
this._process += " (disconnected)";
47+
this.emit("data", "\r\n\nLost connection...\r\n\n");
48+
this.initialize(this.moduleProxy.spawn(this.file, this.args, this.options));
49+
}
3550
}
3651

3752
type NodePty = typeof pty;
@@ -40,6 +55,6 @@ export class NodePtyModule implements NodePty {
4055
public constructor(private readonly proxy: NodePtyModuleProxy) {}
4156

4257
public spawn = (file: string, args: string[] | string, options: pty.IPtyForkOptions): pty.IPty => {
43-
return new NodePtyProcess(this.proxy.spawn(file, args, options));
58+
return new NodePtyProcess(this.proxy, file, args, options);
4459
}
4560
}

‎packages/protocol/src/browser/modules/spdlog.ts

+15-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,16 @@ import { ClientProxy } from "../../common/proxy";
33
import { RotatingLoggerProxy, SpdlogModuleProxy } from "../../node/modules/spdlog";
44

55
class RotatingLogger extends ClientProxy<RotatingLoggerProxy> implements spdlog.RotatingLogger {
6+
public constructor(
7+
private readonly moduleProxy: SpdlogModuleProxy,
8+
private readonly name: string,
9+
private readonly filename: string,
10+
private readonly filesize: number,
11+
private readonly filecount: number,
12+
) {
13+
super(moduleProxy.createLogger(name, filename, filesize, filecount));
14+
}
15+
616
public async trace (message: string): Promise<void> { this.proxy.trace(message); }
717
public async debug (message: string): Promise<void> { this.proxy.debug(message); }
818
public async info (message: string): Promise<void> { this.proxy.info(message); }
@@ -13,6 +23,10 @@ class RotatingLogger extends ClientProxy<RotatingLoggerProxy> implements spdlog.
1323
public async clearFormatters (): Promise<void> { this.proxy.clearFormatters(); }
1424
public async flush (): Promise<void> { this.proxy.flush(); }
1525
public async drop (): Promise<void> { this.proxy.drop(); }
26+
27+
protected handleDisconnect(): void {
28+
this.initialize(this.moduleProxy.createLogger(this.name, this.filename, this.filesize, this.filecount));
29+
}
1630
}
1731

1832
export class SpdlogModule {
@@ -21,7 +35,7 @@ export class SpdlogModule {
2135
public constructor(private readonly proxy: SpdlogModuleProxy) {
2236
this.RotatingLogger = class extends RotatingLogger {
2337
public constructor(name: string, filename: string, filesize: number, filecount: number) {
24-
super(proxy.createLogger(name, filename, filesize, filecount));
38+
super(proxy, name, filename, filesize, filecount);
2539
}
2640
};
2741
}

‎packages/protocol/src/browser/modules/stream.ts

+15
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,11 @@ export class Writable<T extends WritableProxy = WritableProxy> extends ClientPro
8181
}
8282
});
8383
}
84+
85+
protected handleDisconnect(): void {
86+
this.emit("close");
87+
this.emit("finish");
88+
}
8489
}
8590

8691
export class Readable<T extends IReadableProxy = IReadableProxy> extends ClientProxy<T> implements stream.Readable {
@@ -154,6 +159,11 @@ export class Readable<T extends IReadableProxy = IReadableProxy> extends ClientP
154159

155160
return this;
156161
}
162+
163+
protected handleDisconnect(): void {
164+
this.emit("close");
165+
this.emit("end");
166+
}
157167
}
158168

159169
export class Duplex<T extends DuplexProxy = DuplexProxy> extends Writable<T> implements stream.Duplex, stream.Readable {
@@ -230,4 +240,9 @@ export class Duplex<T extends DuplexProxy = DuplexProxy> extends Writable<T> imp
230240

231241
return this;
232242
}
243+
244+
protected handleDisconnect(): void {
245+
super.handleDisconnect();
246+
this.emit("end");
247+
}
233248
}

‎packages/protocol/src/common/proxy.ts

+31-4
Original file line numberDiff line numberDiff line change
@@ -29,21 +29,48 @@ const unpromisify = <T extends ServerProxy>(proxyPromise: Promise<T>): T => {
2929
* need a bunch of `then` calls everywhere.
3030
*/
3131
export abstract class ClientProxy<T extends ServerProxy> extends EventEmitter {
32-
protected readonly proxy: T;
32+
private _proxy: T | undefined;
3333

3434
/**
3535
* You can specify not to bind events in order to avoid emitting twice for
3636
* duplex streams.
3737
*/
38-
public constructor(proxyPromise: Promise<T> | T, bindEvents: boolean = true) {
38+
public constructor(
39+
proxyPromise: Promise<T> | T,
40+
private readonly bindEvents: boolean = true,
41+
) {
3942
super();
40-
this.proxy = isPromise(proxyPromise) ? unpromisify(proxyPromise) : proxyPromise;
41-
if (bindEvents) {
43+
this.initialize(proxyPromise);
44+
if (this.bindEvents) {
45+
this.on("disconnected", (error) => {
46+
try {
47+
this.emit("error", error);
48+
} catch (error) {
49+
// If nothing is listening, EventEmitter will throw an error.
50+
}
51+
this.handleDisconnect();
52+
});
53+
}
54+
}
55+
56+
protected get proxy(): T {
57+
if (!this._proxy) {
58+
throw new Error("not initialized");
59+
}
60+
61+
return this._proxy;
62+
}
63+
64+
protected initialize(proxyPromise: Promise<T> | T): void {
65+
this._proxy = isPromise(proxyPromise) ? unpromisify(proxyPromise) : proxyPromise;
66+
if (this.bindEvents) {
4267
this.proxy.onEvent((event, ...args): void => {
4368
this.emit(event, ...args);
4469
});
4570
}
4671
}
72+
73+
protected abstract handleDisconnect(): void;
4774
}
4875

4976
/**

‎packages/protocol/src/node/server.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ export class Server {
140140
try {
141141
const proxy = this.getProxy(proxyId);
142142
if (typeof proxy.instance[method] !== "function") {
143-
throw new Error(`"${method}" is not a function`);
143+
throw new Error(`"${method}" is not a function on proxy ${proxyId}`);
144144
}
145145

146146
response = proxy.instance[method](...args);

‎packages/vscode/src/workbench.ts

+2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ import { ServiceCollection } from "vs/platform/instantiation/common/serviceColle
3030
import { URI } from "vs/base/common/uri";
3131

3232
export class Workbench {
33+
public readonly retry = client.retry;
34+
3335
private readonly windowId = parseInt(new Date().toISOString().replace(/[-:.TZ]/g, ""), 10);
3436
private _serviceCollection: ServiceCollection | undefined;
3537
private _clipboardContextKey: RawContextKey<boolean> | undefined;

‎scripts/vscode.patch

+92-4
Original file line numberDiff line numberDiff line change
@@ -883,7 +883,7 @@ index acb68c8..bee143a 100644
883883
- !isMacintosh || // macOS only
884884
+ !browser.isMacintosh || // macOS only
885885
diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts
886-
index 7445d7b..0291dee 100644
886+
index 7445d7b..ba6bf4b 100644
887887
--- a/src/vs/workbench/electron-browser/workbench.ts
888888
+++ b/src/vs/workbench/electron-browser/workbench.ts
889889
@@ -19 +19,2 @@ import { Registry } from 'vs/platform/registry/common/platform';
@@ -899,13 +899,15 @@ index 7445d7b..0291dee 100644
899899
@@ -458 +462 @@ export class Workbench extends Disposable implements IPartService {
900900
- addClasses(document.body, platformClass); // used by our fonts
901901
+ addClasses(document.body, platformClass, isWeb ? 'web' : 'native'); // used by our fonts
902-
@@ -633 +637 @@ export class Workbench extends Disposable implements IPartService {
902+
@@ -491,0 +496 @@ export class Workbench extends Disposable implements IPartService {
903+
+ client.onClose(() => this.notificationService.error("Disconnected from shared process. Searching, installing, enabling, and disabling extensions will not work until the page is refreshed."));
904+
@@ -633 +638 @@ export class Workbench extends Disposable implements IPartService {
903905
- if (!isMacintosh && this.useCustomTitleBarStyle()) {
904906
+ if (isWeb || (!isMacintosh && this.useCustomTitleBarStyle())) {
905-
@@ -1241 +1245 @@ export class Workbench extends Disposable implements IPartService {
907+
@@ -1241 +1246 @@ export class Workbench extends Disposable implements IPartService {
906908
- if ((isWindows || isLinux) && this.useCustomTitleBarStyle()) {
907909
+ if ((isWeb || isWindows || isLinux) && this.useCustomTitleBarStyle()) {
908-
@@ -1397 +1401 @@ export class Workbench extends Disposable implements IPartService {
910+
@@ -1397 +1402 @@ export class Workbench extends Disposable implements IPartService {
909911
- } else if (isMacintosh) {
910912
+ } else if (isNative && isMacintosh) {
911913
diff --git a/src/vs/workbench/services/extensions/electron-browser/cachedExtensionScanner.ts b/src/vs/workbench/services/extensions/electron-browser/cachedExtensionScanner.ts
@@ -914,13 +916,65 @@ index 0592910..0ce7e35 100644
914916
+++ b/src/vs/workbench/services/extensions/electron-browser/cachedExtensionScanner.ts
915917
@@ -33,0 +34 @@ function getSystemExtensionsRoot(): string {
916918
+ return (require('vs/../../../../packages/vscode/src/fill/paths') as typeof import ('vs/../../../../packages/vscode/src/fill/paths')).getBuiltInExtensionsDirectory();
919+
diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts
920+
index 2c2f9c7..69fa321 100644
921+
--- a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts
922+
+++ b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts
923+
@@ -34,0 +35 @@ import { Schemas } from 'vs/base/common/network';
924+
+const retry = (require('vs/../../../../packages/vscode/src/workbench') as typeof import ('vs/../../../../packages/vscode/src/workbench')).workbench.retry;
925+
@@ -117,0 +119 @@ export class ExtensionService extends Disposable implements IExtensionService {
926+
+ retry.register('Extension Host', () => this.startExtensionHost());
927+
@@ -435,0 +438 @@ export class ExtensionService extends Disposable implements IExtensionService {
928+
+ extHostProcessWorker.start().then(() => retry.recover('Extension Host'));
929+
@@ -458,0 +462 @@ export class ExtensionService extends Disposable implements IExtensionService {
930+
+ return retry.run('Extension Host');
917931
diff --git a/src/vs/workbench/services/extensions/node/extensionHostProcess.ts b/src/vs/workbench/services/extensions/node/extensionHostProcess.ts
918932
index 484cef9..f728fc8 100644
919933
--- a/src/vs/workbench/services/extensions/node/extensionHostProcess.ts
920934
+++ b/src/vs/workbench/services/extensions/node/extensionHostProcess.ts
921935
@@ -137 +137 @@ function connectToRenderer(protocol: IMessagePassingProtocol): Promise<IRenderer
922936
- process.kill(initData.parentPid, 0); // throws an exception if the main process doesn't exist anymore.
923937
+ // process.kill(initData.parentPid, 0); // throws an exception if the main process doesn't exist anymore.
938+
diff --git a/src/vs/workbench/services/files/node/watcher/nsfw/watcherService.ts b/src/vs/workbench/services/files/node/watcher/nsfw/watcherService.ts
939+
index ca03fc9..e3dcd08 100644
940+
--- a/src/vs/workbench/services/files/node/watcher/nsfw/watcherService.ts
941+
+++ b/src/vs/workbench/services/files/node/watcher/nsfw/watcherService.ts
942+
@@ -18,0 +19 @@ import { getPathFromAmdModule } from 'vs/base/common/amd';
943+
+const retry = (require('vs/../../../../packages/vscode/src/workbench') as typeof import ('vs/../../../../packages/vscode/src/workbench')).workbench.retry;
944+
@@ -35,0 +37 @@ export class FileWatcher {
945+
+ retry.register('Watcher', () => this.startWatching());
946+
@@ -56,0 +59,2 @@ export class FileWatcher {
947+
+ this.toDispose = dispose(this.toDispose);
948+
+ return retry.run('Watcher');
949+
@@ -113 +117 @@ export class FileWatcher {
950+
- }));
951+
+ })).then(() => retry.recover('Watcher'));
952+
diff --git a/src/vs/workbench/services/files/node/watcher/unix/watcherService.ts b/src/vs/workbench/services/files/node/watcher/unix/watcherService.ts
953+
index 7e3a324..b9ccd63 100644
954+
--- a/src/vs/workbench/services/files/node/watcher/unix/watcherService.ts
955+
+++ b/src/vs/workbench/services/files/node/watcher/unix/watcherService.ts
956+
@@ -18,0 +19 @@ import { getPathFromAmdModule } from 'vs/base/common/amd';
957+
+const retry = (require('vs/../../../../packages/vscode/src/workbench') as typeof import ('vs/../../../../packages/vscode/src/workbench')).workbench.retry;
958+
@@ -36,0 +38 @@ export class FileWatcher {
959+
+ retry.register('Watcher', () => this.startWatching());
960+
@@ -59,0 +62,2 @@ export class FileWatcher {
961+
+ this.toDispose = dispose(this.toDispose);
962+
+ return retry.run('Watcher');
963+
@@ -116 +120 @@ export class FileWatcher {
964+
- }));
965+
+ })).then(() => retry.recover('Watcher'));
966+
diff --git a/src/vs/workbench/services/files/node/watcher/win32/csharpWatcherService.ts b/src/vs/workbench/services/files/node/watcher/win32/csharpWatcherService.ts
967+
index 74dad64..34cd83b 100644
968+
--- a/src/vs/workbench/services/files/node/watcher/win32/csharpWatcherService.ts
969+
+++ b/src/vs/workbench/services/files/node/watcher/win32/csharpWatcherService.ts
970+
@@ -14,0 +15 @@ import { getPathFromAmdModule } from 'vs/base/common/amd';
971+
+const retry = (require('vs/../../../../packages/vscode/src/workbench') as typeof import ('vs/../../../../packages/vscode/src/workbench')).workbench.retry;
972+
@@ -40,0 +42 @@ export class OutOfProcessWin32FolderWatcher {
973+
+ retry.register('Watcher', () => this.startWatcher());
974+
@@ -52,0 +55 @@ export class OutOfProcessWin32FolderWatcher {
975+
+ this.handle.stdout.once('data', () => retry.recover('Watcher'));
976+
@@ -110,0 +114 @@ export class OutOfProcessWin32FolderWatcher {
977+
+ return retry.run('Watcher');
924978
diff --git a/src/vs/workbench/services/keybinding/electron-browser/keybindingService.ts b/src/vs/workbench/services/keybinding/electron-browser/keybindingService.ts
925979
index 3c78990..545d91a 100644
926980
--- a/src/vs/workbench/services/keybinding/electron-browser/keybindingService.ts
@@ -931,6 +985,40 @@ index 3c78990..545d91a 100644
931985
@@ -130 +130 @@ export class KeyboardMapperFactory {
932986
- if (OS === OperatingSystem.Windows) {
933987
+ if (isNative && OS === OperatingSystem.Windows) {
988+
diff --git a/src/vs/workbench/services/search/node/searchService.ts b/src/vs/workbench/services/search/node/searchService.ts
989+
index 3eaafa4..0345bad 100644
990+
--- a/src/vs/workbench/services/search/node/searchService.ts
991+
+++ b/src/vs/workbench/services/search/node/searchService.ts
992+
@@ -11 +11 @@ import { Event } from 'vs/base/common/event';
993+
-import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
994+
+import { Disposable, IDisposable, toDisposable, dispose } from 'vs/base/common/lifecycle';
995+
@@ -32,0 +33 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur
996+
+const retry = (require('vs/../../../../packages/vscode/src/workbench') as typeof import ('vs/../../../../packages/vscode/src/workbench')).workbench.retry;
997+
@@ -433,0 +435 @@ export class DiskSearch implements ISearchResultProvider {
998+
+ private toDispose: IDisposable[] = [];
999+
@@ -470,6 +472,16 @@ export class DiskSearch implements ISearchResultProvider {
1000+
- const client = new Client(
1001+
- getPathFromAmdModule(require, 'bootstrap-fork'),
1002+
- opts);
1003+
-
1004+
- const channel = getNextTickChannel(client.getChannel('search'));
1005+
- this.raw = new SearchChannelClient(channel);
1006+
+ const connect = (): void => {
1007+
+ const client = new Client(
1008+
+ getPathFromAmdModule(require, 'bootstrap-fork'),
1009+
+ opts);
1010+
+ client.onDidProcessExit(() => {
1011+
+ this.toDispose = dispose(this.toDispose);
1012+
+ retry.run('Searcher');
1013+
+ }, null, this.toDispose);
1014+
+ this.toDispose.push(client);
1015+
+
1016+
+ const channel = getNextTickChannel(client.getChannel('search'));
1017+
+ this.raw = new SearchChannelClient(channel);
1018+
+ this.raw.clearCache('test-connectivity').then(() => retry.recover('Searcher'));
1019+
+ };
1020+
+ retry.register('Searcher', connect);
1021+
+ connect();
9341022
diff --git a/src/vs/workbench/services/timer/electron-browser/timerService.ts b/src/vs/workbench/services/timer/electron-browser/timerService.ts
9351023
index 6e6fbcc..645bd72 100644
9361024
--- a/src/vs/workbench/services/timer/electron-browser/timerService.ts

0 commit comments

Comments
 (0)
Please sign in to comment.