Skip to content

Commit 52cfcb3

Browse files
guitavanoclaude
andcommitted
fix(liveness): skip self.close() on SIGTERM during HMR/watch dev mode
Deno's HMR and --watch modes use a parent/child process model where the parent sends SIGTERM to signal the child to restart. The liveness middleware's SIGTERM handler was calling self.close(), which kills the process before Deno can complete its restart cycle — causing every dev server to die on the first file change instead of hot-reloading. Only call self.close() in production (k8s) where SIGTERM means the pod must shut down. In dev mode (--unstable-hmr or --watch), let the process terminate naturally so Deno can relaunch it. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent ce2cbd7 commit 52cfcb3

1 file changed

Lines changed: 10 additions & 1 deletion

File tree

runtime/middlewares/liveness.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,21 @@ const buildHandler = (
6565
}
6666
});
6767
};
68+
// In production (k8s), SIGTERM comes from the kubelet and the process must
69+
// shut down. In local dev, Deno's HMR/watch sends SIGTERM to the child
70+
// process expecting a clean restart cycle — calling self.close() here kills
71+
// the process before HMR can relaunch it, breaking hot-reload entirely.
72+
const isHMR = Deno.args.some((a) => a.includes("--unstable-hmr"));
73+
const isWatch = Deno.args.some((a) => a.includes("--watch"));
74+
const isDev = isHMR || isWatch;
6875
try {
6976
if (Deno.build.os !== "windows") {
7077
Deno.addSignalListener("SIGTERM", () => {
7178
const checks = runChecks();
7279
console.log(checks);
73-
self.close();
80+
if (!isDev) {
81+
self.close();
82+
}
7483
});
7584
}
7685
} catch (err) {

0 commit comments

Comments
 (0)