Avoid useless time fetch in DataUpdateCoordinator (#107999)
* Avoid useless time fetch in DataUpdateCoordinator Since we used the async_call_at helper, it would always call dt_util.utcnow() to feed the _handle_refresh_interval which threw it away. This meant we had to fetch time twice as much as needed for each update * tweak * compat * adjust comment
This commit is contained in:
parent
9033f1f3e8
commit
8d3f693907
1 changed files with 24 additions and 11 deletions
|
@ -84,6 +84,7 @@ class DataUpdateCoordinator(BaseDataUpdateCoordinatorProtocol, Generic[_DataT]):
|
|||
self.logger = logger
|
||||
self.name = name
|
||||
self.update_method = update_method
|
||||
self._update_interval_seconds: float | None = None
|
||||
self.update_interval = update_interval
|
||||
self._shutdown_requested = False
|
||||
self.config_entry = config_entries.current_entry.get()
|
||||
|
@ -212,10 +213,21 @@ class DataUpdateCoordinator(BaseDataUpdateCoordinatorProtocol, Generic[_DataT]):
|
|||
self._unsub_shutdown()
|
||||
self._unsub_shutdown = None
|
||||
|
||||
@property
|
||||
def update_interval(self) -> timedelta | None:
|
||||
"""Interval between updates."""
|
||||
return self._update_interval
|
||||
|
||||
@update_interval.setter
|
||||
def update_interval(self, value: timedelta | None) -> None:
|
||||
"""Set interval between updates."""
|
||||
self._update_interval = value
|
||||
self._update_interval_seconds = value.total_seconds() if value else None
|
||||
|
||||
@callback
|
||||
def _schedule_refresh(self) -> None:
|
||||
"""Schedule a refresh."""
|
||||
if self.update_interval is None:
|
||||
if self._update_interval_seconds is None:
|
||||
return
|
||||
|
||||
if self.config_entry and self.config_entry.pref_disable_polling:
|
||||
|
@ -225,19 +237,20 @@ class DataUpdateCoordinator(BaseDataUpdateCoordinatorProtocol, Generic[_DataT]):
|
|||
# than the debouncer cooldown, this would cause the debounce to never be called
|
||||
self._async_unsub_refresh()
|
||||
|
||||
# We use event.async_call_at because DataUpdateCoordinator does
|
||||
# not need an exact update interval.
|
||||
now = self.hass.loop.time()
|
||||
# We use loop.call_at because DataUpdateCoordinator does
|
||||
# not need an exact update interval which also avoids
|
||||
# calling dt_util.utcnow() on every update.
|
||||
hass = self.hass
|
||||
loop = hass.loop
|
||||
|
||||
next_refresh = int(now) + self._microsecond
|
||||
next_refresh += self.update_interval.total_seconds()
|
||||
self._unsub_refresh = event.async_call_at(
|
||||
self.hass,
|
||||
self._job,
|
||||
next_refresh,
|
||||
next_refresh = (
|
||||
int(loop.time()) + self._microsecond + self._update_interval_seconds
|
||||
)
|
||||
self._unsub_refresh = loop.call_at(
|
||||
next_refresh, hass.async_run_hass_job, self._job
|
||||
).cancel
|
||||
|
||||
async def _handle_refresh_interval(self, _now: datetime) -> None:
|
||||
async def _handle_refresh_interval(self, _now: datetime | None = None) -> None:
|
||||
"""Handle a refresh interval occurrence."""
|
||||
self._unsub_refresh = None
|
||||
await self._async_refresh(log_failures=True, scheduled=True)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue