Describe the bug
一个猜测的时序如下
- 线程1: RPC 请求中,但是
SetFailed 发生,版本号+1
- 线程2: 过了 100ms 后,健康检查任务启动
- 线程3: EventDispatcher 上收到了这个 fd 上的
EPOLLIN | EPOLLRDHUP 事件,对端关闭了。准备遍历 epoll_event 数组,但是很不巧被 OS 调度切走了
- 线程2: 健康检查
WaitAndReset 里将 fd 关闭,并令 fd=-1. 之后探测成功,再调用 Revive 将版本号复原,但是 fd=-1
- 线程3: 执行
OnInputEvent, 因为 Revive 恢复了版本号 Address 成功,但是它检测了 s->fd() == -1 时再比较一下 events 里是否有 EPOLLIN. 但是这个 EPOLLIN 事件明显是过期的,因为之前的 fd 已经被其他原因 SetFailed
看日志表现是这样,因为日志中存在大量的 Checking ... Revived ... 健康检查相关的打印,且网络非常不稳定。
如果是这种原因的话,似乎
if (s->fd() < 0) {
#if defined(OS_LINUX)
CHECK(!(events & EPOLLIN)) << "epoll_events=" << events;
#elif defined(OS_MACOSX)
CHECK((short)events != EVFILT_READ) << "kqueue filter=" << events;
#endif
return -1;
}
中的断言可以去掉?
@chenBright
Versions
OS: openeuler 24.03sp3
Compiler: gcc14
brpc: 1.17
Additional context/screenshots
Describe the bug
一个猜测的时序如下
SetFailed发生,版本号+1EPOLLIN | EPOLLRDHUP事件,对端关闭了。准备遍历epoll_event数组,但是很不巧被 OS 调度切走了WaitAndReset里将 fd 关闭,并令fd=-1. 之后探测成功,再调用Revive将版本号复原,但是fd=-1OnInputEvent, 因为Revive恢复了版本号Address成功,但是它检测了s->fd() == -1时再比较一下 events 里是否有EPOLLIN. 但是这个EPOLLIN事件明显是过期的,因为之前的 fd 已经被其他原因SetFailed看日志表现是这样,因为日志中存在大量的
Checking ...Revived... 健康检查相关的打印,且网络非常不稳定。如果是这种原因的话,似乎
中的断言可以去掉?
@chenBright
Versions
OS: openeuler 24.03sp3
Compiler: gcc14
brpc: 1.17
Additional context/screenshots