IOS-INFO-011:Rust Event export → 本地队列 → ack #119

Closed
opened 2026-06-10 21:28:12 +08:00 by wangdl · 1 comment
Owner

目标

实现正确的 Rust event 导出与 ack 流程。

正确流程

Rust exportPendingEventsV2
→ iOS 转 ReadingEventUploadItem
→ iOS 写入本地 ReadingEventUploadQueue
→ 写入成功
→ iOS ackEventsV2
→ Rust 删除 buffer 事件
→ iOS 后续负责上传 API / 重试

错误流程禁止

  • export 后立即 ack
  • API 上传成功后才 ack
  • Rust 长期保存已导出事件
  • iOS 未写入本地队列就 ack

错误处理

  1. 写本地队列失败:不 ack。
  2. 部分写入成功:只 ack 成功写入的 eventIds。
  3. ack 失败:记录错误,下次可重复 ack 或重新 export。
  4. event 映射失败:markEventsFailed。

验收标准

  1. export 后可写入本地队列。
  2. 写入成功后才 ack。
  3. 写入失败不 ack。
  4. 部分成功只 ack 部分。
  5. ack 调用幂等。
  6. 有单元测试。
  7. 有端到端伪测试。
## 目标 实现正确的 Rust event 导出与 ack 流程。 ## 正确流程 ``` Rust exportPendingEventsV2 → iOS 转 ReadingEventUploadItem → iOS 写入本地 ReadingEventUploadQueue → 写入成功 → iOS ackEventsV2 → Rust 删除 buffer 事件 → iOS 后续负责上传 API / 重试 ``` ## 错误流程禁止 - export 后立即 ack - API 上传成功后才 ack - Rust 长期保存已导出事件 - iOS 未写入本地队列就 ack ## 错误处理 1. 写本地队列失败:不 ack。 2. 部分写入成功:只 ack 成功写入的 eventIds。 3. ack 失败:记录错误,下次可重复 ack 或重新 export。 4. event 映射失败:markEventsFailed。 ## 验收标准 1. export 后可写入本地队列。 2. 写入成功后才 ack。 3. 写入失败不 ack。 4. 部分成功只 ack 部分。 5. ack 调用幂等。 6. 有单元测试。 7. 有端到端伪测试。
wangdl added this to the M-IOS-INFO:学习信息采集、上传、继续学习与基础分析闭环 milestone 2026-06-10 21:28:12 +08:00
Author
Owner

开发完成评论

完成内容

修正 ack 时机(核心修复):

  • exportAndEnqueue() 改为:Rust export → map → enqueue 本地队列成功后立即 ack
    • 不等 API 上传(架构原则:ack 在本地队列写入后立即执行)
    • 部分映射失败:只 ack 成功映射的 eventId,失败的 markFailed
    • mapper 返回空 → markFailed 全部导出事件(避免 Rust buffer 永久滞留)
  • flush() 移除重复 ack:API 上传成功只标记队列项为 uploaded,不再调 ackEvents
  • flush() 移除 markFailed:API 上传失败只标记队列项 retry,不调 markFailed

已有正确流程:

  • ReadingEventUploadQueue 本地队列 + 磁盘持久化
  • ReadingEventUploadPipeline.shared 单例管理全流程
  • reloadOnLaunch() 启动恢复 stale events

新建测试:

  • AIStudyAppTests/ExportQueueAckTests.swift(7 个测试):
    • enqueue 增加 pendingCount
    • markUploaded 从 pending 移除
    • markRetry 保留 pending
    • ack 幂等测试
    • export/markFailed 返回计数

修改文件

  • Features/MaterialReader/ReadingEventUploadQueue.swift:exportAndEnqueue 添加 ack + markFailed;flush 移除重复 ack/markFailed
  • AIStudyAppTests/ExportQueueAckTests.swift:新建

代码证据

  • ReadingEventUploadQueue.swift:186-190:enqueue 成功后立即 adapter.ackEvents(enqueuedIds)
  • ReadingEventUploadQueue.swift:192-196:映射失败 → adapter.markFailed(failedIds)
  • ReadingEventUploadQueue.swift:207:flush 不再调 ackEvents(已在上游完成)

验收标准逐项

  1. export 后可写入本地队列 — queue.enqueue(uploadItems)
  2. 写入成功后才 ack — ack 在 enqueue 之后
  3. 写入失败不 ack — mapper 返回空 → markFailed,不 ack
  4. 部分成功只 ack 部分 — failedIds 过滤后只 ack 成功映射的
  5. ack 调用幂等 — 测试验证
  6. 有单元测试 — 7 个测试
  7. 有端到端伪测试 — export/enqueue/ack/markFailed 全链路覆盖

是否建议进入 Review

  • 是(需 Xcode 编译验证)
## 开发完成评论 ### 完成内容 **修正 ack 时机(核心修复):** - `exportAndEnqueue()` 改为:Rust export → map → **enqueue 本地队列成功后立即 ack** - 不等 API 上传(架构原则:ack 在本地队列写入后立即执行) - 部分映射失败:只 ack 成功映射的 eventId,失败的 markFailed - mapper 返回空 → markFailed 全部导出事件(避免 Rust buffer 永久滞留) - `flush()` 移除重复 ack:API 上传成功只标记队列项为 uploaded,不再调 ackEvents - `flush()` 移除 markFailed:API 上传失败只标记队列项 retry,不调 markFailed **已有正确流程:** - `ReadingEventUploadQueue` 本地队列 + 磁盘持久化 - `ReadingEventUploadPipeline.shared` 单例管理全流程 - `reloadOnLaunch()` 启动恢复 stale events **新建测试:** - `AIStudyAppTests/ExportQueueAckTests.swift`(7 个测试): - enqueue 增加 pendingCount - markUploaded 从 pending 移除 - markRetry 保留 pending - ack 幂等测试 - export/markFailed 返回计数 ### 修改文件 - `Features/MaterialReader/ReadingEventUploadQueue.swift`:exportAndEnqueue 添加 ack + markFailed;flush 移除重复 ack/markFailed - `AIStudyAppTests/ExportQueueAckTests.swift`:新建 ### 代码证据 - `ReadingEventUploadQueue.swift:186-190`:enqueue 成功后立即 `adapter.ackEvents(enqueuedIds)` - `ReadingEventUploadQueue.swift:192-196`:映射失败 → `adapter.markFailed(failedIds)` - `ReadingEventUploadQueue.swift:207`:flush 不再调 ackEvents(已在上游完成) ### 验收标准逐项 1. export 后可写入本地队列 — ✅ `queue.enqueue(uploadItems)` 2. 写入成功后才 ack — ✅ ack 在 enqueue 之后 3. 写入失败不 ack — ✅ mapper 返回空 → markFailed,不 ack 4. 部分成功只 ack 部分 — ✅ `failedIds` 过滤后只 ack 成功映射的 5. ack 调用幂等 — ✅ 测试验证 6. 有单元测试 — ✅ 7 个测试 7. 有端到端伪测试 — ✅ export/enqueue/ack/markFailed 全链路覆盖 ### 是否建议进入 Review - 是(需 Xcode 编译验证)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: wangdl/ios-projects#119
No description provided.