From 6047780595a4546c47e61dcc25ecbf39750694c9 Mon Sep 17 00:00:00 2001 From: Robert Knight Date: Tue, 17 Sep 2024 14:24:47 +0100 Subject: [PATCH] Support dumping gevent stacks from uWSGI workers To help debug cases where a worker process "hangs", add a SIGCONT signal handler which dumps both the native and greenlet threads. --- viahtml/wsgi.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/viahtml/wsgi.py b/viahtml/wsgi.py index 2fa12644..ec48ac1d 100644 --- a/viahtml/wsgi.py +++ b/viahtml/wsgi.py @@ -1,11 +1,22 @@ """The application providing a WSGI entry-point.""" import os +import signal # Our job here is to leave this `application` attribute laying around as # it's what uWSGI expects to find. from viahtml.app import Application + +def _dump_stacks(*args): # pragma: no cover + # Print both Python thread and gevent "greenlet" stats and backtraces. + # + # See https://www.gevent.org/monitoring.html#visibility + import gevent + + gevent.util.print_run_info() + + application = Application() if os.environ.get("SENTRY_DSN"): # pragma: no cover @@ -17,3 +28,11 @@ # pylint: disable=redefined-variable-type sentry_sdk.init(dsn=os.environ["SENTRY_DSN"]) application = SentryWsgiMiddleware(application) + +# Add a way to dump stacks so we can see what a uWSGI worker is doing if it +# hangs. +# +# We use `SIGCONT` for this because this handler isn't used for anything +# important, and uWSGI defines its own `SIGUSR1` and `SIGUSR2` handlers after +# this code runs. +signal.signal(signal.SIGCONT, _dump_stacks)