35 lines
950 B
Python
35 lines
950 B
Python
"""
|
|
事件纲要生成进度广播 — 供 NDJSON 订阅端与后台流水线共享。
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import asyncio
|
|
from typing import Any, AsyncIterator, Dict, List
|
|
|
|
_subscribers: Dict[str, List[asyncio.Queue]] = {}
|
|
|
|
|
|
def emit(book_id: str, event: Dict[str, Any]) -> None:
|
|
for q in list(_subscribers.get(book_id, [])):
|
|
try:
|
|
q.put_nowait(event)
|
|
except asyncio.QueueFull:
|
|
pass
|
|
|
|
|
|
async def subscribe(book_id: str) -> AsyncIterator[Dict[str, Any]]:
|
|
q: asyncio.Queue = asyncio.Queue(maxsize=128)
|
|
_subscribers.setdefault(book_id, []).append(q)
|
|
try:
|
|
while True:
|
|
item = await q.get()
|
|
yield item
|
|
if item.get("type") in ("done", "error"):
|
|
break
|
|
finally:
|
|
subs = _subscribers.get(book_id, [])
|
|
if q in subs:
|
|
subs.remove(q)
|
|
if not subs:
|
|
_subscribers.pop(book_id, None)
|