whoops (#1271)
This commit is contained in:
+3
-5
@@ -2054,11 +2054,9 @@ async def process_match_summaries(new_games: List[Dict[str, Any]]) -> None:
|
||||
# Load replay JSON
|
||||
replay_path = replay_data_path(session_id)
|
||||
try:
|
||||
async with aiofiles.open(replay_path, "r", encoding="utf-8") as f:
|
||||
replay_data = json.loads(await f.read())
|
||||
except FileNotFoundError:
|
||||
continue
|
||||
except json.JSONDecodeError:
|
||||
raw = await asyncio.to_thread(replay_path.read_bytes)
|
||||
replay_data = json.loads(gzip.decompress(raw))
|
||||
except (FileNotFoundError, OSError, json.JSONDecodeError):
|
||||
continue
|
||||
|
||||
# Translate vehicle names & sanitize
|
||||
|
||||
@@ -16,6 +16,7 @@ import asyncio
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import time
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
from urllib.parse import quote
|
||||
@@ -205,6 +206,7 @@ async def publish_replay_batch(replays: list[dict[str, Any]]) -> None:
|
||||
"type": "spectra.replay_batch",
|
||||
"version": 1,
|
||||
"source": "srebot",
|
||||
"sent_at": time.time(),
|
||||
"payload": {"replays": replays},
|
||||
}
|
||||
await _append_external_envelope(envelope)
|
||||
@@ -216,6 +218,7 @@ async def publish_event(event_type: str, payload: dict[str, Any]) -> None:
|
||||
"type": event_type,
|
||||
"version": 1,
|
||||
"source": "srebot",
|
||||
"sent_at": time.time(),
|
||||
"payload": payload,
|
||||
}
|
||||
await _append_external_envelope(envelope)
|
||||
|
||||
@@ -20,6 +20,7 @@ from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
import aiohttp
|
||||
import zstandard as zstd
|
||||
from aiohttp import web
|
||||
from dotenv import load_dotenv
|
||||
|
||||
@@ -73,6 +74,8 @@ HOP_BY_HOP_HEADERS = {
|
||||
CONNECTED_WEBSOCKETS: set[web.WebSocketResponse] = set()
|
||||
CONNECTED_LOCK = asyncio.Lock()
|
||||
|
||||
_compressor = zstd.ZstdCompressor(level=3)
|
||||
|
||||
|
||||
def _auth_ok(request: web.Request) -> bool:
|
||||
if not SETTINGS.bearer_token:
|
||||
@@ -201,7 +204,8 @@ async def websocket_handler(request: web.Request) -> web.WebSocketResponse:
|
||||
|
||||
|
||||
async def _broadcast(envelope: dict[str, Any]) -> None:
|
||||
serialized = json.dumps(envelope, ensure_ascii=False, separators=(",", ":"))
|
||||
raw = json.dumps(envelope, ensure_ascii=False, separators=(",", ":")).encode("utf-8")
|
||||
payload = _compressor.compress(raw)
|
||||
async with CONNECTED_LOCK:
|
||||
targets = list(CONNECTED_WEBSOCKETS)
|
||||
|
||||
@@ -215,7 +219,7 @@ async def _broadcast(envelope: dict[str, Any]) -> None:
|
||||
dead: list[web.WebSocketResponse] = []
|
||||
for ws in targets:
|
||||
try:
|
||||
await ws.send_str(serialized)
|
||||
await ws.send_bytes(payload)
|
||||
except Exception as exc:
|
||||
logger.warning(
|
||||
"Failed to send websocket envelope",
|
||||
@@ -233,6 +237,8 @@ async def _broadcast(envelope: dict[str, Any]) -> None:
|
||||
extra={
|
||||
"event_type": envelope.get("type"),
|
||||
"clients": len(targets) - len(dead),
|
||||
"raw_bytes": len(raw),
|
||||
"compressed_bytes": len(payload),
|
||||
"payload_keys": list((envelope.get("payload") or {}).keys())[:8],
|
||||
},
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user