mirror of
https://gitcode.com/JianFeeeee/HomeAgent.git
synced 2026-09-23 02:18:06 +00:00
对照 docs/zh/input-scheduler-design.md 原文修四处(前两处是真缺陷,后两处是 观测面与设计承诺不一致),均配回归用例: 1. §4.3/§5.2「临界区结束后的第一个安全点重新求值」此前**没有实现**: 全仓唯一的武装点是 registerInterrupt,凡被拦成「入队」的中断只能等当前任务 自然结束。可达症状:WebUI 终止按钮连按两次,第二次落在 2s 抢占冷却窗内 → 入队 → 再也不会被求值。修:runTaskSteps 的安全点先 rearmPending()—— 判据与 registerInterrupt 完全同一套(canPreempt + 冷却 + 临界区闸门)。 2. PreemptsByLevel 的语义是「进入 immediate 槽的次数」,但计数发生在 setImmediateLocked 之前:immediate 是单槽,同一安全点前到达的两条同级中断里 被降级的那条也被计成抢占。修:setImmediateLocked 只在真占住槽时返回 true, 计数随之为真;同时把「降级入队」的责任收归调用方,消除同一任务被入队两次的 隐患(实测该隐患会让中断任务执行两次、Executed 虚高)。 3. 状态面 Preempted 此前拿 Stats.Suspended 顶替,与 preempts_by_level 自相矛盾。 修:Preempted = Σ PreemptsByLevel[1..4]。 4. §4.4/Q4「满时阻塞发送方 + 计数并打日志」只做了阻塞:pumpInbox 满时直接返回, 一个字都不计。修:新增 Stats.Backpressure(+DTO 字段) 与只报一次的状态翻转日志; 同时显式处理 enqueue 返回值(静默丢弃会让同步调用方永久挂起)。 另:Stop() 停机前排空待办——给从未运行与已挂起的、带 ResponseCh 的任务补 skipped 终态,否则 cli/clawhubadapter 这类无超时同步注入方永久挂起(§7 I5、§11.3 X4)。 emitResponse 的 ResponseCh 写入改为非阻塞 + 告警,避免一行写错就卡死调度器 goroutine。 验证:go build/vet 干净;go test -count=1 ./internal/agent/... ./internal/plugin/... ./internal/sdk/... ./cmd/... 全绿;go test -race ./internal/agent/core/ ./internal/sdk/ 干净。 新增 scheduler_rearm_test.go 六个用例(冷却期满重新求值/同级降级不计数/Preempted 求和/ 停机补终态/背压计数与翻转/pumpInbox 满计数)。