mirror of https://github.com/home-assistant/core
Fix shutdown being delayed for cancelling tasks (#93287)
This commit is contained in:
parent
72c76d35cc
commit
780f9bcdc0
|
@ -82,7 +82,11 @@ from .exceptions import (
|
|||
from .helpers.aiohttp_compat import restore_original_aiohttp_cancel_behavior
|
||||
from .helpers.json import json_dumps
|
||||
from .util import dt as dt_util, location, ulid as ulid_util
|
||||
from .util.async_ import run_callback_threadsafe, shutdown_run_callback_threadsafe
|
||||
from .util.async_ import (
|
||||
cancelling,
|
||||
run_callback_threadsafe,
|
||||
shutdown_run_callback_threadsafe,
|
||||
)
|
||||
from .util.read_only_dict import ReadOnlyDict
|
||||
from .util.timeout import TimeoutManager
|
||||
from .util.unit_system import (
|
||||
|
@ -678,7 +682,11 @@ class HomeAssistant:
|
|||
start_time: float | None = None
|
||||
current_task = asyncio.current_task()
|
||||
|
||||
while tasks := [task for task in self._tasks if task is not current_task]:
|
||||
while tasks := [
|
||||
task
|
||||
for task in self._tasks
|
||||
if task is not current_task and not cancelling(task)
|
||||
]:
|
||||
await self._await_and_log_pending(tasks)
|
||||
|
||||
if start_time is None:
|
||||
|
@ -791,7 +799,7 @@ class HomeAssistant:
|
|||
# while we are awaiting canceled tasks to get their result
|
||||
# which will result in the set size changing during iteration
|
||||
for task in list(running_tasks):
|
||||
if task.done():
|
||||
if task.done() or cancelling(task):
|
||||
# Since we made a copy we need to check
|
||||
# to see if the task finished while we
|
||||
# were awaiting another task
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
"""Asyncio utilities."""
|
||||
from __future__ import annotations
|
||||
|
||||
from asyncio import Semaphore, gather, get_running_loop
|
||||
from asyncio import Future, Semaphore, gather, get_running_loop
|
||||
from asyncio.events import AbstractEventLoop
|
||||
from collections.abc import Awaitable, Callable
|
||||
import concurrent.futures
|
||||
|
@ -20,6 +20,13 @@ _R = TypeVar("_R")
|
|||
_P = ParamSpec("_P")
|
||||
|
||||
|
||||
def cancelling(task: Future[Any]) -> bool:
|
||||
"""Return True if task is done or cancelling."""
|
||||
# https://docs.python.org/3/library/asyncio-task.html#asyncio.Task.cancelling
|
||||
# is new in Python 3.11
|
||||
return bool((cancelling_ := getattr(task, "cancelling", None)) and cancelling_())
|
||||
|
||||
|
||||
def run_callback_threadsafe(
|
||||
loop: AbstractEventLoop, callback: Callable[..., _T], *args: Any
|
||||
) -> concurrent.futures.Future[_T]:
|
||||
|
|
Loading…
Reference in New Issue