Skip to content

Commit 816ad4d

Browse files
authored
feat: avoid python float conversion in listener hot path (#1245)
1 parent 36ae505 commit 816ad4d

2 files changed

Lines changed: 20 additions & 8 deletions

File tree

src/zeroconf/_listener.pxd

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ from ._utils.time cimport current_time_millis, millis_to_seconds
77

88
cdef object log
99
cdef object logging_DEBUG
10+
cdef object TYPE_CHECKING
1011

12+
cdef cython.uint _MAX_MSG_ABSOLUTE
13+
cdef cython.uint _DUPLICATE_PACKET_SUPPRESSION_INTERVAL
1114

1215
cdef class AsyncListener:
1316

@@ -22,3 +25,5 @@ cdef class AsyncListener:
2225

2326
@cython.locals(now=cython.float, msg=DNSIncoming)
2427
cpdef datagram_received(self, cython.bytes bytes, cython.tuple addrs)
28+
29+
cdef _cancel_any_timers_for_addr(self, object addr)

src/zeroconf/_listener.py

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838

3939

4040
_bytes = bytes
41+
_str = str
42+
_int = int
4143

4244
logging_DEBUG = logging.DEBUG
4345

@@ -110,19 +112,23 @@ def datagram_received(
110112
)
111113
return
112114

113-
v6_flow_scope: Union[Tuple[()], Tuple[int, int]] = ()
114115
if len(addrs) == 2:
116+
v6_flow_scope: Union[Tuple[()], Tuple[int, int]] = ()
115117
# https://github.com/python/mypy/issues/1178
116118
addr, port = addrs # type: ignore
119+
addr_port = addrs
120+
if TYPE_CHECKING:
121+
addr_port = cast(Tuple[str, int], addr_port)
117122
scope = None
118123
else:
119124
# https://github.com/python/mypy/issues/1178
120125
addr, port, flow, scope = addrs # type: ignore
121126
if debug: # pragma: no branch
122127
log.debug('IPv6 scope_id %d associated to the receiving interface', scope)
123128
v6_flow_scope = (flow, scope)
129+
addr_port = (addr, port)
124130

125-
msg = DNSIncoming(data, (addr, port), scope, now)
131+
msg = DNSIncoming(data, addr_port, scope, now)
126132
self.data = data
127133
self.last_time = now
128134
self.last_message = msg
@@ -176,22 +182,23 @@ def handle_query_or_defer(
176182
return
177183
deferred.append(msg)
178184
delay = millis_to_seconds(random.randint(*_TC_DELAY_RANDOM_INTERVAL))
179-
assert self.zc.loop is not None
185+
loop = self.zc.loop
186+
assert loop is not None
180187
self._cancel_any_timers_for_addr(addr)
181-
self._timers[addr] = self.zc.loop.call_later(
182-
delay, self._respond_query, None, addr, port, transport, v6_flow_scope
188+
self._timers[addr] = loop.call_at(
189+
loop.time() + delay, self._respond_query, None, addr, port, transport, v6_flow_scope
183190
)
184191

185-
def _cancel_any_timers_for_addr(self, addr: str) -> None:
192+
def _cancel_any_timers_for_addr(self, addr: _str) -> None:
186193
"""Cancel any future truncated packet timers for the address."""
187194
if addr in self._timers:
188195
self._timers.pop(addr).cancel()
189196

190197
def _respond_query(
191198
self,
192199
msg: Optional[DNSIncoming],
193-
addr: str,
194-
port: int,
200+
addr: _str,
201+
port: _int,
195202
transport: _WrappedTransport,
196203
v6_flow_scope: Union[Tuple[()], Tuple[int, int]] = (),
197204
) -> None:

0 commit comments

Comments
 (0)