Skip to content

Commit

Permalink
perf: avoid creating a task for the debounced listener update
Browse files Browse the repository at this point in the history
Nothing was being awaited in _debounced so it could be
a normal function decorated with @callback to run in
the event loop and did not need to be a coro. This
avoids creating a task when the async_call_later fires
  • Loading branch information
bdraco committed Jun 8, 2024
1 parent 85c6085 commit df1f878
Showing 1 changed file with 16 additions and 11 deletions.
27 changes: 16 additions & 11 deletions custom_components/tesla_custom/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from http import HTTPStatus
import logging
import ssl
from typing import Any

import async_timeout
from homeassistant.config_entries import SOURCE_IMPORT
Expand Down Expand Up @@ -425,7 +426,7 @@ def __init__(
self.energy_site_id = energy_site_id
self.energy_site_ids = {energy_site_id} if energy_site_id else set()
self.update_vehicles = update_vehicles
self._debounce_task = None
self._cancel_debounce_timer = None
self._last_update_time = None
self.last_controller_update_time: float | None = None
self.assumed_state = True
Expand Down Expand Up @@ -488,7 +489,10 @@ async def _async_update_data(self):
)
return data

def async_update_listeners_debounced(self, delay_since_last=0.1, max_delay=1.0):
@callback
def async_update_listeners_debounced(
self, delay_since_last=0.1, max_delay=1.0
) -> None:
"""
Debounced version of async_update_listeners.
Expand All @@ -504,17 +508,18 @@ def async_update_listeners_debounced(self, delay_since_last=0.1, max_delay=1.0):
"""
# If there's an existing debounce task, cancel it
if self._debounce_task:
self._debounce_task()
if self._cancel_debounce_timer:
self._cancel_debounce_timer()
_LOGGER.debug("Previous debounce task cancelled")

# Schedule the call to _debounced, pass max_delay using partial
self._debounce_task = async_call_later(
self.hass, delay_since_last, partial(self._debounced, max_delay)
# Schedule the call to _async_debounced, pass max_delay using partial
self._cancel_debounce_timer = async_call_later(
self.hass, delay_since_last, partial(self._async_debounced, max_delay)
)
_LOGGER.debug("New debounce task scheduled")

async def _debounced(self, max_delay, *args):
@callback
def _async_debounced(self, max_delay: float, *args: Any) -> None:
"""
Debounce method that waits a certain delay since the last update.
Expand All @@ -537,10 +542,10 @@ async def _debounced(self, max_delay, *args):
_LOGGER.debug("Listeners updated")
else:
# If it hasn't been max_delay since the last update,
# schedule the call to _debounced again after the remaining time
self._debounce_task = async_call_later(
# schedule the call to _async_debounced again after the remaining time
self._cancel_debounce_timer = async_call_later(
self.hass,
max_delay - (now - self._last_update_time),
partial(self._debounced, max_delay),
partial(self._async_debounced, max_delay),
)
_LOGGER.debug("Max delay not reached, scheduling another debounce task")

0 comments on commit df1f878

Please sign in to comment.