From 6d04bd201319fc311de6bacc9f8ef57c2dfa7624 Mon Sep 17 00:00:00 2001 From: JianFeeeee Date: Sat, 24 Oct 2026 14:37:51 +0800 Subject: [PATCH] =?UTF-8?q?ci(race):=20ID:17=20=E6=92=A4=20WEBUI-GZIP-RACE?= =?UTF-8?q?=20=E6=8E=92=E9=99=A4=E9=A1=B9=20+=20=E5=88=A0=E8=AF=81?= =?UTF-8?q?=E6=8D=AE=E6=AD=A5=E2=91=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 前置已满足:7457b05 已合入主干(merge-base --is-ancestor 实测 exit=0), webui 的 gzip 竞争按「单写者模型」修掉,该用例不必再从 -race 门里排除。 两处改动(按内容特征定位): · 删排除表里 test|internal/plugins/webui|TestOpenAIStreamIsActuallyStreaming 那一行(修复单 WEBUI-GZIP-RACE)——该用例回到主 go test -race 门里跑; · 删证据步骤①(echo 到其唯一那条 ::error)及其配套注释。 KERNEL-REGISTRY-SETLOCK 那一行原位未动,证据步②照旧保留。 证据步①为何连带删除而不是改写:7457b05 没给 gzip.go 加锁,原静态判据 sync_fields/lock_calls 两值恒为 0(断言是"非 0 才报红"),判据永不触发, 该证据从此只会假绿——留着比删掉更坏。 不含可选改法(把步①判据换成「跑 -race 5 次,0 条 DATA RACE」), 理由:奇偶概率不当代判据。实测该用例 -race 单跑 5 次均 0 条 WARNING: DATA RACE, 但用例本身未正常退出(SIGQUIT / signal arrived during execution,退出码非 0), "0 条报告"既不能证明无竞争,也不能当通过依据;排除项已删、用例已回主门后, 再单留一次"跑 N 次 0 条"等于把本案刚清掉的坏判据换个地方再种一遍。 Co-authored-by: pi --- .github/workflows/ci.yml | 43 ++++++++++++++-------------------------- 1 file changed, 15 insertions(+), 28 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f0a75968..b58d885b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -236,7 +236,6 @@ jobs: set -euo pipefail # 列名:粒度|目标|原因|修复单号 (用 | 分隔,原因内可含空格) read -r -d '' TABLE <<'EOF' || true - test|internal/plugins/webui|TestOpenAIStreamIsActuallyStreaming|gzipResponseWriter 的 mode/wroteHeader/buf 无锁;handler goroutine(发 finish/[DONE])与增量写 goroutine 并发写同一 ResponseWriter(gzip.go:139 读 mode vs gzip.go:206 写 mode)|WEBUI-GZIP-RACE pkg|internal/kernelmod/all|*(整包)|该包把真实整机装起来(bootgraph_test.go 的整机判据) ⇒ 第 4 层 agent 与 plugin-host 并行 Init 时,双方都无锁直写同一 plugin.Registry 的 7 个 Set*(SetLuaVM/SetBaseAPIKey/SetSupervisor/SetTracker/SetConfig/SetStageHost/SetIndexer,registry.go:231-284)。竞争在**内核装配**里,不在本包代码里;任何装整机的用例都会撞上。★ 目标包随 ID:13 迁到此(原 internal/kernelboot/modules 已删)|KERNEL-REGISTRY-SETLOCK EOF @@ -330,38 +329,26 @@ jobs: # ── 证据步骤:把"已知红"变成每次 CI 都可核对的数字 ── # # ★ 这里**不用 continue-on-error 混过去**(那是"假装没红")。 - # 做法相反:显式断言两件事都成立,任一不成立 ⇒ 这一步**真红**: - # ① webui 那条竞争**确实还在**(报告数 > 0)—— 证明排除表没白排除 - # ② 内核那 7 个 Set* **确实还无锁**(栈里出现 registry.go 的 Set*) - # 修好之后这两条会自然失败,提醒去删排除表 —— 这是**期望的**失败, + # 做法相反:显式断言这件事成立,不成立 ⇒ 这一步**真红**: + # 内核那 7 个 Set* **确实还无锁**(形态仍是单行直写) + # 修好之后这条会自然失败,提醒去删排除表 —— 这是**期望的**失败, # 报错信息里直接写了该做什么。 + # (webui 那条排除项已于 2026-10-24 撤除:7457b05 改成 w 单写者模型, + # 没给 gzip.go 加锁 ⇒ 原静态判据 sync_fields/lock_calls 两值恒为 0, + # 判据永不触发,该证据从此只会假绿 ⇒ 故连同排除行一并删除。) + # 撤除时本地核对(原文,不作为判据):该用例在 -race 下单跑 5 次, + # 均 0 条 WARNING: DATA RACE 报告;但用例本身未正常退出 + # (SIGQUIT: quit / signal arrived during execution,耗时 11~30s, + # 退出码非 0),故此数据不能当"已修"的证据。 + # ★ 不留"跑 5 次 0 条 DATA RACE"这类替代证据步骤:排除项已删、 + # 该用例已回到主 go test -race 门里跑,再单独留一次"跑 N 次 0 条" + # 等于拿偶发概率充判据——正是本次撤除要清掉的坏判据,换个地方 + # 再种一遍没有意义。 - name: 已知红的可核对证据(修好后本步会红,提醒删排除项) run: | set -uo pipefail fail=0 - echo "=== ① webui: gzipResponseWriter 无锁并发写(修复单 WEBUI-GZIP-RACE)===" - # - # ★ 同样**不**赌竞争必现:实测该竞争单跑 3/8 命中(偶发), - # 拿"报告数>0"当断言会在没撞上的那 5 次假绿。 - # 改成**静态断言**:struct 无 sync 字段 且 commit 不取锁 ⇒ 无锁仍在。 - # 修好(加锁)后两条件之一变化 ⇒ 本条失败 ⇒ 提醒删排除表。 - GZ=internal/plugins/webui/gzip.go - sync_fields=$(awk '/type gzipResponseWriter struct/,/^}/' "$GZ" | grep -c 'sync\.' || true) - lock_calls=$(awk '/func \(g \*gzipResponseWriter\) commit\(/,/^}/' "$GZ" \ - | grep -cE '\.Lock\(\)|\.RLock\(\)' || true) - echo " gzipResponseWriter 的 sync 字段数: $sync_fields" - echo " commit() 内的加锁调用数: $lock_calls" - if [ "$sync_fields" -ne 0 ] || [ "$lock_calls" -ne 0 ]; then - echo "::error title=webui gzip 竞争可能已修::WEBUI-GZIP-RACE 的锁已补(sync字段=$sync_fields 加锁=$lock_calls)—— 请从 ci.yml 排除表删掉该行,并删掉本证据步骤" - fail=1 - fi - - # 附:顺带跑一次,把当前是否撞上记进日志(**不作为判据**) - out=$(go test -race ./internal/plugins/webui/ \ - -run 'TestOpenAIStreamIsActuallyStreaming' -count=1 -timeout 5m 2>&1 || true) - echo " (参考)本次 DATA RACE 报告数: $(echo "$out" | grep -c 'WARNING: DATA RACE')(偶发,0 不代表已修)" - echo "=== ② kernel: agent↔plugin-host 无锁直写 plugin.Registry(修复单 KERNEL-REGISTRY-SETLOCK)===" # # ★ 这里**不跑**偶发竞争来当证据 —— 实测该竞争单步跑 6/6 次撞不到 @@ -389,7 +376,7 @@ jobs: if [ "$fail" -ne 0 ]; then exit 1 fi - echo " 证据核对完成:两个排除项对应的缺陷均仍在(排除表有效)" + echo " 证据核对完成:排除项对应的缺陷仍在(排除表有效)" # ── 交叉编译:可在无 cgo 下构建的客户端/工具 ── #