Reduce departure latency from 30min worst-case to 6min
Watchdog timeout and departure debounce were both 900s — stacked, worst-case VACANT alert was 30 minutes after leaving. With active ARP scanning every 30s we can confirm absence quickly, so both timers drop to 180s. Override via NET_ALERTER_WATCHDOG_TIMEOUT and NET_ALERTER_DEPARTURE_DEBOUNCE env vars.
This commit is contained in:
@@ -83,7 +83,8 @@ _churn_tracker = {} # {mac: [timestamps of departure events]}
|
|||||||
_churn_lock = threading.Lock()
|
_churn_lock = threading.Lock()
|
||||||
CHURN_THRESHOLD = 3 # cycles in window before suppression
|
CHURN_THRESHOLD = 3 # cycles in window before suppression
|
||||||
CHURN_WINDOW_SEC = 1800 # 30 minutes
|
CHURN_WINDOW_SEC = 1800 # 30 minutes
|
||||||
WATCHDOG_TIMEOUT_SEC = int(os.getenv("NET_ALERTER_WATCHDOG_TIMEOUT", "900"))
|
WATCHDOG_TIMEOUT_SEC = int(os.getenv("NET_ALERTER_WATCHDOG_TIMEOUT", "180"))
|
||||||
|
DEPARTURE_DEBOUNCE_SEC = int(os.getenv("NET_ALERTER_DEPARTURE_DEBOUNCE", "180"))
|
||||||
|
|
||||||
# Mobile device OUI prefixes for personal device detection
|
# Mobile device OUI prefixes for personal device detection
|
||||||
MOBILE_DEVICE_OUIS = {
|
MOBILE_DEVICE_OUIS = {
|
||||||
@@ -1142,8 +1143,8 @@ def on_arrival(mac: str, ip: str, hostname: str = "") -> None:
|
|||||||
|
|
||||||
def on_departure(mac: str) -> None:
|
def on_departure(mac: str) -> None:
|
||||||
"""
|
"""
|
||||||
Handle device departure with 15-minute debounce.
|
Handle device departure with debounce.
|
||||||
Only sends alert if device still gone after 15 min.
|
Only sends alert if device still gone after DEPARTURE_DEBOUNCE_SEC.
|
||||||
"""
|
"""
|
||||||
with known_lock:
|
with known_lock:
|
||||||
if mac not in known_devices:
|
if mac not in known_devices:
|
||||||
@@ -1175,7 +1176,7 @@ def on_departure(mac: str) -> None:
|
|||||||
known_devices[mac]['departing'] = True
|
known_devices[mac]['departing'] = True
|
||||||
known_devices[mac]['depart_initiated'] = time.time()
|
known_devices[mac]['depart_initiated'] = time.time()
|
||||||
|
|
||||||
# Start 15-minute debounce timer
|
# Start departure debounce timer
|
||||||
# Extract timer to cancel outside of lock to avoid deadlock
|
# Extract timer to cancel outside of lock to avoid deadlock
|
||||||
timer_to_cancel = None
|
timer_to_cancel = None
|
||||||
with departure_lock:
|
with departure_lock:
|
||||||
@@ -1211,13 +1212,13 @@ def on_departure(mac: str) -> None:
|
|||||||
logging.info(msg)
|
logging.info(msg)
|
||||||
send_alert(msg)
|
send_alert(msg)
|
||||||
|
|
||||||
timer = threading.Timer(900.0, send_departure_alert) # 15 min = 900 sec
|
timer = threading.Timer(float(DEPARTURE_DEBOUNCE_SEC), send_departure_alert)
|
||||||
timer.daemon = True
|
timer.daemon = True
|
||||||
timer.name = f'departure-debounce-{mac}'
|
timer.name = f'departure-debounce-{mac}'
|
||||||
departure_timers[mac] = timer
|
departure_timers[mac] = timer
|
||||||
timer.start()
|
timer.start()
|
||||||
|
|
||||||
logging.debug(f"Departure debounce started for {mac}, will alert in 15 min if still gone")
|
logging.debug(f"Departure debounce started for {mac}, will alert in {DEPARTURE_DEBOUNCE_SEC}s if still gone")
|
||||||
|
|
||||||
|
|
||||||
def get_primary_interface() -> str:
|
def get_primary_interface() -> str:
|
||||||
|
|||||||
Reference in New Issue
Block a user