Revert "fix: prevent orphaned gateway processes on Windows causing port conflcts and UI freeze (#570)"
This reverts commit 2dc1070213.
This commit is contained in:
@@ -32,33 +32,16 @@ export async function terminateOwnedGatewayProcess(child: Electron.UtilityProces
|
|||||||
|
|
||||||
const pid = child.pid;
|
const pid = child.pid;
|
||||||
logger.info(`Sending kill to Gateway process (pid=${pid ?? 'unknown'})`);
|
logger.info(`Sending kill to Gateway process (pid=${pid ?? 'unknown'})`);
|
||||||
|
|
||||||
// On Windows, use taskkill /F /T to kill the entire process tree.
|
|
||||||
// child.kill() only terminates the direct utilityProcess; grandchild
|
|
||||||
// processes (Python/uv) survive and keep port 18789 occupied.
|
|
||||||
if (process.platform === 'win32' && pid) {
|
|
||||||
import('child_process').then((cp) => {
|
|
||||||
cp.exec(`taskkill /F /PID ${pid} /T`, { timeout: 5000, windowsHide: true }, () => {
|
|
||||||
// best-effort; fall through to timeout if taskkill fails
|
|
||||||
});
|
|
||||||
}).catch(() => { /* ignore */ });
|
|
||||||
} else {
|
|
||||||
try {
|
try {
|
||||||
child.kill();
|
child.kill();
|
||||||
} catch {
|
} catch {
|
||||||
// ignore if already exited
|
// ignore if already exited
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const timeout = setTimeout(() => {
|
const timeout = setTimeout(() => {
|
||||||
if (!exited) {
|
if (!exited) {
|
||||||
logger.warn(`Gateway did not exit in time, force-killing (pid=${pid ?? 'unknown'})`);
|
logger.warn(`Gateway did not exit in time, force-killing (pid=${pid ?? 'unknown'})`);
|
||||||
if (pid) {
|
if (pid) {
|
||||||
if (process.platform === 'win32') {
|
|
||||||
import('child_process').then((cp) => {
|
|
||||||
cp.exec(`taskkill /F /PID ${pid} /T`, { timeout: 5000, windowsHide: true }, () => {});
|
|
||||||
}).catch(() => {});
|
|
||||||
} else {
|
|
||||||
try {
|
try {
|
||||||
process.kill(pid, 'SIGKILL');
|
process.kill(pid, 'SIGKILL');
|
||||||
} catch {
|
} catch {
|
||||||
@@ -66,7 +49,6 @@ export async function terminateOwnedGatewayProcess(child: Electron.UtilityProces
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
resolve();
|
resolve();
|
||||||
}, 5000);
|
}, 5000);
|
||||||
|
|
||||||
@@ -244,9 +226,6 @@ export async function findExistingGatewayProcess(options: {
|
|||||||
const pids = await getListeningProcessIds(port);
|
const pids = await getListeningProcessIds(port);
|
||||||
if (pids.length > 0 && (!ownedPid || !pids.includes(String(ownedPid)))) {
|
if (pids.length > 0 && (!ownedPid || !pids.includes(String(ownedPid)))) {
|
||||||
await terminateOrphanedProcessIds(port, pids);
|
await terminateOrphanedProcessIds(port, pids);
|
||||||
// Verify the port is actually free after killing orphans.
|
|
||||||
// On Windows, TCP TIME_WAIT can hold the port for up to 120s.
|
|
||||||
await waitForPortFree(port, 10000);
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
@@ -459,30 +459,15 @@ if (gotTheLock) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let gatewayCleanedUp = false;
|
app.on('before-quit', () => {
|
||||||
|
|
||||||
app.on('before-quit', (event) => {
|
|
||||||
setQuitting();
|
setQuitting();
|
||||||
|
|
||||||
// On first before-quit, block the quit so we can await gateway cleanup.
|
|
||||||
// On Windows, fire-and-forget leaves orphaned Python/uv processes that
|
|
||||||
// hold port 18789, causing port conflicts on next launch.
|
|
||||||
if (!gatewayCleanedUp) {
|
|
||||||
gatewayCleanedUp = true;
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
hostEventBus.closeAll();
|
hostEventBus.closeAll();
|
||||||
hostApiServer?.close();
|
hostApiServer?.close();
|
||||||
|
// Fire-and-forget: do not await gatewayManager.stop() here.
|
||||||
const stopPromise = gatewayManager.stop().catch((err) => {
|
// Awaiting inside before-quit can stall Electron's quit sequence.
|
||||||
|
void gatewayManager.stop().catch((err) => {
|
||||||
logger.warn('gatewayManager.stop() error during quit:', err);
|
logger.warn('gatewayManager.stop() error during quit:', err);
|
||||||
});
|
});
|
||||||
const timeoutPromise = new Promise<void>((resolve) => setTimeout(resolve, 5000));
|
|
||||||
|
|
||||||
void Promise.race([stopPromise, timeoutPromise]).then(() => {
|
|
||||||
app.exit(0);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user