Skip to content

Commit 08d6e97

Browse files
authored
Merge pull request #1378 from microsoft/fix/wd-request-loop
fix: request loop on certain kinds of Node.js attach failures
2 parents c7ff13b + 73c8641 commit 08d6e97

File tree

6 files changed

+23
-5
lines changed

6 files changed

+23
-5
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ This changelog records changes to stable releases since 1.50.2. "TBA" changes he
44

55
## Nightly (only)
66

7-
Nothing yet...
7+
- fix: request loop on certain kinds of Node.js attach failures ([vscode#156810](https://github.com/microsoft/vscode/issues/156810))
88

99
## v1.71 (August 2022)
1010

src/cdp/webSocketTransport.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,12 @@ import WebSocket from 'ws';
77
import { CancellationTokenSource, timeoutPromise } from '../common/cancellation';
88
import { EventEmitter } from '../common/events';
99
import { HrTime } from '../common/hrnow';
10+
import { delay } from '../common/promiseUtil';
1011
import { isLoopback } from '../common/urlUtils';
1112
import { ITransport } from './transport';
1213

14+
const maxRetryInterval = 50;
15+
1316
export class WebSocketTransport implements ITransport {
1417
private _ws: WebSocket | undefined;
1518
private readonly messageEmitter = new EventEmitter<[string, HrTime]>();
@@ -29,6 +32,7 @@ export class WebSocketTransport implements ITransport {
2932
const targetAddressIsLoopback = await isLoopback(url);
3033

3134
while (true) {
35+
const dontRetryBefore = Date.now() + maxRetryInterval;
3236
try {
3337
const options = {
3438
headers: { host: 'localhost' },
@@ -64,6 +68,11 @@ export class WebSocketTransport implements ITransport {
6468
if (cancellationToken.isCancellationRequested) {
6569
throw err;
6670
}
71+
72+
const retryIn = dontRetryBefore - Date.now();
73+
if (retryIn > 0) {
74+
await delay(retryIn);
75+
}
6776
}
6877
}
6978
}

src/targets/node/autoAttachLauncher.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,10 @@ export class AutoAttachLauncher
220220
...data,
221221
ipcAddress: this.run.serverAddress, // may be outdated from a previous set of vars
222222
});
223-
wd.onEnd(() => this.telemetryItems.delete(pid));
223+
wd.onEnd(() => {
224+
this.telemetryItems.delete(pid);
225+
wd.dispose();
226+
});
224227
}
225228

226229
public static clearVariables(context: vscode.ExtensionContext) {

src/targets/node/program.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,10 @@ export class StubProgram implements IProgram {
106106
export class WatchDogProgram extends StubProgram {
107107
constructor(private readonly wd: WatchDog) {
108108
super();
109-
wd.onEnd(this.stopDefer);
109+
wd.onEnd(data => {
110+
this.stopDefer(data);
111+
this.wd.dispose();
112+
});
110113
}
111114

112115
public stop() {

src/targets/node/watchdogSpawn.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import Cdp from '../../cdp/api';
77
import { RawPipeTransport } from '../../cdp/rawPipeTransport';
88
import { ITransport } from '../../cdp/transport';
99
import { WebSocketTransport } from '../../cdp/webSocketTransport';
10-
import { NeverCancelled } from '../../common/cancellation';
10+
import { CancellationTokenSource } from '../../common/cancellation';
1111
import { IDisposable } from '../../common/disposable';
1212
import { EventEmitter } from '../../common/events';
1313
import { Logger } from '../../common/logging/logger';
@@ -70,6 +70,7 @@ const enum Method {
7070

7171
export class WatchDog implements IDisposable {
7272
private readonly onEndEmitter = new EventEmitter<IStopMetadata>();
73+
private readonly cts = new CancellationTokenSource();
7374
private target?: WebSocketTransport;
7475
private gracefulExit = false;
7576
private targetAlive = false;
@@ -150,6 +151,7 @@ export class WatchDog implements IDisposable {
150151
*/
151152
public dispose() {
152153
this.gracefulExit = true;
154+
this.cts.dispose(true);
153155
this.disposeTarget();
154156
this.server.dispose(); // will cause the end emitter to fire after teardown finishes
155157
}
@@ -188,7 +190,7 @@ export class WatchDog implements IDisposable {
188190

189191
private async createTarget() {
190192
this.gracefulExit = false; // reset
191-
const target = await WebSocketTransport.create(this.info.inspectorURL, NeverCancelled);
193+
const target = await WebSocketTransport.create(this.info.inspectorURL, this.cts.token);
192194
target.onMessage(([data]) => this.server.send(data));
193195
target.onEnd(() => {
194196
if (target) {

src/test/infra/infra-initialize.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
supportsCompletionsRequest : true
3434
supportsConditionalBreakpoints : true
3535
supportsConfigurationDoneRequest : true
36+
supportsDebuggerProperties : true
3637
supportsDelayedStackTraceLoading : true
3738
supportsEvaluateForHovers : true
3839
supportsExceptionFilterOptions : true

0 commit comments

Comments
 (0)