Skip to content

Commit 71ffff3

Browse files
committed
docs: use ifaddr directly, harden the monitor loop, await the goodbye
1 parent f699df7 commit 71ffff3

1 file changed

Lines changed: 18 additions & 7 deletions

File tree

examples/async_interface_monitor.py

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,16 @@
2323
import contextlib
2424
import logging
2525

26-
from zeroconf import get_all_addresses, get_all_addresses_v6
26+
import ifaddr
27+
2728
from zeroconf.asyncio import AsyncServiceInfo, AsyncZeroconf
2829

30+
_LOGGER = logging.getLogger("interface_monitor")
31+
2932

30-
def address_snapshot() -> set[object]:
31-
"""A hashable snapshot of the host's current IPv4 and IPv6 addresses."""
32-
return {*get_all_addresses(), *get_all_addresses_v6()}
33+
def address_snapshot() -> set[tuple[str, int]]:
34+
"""A snapshot of the host's current addresses; a change triggers a reconcile."""
35+
return {(str(ip.ip), ip.network_prefix) for adapter in ifaddr.get_adapters() for ip in adapter.ips}
3336

3437

3538
async def monitor_interfaces(aiozc: AsyncZeroconf, interval: float) -> None:
@@ -38,10 +41,17 @@ async def monitor_interfaces(aiozc: AsyncZeroconf, interval: float) -> None:
3841
while True:
3942
await asyncio.sleep(interval)
4043
current = address_snapshot()
41-
if current != previous:
42-
previous = current
44+
if current == previous:
45+
continue
46+
try:
4347
print("Interfaces changed, reconciling sockets...")
4448
await aiozc.async_update_interfaces()
49+
except Exception:
50+
# Log and retry on the next tick rather than letting the monitor
51+
# die; leave ``previous`` unchanged so the change is re-attempted.
52+
_LOGGER.exception("Interface reconcile failed; will retry")
53+
else:
54+
previous = current
4555

4656

4757
class AsyncRunner:
@@ -63,7 +73,8 @@ async def close(self, info: AsyncServiceInfo) -> None:
6373
self.monitor.cancel()
6474
with contextlib.suppress(asyncio.CancelledError):
6575
await self.monitor
66-
await self.aiozc.async_unregister_service(info)
76+
# Await the goodbye broadcast so the TTL-0 records are actually sent.
77+
await (await self.aiozc.async_unregister_service(info))
6778
await self.aiozc.async_close()
6879

6980

0 commit comments

Comments
 (0)