auto-sync: 2026-05-16 13:55:16
This commit is contained in:
@@ -179,6 +179,41 @@ class DaemonHealth:
|
||||
- `_check_working_tasks()` 中,working 任务超过 `task_timeout`(默认 10 分钟)视为完成
|
||||
- 视为完成时主动 `decrement()`,防止计数器泄漏
|
||||
|
||||
### 5.5 Daemon 崩溃恢复(v2 新增)
|
||||
|
||||
**设计原则**:状态全在 SQLite,Daemon 无状态。重启 = 重新加载所有项目 + 所有任务状态,继续执行。
|
||||
|
||||
**恢复流程**:
|
||||
|
||||
```
|
||||
PM2 检测 Daemon 挂了 → 重启 Daemon
|
||||
│
|
||||
├── 读取 _registry.yaml → 恢复项目列表
|
||||
├── 遍历每个 active 项目 → 打开 SQLite 连接
|
||||
│ └── 读取所有任务状态(pending/working/completed/failed/...)
|
||||
├── 为每个 active 项目启动 ProjectSlot 线程
|
||||
│
|
||||
└── ProjectSlot._tick() 扫描 working 任务
|
||||
└── working 任务 → 重新 spawn Agent(可能冗余执行一次)
|
||||
└── Agent 自己判断:上次做了没有?产出在不在?
|
||||
├── 产出已存在 → 跳过,直接报告完成
|
||||
├── 做到一半 → 继续完成
|
||||
└── 没做过 → 正常执行
|
||||
```
|
||||
|
||||
**关键假设**:
|
||||
1. **SQLite 是真相来源**——所有任务状态、产出记录都在 `.db` 文件里,Daemon 内存无状态
|
||||
2. **Agent 能判断重复**——AI native,Agent 看到 task context + 已有 output 文件,能自主判断是否需要重新执行
|
||||
3. **冗余执行无害**——即使一个节点被多执行一次,结果是幂等的(Agent 会检查产出是否已存在)
|
||||
4. **无限续杯**——重启后 working 节点重新执行,属于已有的"无限续杯"机制(项目内运转机制,不在此设计)
|
||||
|
||||
**不需要额外存储**:
|
||||
- 不需要 checkpoint 文件——SQLite 就是 checkpoint
|
||||
- 不需要 recovery log——`task_attempts` 表已记录每次尝试
|
||||
- 不需要状态快照——每次 tick 从 SQLite 实时读取
|
||||
|
||||
**唯一注意**:`ActiveAgentCounter` 重启后从零开始——但 `_tick()` 会重新扫描 working 任务并重新计数,所以没问题。
|
||||
|
||||
### 5.4 并发调度模型(v2 新增)
|
||||
|
||||
#### 5.4.1 问题
|
||||
|
||||
Reference in New Issue
Block a user