create: Checkpoint 2026-09-30 04:37:44 UTC [cea96f7c13]
MemRelay-Operation: checkpoint-save:issue3-rootcause-diag-20260930-1235 MemRelay-Resource: 7fd55d99-e2fa-4f59-b963-2b14d5e592b7
This commit is contained in:
+45
@@ -0,0 +1,45 @@
|
||||
---
|
||||
title: Checkpoint 2026-09-30 04:37:44 UTC [cea96f7c13]
|
||||
type: checkpoint
|
||||
permalink: main/projects/25464650-ed5d-440e-b362-190f2852d451/checkpoint-2026-09-30-04-37-44-utc-cea96f7c13
|
||||
stable_id: 7fd55d99-e2fa-4f59-b963-2b14d5e592b7
|
||||
scope: project
|
||||
memory_type: checkpoint
|
||||
project_id: 25464650-ed5d-440e-b362-190f2852d451
|
||||
usage_profile_id: 0c9feb46-d06e-43cd-9ef0-c5813c84a998
|
||||
status: active
|
||||
revision: 1
|
||||
request_id: issue3-rootcause-diag-20260930-1235
|
||||
created_at: '2026-09-30T04:37:44.082486+00:00'
|
||||
updated_at: '2026-09-30T04:37:44.082486+00:00'
|
||||
tags:
|
||||
- issue-3
|
||||
- diagnosis
|
||||
---
|
||||
|
||||
# 检查点:issue #3 根因已实证(不是服务端死锁)
|
||||
|
||||
基线 main 4059a15。诊断工作树 E:\code\NixMsg-wt\diag3(分支 diag/issue3-scratch,仅本地,完成后删除)。
|
||||
|
||||
## 结论
|
||||
TestUplinkDMOfflineGroupRecall 等"resp 回不来"是测试用 WebSocket 客户端 test/harness/mqtt.go 的两个缺陷,不是服务端死锁:
|
||||
1. wsMQTT.Recv 把一个 WS 二进制帧当作恰好一个 MQTT 包;mochi 在 outbound 有积压时把多个包放进 outbuf 一次 Write,合成一个 WS 帧(MQTT5 §6 [MQTT-6.0.0-3] 允许)。客户端只解第一个包。实证日志:`WS frame carries 3 MQTT packets: [group_event group_event resp/rid=g1]` 随后 `timeout waiting resp rid=g1`。通过的轮次里也在丢 receipt/group_event。
|
||||
2. wsMQTT.Send / writeWSClientFrame 帧头和载荷分两次 Write、无锁;读循环回 PUBACK 与测试线程发请求并发时交错,把发往服务端的 WS 流写乱,服务端卡在读一个错乱长度的包(无报错日志)。
|
||||
|
||||
## 对照实验(同步 emit,无 20ms sleep)
|
||||
- 原客户端:6 次 1 失败(合帧含 resp)。
|
||||
- 只修接收按字节流拆包:20 次 2 失败(g1、s4,无服务端报错)。
|
||||
- 再修发送加锁+整帧一次写:20/20 通过(125 个合包帧正确拆开);cmd/nixmsg、test/accept、group、broker 全绿。
|
||||
|
||||
## 解决方向
|
||||
- 修 test/harness/mqtt.go:Recv 按字节流缓冲拆包(含 continuation 帧);Send/PONG 加互斥锁并整帧一次 Write。
|
||||
- 修好后删除 internal/app/group/app.go emit 的 goroutine+20ms sleep,改回同步下发。
|
||||
- 不要合入 E:\code\NixMsg-wt\fix3 的 broker 改动(基于错误假设,改变 PUBACK 时序)。
|
||||
- 更正 docs/DEVIATIONS.md 「死锁未修(issue #3)」与 Q accept-rest 第 3/4 条的错误结论。
|
||||
|
||||
## 另发现的真实隐患(待入 issue)
|
||||
- mochi v2.7.9(最新版)inflight.go NextImmediate 先 RLock 再调 GetAll 又 RLock,递归读锁;server.go processPacket 719-728 在 sendQuota>0 且 inflight 非空时调用。客户端带 ReceiveMaximum(SDK 可能带)时,与 publishToClient 的 Inflight.Set 写锁排队可永久互等,卡死该连接读循环及所有向其下发的 goroutine(含 messageLoops)。测试客户端不带 ReceiveMaximum 所以没触发。
|
||||
- identity lifecycle.go 有 kickFlushDelay=20ms sleep(fix #4 引入),待审。
|
||||
|
||||
## 下一步
|
||||
全量审查 + 写 issue(含不冲突的解决方案与并行分组),交负责人审核后由 Grok 团队修。
|
||||
Reference in New Issue
Block a user