diff --git a/custom_components/omie/coordinator.py b/custom_components/omie/coordinator.py index 6bf36fe..0069da8 100644 --- a/custom_components/omie/coordinator.py +++ b/custom_components/omie/coordinator.py @@ -22,6 +22,9 @@ _HOURS = list(range(25)) """Max number of hours in a day (on the day that DST ends).""" +_SCHEDULE_MAX_DELAY = timedelta(seconds=3) +"""The maximum delay after the scheduled time that we will fetch from OMIE to avoid thundering herd.""" + # language=Markdown # # OMIE market sessions and the values that they influence. Time shown below is publication time in the CET timezone plus 10 minutes. @@ -63,7 +66,9 @@ def __init__(self, update_method=market_updater(async_get_clientsession(hass), market_date)) self._market_date = market_date self._none_before = list(map(int, none_before.split(":"))) if none_before is not None else [0, 0] - self._second = random.randint(0, 3) + delay_μs = random.randint(0, _SCHEDULE_MAX_DELAY.seconds * 10 ** 6) + self._schedule_second = delay_μs // 10 ** 6 + self._schedule_microsecond = delay_μs % 10 ** 6 async def _async_update_data(self) -> OMIEModel | None: if self._wait_for_none_before(): @@ -93,8 +98,9 @@ def _schedule_refresh(self) -> None: cet_hour, cet_minute = self._none_before now_cet = utcnow().astimezone(CET) - none_before = now_cet.replace(hour=cet_hour, minute=cet_minute, second=self._second, microsecond=int(self._microsecond * 10 ** 6)) - next_hour = now_cet.replace(minute=0, second=self._second, microsecond=int(self._microsecond * 10 ** 6)) + timedelta(hours=1) + none_before = now_cet.replace(hour=cet_hour, minute=cet_minute, second=self._schedule_second, + microsecond=self._schedule_microsecond) + next_hour = now_cet.replace(minute=0, second=self._schedule_second, microsecond=self._schedule_microsecond) + timedelta(hours=1) # next hour or the none_before time, whichever is soonest next_refresh = (none_before if cet_hour == now_cet.hour and none_before > now_cet else next_hour).astimezone() @@ -111,8 +117,8 @@ def _wait_for_none_before(self) -> bool: none_before = cet_now.replace( hour=cet_hour, minute=cet_minute, - second=self._second, - microsecond=int(self._microsecond * 10 ** 6)) + second=self._schedule_second, + microsecond=self._schedule_microsecond) return cet_now < none_before and none_before.date() == cet_now.date()