From 95cc5c48edb21e72c4a7b21781032f7768a45eac Mon Sep 17 00:00:00 2001 From: Jakob Henning Jensen Date: Mon, 11 Nov 2024 19:23:29 +0100 Subject: [PATCH 1/3] Add delayed shutdown --- docs/deployment.md | 2 ++ uvicorn/config.py | 2 ++ uvicorn/main.py | 4 ++++ uvicorn/server.py | 6 +++++- 4 files changed, 13 insertions(+), 1 deletion(-) diff --git a/docs/deployment.md b/docs/deployment.md index d69fcf88e..86f17388f 100644 --- a/docs/deployment.md +++ b/docs/deployment.md @@ -114,6 +114,8 @@ Options: --timeout-graceful-shutdown INTEGER Maximum number of seconds to wait for graceful shutdown. + --shutdown-delay FLOAT + Time in seconds to delay shutdown when a shutdown-signal is received --ssl-keyfile TEXT SSL key file --ssl-certfile TEXT SSL certificate file --ssl-keyfile-password TEXT SSL keyfile password diff --git a/uvicorn/config.py b/uvicorn/config.py index 65dfe651e..248292d33 100644 --- a/uvicorn/config.py +++ b/uvicorn/config.py @@ -223,6 +223,7 @@ def __init__( headers: list[tuple[str, str]] | None = None, factory: bool = False, h11_max_incomplete_event_size: int | None = None, + shutdown_delay: float = 0, ): self.app = app self.host = host @@ -268,6 +269,7 @@ def __init__( self.encoded_headers: list[tuple[bytes, bytes]] = [] self.factory = factory self.h11_max_incomplete_event_size = h11_max_incomplete_event_size + self.shutdown_delay = shutdown_delay self.loaded = False self.configure_logging() diff --git a/uvicorn/main.py b/uvicorn/main.py index 96a10d538..5ab7d02b7 100644 --- a/uvicorn/main.py +++ b/uvicorn/main.py @@ -408,6 +408,7 @@ def main( app_dir: str, h11_max_incomplete_event_size: int | None, factory: bool, + shutdown_delay: float = 0, ) -> None: run( app, @@ -457,6 +458,7 @@ def main( factory=factory, app_dir=app_dir, h11_max_incomplete_event_size=h11_max_incomplete_event_size, + shutdown_delay=shutdown_delay, ) @@ -509,6 +511,7 @@ def run( app_dir: str | None = None, factory: bool = False, h11_max_incomplete_event_size: int | None = None, + shutdown_delay: float = 0, ) -> None: if app_dir is not None: sys.path.insert(0, app_dir) @@ -560,6 +563,7 @@ def run( use_colors=use_colors, factory=factory, h11_max_incomplete_event_size=h11_max_incomplete_event_size, + shutdown_delay=shutdown_delay, ) server = Server(config=config) diff --git a/uvicorn/server.py b/uvicorn/server.py index f14026f16..8d43896c2 100644 --- a/uvicorn/server.py +++ b/uvicorn/server.py @@ -259,8 +259,12 @@ async def on_tick(self, counter: int) -> bool: return False async def shutdown(self, sockets: list[socket.socket] | None = None) -> None: - logger.info("Shutting down") + if self.config.shutdown_delay: + logger.info(f"Shutting down in {self.config.shutdown_delay} seconds") + self.config.app.uvicorn_shutdown_triggered = True + await asyncio.sleep(self.config.shutdown_delay) + logger.info("Shutting down") # Stop accepting new connections. for server in self.servers: server.close() From 122a6bf1559eaa31a34bfb13e89612c14ae59447 Mon Sep 17 00:00:00 2001 From: Jakob Henning Jensen Date: Thu, 14 Nov 2024 15:35:13 +0100 Subject: [PATCH 2/3] Use class-attribute to track shutdown --- uvicorn/server.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/uvicorn/server.py b/uvicorn/server.py index 8d43896c2..018471981 100644 --- a/uvicorn/server.py +++ b/uvicorn/server.py @@ -48,6 +48,10 @@ def __init__(self) -> None: self.default_headers: list[tuple[bytes, bytes]] = [] +class ShutdownTrigger: + is_shutdown_triggered: bool = False + + class Server: def __init__(self, config: Config) -> None: self.config = config @@ -261,7 +265,7 @@ async def on_tick(self, counter: int) -> bool: async def shutdown(self, sockets: list[socket.socket] | None = None) -> None: if self.config.shutdown_delay: logger.info(f"Shutting down in {self.config.shutdown_delay} seconds") - self.config.app.uvicorn_shutdown_triggered = True + ShutdownTrigger.is_shutdown_triggered = True await asyncio.sleep(self.config.shutdown_delay) logger.info("Shutting down") From 4ba66c953bbd3c5d19e61aa70992a5dfe381228f Mon Sep 17 00:00:00 2001 From: Jakob Henning Jensen Date: Thu, 14 Nov 2024 16:11:54 +0100 Subject: [PATCH 3/3] Remove from deployment.md --- docs/deployment.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/deployment.md b/docs/deployment.md index 86f17388f..d69fcf88e 100644 --- a/docs/deployment.md +++ b/docs/deployment.md @@ -114,8 +114,6 @@ Options: --timeout-graceful-shutdown INTEGER Maximum number of seconds to wait for graceful shutdown. - --shutdown-delay FLOAT - Time in seconds to delay shutdown when a shutdown-signal is received --ssl-keyfile TEXT SSL key file --ssl-certfile TEXT SSL certificate file --ssl-keyfile-password TEXT SSL keyfile password