Skip to content

Commit 22c28cd

Browse files
suzmuehyangah
authored andcommitted
[release] src/goDebugFactory: wait for dlv dap server to start in factory
When we start dlv dap, we want to make sure it has started before sending the info back to vscode so it will be able to connect. Wait for the 'DAP server listening at' message before returning the host. Display the error for the user otherwise. Fixes #1270 Change-Id: Id710b67ceaa87b1f6dff84d8108ac61dfbe15707 Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/300071 Trust: Suzy Mueller <[email protected]> Run-TryBot: Suzy Mueller <[email protected]> TryBot-Result: kokoro <[email protected]> Reviewed-by: Hyang-Ah Hana Kim <[email protected]> Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/300609 Trust: Hyang-Ah Hana Kim <[email protected]>
1 parent 9a653de commit 22c28cd

File tree

1 file changed

+61
-28
lines changed

1 file changed

+61
-28
lines changed

src/goDebugFactory.ts

Lines changed: 61 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,11 @@ export async function startDapServer(
6868
} else {
6969
configuration.port = await getPort();
7070
}
71-
const dlvDapServer = spawnDlvDapServerProcess(configuration);
72-
// Wait to give dlv-dap a chance to start before returning.
73-
return await new Promise<{ port: number; host: string; dlvDapServer: ChildProcessWithoutNullStreams }>((resolve) =>
74-
setTimeout(() => resolve({ port: configuration.port, host: configuration.host, dlvDapServer }), 500)
75-
);
71+
const dlvDapServer = await spawnDlvDapServerProcess(configuration);
72+
return { dlvDapServer, port: configuration.port, host: configuration.host };
7673
}
7774

78-
function spawnDlvDapServerProcess(launchArgs: DebugConfiguration) {
75+
async function spawnDlvDapServerProcess(launchArgs: DebugConfiguration): Promise<ChildProcess> {
7976
const launchArgsEnv = launchArgs.env || {};
8077
const env = Object.assign({}, process.env, launchArgsEnv);
8178

@@ -114,30 +111,66 @@ function spawnDlvDapServerProcess(launchArgs: DebugConfiguration) {
114111
appendToDebugConsole(`Running: ${dlvPath} ${dlvArgs.join(' ')}`);
115112

116113
const dir = parseProgramArgSync(launchArgs).dirname;
117-
const p = spawn(dlvPath, dlvArgs, {
118-
cwd: dir,
119-
env
120-
});
121114

122-
p.stderr.on('data', (chunk) => {
123-
appendToDebugConsole(chunk.toString());
124-
});
125-
p.stdout.on('data', (chunk) => {
126-
appendToDebugConsole(chunk.toString());
127-
});
128-
p.on('close', (code) => {
129-
if (code) {
130-
appendToDebugConsole(`Process exiting with code: ${code} signal: ${p.killed}`);
131-
} else {
132-
appendToDebugConsole(`Process exited normally: ${p.killed}`);
133-
}
134-
});
135-
p.on('error', (err) => {
136-
if (err) {
137-
appendToDebugConsole(`Error: ${err}`);
138-
}
115+
return await new Promise<ChildProcess>((resolve, reject) => {
116+
const p = spawn(dlvPath, dlvArgs, {
117+
cwd: dir,
118+
env
119+
});
120+
let started = false;
121+
const timeoutToken: NodeJS.Timer = setTimeout(
122+
() => reject(new Error('timed out while waiting for DAP server to start')),
123+
5_000
124+
);
125+
126+
const stopWaitingForServerToStart = (err?: string) => {
127+
clearTimeout(timeoutToken);
128+
started = true;
129+
if (err) {
130+
killProcessTree(p); // We do not need to wait for p to actually be killed.
131+
reject(new Error(err));
132+
} else {
133+
resolve(p);
134+
}
135+
};
136+
137+
p.stdout.on('data', (chunk) => {
138+
if (!started) {
139+
if (chunk.toString().startsWith('DAP server listening at:')) {
140+
stopWaitingForServerToStart();
141+
} else {
142+
stopWaitingForServerToStart(
143+
`Expected 'DAP server listening at:' from debug adapter got '${chunk.toString()}'`
144+
);
145+
}
146+
}
147+
appendToDebugConsole(chunk.toString());
148+
});
149+
p.stderr.on('data', (chunk) => {
150+
if (!started) {
151+
stopWaitingForServerToStart(`Unexpected error from dlv dap on start: '${chunk.toString()}'`);
152+
}
153+
appendToDebugConsole(chunk.toString());
154+
});
155+
p.on('close', (code) => {
156+
if (!started) {
157+
stopWaitingForServerToStart(`dlv dap closed with code: '${code}' signal: ${p.killed}`);
158+
}
159+
if (code) {
160+
appendToDebugConsole(`Process exiting with code: ${code} signal: ${p.killed}`);
161+
} else {
162+
appendToDebugConsole(`Process exited normally: ${p.killed}`);
163+
}
164+
});
165+
p.on('error', (err) => {
166+
if (!started) {
167+
stopWaitingForServerToStart(`Unexpected error from dlv dap on start: '${err}'`);
168+
}
169+
if (err) {
170+
appendToDebugConsole(`Error: ${err}`);
171+
}
172+
});
139173
});
140-
return p;
141174
}
142175

143176
function parseProgramArgSync(

0 commit comments

Comments
 (0)