From f117ddc6fadac72c675225bd7b00e06e2cbc89b4 Mon Sep 17 00:00:00 2001 From: Shay Levy Date: Fri, 22 Jan 2021 01:23:50 +0200 Subject: [PATCH] Stop update_coordinator schedule refresh when HA is stopping (#45338) * Stop update_coordinator schedule refresh when HA is stopping * Add unittests * Fix event type --- homeassistant/helpers/update_coordinator.py | 15 +++++++++++- tests/helpers/test_update_coordinator.py | 26 +++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/homeassistant/helpers/update_coordinator.py b/homeassistant/helpers/update_coordinator.py index 895eff01f57..8df2c57b1e7 100644 --- a/homeassistant/helpers/update_coordinator.py +++ b/homeassistant/helpers/update_coordinator.py @@ -9,7 +9,8 @@ import urllib.error import aiohttp import requests -from homeassistant.core import CALLBACK_TYPE, HassJob, HomeAssistant, callback +from homeassistant.const import EVENT_HOMEASSISTANT_STOP +from homeassistant.core import CALLBACK_TYPE, Event, HassJob, HomeAssistant, callback from homeassistant.helpers import entity, event from homeassistant.util.dt import utcnow @@ -66,6 +67,10 @@ class DataUpdateCoordinator(Generic[T]): self._debounced_refresh = request_refresh_debouncer + self.hass.bus.async_listen_once( + EVENT_HOMEASSISTANT_STOP, self._async_stop_refresh + ) + @callback def async_add_listener(self, update_callback: CALLBACK_TYPE) -> Callable[[], None]: """Listen for data updates.""" @@ -214,6 +219,14 @@ class DataUpdateCoordinator(Generic[T]): for update_callback in self._listeners: update_callback() + @callback + def _async_stop_refresh(self, _: Event) -> None: + """Stop refreshing when Home Assistant is stopping.""" + self.update_interval = None + if self._unsub_refresh: + self._unsub_refresh() + self._unsub_refresh = None + class CoordinatorEntity(entity.Entity): """A class for entities using DataUpdateCoordinator.""" diff --git a/tests/helpers/test_update_coordinator.py b/tests/helpers/test_update_coordinator.py index 0651a4a9324..e9754f83a26 100644 --- a/tests/helpers/test_update_coordinator.py +++ b/tests/helpers/test_update_coordinator.py @@ -9,6 +9,8 @@ import aiohttp import pytest import requests +from homeassistant.const import EVENT_HOMEASSISTANT_STOP +from homeassistant.core import CoreState from homeassistant.helpers import update_coordinator from homeassistant.util.dt import utcnow @@ -284,3 +286,27 @@ async def test_async_set_updated_data(crd): crd.async_set_updated_data(300) # We have created a new refresh listener assert crd._unsub_refresh is not old_refresh + + +async def test_stop_refresh_on_ha_stop(hass, crd): + """Test no update interval refresh when Home Assistant is stopping.""" + # Add subscriber + update_callback = Mock() + crd.async_add_listener(update_callback) + + update_interval = crd.update_interval + + # Test we update with subscriber + async_fire_time_changed(hass, utcnow() + update_interval) + await hass.async_block_till_done() + assert crd.data == 1 + + # Fire Home Assistant stop event + hass.bus.async_fire(EVENT_HOMEASSISTANT_STOP) + hass.state = CoreState.stopping + await hass.async_block_till_done() + + # Make sure no update with subscriber after stop event + async_fire_time_changed(hass, utcnow() + update_interval) + await hass.async_block_till_done() + assert crd.data == 1