Skip to content

forge-engine: multi-instance duplicate triggers from per-session engine-channel #27

@AmberCXX

Description

@AmberCXX

问题描述

当多个 Claude Code session 同时运行时,每个 session 都启动独立的 engine-channel MCP 子进程。所有 engine-channel 实例各自注册定时器并独立触发任务,导致:

症状

  1. 任务重复触发:同一任务被 N 个 engine-channel 实例同时触发。实测 22:59 的睡觉提醒在同一天被触发了 4 次(对应 4 个在线实例)。
  2. 调度状态抖动:修改 engine.d/ 下任一配置文件时,N 个 engine-channel 各自执行 partial reload,trigger-log 中同一条 部分重排 日志出现 N×M 次(M 为文件 watcher 触发次数)。
  3. session 死亡 = 定时器丢失forge-engine: missed task recovery on session restart + busy-session task drop #19 已加了错过任务的通知补救,但如果所有 session 都死了(比如夜间),定时器全丢,直到有人重开 session。

复现

# Terminal 1: 启动一个 CC session(engine-channel 自动启动)
# Terminal 2: 启动另一个 CC session(又一个 engine-channel)
# 等下一个整点任务触发 → 收到 2 条相同通知

当前环境有 3 个 CC session 运行中:

s000 → engine-channel PID 54699
s001 → engine-channel PID 69013  
s002 → engine-channel PID 74905

engine trigger log 证据(22:59 任务触发 4 次):

## 2026-05-11 22:59 — heartbeat
- 来源: task_hourly_checkin.json
- 内容: 🌙 睡觉提醒 ...
## 2026-05-11 22:59 — heartbeat  ← 重复
## 2026-05-11 22:59 — heartbeat  ← 重复
## 2026-05-11 22:59 — heartbeat  ← 重复

根因

engine-channel.ts 是 CC MCP server 子进程,生命周期绑定 CC session。多个 session = 多个独立调度器 = 无协调、无去重。

当前架构:

Hub daemon (stable, one instance)
  ├── engine-channel (session 1) → timers + fire
  ├── engine-channel (session 2) → timers + fire  ← 重复
  └── engine-channel (session 3) → timers + fire  ← 重复

建议方案

把 scheduler 从 engine-channel 移到 Hub daemon,Hub 内部维护单一调度器实例:

Hub daemon (stable, one instance)
  ├── engine-scheduler (built into Hub) → one set of timers → fire exactly once
  │   └── notifies connected CC sessions via MCP
  ├── CC session 1 (receives task notifications)
  └── CC session 2 (receives task notifications, can serve as fallback executor)

要点:

  • 调度器是 Hub daemon 的一部分(和 message routing 同级),不再依赖 CC session 生命周期
  • 任务触发时 Hub 通过 MCP notification 通知在线 session
  • 多 session 时由 primary instance 执行(或由 Hub 做简单的 instance affinity),避免重复
  • engine-channel 可简化为纯桥接层(接收 Hub 事件 → 转发给 CC),不再管理定时器

临时 workaround

用户侧:只保留 1 个 CC session,关掉多余的 terminal。但这与多任务并行工作流冲突。


环境:macOS 14.6.1 · Bun 1.3.13 · forge-hub v0.2.0

forge-hub doctor 输出:

✓ Bun installed
✓ Hub server runtime
✓ Hub client runtime
✓ LaunchAgent plist
✓ MCP registered
✓ ffmpeg available
✓ lark-cli available
✓ approval_channels configured: [feishu, wechat]
✓ Hub server running (v0.2.0, uptime 1964min)
✅ All checks passed

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions