Skip to content

Commit b5037f4

Browse files
committed
Reduce chance of accidental synchronization of ServiceInfo requests
- ServiceInfo requests are frequently triggered by multicast responses to ServiceBrowser requests. When multiple instances of zeroconf are present on the same network, they can all end up sending ServiceInfo queries at the same time. We now use a random delay as described in rfc6762 sec 5.2 after the first request. Ideally we would add the delay before the first query as well, however that may break existing workflows so it was not done at this time.
1 parent 5fb3e20 commit b5037f4

1 file changed

Lines changed: 12 additions & 0 deletions

File tree

zeroconf/_services/info.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
"""
2222

2323
import ipaddress
24+
import random
2425
import socket
2526
from typing import Any, Dict, List, Optional, TYPE_CHECKING, Union, cast
2627

@@ -52,6 +53,16 @@
5253
)
5354

5455

56+
# https://datatracker.ietf.org/doc/html/rfc6762#section-5.2
57+
# The most common case for calling ServiceInfo is from a
58+
# ServiceBrowser. After the first request we add a few random
59+
# milliseconds to the delay between requests to reduce the chance
60+
# that there are multiple ServiceBrowser callbacks running on
61+
# the network that are firing at the same time when they
62+
# see the same multicast response and decide to refresh
63+
# the A/AAAA/SRV records for a host.
64+
_AVOID_SYNC_DELAY_RANDOM_INTERVAL = (20, 120)
65+
5566
if TYPE_CHECKING:
5667
from .._core import Zeroconf
5768

@@ -455,6 +466,7 @@ async def async_request(
455466
zc.async_send(out)
456467
next_ = now + delay
457468
delay *= 2
469+
next_ += random.randint(*_AVOID_SYNC_DELAY_RANDOM_INTERVAL)
458470

459471
await zc.async_wait(min(next_, last) - now)
460472
now = current_time_millis()

0 commit comments

Comments
 (0)