JianFeeeee
f33ebee01b
test(agent/core): 消除测试对 scheduler.queue 的无锁直读,并加判据防回归
## 起因
offload_test.go 等 4 个文件里有 18 处 `len(s.queue)` / `range s.queue`,
全在锁外。当时**安全**——那些测试用 newRootWithoutSchedulerLoop,
刻意不启 schedulerLoop,所以没有并发写者。
但这个安全性 ① 不由测试自身保证,只由「别改构造函数」这个口头约定保证;
② 一旦有人换成 newRootWith 就变成真竞争,症状是「今天全绿、改一次就炸」。
先确认生产代码没问题:逐处核对 scheduler.go 里 6 个读 s.queue 的函数,
全部在 mu.Lock/RLock 内(takeQueuedInputs/hasRoom/nextRef/armStop/
pendingEvents/takeAllPendingEvents)。所以这是**测试的隐患**,不是核心缺陷。
## 改动
- scheduler.go 新增两个带锁只读访问器:
· queueLen() —— 替代 len(s.queue)
· queueSnapshot() —— 返回浅拷贝,替代 range/索引(拷贝保证 len 与
range 不会在遍历中途变化)
- 4 个测试文件 18 处直读全部改走访问器
- 新增 queue_access_test.go:AST 静态判据,扫所有 *_test.go,
同一函数内出现过 Lock/RLock 即视为持锁(Go 的 defer Unlock 静态难还原,
按函数近似足够保守);命中无锁直读即红
## 判据自检
静态判据最大的失败模式是「根本没抓到东西」,所以带双向自检:
- 正向:注入一处无锁直读 → 必须被抓到
- 反向:注入一处持锁直读 → 必须**不**被报(否则噪声大没人看)
- 真变异:把一处访问器改回 `len(s.queue)` → 红
## 验证
- go build ./... / go vet / go test ./internal/... 全绿
- go test -race ./internal/agent/core/ 无数据竞争
- 部署后:39 插件加载、3 个 multimodal 工具注册、0 panic/fatal
- graph.db integrity ok,blocks 2787 未动
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-10-06 09:22:12 +08:00
..
2026-09-19 16:49:16 +08:00
2026-09-15 07:47:16 +08:00
2026-09-11 11:45:24 +08:00
2026-10-06 09:07:18 +08:00
2026-09-27 15:15:57 +08:00
2026-09-27 16:29:24 +08:00
2026-09-27 13:40:22 +08:00
2026-09-27 13:40:22 +08:00
2026-09-15 06:32:36 +08:00
2026-10-05 11:25:20 +08:00
2026-10-05 11:25:20 +08:00
2026-09-11 11:45:24 +08:00
2026-09-13 12:23:28 +08:00
2026-10-05 11:25:20 +08:00
2026-10-05 11:25:20 +08:00
2026-10-05 11:25:20 +08:00
2026-10-06 09:07:18 +08:00
2026-08-18 09:07:21 +08:00
2026-10-05 11:25:20 +08:00
2026-10-05 11:25:20 +08:00
2026-09-13 09:06:50 +08:00
2026-09-14 23:14:38 +08:00
2026-09-13 15:41:07 +08:00
2026-09-13 15:35:59 +08:00
2026-10-05 11:25:20 +08:00
2026-09-15 09:37:29 +08:00
2026-09-15 08:13:52 +08:00
2026-09-11 13:45:25 +08:00
2026-09-11 13:45:25 +08:00
2026-09-11 11:45:24 +08:00
2026-09-13 00:25:52 +08:00
2026-10-05 11:25:20 +08:00
2026-10-05 11:25:20 +08:00
2026-09-15 08:13:52 +08:00
2026-10-05 11:25:20 +08:00
2026-09-04 06:25:51 +08:00
2026-09-04 06:25:51 +08:00
2026-10-06 09:07:18 +08:00
2026-10-06 09:22:12 +08:00
2026-09-19 17:43:16 +08:00
2026-09-13 09:13:19 +08:00
2026-09-13 16:04:16 +08:00
2026-10-05 11:25:20 +08:00
2026-10-05 11:25:20 +08:00
2026-10-05 11:25:20 +08:00
2026-09-27 11:27:24 +08:00
2026-09-12 13:57:06 +08:00
2026-09-12 13:57:06 +08:00
2026-09-19 16:49:16 +08:00
2026-10-06 09:07:18 +08:00
2026-10-06 09:07:18 +08:00
2026-09-19 11:57:50 +08:00
2026-10-05 11:25:20 +08:00
2026-09-27 11:55:33 +08:00
2026-09-13 14:34:44 +08:00
2026-09-11 20:31:50 +08:00
2026-09-10 23:59:12 +08:00
2026-10-06 09:22:12 +08:00
2026-09-15 08:13:52 +08:00
2026-09-13 15:09:44 +08:00
2026-09-13 20:19:37 +08:00
2026-09-19 17:43:16 +08:00
2026-09-19 17:47:44 +08:00
2026-09-26 20:09:17 +08:00
2026-09-26 21:55:12 +08:00
2026-09-26 20:09:17 +08:00
2026-09-13 08:59:15 +08:00
2026-09-14 09:05:14 +08:00
2026-09-13 07:00:51 +08:00
2026-09-13 07:18:03 +08:00
2026-09-13 07:00:51 +08:00
2026-09-14 10:39:25 +08:00
2026-09-13 06:10:44 +08:00
2026-09-13 07:00:51 +08:00
2026-09-13 07:00:51 +08:00
2026-09-13 07:31:32 +08:00
2026-10-06 09:22:12 +08:00
2026-10-06 09:22:12 +08:00
2026-09-10 20:36:39 +08:00
2026-09-13 08:59:15 +08:00
2026-09-13 08:59:15 +08:00
2026-09-03 12:37:58 +08:00
2026-07-24 14:49:08 +08:00
2026-09-27 16:29:24 +08:00
2026-09-27 16:29:24 +08:00
2026-09-12 14:56:25 +08:00
2026-10-05 11:25:20 +08:00
2026-10-05 11:25:20 +08:00
2026-09-18 11:39:04 +08:00
2026-09-27 09:17:16 +08:00
2026-09-27 08:55:25 +08:00
2026-09-19 16:49:16 +08:00
2026-09-13 06:24:20 +08:00
2026-09-13 07:00:51 +08:00
2026-09-13 06:17:49 +08:00
2026-10-05 11:25:20 +08:00
2026-09-17 18:56:15 +08:00
2026-09-17 18:56:15 +08:00
2026-09-19 14:24:31 +08:00
2026-10-05 11:25:20 +08:00
2026-10-05 11:25:20 +08:00
2026-09-27 15:59:11 +08:00
2026-09-27 11:17:06 +08:00
2026-10-05 11:25:20 +08:00
2026-09-27 08:55:25 +08:00
2026-10-06 09:07:18 +08:00
2026-10-06 09:07:18 +08:00
2026-09-27 11:17:06 +08:00
2026-09-27 09:17:16 +08:00
2026-09-14 16:45:04 +08:00
2026-09-27 14:05:38 +08:00
2026-10-05 11:25:20 +08:00
2026-10-05 11:25:20 +08:00
2026-10-05 11:25:20 +08:00
2026-09-26 16:19:10 +08:00