(request)
| 265 | |
| 266 | @routes.get('/ws') |
| 267 | async def websocket_handler(request): |
| 268 | ws = web.WebSocketResponse() |
| 269 | await ws.prepare(request) |
| 270 | sid = request.rel_url.query.get('clientId', '') |
| 271 | if sid: |
| 272 | # Reusing existing session, remove old |
| 273 | self.sockets.pop(sid, None) |
| 274 | else: |
| 275 | sid = uuid.uuid4().hex |
| 276 | |
| 277 | # Store WebSocket for backward compatibility |
| 278 | self.sockets[sid] = ws |
| 279 | # Store metadata separately |
| 280 | self.sockets_metadata[sid] = {"feature_flags": {}} |
| 281 | |
| 282 | try: |
| 283 | # Send initial state to the new client |
| 284 | await self.send("status", {"status": self.get_queue_info(), "sid": sid}, sid) |
| 285 | # On reconnect if we are the currently executing client send the current node |
| 286 | if self.client_id == sid and self.last_node_id is not None: |
| 287 | await self.send("executing", { "node": self.last_node_id }, sid) |
| 288 | |
| 289 | # Flag to track if we've received the first message |
| 290 | first_message = True |
| 291 | |
| 292 | async for msg in ws: |
| 293 | if msg.type == aiohttp.WSMsgType.ERROR: |
| 294 | logging.warning('ws connection closed with exception %s' % ws.exception()) |
| 295 | elif msg.type == aiohttp.WSMsgType.TEXT: |
| 296 | try: |
| 297 | data = json.loads(msg.data) |
| 298 | # Check if first message is feature flags |
| 299 | if first_message and data.get("type") == "feature_flags": |
| 300 | # Store client feature flags |
| 301 | client_flags = data.get("data", {}) |
| 302 | self.sockets_metadata[sid]["feature_flags"] = client_flags |
| 303 | |
| 304 | # Send server feature flags in response |
| 305 | await self.send( |
| 306 | "feature_flags", |
| 307 | feature_flags.get_server_features(), |
| 308 | sid, |
| 309 | ) |
| 310 | |
| 311 | logging.debug( |
| 312 | f"Feature flags negotiated for client {sid}: {client_flags}" |
| 313 | ) |
| 314 | first_message = False |
| 315 | except json.JSONDecodeError: |
| 316 | logging.warning( |
| 317 | f"Invalid JSON received from client {sid}: {msg.data}" |
| 318 | ) |
| 319 | except Exception as e: |
| 320 | logging.error(f"Error processing WebSocket message: {e}") |
| 321 | finally: |
| 322 | self.sockets.pop(sid, None) |
| 323 | self.sockets_metadata.pop(sid, None) |
| 324 | return ws |
nothing calls this directly
no test coverage detected