JianFeeeee
b1ec278136
feat(obs): 抢占日志说出「受害者是谁」——suspend/resume 此前完全不落日志
排查「我的任务怎么被莫名打断了」时撞上的观测缺口。
## 缺口
`executeNewTask` 里挂起、`resumeTask` 里恢复,两处都**只发事件、不写日志**:
a.sched.suspend(t, f)
a.publishEvent(events.EventScheduler, map[string]any{"action": "suspend", ...})
于是生产日志里只有两行:`interrupt from X` 与 `LLM request cancelled by
preemption` —— **看不到受害者是谁、被谁挤下去、后来有没有恢复**。后果是实测过的:
按时间先后猜凶手,把时间上相邻的输入误认成抢占者。
## 改动
- `sourceOf(task, frame)`:取可辨识来源(`evt.Source` 优先,回退 OutputChannel,
自循环任务给 `self:<channel>`)。取 Source 而**不是** OutputChannel:
前者回答「谁送来的」(qq / homeagent-mail-bridge / timer / child/xxx),
后者只回答投递到哪个通道;多数场景同名,但因果链上要的是前者。
- `describeTask(task)`:`task#N class=queued|interrupt level=L`。
- `suspendDepth()`:日志专用,走锁而不是让日志点直接摸 `suspendStack`。
- 三个日志点:抢占开始(含 victim)、挂起(含来源与栈深)、恢复。
输出形状:
[agent] preempt start: task#2 class=interrupt level=4 from cli -> victim task#1 class=queued level=0 (qq)
[agent] suspend: task#1 class=queued level=0 (qq) yields to an interrupt; suspendStack=0
[agent] resume: task#1 class=queued level=0 (qq) resumes after the interrupt finished
## 验证
- 新增 preempt_logging_test.go:抢占后栈深 0→1、sourceOf 取到 qq、self/nil 不 panic。
- 实测日志(TestPreempt_HigherPreemptsAndResumes)三条齐全,能一眼看出
是 `cli` 的 L4 挤掉了 `qq` 的排队任务、随后 qq 恢复。
- `go test ./internal/... ./cmd/...` 全绿。
2026-09-19 11:31:04 +08:00
..
2026-08-05 09:59:33 +08:00
2026-09-15 07:47:16 +08:00
2026-09-11 11:45:24 +08:00
2026-09-17 18:56:15 +08:00
2026-09-15 06:32:36 +08:00
2026-09-15 06:32:36 +08:00
2026-09-11 11:45:24 +08:00
2026-09-13 12:23:28 +08:00
2026-09-15 09:27:39 +08:00
2026-09-18 11:39:04 +08:00
2026-08-18 09:07:21 +08:00
2026-09-15 09:03:36 +08:00
2026-09-15 09:16:22 +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-09-15 09:37:29 +08:00
2026-09-15 09:37:29 +08:00
2026-07-28 11:42: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-09-13 10:36:04 +08:00
2026-09-15 08:13:52 +08:00
2026-09-15 09:37:29 +08:00
2026-09-04 06:25:51 +08:00
2026-09-04 06:25:51 +08:00
2026-09-13 09:13:19 +08:00
2026-09-13 16:04:16 +08:00
2026-09-13 16:04:16 +08:00
2026-09-12 13:57:06 +08:00
2026-09-12 13:57:06 +08:00
2026-07-16 12:11:16 +08:00
2026-08-18 09:07:21 +08:00
2026-09-19 11:31:04 +08:00
2026-09-18 11:26:12 +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-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-13 11:38:03 +08:00
2026-09-14 15:33:23 +08:00
2026-09-15 09:37:29 +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-09-13 07:00:51 +08:00
2026-09-19 11:31:04 +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-03 12:37:58 +08:00
2026-09-12 14:56:25 +08:00
2026-09-17 18:56:15 +08:00
2026-09-18 11:39:04 +08:00
2026-09-13 08:59:15 +08:00
2026-09-13 08:59:15 +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-09-18 11:26:12 +08:00
2026-09-17 18:56:15 +08:00
2026-09-17 18:56:15 +08:00
2026-07-27 15:26:23 +08:00
2026-09-15 09:37:29 +08:00
2026-09-15 09:37:29 +08:00
2026-09-14 16:45:04 +08:00
2026-09-06 09:51:31 +08:00