From c012480b7e347a715e1500bb0aaea687bc6c540f Mon Sep 17 00:00:00 2001 From: Cobra Date: Mon, 13 Apr 2026 17:07:25 -0400 Subject: [PATCH] =?UTF-8?q?fix=20=5Fcheck=5Fchurn=20self-deadlock=20?= =?UTF-8?q?=E2=80=94=20remove=20redundant=20known=5Flock=20nesting?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit on_departure() holds known_lock when calling _check_churn(). When churn threshold is hit, the nested `with known_lock:` inside _check_churn tried to reacquire an already-held non-reentrant lock → permanent deadlock. This killed the production process on the OPi Zero 3 after ~15 hours of runtime on 2026-04-12 at ~02:12 UTC. infrastructure_ips.add() is safe without the inner lock since the caller already holds known_lock. Also: reset _churn_tracker between tests to prevent cross-test state accumulation that triggered the churn threshold in test isolation. --- net_alerter/net_alerter.py | 3 +-- net_alerter/test_net_alerter.py | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/net_alerter/net_alerter.py b/net_alerter/net_alerter.py index d9eb169..6f79466 100644 --- a/net_alerter/net_alerter.py +++ b/net_alerter/net_alerter.py @@ -151,8 +151,7 @@ def _check_churn(mac: str, ip: str) -> bool: events.append(now) _churn_tracker[mac] = events if len(events) >= CHURN_THRESHOLD: - with known_lock: - infrastructure_ips.add(ip) + infrastructure_ips.add(ip) logging.info(f"Churn suppression: {ip} (MAC:{mac}) cycled {len(events)}x in {CHURN_WINDOW_SEC//60}min — auto-added to infrastructure") return True return False diff --git a/net_alerter/test_net_alerter.py b/net_alerter/test_net_alerter.py index 3d4741e..bebd48f 100644 --- a/net_alerter/test_net_alerter.py +++ b/net_alerter/test_net_alerter.py @@ -39,6 +39,7 @@ def cleanup_after_each_test(): net_alerter.departure_timers.clear() net_alerter.known_devices.clear() net_alerter.last_departed_time.clear() + net_alerter._churn_tracker.clear() cleanup_flap_state() # Force garbage collection to ensure threads are cleaned up import gc