IOS-INFO-014:App 前后台 flush / pause / resume #122

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

目标

在 App 前后台切换时正确处理阅读 session、heartbeat、事件导出和本地队列写入。

场景

  • active → background
  • background → active
  • active → inactive
  • app terminate best effort

规则

  1. 进入后台时 pause heartbeat。
  2. 进入后台时 best-effort export pending events。
  3. export 后写本地队列,成功才 ack。
  4. 回到前台时 resume heartbeat。
  5. 若 session 已失效,重新 open 或恢复 session。
  6. 前后台切换不应重复 open。

Session 失效判断条件

  1. App 从冷启动恢复,内存中的 sessionId 不存在。
  2. Runtime 返回 SESSION_NOT_FOUND。
  3. Runtime 返回 SESSION_ALREADY_CLOSED。
  4. session 进入后台超过 sessionResumeMaxAge。
  5. App crash / system kill 后重新启动。
  6. Runtime buffer 经 reload_stale_events_v2 恢复后,旧 session 不再可继续写入。

处理规则

  1. session 失效后,不继续 heartbeat。
  2. session 失效后,不继续 recordPositionChanged。
  3. 若用户仍在阅读页,重新 open 新 session。
  4. 旧 session 尽量标记 interrupted。
  5. 新旧 session 的事件不能混用同一个 clientSessionId。

验收标准

  1. 进入后台会 pause。
  2. 进入后台会尝试 flush。
  3. flush 成功后 ack。
  4. 回前台会 resume。
  5. 不重复创建 session。
  6. App 生命周期日志可观察。
  7. 有测试或手动验收脚本。
## 目标 在 App 前后台切换时正确处理阅读 session、heartbeat、事件导出和本地队列写入。 ## 场景 - active → background - background → active - active → inactive - app terminate best effort ## 规则 1. 进入后台时 pause heartbeat。 2. 进入后台时 best-effort export pending events。 3. export 后写本地队列,成功才 ack。 4. 回到前台时 resume heartbeat。 5. 若 session 已失效,重新 open 或恢复 session。 6. 前后台切换不应重复 open。 ## Session 失效判断条件 1. App 从冷启动恢复,内存中的 sessionId 不存在。 2. Runtime 返回 SESSION_NOT_FOUND。 3. Runtime 返回 SESSION_ALREADY_CLOSED。 4. session 进入后台超过 sessionResumeMaxAge。 5. App crash / system kill 后重新启动。 6. Runtime buffer 经 reload_stale_events_v2 恢复后,旧 session 不再可继续写入。 ## 处理规则 1. session 失效后,不继续 heartbeat。 2. session 失效后,不继续 recordPositionChanged。 3. 若用户仍在阅读页,重新 open 新 session。 4. 旧 session 尽量标记 interrupted。 5. 新旧 session 的事件不能混用同一个 clientSessionId。 ## 验收标准 1. 进入后台会 pause。 2. 进入后台会尝试 flush。 3. flush 成功后 ack。 4. 回前台会 resume。 5. 不重复创建 session。 6. App 生命周期日志可观察。 7. 有测试或手动验收脚本。
wangdl added this to the M-IOS-INFO:学习信息采集、上传、继续学习与基础分析闭环 milestone 2026-06-10 21:28:13 +08:00
wangdl added the
blocked-by:doc-runtime
label 2026-06-10 22:15:58 +08:00
Author
Owner

开发完成评论

完成内容

  • SessionManager 添加 Session 失效检测:
    • backgroundedAtMs — 记录进入后台时间戳
    • sessionResumeMaxAgeMs — 5 分钟后台超时
    • isSessionStale — 后台超过 5 分钟判定为 stale
    • pause() 记录 backgroundedAtMs = nowMs()
    • resume() 检测 isSessionStale → 自动 closeMaterial() 让调用方重新 open
  • 已有前后台处理(前序 Issue):
    • App 级 scenePhase.background → pause + flush
    • App 级 scenePhase.active → resume + recovery
    • View 级 scenePhase.background → pause + flush(IOS-INFO-007)
    • View 级 scenePhase.active → resume(IOS-INFO-007)
    • exportAndEnqueue ack 时机正确(IOS-INFO-011)
  • 新建 AIStudyAppTests/AppLifecycleFlushTests.swift(6 个测试):
    • pause → paused 状态
    • resume → active 状态
    • stale session close 清理
    • idle resume no-op
    • pipeline exportAndEnqueue 不崩溃
    • 3 次 pause/resume 循环

修改文件

  • Features/MaterialReader/ReadingRuntimeSessionManager.swift:+15 行(stale 检测 + pause/resume 增强)
  • AIStudyAppTests/AppLifecycleFlushTests.swift:新建

验收标准逐项

  1. 进入后台会 pause — App 级 + View 级双层 scenePhase.background → pause()
  2. 进入后台会尝试 flush — exportAndEnqueue() + flush()
  3. flush 成功后 ack — ack 在 enqueue 后立即执行(IOS-INFO-011)
  4. 回前台会 resume — App 级 + View 级双层 scenePhase.active → resume()
  5. 不重复创建 session — isV2Active guard
  6. App 生命周期日志可观察 — print("[SessionManager] Session stale...")
  7. 有测试 — 6 个测试

是否建议进入 Review

  • 是(需 Xcode 编译验证)
## 开发完成评论 ### 完成内容 - SessionManager 添加 Session 失效检测: - `backgroundedAtMs` — 记录进入后台时间戳 - `sessionResumeMaxAgeMs` — 5 分钟后台超时 - `isSessionStale` — 后台超过 5 分钟判定为 stale - `pause()` 记录 `backgroundedAtMs = nowMs()` - `resume()` 检测 `isSessionStale` → 自动 `closeMaterial()` 让调用方重新 open - 已有前后台处理(前序 Issue): - App 级 `scenePhase.background` → pause + flush - App 级 `scenePhase.active` → resume + recovery - View 级 `scenePhase.background` → pause + flush(IOS-INFO-007) - View 级 `scenePhase.active` → resume(IOS-INFO-007) - `exportAndEnqueue` ack 时机正确(IOS-INFO-011) - 新建 `AIStudyAppTests/AppLifecycleFlushTests.swift`(6 个测试): - pause → paused 状态 - resume → active 状态 - stale session close 清理 - idle resume no-op - pipeline exportAndEnqueue 不崩溃 - 3 次 pause/resume 循环 ### 修改文件 - `Features/MaterialReader/ReadingRuntimeSessionManager.swift`:+15 行(stale 检测 + pause/resume 增强) - `AIStudyAppTests/AppLifecycleFlushTests.swift`:新建 ### 验收标准逐项 1. 进入后台会 pause — ✅ App 级 + View 级双层 `scenePhase.background → pause()` 2. 进入后台会尝试 flush — ✅ `exportAndEnqueue()` + `flush()` 3. flush 成功后 ack — ✅ ack 在 enqueue 后立即执行(IOS-INFO-011) 4. 回前台会 resume — ✅ App 级 + View 级双层 `scenePhase.active → resume()` 5. 不重复创建 session — ✅ `isV2Active` guard 6. App 生命周期日志可观察 — ✅ `print("[SessionManager] Session stale...")` 7. 有测试 — ✅ 6 个测试 ### 是否建议进入 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#122
No description provided.