diff --git a/xcube/server/webservers/tornado.py b/xcube/server/webservers/tornado.py index 8b29e6f06..9de5c2d89 100644 --- a/xcube/server/webservers/tornado.py +++ b/xcube/server/webservers/tornado.py @@ -23,6 +23,8 @@ import concurrent.futures import functools import logging +import signal +import sys import traceback import urllib.parse from typing import (Any, Optional, Sequence, Union, Callable, Type, @@ -64,6 +66,7 @@ def __init__(self, io_loop: Optional[tornado.ioloop.IOLoop] = None): self._application = application or tornado.web.Application() self._io_loop = io_loop + self._server: Optional[tornado.web.HTTPServer] = None self.configure_logging() @property @@ -149,7 +152,9 @@ def start(self, ctx: Context): address = config["address"] tornado_settings = config.get("tornado", {}) - self.application.listen(port, address=address, **tornado_settings) + self._server = self.application.listen(port, + address=address, + **tornado_settings) address_ = "127.0.0.1" if address == "0.0.0.0" else address # TODO: get test URL template from configuration @@ -158,9 +163,13 @@ def start(self, ctx: Context): LOG.info(f"Try {test_url}") LOG.info(f"Press CTRL+C to stop service") + self.configure_signals() + self.io_loop.start() def stop(self, ctx: Context): + if self._server is not None: + self._server.stop() self.io_loop.stop() def call_later(self, @@ -188,6 +197,14 @@ def run_in_executor( *args ) + def configure_signals(self): + def sig_handler(signum, frame): + self.io_loop.add_callback_from_signal(self.stop) + + signal.signal(signal.SIGTERM, sig_handler) + signal.signal(signal.SIGINT, sig_handler) + signal.signal(signal.SIGABRT, sig_handler) + @staticmethod def configure_logging(): # Configure Tornado loggers to use root handlers, so we