Avoid unnecessary Task in debouncer (#89370)

This commit is contained in:
epenet 2023-03-09 11:41:59 +01:00 committed by GitHub
parent c9d5baca75
commit dbebe57d51
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -94,11 +94,6 @@ class Debouncer(Generic[_R_co]):
"""Handle a finished timer.""" """Handle a finished timer."""
assert self._job is not None assert self._job is not None
self._timer_task = None
if not self._execute_at_end_of_timer:
return
self._execute_at_end_of_timer = False self._execute_at_end_of_timer = False
# Locked means a call is in progress. Any call is good, so abort. # Locked means a call is in progress. Any call is good, so abort.
@ -108,7 +103,7 @@ class Debouncer(Generic[_R_co]):
async with self._execute_lock: async with self._execute_lock:
# Abort if timer got set while we're waiting for the lock. # Abort if timer got set while we're waiting for the lock.
if self._timer_task: if self._timer_task:
return # type: ignore[unreachable] return
try: try:
task = self.hass.async_run_hass_job(self._job) task = self.hass.async_run_hass_job(self._job)
@ -117,6 +112,7 @@ class Debouncer(Generic[_R_co]):
except Exception: # pylint: disable=broad-except except Exception: # pylint: disable=broad-except
self.logger.exception("Unexpected exception from %s", self.function) self.logger.exception("Unexpected exception from %s", self.function)
# Schedule a new timer to prevent new runs during cooldown
self._schedule_timer() self._schedule_timer()
@callback @callback
@ -129,12 +125,16 @@ class Debouncer(Generic[_R_co]):
self._execute_at_end_of_timer = False self._execute_at_end_of_timer = False
@callback @callback
def _schedule_timer(self) -> None: def _on_debounce(self) -> None:
"""Schedule a timer.""" """Create job task, but only if pending."""
self._timer_task = self.hass.loop.call_later( self._timer_task = None
self.cooldown, if self._execute_at_end_of_timer:
lambda: self.hass.async_create_task( self.hass.async_create_task(
self._handle_timer_finish(), self._handle_timer_finish(),
f"debouncer {self._job} finish cooldown={self.cooldown}, immediate={self.immediate}", f"debouncer {self._job} finish cooldown={self.cooldown}, immediate={self.immediate}",
), )
)
@callback
def _schedule_timer(self) -> None:
"""Schedule a timer."""
self._timer_task = self.hass.loop.call_later(self.cooldown, self._on_debounce)