vercel / next.js

The React Framework
https://nextjs.org
MIT License
122.59k stars 26.23k forks source link

Allow dev server to exit cleanly (SIGINT/SIGTERM) #67165

Open bgw opened 4 days ago

bgw commented 4 days ago

Next's dev server uses a parent/child process model. The parent process acts as a monitor, and it able to restart the server upon configuration changes or upload telemetry even in the case of a crash. The child listens for http requests and does all the real work.

Previously we were sending SIGKILL immediately to the child when the parent process got SIGINT or SIGTERM. This ensures that the child exits as quickly as possible, but it also means that the child probably won't have time to finish flushing files to disk (trace files, cache hit statistics, etc.), and can lead to incomplete writes.

We should give the child a small amount of time to exit cleanly with SIGINT/SIGTERM before sending SIGKILL. The timeout is needed in case the child process is unresponsive/hanging.

Tradeoffs

This does cause a short hang for 1 second when the server is heavily loaded (e.g. trying to compile a page, both with webpack and with turbo), and often the process is not able to exit within the 1 second threshold in this case.

At least on the turbopack side, we should be able to better handle this by shutting down the tokio runtime (but this would require creating a second runtime for cleanup) or by preventing turbo-tasks from spawning any more work. That would more quickly free up the CPU to be able to handle the high-priority exit work.

Testing

Run the dev server with DEBUG="next:*" and see the log messages about server shutdown when pressing ctrl+c.

bgw commented 4 days ago

[!WARNING] This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite. Learn more

This stack of pull requests is managed by Graphite. Learn more about stacking.

Join @bgw and the rest of your teammates on Graphite Graphite