当前 heartbeatService 的实现存在三个相互关联的缺陷,导致在日常使用中(尤其是开发阶段频繁重启 Alma 的场景)heartbeat 几乎无法按预期触发,并且触发时会无差别终止所有正在执行的 agent 任务。
从 API 行为和 /api/heartbeat/status 的返回值推断,start() 使用了 setInterval 而非立即执行,且 lastHeartbeatTime 未持久化。以下用伪代码描述推断出的当前行为:
// 推断的当前行为(伪代码) class HeartbeatService { lastHeartbeatTime = 0; // 纯内存变量,重启归零 start() { this.timer = setInterval( // 无首跳 () => this.tick(), 60 * this.config.intervalMinutes * 1000 ); } } setInterval 不会在调用时立即执行回调,而是等待完整的一个 interval 周期后才触发第一次。假设 interval 设为 60 分钟,Alma 启动后需要等整整 60 分钟才会执行第一次 heartbeat。
如果用户在这 60 分钟内重启了 Alma(开发阶段很常见),计时器重置,又要再等 60 分钟。结果是 heartbeat 可能永远不会触发。
lastHeartbeatTime 纯内存,重启归零lastHeartbeatTime 没有持久化到 SQLite 或 settings JSON。每次 Alma 重启,这个值回到 0。这意味着:
重启后无法判断"距离上次 heartbeat 过了多久"
无法做出"是否需要立即补跳"的决策
日志中也无法追溯 heartbeat 历史
即使检测到距离上次 heartbeat 已经过了多个 interval,当前实现也不会补发。比如 Alma 关闭了 3 小时后重新打开,interval 是 60 分钟,理论上错过了 3 次 heartbeat,但重启后只会静默等待下一个完整 interval。
这个问题跟上面三个缺陷叠加后尤其严重。实测中观察到 heartbeat 触发时会无差别终止正在执行的 agent 任务(多个并行 agent 被同时中断),导致任务执行不完整。如果 heartbeat 的触发时机不可预测(因为缺陷1-3),用户无法合理规避这个中断。
由于缺陷2(无持久化),重启后 agent 无法知道自己被中断过,也无法从断点恢复。
建议的修复方案
start() { this.tick(); // ← 新增:立即执行一次 this.timer = setInterval( () => this.tick(), 60 * this.config.intervalMinutes * 1000 ); } lastHeartbeatTime(约 5 行)将 lastHeartbeatTime 写入 app_settings 表或独立的 JSON 文件。每次 tick() 执行后更新持久化值,启动时从持久化存储读取。
start() { this.lastHeartbeatTime = this.loadFromStorage() || 0; // ... } tick() { // ... 执行 heartbeat 逻辑 this.lastHeartbeatTime = Date.now(); this.saveToStorage(this.lastHeartbeatTime); } start() { const last = this.loadFromStorage() || 0; const elapsed = Date.now() - last; const intervalMs = 60 * this.config.intervalMinutes * 1000; if (elapsed >= intervalMs) { this.tick(); // 补跳 } else { // 只等剩余时间,而不是完整 interval setTimeout(() => { this.tick(); this.timer = setInterval(() => this.tick(), intervalMs); }, intervalMs - elapsed); return; } this.timer = setInterval(() => this.tick(), intervalMs); } 当前 heartbeat 触发时直接终止所有 agent。建议改为:
检查是否有 agent 正在执行任务
如果有,等待当前任务完成(或设一个超时上限,比如 30 秒)
任务完成或超时后再执行 heartbeat 逻辑
如果无法等待,至少让 agent 写一个 checkpoint,以便恢复后能从断点继续
这一条改动量较大,可以作为后续优化。
Alma 版本:v0.0.738
操作系统:Windows 11
使用场景:通过 Discord bridge 运行多 agent 长任务
复现频率:每次重启 Alma 后 heartbeat 行为异常,100% 可复现
Please authenticate to join the conversation.
In Review
Feature Request
About 4 hours ago

karlamo
Get notified by email when there are changes.
In Review
Feature Request
About 4 hours ago

karlamo
Get notified by email when there are changes.