feat: avoid waking async_request when record updates are not relevant… · python-zeroconf/python-zeroconf@a3f970c
@@ -20,6 +20,7 @@
2020 USA
2121"""
222223+import asyncio
2324import ipaddress
2425import random
2526from functools import lru_cache
@@ -37,10 +38,14 @@
3738from .._logger import log
3839from .._protocol.outgoing import DNSOutgoing
3940from .._updates import RecordUpdate, RecordUpdateListener
40-from .._utils.asyncio import get_running_loop, run_coro_with_timeout
41+from .._utils.asyncio import (
42+get_running_loop,
43+run_coro_with_timeout,
44+wait_event_or_timeout,
45+)
4146from .._utils.name import service_type_name
4247from .._utils.net import IPVersion, _encode_address
43-from .._utils.time import current_time_millis
48+from .._utils.time import current_time_millis, millis_to_seconds
4449from ..const import (
4550_CLASS_IN,
4651_CLASS_UNIQUE,
@@ -166,6 +171,7 @@ def __init__(
166171self.host_ttl = host_ttl
167172self.other_ttl = other_ttl
168173self.interface_index = interface_index
174+self._notify_event: Optional[asyncio.Event] = None
169175170176@property
171177def name(self) -> str:
@@ -221,6 +227,12 @@ def properties(self) -> Dict:
221227 """
222228return self._properties
223229230+async def async_wait(self, timeout: float) -> None:
231+"""Calling task waits for a given number of milliseconds or until notified."""
232+if self._notify_event is None:
233+self._notify_event = asyncio.Event()
234+await wait_event_or_timeout(self._notify_event, timeout=millis_to_seconds(timeout))
235+224236def addresses_by_version(self, version: IPVersion) -> List[bytes]:
225237"""List addresses matching IP version.
226238@@ -384,7 +396,9 @@ def async_update_records(self, zc: 'Zeroconf', now: float, records: List[RecordU
384396385397 This method will be run in the event loop.
386398 """
387-self._process_records_threadsafe(zc, now, records)
399+if self._process_records_threadsafe(zc, now, records) and self._notify_event:
400+self._notify_event.set()
401+self._notify_event.clear()
388402389403def _process_records_threadsafe(self, zc: 'Zeroconf', now: float, records: List[RecordUpdate]) -> bool:
390404"""Thread safe record updating.
@@ -605,7 +619,7 @@ async def async_request(
605619delay *= 2
606620next_ += random.randint(*_AVOID_SYNC_DELAY_RANDOM_INTERVAL)
607621608-await zc.async_wait(min(next_, last) - now)
622+await self.async_wait(min(next_, last) - now)
609623now = current_time_millis()
610624finally:
611625zc.async_remove_listener(self)