Skip to content

brpc socket极端场景下修改完version但是没有启动health check,导致socket无法建立新连接 #3058

Description

@howzi

Describe the bug
参考#1773
#1817 中的改动。
其中引入的_hc_started会导致极端情况下,跳过一次health check。

Image 具体的问题和#1773中的一样,revive在1处恢复了`_versioned_ref`的version,如果在2之前切出去 Image 这时候SetFailed再次更新了`_versioned_ref`的version(+1),并进入到了OnFailed中 Image 这时候上一个HC还没结束,`_hc_started`变更失败并跳过了触发健康检查,那么`_versioned_ref`就永远也没法恢复了。

To Reproduce
和#1773一样,这里复制下

可以使用brpc example里面的client server测试例子,将上图中1,2之间加一个bthread_usleep(10000*1000) -> sleep 10s模拟两个操作之间pthread被切走的情况,然后

./server
./client
restart server 为了触发client端第一个SetFailed进入健康检查并进入到Socket::Revive 1的位置(cas成功之后)开始sleep
restart server 在sleep完成之前,为了触发client端第二个SetFailed并且没有把socket refcount-1
就可以稳定复现该问题

Expected behavior

Versions
所有

Additional context/screenshots

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions