From 78f6cbf8ab70a4cbb955047e1ff941841b0c251e Mon Sep 17 00:00:00 2001 From: Adam Hopkins Date: Wed, 31 Dec 2025 15:27:28 +0200 Subject: [PATCH 1/2] Reset how loop grabbed in shutdown --- sanic/app.py | 22 +++++++++++++++++----- sanic/server/runners.py | 2 +- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/sanic/app.py b/sanic/app.py index 756656e383..6b6535232a 100644 --- a/sanic/app.py +++ b/sanic/app.py @@ -1882,7 +1882,10 @@ def purge_tasks(self) -> None: } def shutdown_tasks( - self, timeout: float | None = None, increment: float = 0.1 + self, + timeout: float | None = None, + increment: float = 0.1, + loop: asyncio.AbstractEventLoop | None = None, ) -> None: """Cancel all tasks except the server task. @@ -1897,6 +1900,8 @@ def shutdown_tasks( to complete. Defaults to `None`. increment (float): The amount of time to wait between checks for whether the tasks have completed. Defaults to `0.1`. + loop (Optional[asyncio.AbstractEventLoop]): The event loop to use + for waiting. If not provided, attempts to get the running loop. """ for task in self.tasks: if task.get_name() != "RunServer": @@ -1905,10 +1910,17 @@ def shutdown_tasks( if timeout is None: timeout = self.config.GRACEFUL_SHUTDOWN_TIMEOUT - while len(self._task_registry) and timeout: - with suppress(RuntimeError): - running_loop = get_running_loop() - running_loop.run_until_complete(asyncio.sleep(increment)) + if loop is None: + try: + loop = get_running_loop() + except RuntimeError: + loop = asyncio.get_event_loop() + + while self._task_registry and timeout > 0: + try: + loop.run_until_complete(asyncio.sleep(increment)) + except RuntimeError: + pass self.purge_tasks() timeout -= increment diff --git a/sanic/server/runners.py b/sanic/server/runners.py index a3b963fde5..31c8b73a57 100644 --- a/sanic/server/runners.py +++ b/sanic/server/runners.py @@ -321,7 +321,7 @@ def _cleanup(): loop.run_until_complete(asyncio.sleep(0.1)) start_shutdown = start_shutdown + 0.1 - app.shutdown_tasks(graceful - start_shutdown) + app.shutdown_tasks(graceful - start_shutdown, loop=loop) # Force close non-idle connection after waiting for # graceful_shutdown_timeout From 7eaf9facce5c2c9add74ab21148de98c4e85e5a6 Mon Sep 17 00:00:00 2001 From: Adam Hopkins Date: Wed, 7 Jan 2026 08:18:31 +0200 Subject: [PATCH 2/2] Update sanic/app.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- sanic/app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sanic/app.py b/sanic/app.py index 6b6535232a..e4ed35dbe8 100644 --- a/sanic/app.py +++ b/sanic/app.py @@ -1914,7 +1914,7 @@ def shutdown_tasks( try: loop = get_running_loop() except RuntimeError: - loop = asyncio.get_event_loop() + loop = asyncio.get_event_loop_policy().get_event_loop() while self._task_registry and timeout > 0: try: