amoxic opened a new issue, #3245:
URL: https://github.com/apache/brpc/issues/3245
**Describe the bug**
在服务端处理带 stream 的 RPC 时,如果 handler 中调用了 `brpc::StreamAccept()`,但在 brpc 发送 RPC
response 并绑定 stream 到 host socket 之前,对端连接刚好断开,那么
`Socket::AddStream()` 会返回失败,随后 `Stream::SetHostSocket()` 触发
`CHECK(false)`,直接导致进程 abort。
相关调用链:
`SendRpcResponse() -> Stream::SetHostSocket() -> Socket::AddStream() ->
CHECK(false)`
fatal 日志类似:
`stream.cpp:648 Check failed: false <stream_id> fail to add stream to host
socket`
**To Reproduce**
一个通用场景如下:
1. 服务端收到一个带 remote stream 的请求
2. handler 中调用 `brpc::StreamAccept(...)`
3. handler 正常返回
4. 在 `StreamAccept()` 成功之后、`SendRpcResponse()` 执行之前,对端关闭连接或底层 TCP reset
5. 服务端在 `Stream::SetHostSocket()` 中崩溃
最小化代码形态大致如下:
```cpp
void Foo(::google::protobuf::RpcController* controller,
const Request* req,
Response* res,
::google::protobuf::Closure* done) {
brpc::ClosureGuard done_guard(done);
auto* cntl = static_cast<brpc::Controller*>(controller);
brpc::StreamId stream_id;
brpc::StreamOptions opt;
opt.handler = &handler;
if (brpc::StreamAccept(&stream_id, *cntl, &opt) != 0) {
cntl->SetFailed("StreamAccept failed");
return;
}
res->set_ok(true);
}
这个问题更容易在网络抖动、连接被主动 reset、或者对端反复重连时触发。
**Expected behavior**
这类情况应该被当作一个可恢复的连接失败处理:
- 当前 stream / 当前 RPC 失败
- 服务端进程继续运行
而不是因为 CHECK(false) 直接崩溃整个进程。
**Versions**
OS: Rocky 9.6
Compiler: g++ (GCC) 12.2.1
brpc: 1.16
protobuf:
**Additional context/screenshots**
从源码看,Socket::AddStream() 在 socket 已 failed 时返回 -1,这更像是一个运行期边界条件,而不是必须用
CHECK(false) 处理的“不可能事件”。
想确认一下,社区是否接受把这里改为普通错误返回/失败清理,而不是直接 abort?
--
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]