fix: 修复流式 handler 中途抛异常时 end/error 消息错位的问题

_dispatch 处理生成器(yield)handler 时之前用 try/finally 包裹迭代,
导致中途抛异常时会先发一条 end、再发一条 error。Go 侧 invokeStreamOut
读到第一条终止消息(end)就直接返回并把连接标记健康放回池子,遗留的
error 消息留在 socket 里,会被下一个复用该连接的调用错误地当成自己的
响应读走,造成两次完全不相关的调用结果串号。

改成不用 finally,只在生成器正常耗尽后发送一次 end;异常直接交给外层
统一处理发送 error,保证一次调用只产生一条终止消息。

新增 pool_test.go 里的 TestStreamErrorMidwayCorruptsNextCall 复现并验证修复。
This commit is contained in:
2026-07-23 13:44:45 +08:00
parent 0f4a4ded53
commit 983d106166
3 changed files with 52 additions and 5 deletions
+8
View File
@@ -51,6 +51,14 @@ def double_stream(numbers: Iterator[int]) -> Iterator[int]:
yield n * n
@expose
def stream_then_raise(n: int) -> Iterator[int]:
"""流式输出中途抛异常,用于复现 _dispatch 里 end/error 消息错位的问题"""
for i in range(n):
yield i
raise ValueError("boom: stream_then_raise 中途失败")
# ── structdataclass / dict)类型 ───────────────────────────────────────────