Fix V2 race conditions, auth gaps, serialization bugs, and async stats
Phase 1 - Critical Fixes: - Add game_lock (asyncio.Lock) to Room class for serializing mutations - Wrap all game action handlers in lock to prevent race conditions - Split Card.to_dict into to_dict (full data) and to_client_dict (hidden) - Fix CardState.from_dict to handle missing rank/suit gracefully - Fix GameOptions reconstruction in recovery_service (dict -> object) - Extend state cache TTL from 4h to 24h, add touch_game method Phase 2 - Security: - Add optional WebSocket authentication via token query param - Use authenticated user ID/name when available - Add auth support to spectator WebSocket endpoint Phase 3 - Performance: - Make stats processing async (fire-and-forget) to avoid blocking game completion notifications Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -11,6 +11,7 @@ A Room contains:
|
||||
- Settings for number of decks, rounds, etc.
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import random
|
||||
import string
|
||||
from dataclasses import dataclass, field
|
||||
@@ -57,6 +58,7 @@ class Room:
|
||||
game: The Game instance containing actual game state.
|
||||
settings: Room settings (decks, rounds, etc.).
|
||||
game_log_id: SQLite log ID for analytics (if logging enabled).
|
||||
game_lock: asyncio.Lock for serializing game mutations to prevent race conditions.
|
||||
"""
|
||||
|
||||
code: str
|
||||
@@ -64,6 +66,7 @@ class Room:
|
||||
game: Game = field(default_factory=Game)
|
||||
settings: dict = field(default_factory=lambda: {"decks": 1, "rounds": 1})
|
||||
game_log_id: Optional[str] = None
|
||||
game_lock: asyncio.Lock = field(default_factory=asyncio.Lock)
|
||||
|
||||
def add_player(
|
||||
self,
|
||||
|
||||
Reference in New Issue
Block a user