From f578efa14539b5f446b90796231124db8afd2e3a Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Thu, 2 Jul 2026 22:46:53 +0800 Subject: [PATCH] ingest: graceful shutdown on SIGTERM Handle SIGTERM (and SIGINT) to stop the HTTP server cleanly instead of being killed after Docker's grace period, so `docker compose down` returns in ~1s and the queue, HTTP clients and database are closed properly. shutdown() runs on a helper thread since it must not run on the serving thread. Co-Authored-By: Claude Opus 4.8 --- ingest/radieo/__main__.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/ingest/radieo/__main__.py b/ingest/radieo/__main__.py index 7923a9c..160f4ff 100644 --- a/ingest/radieo/__main__.py +++ b/ingest/radieo/__main__.py @@ -1,6 +1,8 @@ """Entry point: wire providers/fetchers into the queue and serve GET /next.""" import logging +import signal +import threading from . import config from .api import IngestServer @@ -159,6 +161,17 @@ def main() -> None: config.CACHE_DIR, config.STATE_DB, ) + + # Shut down cleanly on `docker compose down` (SIGTERM) instead of being + # killed after the grace period. shutdown() must run off the serving + # thread, so hand it to a helper thread. + def _handle_signal(signum, _frame): + log.info("received signal %d, shutting down", signum) + threading.Thread(target=server.shutdown, daemon=True).start() + + signal.signal(signal.SIGTERM, _handle_signal) + signal.signal(signal.SIGINT, _handle_signal) + try: server.serve_forever() except KeyboardInterrupt: