Manages client connections and activity tracking
| 72 | del self.buffer[seq] |
| 73 | |
| 74 | class ClientManager: |
| 75 | """Manages client connections and activity tracking""" |
| 76 | |
| 77 | def __init__(self): |
| 78 | self.last_activity = {} # Maps client IPs to last activity timestamp |
| 79 | self.lock = threading.Lock() |
| 80 | |
| 81 | def record_activity(self, client_ip: str): |
| 82 | """Record client activity timestamp""" |
| 83 | with self.lock: |
| 84 | prev_time = self.last_activity.get(client_ip) |
| 85 | current_time = time.time() |
| 86 | self.last_activity[client_ip] = current_time |
| 87 | if not prev_time: |
| 88 | logging.info(f"New client connected: {client_ip}") |
| 89 | else: |
| 90 | logging.debug(f"Client activity: {client_ip}") |
| 91 | |
| 92 | def cleanup_inactive(self, timeout: float) -> bool: |
| 93 | """Remove inactive clients""" |
| 94 | now = time.time() |
| 95 | with self.lock: |
| 96 | active_clients = { |
| 97 | ip: last_time |
| 98 | for ip, last_time in self.last_activity.items() |
| 99 | if (now - last_time) < timeout |
| 100 | } |
| 101 | |
| 102 | removed = set(self.last_activity.keys()) - set(active_clients.keys()) |
| 103 | if removed: |
| 104 | for ip in removed: |
| 105 | inactive_time = now - self.last_activity[ip] |
| 106 | logging.warning(f"Client {ip} inactive for {inactive_time:.1f}s, removing") |
| 107 | |
| 108 | self.last_activity = active_clients |
| 109 | if active_clients: |
| 110 | oldest = min(now - t for t in active_clients.values()) |
| 111 | logging.debug(f"Active clients: {len(active_clients)}, oldest activity: {oldest:.1f}s ago") |
| 112 | |
| 113 | return len(active_clients) == 0 |
| 114 | |
| 115 | class StreamManager: |
| 116 | """ |