DEBUG.WIKI
京东云;让 AI 进入真实业务;零售 · 物流 · 客服 · 硬件;查看方案 →
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国
Evoxt;最高 6.0GHz CPU;高频云服务器 · 免费每周备份;查看配置 →

RealtimeSession.close 抛异常后 async for 不退出,关闭流程该如何收尾

一个任务负责关闭 Realtime 会话,另一个任务还在 async for 中接收事件。关闭任务已经报错,消费任务却一直等,进程停不下来。这种现象要检查事件队列的结束通知,而不只是 WebSocket 有没有重连成功。

RealtimeSession.close 抛异常后 async for 不退出,关闭流程该如何收尾

一个任务负责关闭 Realtime 会话,另一个任务还在 async for 中接收事件。关闭任务已经报错,消费任务却一直等,进程停不下来。这种现象要检查事件队列的结束通知,而不只是 WebSocket 有没有重连成功。

一个已修复的关闭失败路径

Agents SDK #5070 给出了不联网复现:让测试模型的 close 抛出异常,观察事件消费者是否退出。报告涉及 v0.22.2 和 main 9f6f6b10。

旧实现已经停止接收新事件,但底层 close 失败后,等待队列的消费者没有得到结束信号,于是继续等待永远不会到来的事件。示例中的 close failed 是人为注入的测试错误文本,实际网络关闭失败可以有别的消息。

#5172 于 2026 年 9 月 25 日合并:关闭开始时唤醒读者,已缓存事件可以被消费完,之后迭代结束。底层清理失败仍会返回给关闭调用者,并保留重试机会。

应用需要区分两个结果

“事件消费者已经结束”和“模型连接已经成功关闭”要分别记录。修复后前者可以完成,而后者仍可能失败。不要在看到 async for 退出后,就把关闭异常当作无关日志丢掉。

升级到包含修复的版本是首选。无法马上升级时,可以由创建消费任务的上层代码负责有界等待;关闭失败后取消并等待消费任务退出,同时处理实际传输资源的清理。避免只调用 cancel 而不等待任务完成,也不要静默忽略所有 CancelledError 以外的清理异常。

建议保留的回归场景

用官方 ScriptedRealtimeModel 的关闭错误注入能力,可以离线验证:

  1. close 的调用者仍能收到清理错误
  2. 等待事件的消费者能在限定时间内退出
  3. 关闭前排队的事件按预期处理
  4. 两个消费者并存时,都不会留在等待状态
  5. 再次尝试 close 时,仍有机会清理底层模型

这组断言能覆盖“关闭报错但应用仍可有序停止”的需求。PR 合并时间不等于首次发布版本,选定 SDK 后还应核对变更记录并重跑自己的并发测试。