Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf: avoid creating a task for debounced listener update #990

Merged
merged 2 commits into from
Jun 8, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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_update_time: float | None = None
self.assumed_state = True
Expand Down Expand Up @@ -485,7 +486,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 @@ -501,17 +505,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(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

async_call_later does not return a task, it returns a callback that can be used to cancel the timer

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 @@ -534,10 +539,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")
Loading