Repository navigation
fix: 接受循环代次门控——修复重连竞速泄漏监听器(#47 阶段二)+ 长期观察基建 - #52
Merged
Merged
Conversation
竞速混沌(Soak_ReconnectRacing_LongRun,60% 动作并发竞速)复现:用户重连与 自动重连竞速产生多个并发 StartAsync 接受循环时,被取代的僵尸循环完成 accept 后看到 _server 已被新循环替换,跳过单客户端的监听器关闭——泄漏一个仍在监听 但永无人 accept 的 socket,客户端 SYN 进入无人消费的 backlog 后 ConnectAsync 永久挂起(形态为'卡死 220 秒'或终局连接拒绝,均实测捕获)。 修复:_acceptLoopId 代次(StartCore 递增);被取代的循环在取得 _acceptLock 后 静默退出,监听器的创建/关闭/accept 只归属当代循环。 随附长期观察基建: - StateTransitionRecorder:全程记录并校验状态机合法转移、非 Connected 态 编号归零(P1-1 线性化不变式)、Connected 态编号严格递增、终态收敛;统计 Connected→Connected 直连迁移(竞速观测指标) - Soak_ReconnectRacing_LongRun:重连动作高占比(40% 竞速 + 20% 纯用户重连) + 普通消息 FIFO 完整性探针 + 状态机全程校验,env 门控 - soak.yml:每夜 03:00(北京时间)600s 双平台跑浸泡套件,失败自动通知 - 楔形回归测试预算放宽(并行负载下 ~1/15 概率闪失的时序余量)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
长期观察立项后的第一轮就抓到了真 bug。
复现与根因(有完整状态轨迹证据)
新增的竞速混沌(重连动作占 60%:杀对端自动重连 + 用户
Reconnect()并发)第一轮即稳定复现两种故障形态:客户端ConnectAsync永久挂起(220 秒死寂区后由迟到的 SocketException 解锁,或直到测试超时)、终局连接被拒 60 秒。根因:用户重连与自动重连竞速产生多个并发
StartAsync接受循环时,被取代的"僵尸"循环完成 accept 后看到_server已被新循环替换成 null,跳过了 AcceptFirstClientOnly 的监听器关闭——泄漏一个"仍在监听但永无人 accept"的 socket。后续客户端的 SYN 被内核送进这个无人消费的 backlog,ConnectAsync永久挂起(比拒绝严重得多)。此前 #47 排查复现不出来的原因是强度不够(原混沌重连动作只占 3%)。修复:代次门控(原 #47 阶段二方案)
_acceptLoopId每次StartCore递增;接受循环在取得_acceptLock后校验代次,被取代者静默退出——监听器的创建/关闭/accept 只归属当代循环,僵尸循环既不能泄漏监听器、也不能以过期身份发布 Connected。修复后竞速混沌 3×15s + 60s 全过(故障前 4 次迭代即卡死,修复后 58+ 次迭代正常运转)。长期观察基建(本 PR 的另一半)
StateTransitionRecorder:全程记录状态转移并校验——合法转移边、非 Connected 态编号必须为 0(P1-1 线性化不变式的运行时验证)、Connected 态编号严格递增不复用、终态收敛;另统计 Connected→Connected 直连迁移次数(竞速观测指标,输出到测试日志);Soak_ReconnectRacing_LongRun:竞速专用长时混沌(env 门控)+ 普通消息 FIFO 完整性探针 + 上述全程校验;soak.yml:每夜北京时间 03:00 以 600 秒在 ubuntu + windows 双平台跑整个浸泡套件,失败自动通知;支持workflow_dispatch手动指定时长;测试
85×3 = 255 全绿 × 两轮。