Skip to content

fix(ws): cancel native lifecycle when closed during handshake - #40

Open
JackCaow wants to merge 6 commits into
masterfrom
fix/issue-39-close-cancellation
Open

JackCaow wants to merge 6 commits into
masterfrom
fix/issue-39-close-cancellation

Conversation

@JackCaow

@JackCaow JackCaow commented Oct 14, 2026 •

Copy link
Copy Markdown
Collaborator

首次握手完成前调用 close() 时,NAPI 没有保存关闭意图,旧实例仍会建立连接并持续重连;重连握手中的关闭也可能迟到,先发送缓存并发出 Connected。

本修复从构造开始持有原生终止控制,覆盖首次握手、多端点竞速、重连握手、退避、发送/缓存重放和事件转发。关闭可重复调用,拒绝后续发送并丢弃缓存。closeAndWait() 在调用时同步记录关闭意图,再返回等待该 WS 管理器及事件转发退出的 Promise;不等待共享 DNS 后台刷新、对端确认或已排入 Node 队列的回调。包装对象释放时也请求取消。

在途发送被取消后直接丢弃连接,不再次驱动该 sink 的 Close/flush;空闲连接保留 code/reason,Close 最多等待 100ms。取消分支保留已由 recv 取出的 Close 命令,避免丢失参数。多端点握手直接持有 futures,取消竞速不留下后台握手。未改变重试计数/快速断连策略。

最终 head:314b69ab8c68898ab2a44d5cb5dc3665c500465b。默认发行构建的关闭生命周期逻辑与独立复审通过的 846ddba 相同。新增 lifecycle-test-hooks 为默认关闭的测试编译特性:在真实 Native/Reqwest 连接的 Sink 上控制 flush,Windows CI 明确等待原生 Pending,再关闭并在 10ms 后释放闸门,严格断言取消后 Sink 调用为 0、真实服务端用户数据为 0。若 Pending 未建立、取消后再 write/flush、用户数据到达服务端或测试特性缺失,测试失败;没有 Windows 跳过分支。Linux/macOS 保留默认构建的真实网络背压测试。默认插件已验证无测试挂钩导出。

验证:

  • 本机默认构建真实网络回归:12 通过、0 失败、0 跳过。
  • 本机测试特性构建受控 Pending 回归:12 通过、0 失败、0 跳过,覆盖两后端 × 原生/TS API,包含同步拒绝发送、空闲 Close 参数、首次握手、重连、重复关闭和 GC。
  • 隔离负对照:在 /tmp/catcher-gate-negative-control 恢复旧的“取消后 Close/flush”一处路径,重新构建插件;8 通过、4 失败、0 跳过,四个组合分别记录 76/74/62/55 次取消后 Sink 调用。故意破坏代码未提交或污染正式工作区。
  • pnpm typecheck、默认工作区 cargo clippy --workspace --all-targets -- -D warnings、测试特性 cargo clippy -p catcher-ws -p catcher-napi-ws --all-targets --features lifecycle-test-hooks -- -D warnings 通过。
  • cargo test -p catcher-ws -p catcher-napi-ws --lib:46 + 4 通过;最终 CI 已执行完整 Rust 工作区检查与测试。
  • 只读独立 API 脚本:四组各 200 次 closeAndWait() 后立即 send,800/800 同步拒绝、0 late 消息、0 错误 Close 帧。
  • 只读独立背压脚本:两后端关闭后 10ms/200ms 恢复读取仅收到约 1.68–1.87MB,不再收到完整 32MiB 或追加 Close。原审阅证据未修改。
  • WS 集成验证:33 通过、2 个 CI 模式弱网样例跳过。

最终 SHA CI 已完成:10/10 jobs success。Linux、macOS、Windows 三平台 WS 日志各为 12 pass、0 fail、0 skip;普通 test job 也通过。此前 482a6a7 的 Windows 8 pass/4 skipped 不作为验收结果。

本机初始全量 TS 曾有 345 通过、1 跳过、2 个 HTTP 失败。未修改基线 050b913ae80f3c77ad97b19faba8d8fd87d2368e 重建插件并匹配同一可选 https-proxy-agent 依赖后,两项均可复现:HTTP 丢包断言失败与代理 CONNECT 失败。未扩展为无关 HTTP 修复。

保持 Draft,未合并或发布。未验证已发布 1.0.0 二进制或 Intel Mac 现场根因。

Fixes #39

@JackCaow
JackCaow marked this pull request as ready for review October 14, 2026 13:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(napi-ws): 关闭丢失导致旧实例持续重连

1 participant