fix: harden realtime pipeline lifecycle

This commit is contained in:
Xin Wang
2026-09-07 08:27:52 +08:00
parent 43f2cc445e
commit 8025ed8aa0
12 changed files with 445 additions and 42 deletions
+26 -3
View File
@@ -12,13 +12,33 @@ from loguru import logger
active_connections: set[object] = set()
pipeline_tasks: set[asyncio.Task[None]] = set()
connection_tasks: dict[object, asyncio.Task[None]] = {}
connection_cleanup_tasks: set[asyncio.Task[None]] = set()
DEFAULT_CLOSE_GRACE_SECONDS = 10.0
async def _disconnect_connection(connection: object) -> None:
"""Release media even when construction failed before transport startup."""
try:
async with asyncio.timeout(DEFAULT_CLOSE_GRACE_SECONDS):
await connection.disconnect()
except Exception as exc:
logger.warning(f"Realtime 连接清理失败: {type(exc).__name__}")
def _consume_pipeline_result(task: asyncio.Task[None], connection: object) -> None:
pipeline_tasks.discard(task)
if connection_tasks.get(connection) is task:
connection_tasks.pop(connection, None)
if connection in active_connections:
active_connections.discard(connection)
# Run after the pipeline task is done: closed handlers can safely wait
# for that task without making pipeline shutdown wait on itself.
cleanup = asyncio.create_task(
_disconnect_connection(connection),
name=f"realtime-disconnect:{getattr(connection, 'pc_id', id(connection))}",
)
connection_cleanup_tasks.add(cleanup)
cleanup.add_done_callback(connection_cleanup_tasks.discard)
try:
error = task.exception()
except asyncio.CancelledError:
@@ -86,11 +106,15 @@ async def shutdown_active_sessions(
) -> None:
connections = list(active_connections)
if connections:
active_connections.difference_update(connections)
await asyncio.gather(
*(connection.disconnect() for connection in connections),
*(_disconnect_connection(connection) for connection in connections),
return_exceptions=True,
)
active_connections.difference_update(connections)
cleanup_tasks = list(connection_cleanup_tasks)
if cleanup_tasks:
await asyncio.gather(*cleanup_tasks, return_exceptions=True)
tasks = list(pipeline_tasks)
if not tasks:
@@ -106,4 +130,3 @@ async def shutdown_active_sessions(
logger.info(
f"Realtime 会话清理完成: normal={len(done)} cancelled={len(cancelled)}"
)