fix additional refrerence can not release when socket is reviving#1817
Conversation
|
LGTM |
|
@wwbmmm 大概什么时候能合呢? |
|
@zyearn 麻烦看看这个pr。 |
|
@chenBright 我这两天看一下。 |
|
一个Nice To Have:这里会有2次HC,第一次HC是真正的HC,第二次HC是因为这个极端case导致的false positive(其实对端server已经恢复了),理论上只做一次HC即可。 可以不用在这个PR实现,有兴趣的话可以想想怎么解决 :) |
设个标志_is_hc_started(atomic),默认为false。hc开始的时候判断_is_hc_started.compare_exchange_strong(expect, true,butil::memory_order_relaxed),其中expect为false。如果为true,则表示无hc,可以进行hc;否则,跳过,不进行hc。当hc结束时,将_is_hc_started置为false。这样应该可以避免同时进行2次hc的问题。 |
bfc1621 to
485bbf8
Compare
485bbf8 to
ec32816
Compare
Another Nice-to-have: 有一种情况会导致2次连续(不并发)的HC:SetFailed后调度出去,另外一个线程的HC结束,然后SetFailed继续执行到StartHealthCheck。当然第二次是必要的因为第一次HC之后如果server立刻down了,这第二次HC可以检测出来,不过这个场景大概率第二次HC是成功的,因为之前紧接的第一次是成功的。 我们还可以继续优化掉这个第二次HC吗?如果发生了server在第一次HC后立刻down的情况,可以在下一次用户主动的rpc call的时候再触发HC. |
这种情况好像没有好的优化方法,此场景下的第二次SetFailed和普通场景下的SetFailed差不多。_versioned_ref的恢复需要HC,如果发生了server在第一次HC后立刻down的情况,不在这次触发HC的话,_versioned_ref就无法恢复,用户也无法address到socket,主动rpc call了。 |
是的,这是这个优化在实现上比较难的地方,先暂时放一放吧。 |
|
感谢贡献 |
fix #1773
#1774 的pr是使用了加锁的方案,该pr实现了@wwbmmm在 #1774 提到的方案:
_recycle_flag增加reviving状态。如果ReleaseAddtionalReference发现状态是reviving就一直等,直到遇到其它两个状态再继续释放additional refrerence。