Vanillaxi commented on issue #3457:
URL: https://github.com/apache/dubbo-go/issues/3457#issuecomment-4825272495
目前 Dubbo-go Triple 还没有完整支持 connect-go v1.18.0 中的 non-blocking close 行为,`
receive side close `路径仍然有不必要阻塞的风险。
- `ClientStreamForClient.CloseAndReceive `会依次调用 `CloseRequest`、接收 `unary
response`、再调用 `CloseResponse`。
- `ServerStreamForClient.Close` 和 `BidiStreamForClient.CloseResponse` 最终都会走到
`conn.CloseResponse`。
- `BidiStreamForClient.CloseRequest` 最终走的是 `conn.CloseRequest`。
- `CloseRequest `当前相对安全,因为底层是`duplexHTTPCall.CloseWrite()`,主要是启动请求并关闭
`request pipe writer`。但 `CloseResponse` 目前不是非阻塞的。它最终会走到
`duplexHTTPCall.CloseRead()`,而 `CloseRead` 当前会先等待 `responseReady`,然后通过
`discard(response.Body)` 尝试 drain response body,最后再 close body。这个行为和 connect-go
#791 修复前的旧逻辑一致。虽然 discard 有 4MiB 限制,但如果对端不继续发送响应 body,仍然可能阻塞在读取 response body上。
建议方案:
1. 先补针对性的回归测试:
- server-stream:服务端发送一条消息后保持响应不结束,客户端 Receive 一条后调用 Close,断言 Close 能快速返回。
- bidi-stream:服务端提前返回或停止读取,客户端调用 CloseResponse,断言不会阻塞。
- client-stream:服务端在客户端发送完成前提前返回 error,客户端 CloseAndReceive 应能拿到错误并完成清理,不应
hang。
- 可以额外加一个 duplexHTTPCall 级别的小测试,用阻塞的 response body 验证 CloseRead 不再 drain
body。
2. 只回迁和生命周期相关的行为:
- 修改 `duplexHTTPCall.CloseRead()`,不再在 close 时 discard/drain response.Body。
- response ready 后直接关闭 response.Body。
- 保留 Receive 路径读取到 EOF 后解析 trailers 的行为。如果用户需要最终 trailers/status,应该继续
Receive 到 EOF,而不是依赖 CloseResponse 来 drain。
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]