Repository navigation
fix: 状态机停机竞速守门与回调重入会话撕裂修复 + 行为基线(#68 PR-1) - #94
Merged
Merged
Conversation
This was referenced Oct 15, 2026
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.
关闭范围:#68 的 PR-1(行为基线固定 + 排查中发现的两类独立缺陷修复)。不包含内部 Session 对象重构(后续 PR)。
修复的独立缺陷(排查 #68 时实测复现)
1. 终态竞速污染 + 空引用
Dispose与Reconnect/连接成功竞速:已通过停机检查、尚未写入State的发布线程被抢占,停机写入Disconnected后迟到的 Retry/Connected 把终态翻转(State停在 Retry/Connected)——以ConcurrentDisposeAndReconnect_TerminalInvariantsHold高频复现(首迭代即中)。_lifetimeCts空引用(!抑制挡不住竞速,NRE 实测复现)。await ConnectAsync/AcceptAsync返回后无守门,迟到发布会重建会话、socket 无人关闭泄漏到终结器。2. 回调重入会话撕裂
Reconnect():迟到发布帧的StartSession以过期编号/纪元"兜底重建"僵尸会话,其StopSessionCore会关掉新会话刚建立的 socket(编号复用 + 会话失活;ConnectedCallback_ReconnectReentry_ConvergesToUsableSession实测复现,10s 收不到消息)。修复方式(最小侵入,不重构所有权结构)
CommunicationStateChanging拆为发布段(新增_publishGate锁内:停机/过期纪元判定 + 编号纪元簿记 +State写入)与通知段(锁外回调/等待器/派发——回调可安全重入);停机后到达的非终态发布整体丢弃,终态恒为最后可见状态。Shutdown末尾关闭块共用_sessionGate,窗口闭合);_socket被新连接覆盖时旧值当场释放。_sessionGate后复查停机;令牌源已回收则放弃派发(容忍取消与回收之间的 ODE)。行为基线(
StateOwnershipBaselineTests,7 例)迟到发布确定性门控(白盒直发);回调重入收敛性(Connected 内 Reconnect:新会话可用、编号恒非零不复用、合法转移序列;Connected 内 DisposeAsync:终态干净、消息流自然结束);连接成功×停机竞速、并发 Dispose+Reconnect 终态不变量(无泄漏 socket/监听器/孤儿会话,端口可重占)。
DESIGN
新增"状态机与所有权规范"章节:状态转换全表、发布段/通知段规则、资源所有权表、锁清单、允许重入点、已知限制(拆除同步等待持锁 2s、
_socket字段语义——即 #68 后续 PR 的 Session 对象重构方向)。验证
RapidServerInitiatedReconnects_PortStaysAcceptable(自带"并行负载下偶发慢收敛"史)在高并发压力下偶发超时;压力测试迭代量收敛(25→10、15→8)后连续多轮稳定。若 CI 偶红该用例,指向已知限制①(StopSessionCore 持锁同步等待),属 PR-2 范围。