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

2324

import ipaddress

2425

import random

2526

from functools import lru_cache

@@ -37,10 +38,14 @@

3738

from .._logger import log

3839

from .._protocol.outgoing import DNSOutgoing

3940

from .._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+

)

4146

from .._utils.name import service_type_name

4247

from .._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

4449

from ..const import (

4550

_CLASS_IN,

4651

_CLASS_UNIQUE,

@@ -166,6 +171,7 @@ def __init__(

166171

self.host_ttl = host_ttl

167172

self.other_ttl = other_ttl

168173

self.interface_index = interface_index

174+

self._notify_event: Optional[asyncio.Event] = None

169175170176

@property

171177

def name(self) -> str:

@@ -221,6 +227,12 @@ def properties(self) -> Dict:

221227

"""

222228

return 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+224236

def 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()

388402389403

def _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(

605619

delay *= 2

606620

next_ += 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)

609623

now = current_time_millis()

610624

finally:

611625

zc.async_remove_listener(self)