Files
cc-web/.trellis/tasks/07-30-sidebar-title-refresh-storm/research/root-cause.md
2026-07-30 18:06:39 +08:00

1.5 KiB

侧栏刷新风暴根因记录

数据流

协作/会话事件
  → 服务端保存父会话并更新 updated
  → sendSessionList / broadcastSessionList
  → 前端 handleServerMessage
  → renderSessionList
  → 清空并重建整个 session-list

关键证据

  • renderSessionList() 第一行清空 sessionList.innerHTML,每次重新创建所有项目分组和会话节点。
  • session_list 与 session_message 路径都无条件调用该函数。
  • sendCcwebMcpChildAgentUpdate() 每次 child 增量都会调用 broadcastSessionList()。
  • updatePersistedCcwebMcpChildTool() 每次增量都会改写父会话的 updated,因此完整 payload 字节级比较无法去重。
  • waitingOnChildren 来自跨会话回复队列,不直接来自 MCP child-agent 状态。
  • 服务端事件循环指标正常,现象不是服务进程阻塞。

技术判断

仅移除 child 广播会遗漏普通消息等同类来源,也可能延迟未读状态。仅做节流仍会周期性替换点击节点。最稳妥的边界是前端结构视图签名:把会话数组当前顺序和所有结构/状态字段纳入签名,但排除仅用于相对时间展示的 updated;签名相同时原位更新时间,签名变化时才重建。

测试重点

  • 首次渲染会清空并建立列表。
  • 仅更新时间变化时不再次清空列表,并保留原节点身份。
  • 标题、状态或顺序变化时签名变化并允许重建。
  • 原位时间刷新使用 data-id 精确匹配会话。