feat: Improve performance of loading records from cache in ServiceInfo · python-zeroconf/python-zeroconf@a65abcd
@@ -107,6 +107,9 @@ def _cached_ip_addresses(address: Union[str, bytes, int]) -> Optional[Union[IPv4
107107return None
108108109109110+_cached_ip_addresses_wrapper = _cached_ip_addresses
111+112+110113class ServiceInfo(RecordUpdateListener):
111114"""Service information.
112115@@ -197,7 +200,7 @@ def __init__(
197200self.host_ttl = host_ttl
198201self.other_ttl = other_ttl
199202self.interface_index = interface_index
200-self._new_records_futures: Set[asyncio.Future] = set()
203+self._new_records_futures: Optional[Set[asyncio.Future]] = None
201204self._dns_address_cache: Optional[List[DNSAddress]] = None
202205self._dns_pointer_cache: Optional[DNSPointer] = None
203206self._dns_service_cache: Optional[DNSService] = None
@@ -240,7 +243,7 @@ def addresses(self, value: List[bytes]) -> None:
240243self._get_address_and_nsec_records_cache = None
241244242245for address in value:
243-addr = _cached_ip_addresses(address)
246+addr = _cached_ip_addresses_wrapper(address)
244247if addr is None:
245248raise 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]]]:
272275273276async 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()
275280await wait_for_future_set_or_timeout(
276281loop or asyncio.get_running_loop(), self._new_records_futures, timeout
277282 )
@@ -409,7 +414,7 @@ def _get_ip_addresses_from_cache_lifo(
409414for record in self._get_address_records_from_cache_by_type(zc, type):
410415if record.is_expired(now):
411416continue
412-ip_addr = _cached_ip_addresses(record.address)
417+ip_addr = _cached_ip_addresses_wrapper(record.address)
413418if ip_addr is not None:
414419address_list.append(ip_addr)
415420address_list.reverse() # Reverse to get LIFO order
@@ -455,12 +460,17 @@ def _process_record_threadsafe(self, zc: 'Zeroconf', record: DNSRecord, now: flo
455460456461record_key = record.key
457462record_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
459465if 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)
462468if 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+ )
464474return False
465475466476if ip_addr.version == 4:
@@ -492,22 +502,24 @@ def _process_record_threadsafe(self, zc: 'Zeroconf', record: DNSRecord, now: flo
492502return False
493503494504if record_type is DNSText:
505+dns_text_record = record
495506if 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)
498509return True
499510500511if record_type is DNSService:
512+dns_service_record = record
501513if TYPE_CHECKING:
502-assert isinstance(record, DNSService)
514+assert isinstance(dns_service_record, DNSService)
503515old_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
511523if old_server_key != self.server_key:
512524self._set_ipv4_addresses_from_cache(zc, now)
513525self._set_ipv6_addresses_from_cache(zc, now)