diff --git a/src/judas_server/backend/backend_server.py b/src/judas_server/backend/backend_server.py index fac89b1..6dc5c21 100644 --- a/src/judas_server/backend/backend_server.py +++ b/src/judas_server/backend/backend_server.py @@ -28,27 +28,6 @@ class BackendServer: ) self.logger.debug("Initializing Server...") - self.known_clients: dict[str, dict[str, str | float]] = {} - try: - with open("cache/known_clients.yaml", "r") as f: - self.known_clients = ( - yaml.safe_load(f).get("known_clients", {}) or {} - ) - self.logger.debug( - f"Loaded known clients: {self.known_clients}" - ) - self.logger.info( - f"Loaded {len(self.known_clients)} known clients" - ) - except FileNotFoundError: - self.logger.warning( - "known_clients.yaml not found, creating empty known clients list" - ) - with open("cache/known_clients.yaml", "w") as f: - yaml.safe_dump({"known_clients": {}}, f) - except Exception as e: - self.logger.error(f"Error loading known clients: {e}") - self.selector = selectors.DefaultSelector() self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.server_socket.setsockopt( @@ -63,16 +42,61 @@ class BackendServer: self.clients: dict[str, Client] = {} - if self.known_clients: - for client_id in self.known_clients: + self.known_clients: dict[str, dict[str, str | float]] = ( + self._load_known_clients() + ) + + self.running: bool = False + + def _load_known_clients(self) -> dict[str, dict[str, str | float]]: + """Load the list of known clients from a YAML file and validate.""" + known_clients: dict[str, dict[str, str | float]] = {} + + try: + with open("cache/known_clients.yaml", "r") as f: + data = yaml.safe_load(f) + + if not isinstance(data, dict): + raise ValueError("YAML root must be a dict") + + known_clients = data.get("known_clients", {}) or {} + + if not isinstance(known_clients, dict): + raise ValueError("'known_clients' must be a dict") + + for client_id, client_data in known_clients.items(): + if not isinstance(client_data, dict): + raise ValueError( + f"Client {client_id} data must be a dict" + ) + last_seen = client_data.get("last_seen", 0.0) + if not isinstance(last_seen, (float, int)): + raise ValueError( + f"Client {client_id} 'last_seen' must be a float or int" + ) + + self.logger.debug(f"Loaded known clients: {known_clients}") + self.logger.info(f"Loaded {len(known_clients)} known clients") + + for client_id in known_clients: client = Client(id=client_id, addr=None, socket=None) client.status = ClientStatus.OFFLINE client.last_seen = float( - self.known_clients[client_id].get("last_seen", 0.0) + known_clients[client_id].get("last_seen", 0.0) ) self.clients[client_id] = client - self.running: bool = False + except FileNotFoundError: + self.logger.warning( + "known_clients.yaml not found, creating empty known clients list" + ) + with open("cache/known_clients.yaml", "w") as f: + yaml.safe_dump({"known_clients": {}}, f) + except Exception as e: + self.logger.error(f"Error loading known clients: {e}") + raise + + return known_clients def _save_known_clients(self) -> None: """Save the list of known clients to a YAML file."""