Skip to content

feat: 消息队列 peek/ACK + 持久化,防止消息丢失#3

Open
Isaac20231231 wants to merge 2 commits intoanjiacm:releasefrom
Isaac20231231:fix/feishu-message-dedup
Open

feat: 消息队列 peek/ACK + 持久化,防止消息丢失#3
Isaac20231231 wants to merge 2 commits intoanjiacm:releasefrom
Isaac20231231:fix/feishu-message-dedup

Conversation

@Isaac20231231
Copy link
Copy Markdown
Contributor

Summary

  • GET /api/messages 从破坏性消费改为 peek(非破坏性读取)
  • 新增 POST /api/messages/ack 支持 upToId 精确确认
  • 消息入队时自动分配 _id,持久化到 data/message-queue.json
  • 新增 GET /api/claude/status 只读端点(飞书 Bot 依赖)
  • 轮询脚本增加本地 pending-messages.json 兜底机制
  • PID 文件路径改为动态 ${PROJECT_NAME},避免多实例冲突

问题背景

旧版 GET /api/messages 采用"读取即删除"语义,存在多个可靠性问题:

  1. Claude 收到消息但处理前崩溃 → 消息永久丢失
  2. 调试用 curl GET /api/messages 也会消费生产消息(实际已造成事故)
  3. 合并窗口(sleep + 二次 GET)存在竞争条件
  4. 消息仅存内存,Dashboard 重启后队列清空
  5. 缺少 GET /api/claude/status,飞书 Bot 始终认为 Claude offline

数据流(优化后)

外部消息 → POST /api/messages(入队 + 分配_id + 持久化)
                    ↓
轮询(peek,不删) → 发现消息 → 写 pending-messages.json → exit 唤醒 Claude
                    ↓
Claude 处理 → POST /api/messages/ack → 清除已处理 → 重启轮询
                    ↓
           Claude 崩溃?→ 消息仍在队列 + 本地文件 → 下次启动自动恢复

改动文件

文件 改动
skeleton/web/server.js peek/ACK 端点 + 持久化 + GET claude/status + 动态 PID
skeleton/scripts/dashboard-poll.sh peek 模式 + 本地兜底 + 启动时恢复检查
skeleton/CLAUDE.md.tmpl API 速查表更新 + 处理流程更新
skeleton/.gitignore 排除 data/*.jsondata/*.log

Test plan

  • POST 测试消息,GET 确认消息仍在(不被消费)
  • POST /api/messages/ack 确认消息被清除
  • 重启 Dashboard,确认消息从 message-queue.json 恢复
  • GET /api/claude/status 返回正确状态
  • 轮询脚本发现消息后写入 pending-messages.json
  • 模拟崩溃(不 ACK),下次启动仍能读到消息

问题:飞书 WebSocket 长连接在网络波动或重连时,会重复投递同一条消息,
导致自动回复(离线提示)发送多次。

修复:
- 新增 _seen_messages 内存缓存,基于 message_id 去重
- 60秒 TTL 自动过期清理,不占用额外内存
- 在 on_message 入口处检查,重复消息直接跳过
问题:
- GET /api/messages 读取即删除,Claude 处理前崩溃则消息永久丢失
- 调试用 curl GET 也会消费生产消息(已造成实际事故)
- 缺少 GET /api/claude/status 端点,飞书 Bot 始终认为 Claude offline
- 消息仅存内存,Dashboard 重启后队列清空
- PID 文件路径硬编码,多项目实例冲突

修复:
- GET /api/messages 改为 peek(非破坏性读取)
- 新增 POST /api/messages/ack 支持 upToId 精确确认
- 消息入队时分配自增 _id,持久化到 data/message-queue.json
- 新增 GET /api/claude/status 只读端点
- 轮询脚本增加本地 pending-messages.json 兜底
- PID 路径改为动态 ${PROJECT_NAME}
- .gitignore 排除运行时数据文件
- CLAUDE.md.tmpl 更新 API 速查表和处理流程
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant