Skip to content

Commit 68871c3

Browse files
authored
feat: speed up matching types in the ServiceBrowser (#1144)
1 parent da10a3b commit 68871c3

2 files changed

Lines changed: 18 additions & 6 deletions

File tree

src/zeroconf/_services/browser.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
cast,
4040
)
4141

42-
from .._dns import DNSAddress, DNSPointer, DNSQuestion, DNSQuestionType, DNSRecord
42+
from .._dns import DNSPointer, DNSQuestion, DNSQuestionType, DNSRecord
4343
from .._logger import log
4444
from .._protocol.outgoing import DNSOutgoing
4545
from .._services import (
@@ -49,7 +49,7 @@
4949
SignalRegistrationInterface,
5050
)
5151
from .._updates import RecordUpdate, RecordUpdateListener
52-
from .._utils.name import possible_types, service_type_name
52+
from .._utils.name import cached_possible_types, service_type_name
5353
from .._utils.time import current_time_millis, millis_to_seconds
5454
from ..const import (
5555
_BROWSER_BACKOFF_LIMIT,
@@ -62,6 +62,8 @@
6262
_MDNS_ADDR,
6363
_MDNS_ADDR6,
6464
_MDNS_PORT,
65+
_TYPE_A,
66+
_TYPE_AAAA,
6567
_TYPE_PTR,
6668
)
6769

@@ -338,7 +340,9 @@ def service_state_changed(self) -> SignalRegistrationInterface:
338340

339341
def _names_matching_types(self, names: Iterable[str]) -> List[Tuple[str, str]]:
340342
"""Return the type and name for records matching the types we are browsing."""
341-
return [(type_, name) for name in names for type_ in self.types.intersection(possible_types(name))]
343+
return [
344+
(type_, name) for name in names for type_ in self.types.intersection(cached_possible_types(name))
345+
]
342346

343347
def _enqueue_callback(
344348
self,
@@ -363,8 +367,12 @@ def _async_process_record_update(
363367
self, now: float, record: DNSRecord, old_record: Optional[DNSRecord]
364368
) -> None:
365369
"""Process a single record update from a batch of updates."""
366-
if isinstance(record, DNSPointer):
367-
for type_ in self.types.intersection(possible_types(record.name)):
370+
record_type = record.type
371+
372+
if record_type is _TYPE_PTR:
373+
if TYPE_CHECKING:
374+
record = cast(DNSPointer, record)
375+
for type_ in self.types.intersection(cached_possible_types(record.name)):
368376
if old_record is None:
369377
self._enqueue_callback(ServiceStateChange.Added, type_, record.alias)
370378
elif record.is_expired(now):
@@ -377,7 +385,7 @@ def _async_process_record_update(
377385
if old_record or record.is_expired(now):
378386
return
379387

380-
if isinstance(record, DNSAddress):
388+
if record_type in (_TYPE_A, _TYPE_AAAA):
381389
# Iterate through the DNSCache and callback any services that use this address
382390
for type_, name in self._names_matching_types(
383391
{service.name for service in self.zc.cache.async_entries_with_server(record.name)}

src/zeroconf/_utils/name.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
USA
2121
"""
2222

23+
from functools import lru_cache
2324
from typing import Set
2425

2526
from .._exceptions import BadTypeInNameException
@@ -170,3 +171,6 @@ def possible_types(name: str) -> Set[str]:
170171
break
171172
types.add('.'.join(parts))
172173
return types
174+
175+
176+
cached_possible_types = lru_cache(maxsize=256)(possible_types)

0 commit comments

Comments
 (0)