Cancel coordinator refresh timer on Home Assistant shutdown (#183659)

This commit is contained in:
Simone Chemelli
2026-09-30 16:18:33 +02:00
committed by GitHub
parent 38ff78fb0e
commit cedc4cbe4f
2 changed files with 36 additions and 3 deletions
+18 -3
View File
@@ -17,7 +17,14 @@ import requests
from homeassistant import config_entries
from homeassistant.const import EVENT_HOMEASSISTANT_STOP
from homeassistant.core import CALLBACK_TYPE, Event, HomeAssistant, callback
from homeassistant.core import (
CALLBACK_TYPE,
Event,
HassJob,
HassJobType,
HomeAssistant,
callback,
)
from homeassistant.exceptions import (
ConfigEntryAuthFailed,
ConfigEntryError,
@@ -274,12 +281,20 @@ class DataUpdateCoordinator(BaseDataUpdateCoordinatorProtocol, Generic[_DataT]):
self._retry_after = None
next_refresh = int(loop.time()) + self._microsecond + update_interval
# Cancelled when Home Assistant stops so a refresh can't fire during
# the close stage, after shared resources like aiohttp sessions are closed
refresh_job = HassJob(
self.__wrap_handle_refresh_interval,
f"{self.name} refresh interval",
job_type=HassJobType.Callback,
cancel_on_shutdown=True,
)
self._unsub_refresh = loop.call_at(
next_refresh, self.__wrap_handle_refresh_interval
next_refresh, self.__wrap_handle_refresh_interval, refresh_job
).cancel
@callback
def __wrap_handle_refresh_interval(self) -> None:
def __wrap_handle_refresh_interval(self, _: HassJob) -> None:
"""Handle a refresh interval occurrence."""
if self.config_entry:
self.config_entry.async_create_background_task(
+18
View File
@@ -711,6 +711,24 @@ async def test_stop_refresh_on_ha_stop(
assert crd.data == 2
async def test_no_refresh_after_ha_close(
hass: HomeAssistant, crd: update_coordinator.DataUpdateCoordinator[int]
) -> None:
"""Test a pending refresh does not fire once Home Assistant has closed."""
crd.async_add_listener(Mock())
async_fire_time_changed(hass, utcnow() + crd.update_interval)
await hass.async_block_till_done()
assert crd.data == 1
await hass.async_stop()
# Shared resources like the aiohttp session are closed at this point
async_fire_time_changed(hass, utcnow() + crd.update_interval * 2)
await hass.async_block_till_done()
assert crd.data == 1
@pytest.mark.parametrize(
"err_msg",
[