import asyncio import json from typing import AsyncGenerator class EventBroadcaster: def __init__(self): self._queues: set[asyncio.Queue] = set() async def subscribe(self) -> AsyncGenerator[str, None]: queue: asyncio.Queue[str] = asyncio.Queue(maxsize=32) self._queues.add(queue) try: while True: try: msg = await asyncio.wait_for(queue.get(), timeout=25) yield msg except asyncio.TimeoutError: yield ": keepalive\n\n" except asyncio.CancelledError: pass finally: self._queues.discard(queue) def broadcast(self, event_type: str, data: dict | None = None) -> None: if not self._queues: return msg = f"event: {event_type}\ndata: {json.dumps(data or {})}\n\n" for queue in list(self._queues): try: queue.put_nowait(msg) except asyncio.QueueFull: pass broadcaster = EventBroadcaster()