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 <noreply@anthropic.com>
This commit is contained in:
parent
f4eaf8e7d1
commit
f578efa145
1 changed files with 13 additions and 0 deletions
|
|
@ -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:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue