import asyncio from typing import Any from fastapi import WebSocket from core.logger import logger class ConnectionManager: def __init__(self): self._connections: set[WebSocket] = set() self._lock = asyncio.Lock() async def connect(self, websocket: WebSocket) -> None: await websocket.accept() async with self._lock: self._connections.add(websocket) async def disconnect(self, websocket: WebSocket) -> None: async with self._lock: self._connections.discard(websocket) async def send_json(self, websocket: WebSocket, payload: dict[str, Any]) -> None: await websocket.send_json(payload) async def broadcast(self, payload: dict[str, Any]) -> None: async with self._lock: connections = list(self._connections) stale_connections: list[WebSocket] = [] for connection in connections: try: await connection.send_json(payload) except Exception as exc: logger.warning(f"WebSocket broadcast failed: {exc}") stale_connections.append(connection) if stale_connections: async with self._lock: for connection in stale_connections: self._connections.discard(connection) manager = ConnectionManager()