diff --git a/files/nats_registration_listener.py b/files/nats_registration_listener.py index 14f121a..e03ad4f 100644 --- a/files/nats_registration_listener.py +++ b/files/nats_registration_listener.py @@ -316,6 +316,18 @@ async def main(): DEDUPE_TTL = float(os.environ.get("DEDUP_TTL", "2.0")) recent_payloads: Dict[bytes, float] = {} + # ---- Per-device lock keyed by normalized MAC (prevents overlap for same device) + mac_locks: Dict[str, asyncio.Lock] = {} + mac_locks_guard = asyncio.Lock() + + async def get_mac_lock(mac_key: str) -> asyncio.Lock: + async with mac_locks_guard: + lk = mac_locks.get(mac_key) + if lk is None: + lk = asyncio.Lock() + mac_locks[mac_key] = lk + return lk + async def disconnected_cb(): await log_status(f"[{ts()}] Disconnected from NATS.") @@ -375,7 +387,9 @@ async def main(): bell_prefix = "" # ASCII BEL when action_next present (3x) netbox_time_ms = 0.0 - if product == "fox100": + async def handle_fox100(): + nonlocal host_suffix, bell_prefix, netbox_time_ms + nb_start = time.perf_counter() try: host, iface_id, dev_id, status_val, tag_slugs, action_next, action_last, action_next_timestamp, action_state = nb_lookup_device_by_mac( @@ -597,6 +611,14 @@ async def main(): await nb_problem(log_status, f"[{ts()}] nb: unexpected error mac={mac!r} err={e!r}") netbox_time_ms = (time.perf_counter() - nb_start) * 1000 + if product == "fox100": + mac_key = normalize_mac(mac) + if mac_key: + async with (await get_mac_lock(mac_key)): + await handle_fox100() + else: + await handle_fox100() + total_ms = (monotonic() - t_start) * 1000 async with NB_PROBLEM_LOCK: @@ -643,4 +665,4 @@ if __name__ == "__main__": try: asyncio.run(main()) except KeyboardInterrupt: - pass \ No newline at end of file + pass