Fix graceful shutdown on SIGTERM#1396
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughThis PR adds graceful shutdown support to Robyn so that ChangesGraceful Shutdown Implementation
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. 📋 Issue PlannerBuilt with CodeRabbit's Coding Plans for faster development and fewer bugs. View plan used: ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
robyn/reloader.py (1)
112-115: ⚡ Quick win
finallywaits without first terminating the subprocess.Unlike the signal handler (Line 96-97), this cleanup path calls
wait_for_server_shutdown()without a precedingstop_server(). If the observer loop exits without the signal handler having run, the server subprocess never receives SIGTERM — it blocks for the fullGRACEFUL_SHUTDOWN_TIMEOUTand is then force-killed, skipping graceful shutdown. Sending terminate first is also safe when the process is already reaped (send_signalis a no-op oncereturncodeis set).♻️ Terminate before waiting
finally: observer.stop() observer.join() + event_handler.stop_server() event_handler.wait_for_server_shutdown()🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@robyn/reloader.py` around lines 112 - 115, The finally cleanup currently calls observer.stop(), observer.join(), then event_handler.wait_for_server_shutdown() without terminating the child; call the server termination first to mirror the signal handler: invoke the stop_server() behavior on the event handler/subprocess (e.g., call event_handler.stop_server() or otherwise send SIGTERM to the subprocess) before calling event_handler.wait_for_server_shutdown(), then stop and join the observer; this ensures the subprocess receives a terminate signal and can perform graceful shutdown rather than waiting for the timeout.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@robyn/reloader.py`:
- Around line 112-115: The finally cleanup currently calls observer.stop(),
observer.join(), then event_handler.wait_for_server_shutdown() without
terminating the child; call the server termination first to mirror the signal
handler: invoke the stop_server() behavior on the event handler/subprocess
(e.g., call event_handler.stop_server() or otherwise send SIGTERM to the
subprocess) before calling event_handler.wait_for_server_shutdown(), then stop
and join the observer; this ensures the subprocess receives a terminate signal
and can perform graceful shutdown rather than waiting for the timeout.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: f00838ae-ddc1-47fa-af5b-ac0ca5ff0139
📒 Files selected for processing (3)
integration_tests/test_graceful_shutdown.pyrobyn/processpool.pyrobyn/reloader.py
Description
This PR fixes #1324.
Summary
This PR makes SIGTERM trigger Robyn's graceful shutdown path instead of requiring callers to use
process.kill()as a workaround. It adds a fixed shutdown grace period before falling back to force-kill behavior, updates the dev reloader to wait for graceful termination, and adds a POSIX integration regression test that verifiesprocess.terminate()runs@app.shutdown_handler.PR Checklist
Please ensure that:
Pre-Commit Instructions:
Documentation note: no documentation update was added because this fixes existing shutdown behavior and adds regression coverage.
Summary by CodeRabbit
Release Notes
New Features
Tests