feat: improve performance of loading records from cache in ServiceInf… · python-zeroconf/python-zeroconf@6257d49

@@ -107,6 +107,9 @@ def _cached_ip_addresses(address: Union[str, bytes, int]) -> Optional[Union[IPv4

107107

return None

108108109109110+

_cached_ip_addresses_wrapper = _cached_ip_addresses

111+112+110113

class ServiceInfo(RecordUpdateListener):

111114

"""Service information.

112115

@@ -197,7 +200,7 @@ def __init__(

197200

self.host_ttl = host_ttl

198201

self.other_ttl = other_ttl

199202

self.interface_index = interface_index

200-

self._new_records_futures: Set[asyncio.Future] = set()

203+

self._new_records_futures: Optional[Set[asyncio.Future]] = None

201204

self._dns_address_cache: Optional[List[DNSAddress]] = None

202205

self._dns_pointer_cache: Optional[DNSPointer] = None

203206

self._dns_service_cache: Optional[DNSService] = None

@@ -240,7 +243,7 @@ def addresses(self, value: List[bytes]) -> None:

240243

self._get_address_and_nsec_records_cache = None

241244242245

for address in value:

243-

addr = _cached_ip_addresses(address)

246+

addr = _cached_ip_addresses_wrapper(address)

244247

if addr is None:

245248

raise TypeError(

246249

"Addresses must either be IPv4 or IPv6 strings, bytes, or integers;"

@@ -272,6 +275,8 @@ def properties(self) -> Dict[Union[str, bytes], Optional[Union[str, bytes]]]:

272275273276

async def async_wait(self, timeout: float, loop: Optional[asyncio.AbstractEventLoop] = None) -> None:

274277

"""Calling task waits for a given number of milliseconds or until notified."""

278+

if not self._new_records_futures:

279+

self._new_records_futures = set()

275280

await wait_for_future_set_or_timeout(

276281

loop or asyncio.get_running_loop(), self._new_records_futures, timeout

277282

)

@@ -409,7 +414,7 @@ def _get_ip_addresses_from_cache_lifo(

409414

for record in self._get_address_records_from_cache_by_type(zc, type):

410415

if record.is_expired(now):

411416

continue

412-

ip_addr = _cached_ip_addresses(record.address)

417+

ip_addr = _cached_ip_addresses_wrapper(record.address)

413418

if ip_addr is not None:

414419

address_list.append(ip_addr)

415420

address_list.reverse() # Reverse to get LIFO order

@@ -455,12 +460,17 @@ def _process_record_threadsafe(self, zc: 'Zeroconf', record: DNSRecord, now: flo

455460456461

record_key = record.key

457462

record_type = type(record)

458-

if record_key == self.server_key and record_type is DNSAddress:

463+

if record_type is DNSAddress and record_key == self.server_key:

464+

dns_address_record = record

459465

if TYPE_CHECKING:

460-

assert isinstance(record, DNSAddress)

461-

ip_addr = _cached_ip_addresses(record.address)

466+

assert isinstance(dns_address_record, DNSAddress)

467+

ip_addr = _cached_ip_addresses_wrapper(dns_address_record.address)

462468

if ip_addr is None:

463-

log.warning("Encountered invalid address while processing %s: %s", record, record.address)

469+

log.warning(

470+

"Encountered invalid address while processing %s: %s",

471+

dns_address_record,

472+

dns_address_record.address,

473+

)

464474

return False

465475466476

if ip_addr.version == 4:

@@ -492,22 +502,24 @@ def _process_record_threadsafe(self, zc: 'Zeroconf', record: DNSRecord, now: flo

492502

return False

493503494504

if record_type is DNSText:

505+

dns_text_record = record

495506

if TYPE_CHECKING:

496-

assert isinstance(record, DNSText)

497-

self._set_text(record.text)

507+

assert isinstance(dns_text_record, DNSText)

508+

self._set_text(dns_text_record.text)

498509

return True

499510500511

if record_type is DNSService:

512+

dns_service_record = record

501513

if TYPE_CHECKING:

502-

assert isinstance(record, DNSService)

514+

assert isinstance(dns_service_record, DNSService)

503515

old_server_key = self.server_key

504-

self._name = record.name

505-

self.key = record.key

506-

self.server = record.server

507-

self.server_key = record.server_key

508-

self.port = record.port

509-

self.weight = record.weight

510-

self.priority = record.priority

516+

self._name = dns_service_record.name

517+

self.key = dns_service_record.key

518+

self.server = dns_service_record.server

519+

self.server_key = dns_service_record.server_key

520+

self.port = dns_service_record.port

521+

self.weight = dns_service_record.weight

522+

self.priority = dns_service_record.priority

511523

if old_server_key != self.server_key:

512524

self._set_ipv4_addresses_from_cache(zc, now)

513525

self._set_ipv6_addresses_from_cache(zc, now)