Make the remote browser die with the run
The leash that ties the Windows browser to the run never held. Three findings, each measured: - stdin is not a signal: only the first chunk a caller writes reaches the remote command, so the stdin heartbeat looked like a dead caller and killed a run at check 44. - a dropped SSH connection does not kill the remote command; Windows OpenSSH leaves it running. Six orphaned chrome.exe survived a SIGKILLed tunnel -- this is what locked up the desktop. - Get-NetTCPConnection goes through WMI, which is denied to the non-admin test account; the broken CIM session took a browser down mid-run. The launcher now watches the forwarded CDP port with .NET sockets: a connected client means the run is alive, 45 s without one ends it. A job object with KILL_ON_JOB_CLOSE and a 30-minute cap catch the rest, and the caller shoots the browser on the way out instead of waiting for the idle window. Measured: survives 80 s of an idle held connection, gone 44 s after kill -9 on node, immediately on an ordered end. Full suite 267 checks in 128 s and 24 smoke checks in 16 s against an RTX 4070, with this machine at load 0.04.
This commit is contained in:
1 parent
9bc109518e
commit
47492bcbe8
3 files changed
+125
-21
No files matched your search
+26
-3
@@ -95,9 +95,32 @@ export function launchBrowser({ port, width, height }) {
|
||||
remote,
|
||||
`powershell -NoProfile -ExecutionPolicy Bypass -File gm-browser.ps1 -Port ${port} -Size ${width},${height}`,
|
||||
],
|
||||
// stdin stays open on purpose: closing it is what tells the launcher to kill the browser.
|
||||
{ stdio: ['pipe', 'ignore', 'pipe'] },
|
||||
{ stdio: ['ignore', 'ignore', 'pipe'] },
|
||||
);
|
||||
|
||||
return { proc, stop: () => proc.stdin.end(), where: `remote browser on ${remote}` };
|
||||
return {
|
||||
proc,
|
||||
/**
|
||||
* The launcher notices a finished run on its own, but only after its idle window – a browser
|
||||
* lingering a minute on someone else's desktop is rude, so end it now and let that window be
|
||||
* the net for runs that die without reaching here.
|
||||
*/
|
||||
stop: () => {
|
||||
try {
|
||||
execFileSync(
|
||||
'ssh',
|
||||
[
|
||||
...sshArgs(key),
|
||||
remote,
|
||||
'powershell -NoProfile -Command "Get-Process chrome,msedge -ErrorAction SilentlyContinue | Stop-Process -Force"',
|
||||
],
|
||||
{ stdio: 'pipe', timeout: 20_000 },
|
||||
);
|
||||
} catch {
|
||||
// Unreachable host, denied, already gone: the idle window still collects it.
|
||||
}
|
||||
proc.kill('SIGTERM');
|
||||
},
|
||||
where: `remote browser on ${remote}`,
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user