P5-跨面板建楼状态同步装置

文档发表:2026-07-08 · 阅读:80 · 更新:2026-08-05

学术论文 · 四川的梦科技有限公司 · 2026-07-27


摘要

多面板 IDE 中,同一对话可能在不同面板中同时打开,需防止双重发送和状态不一致。现有跨 iframe 通信方案(BroadcastChannel/postMessage/服务端轮询)在跨域限制、状态一致性、延迟等方面存在不足。本文提出跨面板建楼状态同步装置——基于父窗口中央注册表(parent.__qqq_buildingRegistry + parent.__qqq_questOwners)+ IPC sync 桥 + 状态机转移校验的三层架构。该装置保证同一对话同时仅在一个面板可操作,所有面板实时同步建楼状态,彗星电子钟等全局 UI 正确反映工作状态。


1. 引言

qqq-shell-v2 的 AI 面板采用三面板架构:左翼(panel=0)、中面板(panel=1)、右翼(panel=2)。每个面板运行在独立 iframe 中。用户可在任一面板中操作对话,但同一对话同时只能在一个面板中处于活跃状态。

需要同步的状态包括:

  1. 所有权:哪个面板正在操作哪个对话?
  2. 建楼状态:对话是否正在 sending/stopping/fatal?
  3. 全局 UI:彗星电子钟应显示哪个面板的工作状态?

2. 系统设计

2.1 三层架构

┌─────────────┐  ┌─────────────┐  ┌─────────────┐
│ iframe 左翼 │  │ iframe 中面板│  │ iframe 右翼  │
│ panel=0     │  │ panel=1     │  │ panel=2      │
└──────┬──────┘  └──────┬──────┘  └──────┬──────┘
       │                │                │
       └────────────────┼────────────────┘
                        │ postMessage
               ┌────────▼────────┐
               │  父窗口 (shell)  │
               │ __qqq_questOwners│  ← 所有权注册表
               │ __qqq_buildingReg│  ← 建楼状态注册表
               │ __qqq_agentPool  │  ← Agent 实例池
               └────────┬────────┘
                        │ IPC sync relay
               ┌────────▼────────┐
               │  Electron 主进程 │
               │  sync:broadcast  │
               └─────────────────┘

2.2 所有权注册表

parent.__qqq_questOwners: Map<questId → panelId>
  • 零 TTL、零 IO、纯内存同步映射
  • 面板 switchQuest 时:先通过 _parentGetQuestOwner 检查 → 若已被占用且非本面板 → 拒绝
  • 切换前:_parentReleaseQuest(旧 questId) → _parentClaimQuest(新 questId)

2.3 建楼状态注册表

parent.__qqq_buildingRegistry: Map<questId → {stopState, panelId}>
  • stopState: idle | sending | stopping | fatal
  • 状态转移校验表:idle→[sending, fatal], sending→[stopping, fatal, idle], stopping→[idle, fatal], fatal→[sending]
  • 非法转移不阻断但 console.warn
  • finally 块兜底防僵尸:agent-loop 完结路径无条件 unregisterBuilding

2.4 IPC Sync 桥

_broadcast(type, data) {
  parent.qqqideBridge.sync.broadcast(type, data)
}
// → Electron 主进程 relay → 所有 webContents(含发送者)
// _handleSyncMessage 首行过滤 msg.windowId === _windowId

2.5 Agent 实例池

parent.__qqq_agentPool: Map<questId → AgentLoop实例>

三面板共享同一 agent 实例。任一面板建楼 → 写入 ag._houses → 另两个面板自动可见 → 切换对话不再出现"死卡片"。


3. 彗星电子钟同步

电子钟需显示"哪个对话正在建楼"及耗时:

  1. 每 200ms 滴答:遍历 parent.__qqq_agentPool → 找到 stopState==='sending' 的 agent
  2. 豆腐块(招牌行):仅在本面板 questActiveId 对应 agent 正在 sending 时显示时钟
  3. 下拉列表:每个 quest 独立插入时钟,各自计算秒数
  4. 广播兜底:若 poll 检测到 agent 状态与本地不同步 → 触发广播纠正

4. 正确性分析

场景保障机制
用户在中面板操作 q5,左翼也尝试操作 q5所有权注册表拒绝(q5 已被 panel=1 占用)
中面板 crashfinally 块清除注册表条目,q5 重新可用
同一面板双击 Enter_execSendBusy 同步锁 + stopState 状态机防并发
彗星电子钟显示错误面板的工作状态data-qid 绑定各自 questId,独立计算

5. 结论

跨面板建楼状态同步装置通过父窗口中央注册表 + IPC 广播 + 状态机校验,在 iframe 隔离架构中实现了强一致的多面板协同。所有权系统保证互斥操作,Agent 实例池消除多副本竞态。


参考文献

[1] MDN — window.postMessage. developer.mozilla.org. [2] BroadcastChannel API — W3C Specification. [3] qqq-shell-v2 架构文档 §28/§30/§46b, 2026.