mirror of
https://github.com/smittix/intercept.git
synced 2026-07-30 11:38:09 -07:00
fix: skip custom signal handlers when running under gunicorn
The custom SIGINT/SIGTERM handler in utils/process.py overrode gunicorn's own signal management, causing KeyboardInterrupt to fire inside the gevent worker on Ctrl+C instead of allowing gunicorn's graceful shutdown. Now detects if another signal manager (gunicorn) has already installed handlers and defers to it. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+23
-7
@@ -104,13 +104,29 @@ def _signal_handler(signum, frame):
|
|||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
|
|
||||||
# Only register signal handlers if we're not in a thread
|
# Only register signal handlers when running standalone (not under gunicorn).
|
||||||
try:
|
# Gunicorn manages its own SIGINT/SIGTERM handling for graceful shutdown;
|
||||||
signal.signal(signal.SIGTERM, _signal_handler)
|
# overriding those signals causes KeyboardInterrupt in the wrong context.
|
||||||
signal.signal(signal.SIGINT, _signal_handler)
|
def _is_under_gunicorn():
|
||||||
except ValueError:
|
"""Check if we're running inside a gunicorn worker."""
|
||||||
# Can't set signal handlers from a thread
|
try:
|
||||||
pass
|
import gunicorn.arbiter # noqa: F401
|
||||||
|
# If gunicorn is importable AND we were invoked via gunicorn, the
|
||||||
|
# arbiter will have installed its own signal handlers already.
|
||||||
|
# Check the current SIGTERM handler — if it's not the default,
|
||||||
|
# gunicorn (or another manager) owns signals.
|
||||||
|
current = signal.getsignal(signal.SIGTERM)
|
||||||
|
return current not in (signal.SIG_DFL, signal.SIG_IGN, None)
|
||||||
|
except ImportError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if not _is_under_gunicorn():
|
||||||
|
try:
|
||||||
|
signal.signal(signal.SIGTERM, _signal_handler)
|
||||||
|
signal.signal(signal.SIGINT, _signal_handler)
|
||||||
|
except ValueError:
|
||||||
|
# Can't set signal handlers from a thread
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
def cleanup_stale_processes() -> None:
|
def cleanup_stale_processes() -> None:
|
||||||
|
|||||||
Reference in New Issue
Block a user