[projects/pld-builder.new] request_handler_server: graceful shutdown on SIGTERM/SIGHUP/SIGINT
arekm
arekm at pld-linux.org
Sat Apr 25 16:39:11 CEST 2026
commit 346d1c6d771359bbbf28018b46a1d92a04805844
Author: Arkadiusz Miśkiewicz <arekm at maven.pl>
Date: Sat Apr 25 16:11:17 2026 +0200
request_handler_server: graceful shutdown on SIGTERM/SIGHUP/SIGINT
PLD_Builder/request_handler_server.py | 71 +++++++++++++++++++++++------------
1 file changed, 47 insertions(+), 24 deletions(-)
---
diff --git a/PLD_Builder/request_handler_server.py b/PLD_Builder/request_handler_server.py
index 74b90e1..5bcdaac 100644
--- a/PLD_Builder/request_handler_server.py
+++ b/PLD_Builder/request_handler_server.py
@@ -4,6 +4,7 @@ import socket
import string
import time
import log
+import signal
import ssl
import sys
import traceback
@@ -16,12 +17,27 @@ from socketserver import ForkingMixIn
import request_handler
import path
+_shutdown_signum = None
+
+def _on_shutdown_signal(signum, frame):
+ global _shutdown_signum
+ _shutdown_signum = signum
+
class ForkingHTTPServer(ForkingMixIn, HTTPServer):
# Each request runs in a forked child so a slow handler (GPG verify,
# queue locking, SRPM processing) cannot block accept() of new clients,
# which surfaced on TLS as _ssl.c:1015 handshake timeouts. Forking also
# isolates module-level mutable state (acl.current_user, etc.).
- pass
+
+ def finish_request(self, request, client_address):
+ # _on_shutdown_signal is inherited by the child, but it just sets a
+ # module-level flag the child never checks - so SIGTERM to a child
+ # would silently do nothing. Restore the default action so a stuck
+ # child can be terminated with kill -TERM rather than only SIGKILL.
+ signal.signal(signal.SIGTERM, signal.SIG_DFL)
+ signal.signal(signal.SIGHUP, signal.SIG_DFL)
+ signal.signal(signal.SIGINT, signal.SIG_DFL)
+ super().finish_request(request, client_address)
class MyHandler(BaseHTTPRequestHandler):
@@ -93,31 +109,38 @@ def main(srv_ssl=False):
write_css();
write_js();
socket.setdefaulttimeout(30)
+ # Default action for SIGTERM/SIGHUP is silent termination; for SIGINT
+ # it's KeyboardInterrupt. Capture all three through the same handler
+ # so the accept loop notices and runs server_close(), which reaps
+ # in-flight forked children.
+ signal.signal(signal.SIGTERM, _on_shutdown_signal)
+ signal.signal(signal.SIGHUP, _on_shutdown_signal)
+ signal.signal(signal.SIGINT, _on_shutdown_signal)
+ init_conf()
+ host = ""
+ port = config.request_handler_server_port
+ if srv_ssl:
+ port = config.request_handler_server_ssl_port
+
try:
- init_conf()
- host = ""
- port = config.request_handler_server_port
+ server = ForkingHTTPServer((host, port), MyHandler)
if srv_ssl:
- port = config.request_handler_server_ssl_port
-
- try:
- server = ForkingHTTPServer((host, port), MyHandler)
- if srv_ssl:
- context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
- context.load_cert_chain(certfile=config.request_handler_server_ssl_cert,
- keyfile=config.request_handler_server_ssl_key)
- context.load_verify_locations(cafile="/etc/certs/ca-certificates.crt")
- server.socket = context.wrap_socket(server.socket, server_side=True)
- except Exception as e:
- log.notice("request_handler_server: can't start server on [%s:%d], ssl=%s: %s" % (host, port, str(srv_ssl), e))
- print >> sys.stderr, "ERROR: Can't start server on [%s:%d], ssl=%s: %s" % (host, port, str(srv_ssl), e)
- sys.exit(1)
-
- log.notice('request_handler_server: started on [%s:%d], ssl=%s...' % (host, port, str(srv_ssl)))
- server.serve_forever()
- except KeyboardInterrupt:
- log.notice('request_handler_server: ^C received, shutting down server')
- server.socket.close()
+ context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
+ context.load_cert_chain(certfile=config.request_handler_server_ssl_cert,
+ keyfile=config.request_handler_server_ssl_key)
+ context.load_verify_locations(cafile="/etc/certs/ca-certificates.crt")
+ server.socket = context.wrap_socket(server.socket, server_side=True)
+ except Exception as e:
+ log.notice("request_handler_server: can't start server on [%s:%d], ssl=%s: %s" % (host, port, str(srv_ssl), e))
+ print >> sys.stderr, "ERROR: Can't start server on [%s:%d], ssl=%s: %s" % (host, port, str(srv_ssl), e)
+ sys.exit(1)
+
+ log.notice('request_handler_server: started on [%s:%d], ssl=%s...' % (host, port, str(srv_ssl)))
+ server.timeout = 1.0
+ while _shutdown_signum is None:
+ server.handle_request()
+ log.notice('request_handler_server: %s received, shutting down server' % signal.Signals(_shutdown_signum).name)
+ server.server_close()
if __name__ == '__main__':
srv_ssl = False
================================================================
---- gitweb:
http://git.pld-linux.org/gitweb.cgi/projects/pld-builder.new.git/commitdiff/33d0188f0225eeed4f279d76812f280f6c83a2e8
More information about the pld-cvs-commit
mailing list