Skip to content

fix(watch): don't let a re-raised signal kill the watcher on restart - #36268

Open
minato32 wants to merge 1 commit into
denoland:mainfrom
minato32:fix/35942-watch-signal-reraise
Open

fix(watch): don't let a re-raised signal kill the watcher on restart#36268
minato32 wants to merge 1 commit into
denoland:mainfrom
minato32:fix/35942-watch-signal-reraise

Conversation

@minato32

Copy link
Copy Markdown
Contributor

On file change the watcher raises a synthetic SIGTERM to give JS code a chance to clean up before restarting. If a handler unregisters itself and then re-raises a real OS SIGTERM — the signal-exit "unload + re-raise" pattern bundled in Vite 8 / rolldown — that real signal reaches the signal thread with no handler registered, so it ran the exit callbacks + the OS default action and terminated the whole watcher instead of restarting it. Any Vite 8 dev server under deno run --watch dies on the first restart.

Fix

Add a scoped suppression flag to deno_signals. While set, an unhandled terminating signal (SIGTERM/SIGINT/SIGHUP) is consumed instead of running the exit callbacks and the OS default action. The file watcher enables it around the graceful-restart window — set before raise(), since the re-raise happens synchronously inside the JS handler — and clears it once the graceful wait is done.

Scoped to the restart path only; normal exit and Ctrl+C behavior are unchanged.

Test

run_watch_sigterm_reraise_on_restart in tests/integration/watcher_tests.rs reproduces the unload+re-raise pattern with node:process and asserts the watcher restarts (was: process died).

Closes #35942

On file change the watcher raises a synthetic SIGTERM so JS code can clean
up before restarting. A handler that unregisters itself and re-raises a real
OS SIGTERM (the signal-exit "unload + re-raise" pattern bundled in Vite 8 /
rolldown) then reaches the signal thread with no handler registered, which
ran the exit callbacks and the OS default action, killing the watcher instead
of restarting it.

Add a scoped suppression flag to deno_signals: while set, an unhandled
terminating signal (SIGTERM/SIGINT/SIGHUP) is consumed rather than exiting.
The watcher enables it around the graceful-restart window (before raising, so
the synchronous re-raise is covered).

Closes denoland#35942
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

deno run --watch dies when a SIGTERM handler unregisters itself and re-raises a real SIGTERM (signal-exit pattern, affects every Vite 8 dev server)

1 participant