Make dev_server_start idempotent to prevent HMR breakage and 502s

This commit is contained in:
2026-06-12 16:42:26 -07:00
parent 76c0241bd1
commit de950b1fb0
2 changed files with 26 additions and 8 deletions

View File

@@ -181,13 +181,9 @@ export default function PreviewTab() {
const path = currentPath.startsWith("/")
? currentPath
: `/${currentPath}`;
// Add the refreshKey as a query param so the iframe completely remounts/refetches
// when the user hits the manual refresh button.
const urlObj = new URL(`${base}${path}`);
urlObj.searchParams.set("_refresh", refreshKey.toString());
setIframeSrc(urlObj.toString());
setIframeSrc(`${base}${path}`);
}
}, [primaryRunning?.url, currentPath, refreshKey]);
}, [primaryRunning?.url, currentPath]);
useEffect(() => {
if (!bridge || !iframeSrc || !iframeDomRef.current) return;

View File

@@ -873,14 +873,36 @@ export async function startDevServer(
// to keep the dashboard clean and prevent memory leaks.
const existingRows = await query<{
id: string;
pid: number | null;
project_id: string;
workspace: string;
name: string;
command: string;
port: number;
pid: number | null;
preview_url: string;
state: "starting" | "running" | "stopped" | "failed";
started_at: string;
stopped_at: string | null;
}>(
`SELECT id, pid, port FROM fs_dev_servers
`SELECT * FROM fs_dev_servers
WHERE project_id = $1 AND state IN ('starting','running','failed')`,
[opts.projectId],
);
// IDEMPOTENCY: If the exact same command is already starting or running on the same port,
// do not kill it! Just return the existing record. This prevents the AI from accidentally
// bouncing the server and dropping the cache after every file edit, which leads to 502s.
const alreadyRunning = existingRows.find(
(r) =>
r.port === opts.port &&
r.command === opts.command &&
(r.state === "starting" || r.state === "running"),
);
if (alreadyRunning) {
return alreadyRunning;
}
const killPortNodeCmd =
`node -e '` +
`const fs = require("fs"); ` +