From b98d2534c8ea2a08988bbe07aa9831af0b41c527 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 1 Sep 2023 19:09:11 -0500 Subject: [PATCH 1/6] feat: avoid python float conversion in listener hot path --- src/zeroconf/_listener.pxd | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/zeroconf/_listener.pxd b/src/zeroconf/_listener.pxd index 0f32a44a7..687b7467e 100644 --- a/src/zeroconf/_listener.pxd +++ b/src/zeroconf/_listener.pxd @@ -9,6 +9,8 @@ cdef object logging_DEBUG from ._protocol.incoming cimport DNSIncoming +cdef cython.uint _MAX_MSG_ABSOLUTE + cdef class AsyncListener: cdef public object zc From ef38adf51a0458710d390365befac1f47bd7cfd5 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 1 Sep 2023 19:11:26 -0500 Subject: [PATCH 2/6] feat: add uint --- src/zeroconf/_listener.pxd | 1 + 1 file changed, 1 insertion(+) diff --git a/src/zeroconf/_listener.pxd b/src/zeroconf/_listener.pxd index 322940824..e98a6c4af 100644 --- a/src/zeroconf/_listener.pxd +++ b/src/zeroconf/_listener.pxd @@ -10,6 +10,7 @@ cdef object logging_DEBUG cdef cython.uint _MAX_MSG_ABSOLUTE +cdef cython.uint _DUPLICATE_PACKET_SUPPRESSION_INTERVAL cdef class AsyncListener: From 3b50641add69e96e0f615011d997f97d7194b899 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 1 Sep 2023 19:16:47 -0500 Subject: [PATCH 3/6] fix: reduce variable copy --- src/zeroconf/_listener.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/zeroconf/_listener.py b/src/zeroconf/_listener.py index bc0af296f..e650bd578 100644 --- a/src/zeroconf/_listener.py +++ b/src/zeroconf/_listener.py @@ -110,10 +110,13 @@ def datagram_received( ) return - v6_flow_scope: Union[Tuple[()], Tuple[int, int]] = () if len(addrs) == 2: + v6_flow_scope: Union[Tuple[()], Tuple[int, int]] = () # https://github.com/python/mypy/issues/1178 addr, port = addrs # type: ignore + addr_port = addrs + if TYPE_CHECKING: + addr_port = cast(Tuple[str, int], addr_port) scope = None else: # https://github.com/python/mypy/issues/1178 @@ -121,8 +124,9 @@ def datagram_received( if debug: # pragma: no branch log.debug('IPv6 scope_id %d associated to the receiving interface', scope) v6_flow_scope = (flow, scope) + addr_port = (addr, port) - msg = DNSIncoming(data, (addr, port), scope, now) + msg = DNSIncoming(data, addr_port, scope, now) self.data = data self.last_time = now self.last_message = msg From e6e94a82c2d0f114d08f58d563577a1cd2fc684b Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 1 Sep 2023 19:17:02 -0500 Subject: [PATCH 4/6] fix: reduce variable copy --- src/zeroconf/_listener.pxd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zeroconf/_listener.pxd b/src/zeroconf/_listener.pxd index e98a6c4af..04b9f18bc 100644 --- a/src/zeroconf/_listener.pxd +++ b/src/zeroconf/_listener.pxd @@ -7,7 +7,7 @@ from ._utils.time cimport current_time_millis, millis_to_seconds cdef object log cdef object logging_DEBUG - +cdef object TYPE_CHECKING cdef cython.uint _MAX_MSG_ABSOLUTE cdef cython.uint _DUPLICATE_PACKET_SUPPRESSION_INTERVAL From c6d49346112a9959ccb780ba45a4f798c375b6f3 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 1 Sep 2023 19:23:10 -0500 Subject: [PATCH 5/6] feat: add a cython def for _cancel_any_timers_for_addr --- src/zeroconf/_listener.pxd | 2 ++ src/zeroconf/_listener.py | 8 +++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/zeroconf/_listener.pxd b/src/zeroconf/_listener.pxd index 04b9f18bc..75114d565 100644 --- a/src/zeroconf/_listener.pxd +++ b/src/zeroconf/_listener.pxd @@ -25,3 +25,5 @@ cdef class AsyncListener: @cython.locals(now=cython.float, msg=DNSIncoming) cpdef datagram_received(self, cython.bytes bytes, cython.tuple addrs) + + cdef _cancel_any_timers_for_addr(self, object addr) diff --git a/src/zeroconf/_listener.py b/src/zeroconf/_listener.py index e650bd578..b5c1f7877 100644 --- a/src/zeroconf/_listener.py +++ b/src/zeroconf/_listener.py @@ -38,6 +38,8 @@ _bytes = bytes +_str = str +_int = int logging_DEBUG = logging.DEBUG @@ -186,7 +188,7 @@ def handle_query_or_defer( delay, self._respond_query, None, addr, port, transport, v6_flow_scope ) - def _cancel_any_timers_for_addr(self, addr: str) -> None: + def _cancel_any_timers_for_addr(self, addr: _str) -> None: """Cancel any future truncated packet timers for the address.""" if addr in self._timers: self._timers.pop(addr).cancel() @@ -194,8 +196,8 @@ def _cancel_any_timers_for_addr(self, addr: str) -> None: def _respond_query( self, msg: Optional[DNSIncoming], - addr: str, - port: int, + addr: _str, + port: _int, transport: _WrappedTransport, v6_flow_scope: Union[Tuple[()], Tuple[int, int]] = (), ) -> None: From 014e2097842fc8fb75c591d71780db22263be05d Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 1 Sep 2023 19:37:36 -0500 Subject: [PATCH 6/6] feat: cleanup loop overhead --- src/zeroconf/_listener.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/zeroconf/_listener.py b/src/zeroconf/_listener.py index b5c1f7877..8da9381c9 100644 --- a/src/zeroconf/_listener.py +++ b/src/zeroconf/_listener.py @@ -182,10 +182,11 @@ def handle_query_or_defer( return deferred.append(msg) delay = millis_to_seconds(random.randint(*_TC_DELAY_RANDOM_INTERVAL)) - assert self.zc.loop is not None + loop = self.zc.loop + assert loop is not None self._cancel_any_timers_for_addr(addr) - self._timers[addr] = self.zc.loop.call_later( - delay, self._respond_query, None, addr, port, transport, v6_flow_scope + self._timers[addr] = loop.call_at( + loop.time() + delay, self._respond_query, None, addr, port, transport, v6_flow_scope ) def _cancel_any_timers_for_addr(self, addr: _str) -> None: