From f570bb5738f0dac4626c791703740d7c0c3aca25 Mon Sep 17 00:00:00 2001 From: Unrud Date: Mon, 31 Aug 2020 13:54:47 +0200 Subject: [PATCH] Exit immediately after cleanup when signal is received Waiting for clients introduces the risk that we exceed some timeout (e.g. from systemd) and get killed instead. --- radicale/__main__.py | 26 ++++++++++++++------------ radicale/tests/test_server.py | 7 ++----- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/radicale/__main__.py b/radicale/__main__.py index 9e0c3e472..d0ea10ea8 100644 --- a/radicale/__main__.py +++ b/radicale/__main__.py @@ -27,7 +27,6 @@ import contextlib import os import signal -import socket import sys from radicale import VERSION, config, log, server, storage @@ -36,10 +35,22 @@ def run(): """Run Radicale as a standalone server.""" + + # Raise SystemExit when signal arrives to run cleanup code + # (like destructors, try-finish etc.), otherwise the process exits + # without running any of them + def signal_handler(signal_number, stack_frame): + sys.exit(1) + signal.signal(signal.SIGTERM, signal_handler) + signal.signal(signal.SIGINT, signal_handler) + if os.name == "posix": + signal.signal(signal.SIGHUP, signal_handler) + log.setup() # Get command-line arguments - parser = argparse.ArgumentParser(usage="radicale [OPTIONS]") + parser = argparse.ArgumentParser( + prog="radicale", usage="%(prog)s [OPTIONS]") parser.add_argument("--version", action="version", version=VERSION) parser.add_argument("--verify-storage", action="store_true", @@ -137,17 +148,8 @@ def run(): sys.exit(1) return - # Create a socket pair to notify the server of program shutdown - shutdown_socket, shutdown_socket_out = socket.socketpair() - - # SIGTERM and SIGINT (aka KeyboardInterrupt) shutdown the server - def shutdown(signal_number, stack_frame): - shutdown_socket.close() - signal.signal(signal.SIGTERM, shutdown) - signal.signal(signal.SIGINT, shutdown) - try: - server.serve(configuration, shutdown_socket_out) + server.serve(configuration) except Exception as e: logger.fatal("An exception occurred during server startup: %s", e, exc_info=True) diff --git a/radicale/tests/test_server.py b/radicale/tests/test_server.py index c2aea6b60..a58e94ec7 100644 --- a/radicale/tests/test_server.py +++ b/radicale/tests/test_server.py @@ -172,17 +172,14 @@ def test_command_line_interface(self): config_args.append(long_name) config_args.append( self.configuration.get_raw(section, option)) - env = os.environ.copy() - env["PYTHONPATH"] = os.pathsep.join(sys.path) p = subprocess.Popen( - [sys.executable, "-m", "radicale"] + config_args, env=env) + [sys.executable, "-m", "radicale"] + config_args, + env={**os.environ, "PYTHONPATH": os.pathsep.join(sys.path)}) try: self.get("/", is_alive_fn=lambda: p.poll() is None, check=302) finally: p.terminate() p.wait() - if os.name == "posix": - assert p.returncode == 0 def test_wsgi_server(self): config_path = os.path.join(self.colpath, "config")