| feature_ids | ||||
|---|---|---|---|---|
| topics |
|
|||
| doc_kind | decision | |||
| created | 2026-02-26 |
日期: 2026-02-09 状态: 已决定 决策者: Ragdoll + operator
Thread 删除时需要级联清理关联数据(messages, tasks, memory, delivery cursors)。这些数据分散在多个 Store 中,可能同时存在 Redis 和内存实现。
采用 Promise.allSettled() best-effort 级联删除。
const cascadeResults = await Promise.allSettled([
messageStore?.deleteByThread(id),
taskStore?.deleteByThread(id),
memoryStore?.deleteThread(id),
deliveryCursorStore?.deleteByThreadForUser(userId, id),
]);- Thread 删除本身成功即返回 204
- 级联删除失败只
console.warn(),不阻塞 UI 操作 - 任何 Store 不可用时跳过(
?.可选链)
Redis 没有跨 key 事务,也没有使用 Lua 脚本。如果级联过程中 Redis 断连:
- Thread 记录已删除
- 部分关联数据可能残留
- Messages: Redis TTL 7 天自然过期
- Tasks: Redis TTL 30 天自然过期
- Memory: Redis TTL 自然过期
- Delivery Cursors: Redis TTL 7 天自然过期
- Clowder AI 是开发工具,不是金融系统 — 孤儿数据不会造成资金损失
- Redis 跨 key 事务 (MULTI/EXEC) 不支持跨不同数据结构的回滚
- 添加后台清理任务增加复杂度,收益不明显
- TTL 已经提供了兜底清理机制
- 备选方案 A:强一致删除(全部成功才返回成功)
- 不选原因:会把非关键存储抖动放大成用户可见失败,删除体验脆弱且恢复成本高。
- 备选方案 B:Lua/MULTI 跨存储原子事务
- 不选原因:现有数据跨多 Store/多 key 结构,事务改造复杂且无法覆盖所有实现路径。
- 备选方案 C:删除即触发后台补偿任务(必做)
- 不选原因:会引入新的调度系统和观测面,当前阶段收益低于复杂度成本。
不做边界:本轮不承诺强一致与即时零孤儿,仅保证 best-effort 删除 + TTL 兜底收敛。
如需强一致性(如 Thread 用于计费),可引入:
- 后台定期扫描清理任务
- 软删除标记 + 延迟清理
当前阶段不需要。
Ragdoll 🐾 (2026-02-09)