外观
P2 Startup CoreProfile Stop/Drain v1 方案
根因证据
- iOS 17 启用 sampling trigger 后的 willFinish 300ms 仍为
outside-core-window;iOS 18 修正前后均为outside-core-window,末端缺口量级相近。第二 trigger 没有关闭门禁,不能作为默认路径的充分证据。 - 当前实时循环收到 stop 后先取消所有消费任务;
CoreProfileSessionTap.stop()直到 owner 关闭 channel 时才执行。即源 stop/flush 发生在消费者已退出之后,最后缓冲 chunk 无法进入 immutable raw Session。 - 现有 raw Session 的最后一个 CoreProfile chunk 仍是满尺寸数据块,且设备端最大 Mach tick 早于 Fixture marker end,符合“尾部未排空”的表现。
修正顺序
text
stop requested
→ send CoreProfile stop on existing service/channel
→ keep the existing single consumer alive
→ append all final chunks to immutable raw Session
→ wait for explicit end-of-stream or 2s post-stop quiescence(最长 6s)
→ close subscription
→ close channel/provider- 不建立第二 socket、第二 DTX owner 或第二 CoreProfile subscription。
- 非 CoreProfile adapter 维持原停止顺序。
- sampling trigger 保留为显式候选开关,默认关闭;只有 E4 显示独特收益后才可改为默认。
原始字段与质量门禁
每个 CoreProfile raw payload 增加:
| 字段 | 含义 |
|---|---|
streamPhase | active 或 post-stop-drain |
endOfStream | 空结束通知为 true,普通 chunk 为 false |
Session 结果增加 coreProfileDrainStatus:not-required、end-of-stream、quiescent、timeout、failed,并记录 coreProfilePostStopChunkCount、coreProfileDrainIdleSeconds=2、coreProfileDrainMaxSeconds=6。
text
coreProfileDrainPassed = coreProfileDrainStatus IN {"end-of-stream", "quiescent"}
AND coreProfileDrainIdleSeconds == 2
AND coreProfileDrainMaxSeconds == 6
clockBridgePassed = sameTimebase
AND insideCoreWindow
AND markerDelayErrorMs <= markerToleranceMs
AND identityVerified
AND droppedEventHighWater == 0
fixtureEvidencePassed = coreProfileDrainPassed
AND clockBridgePassed
AND delayErrorMs <= toleranceMsCoreProfile 协议未承诺 stop 后一定发送空结束通知,因此 quiescent 定义为:stop 已发出,已有消费者持续排空,最后一条 post-stop 消息后连续 2 秒无新消息,且总等待不超过 6 秒。若达到总超时,即使 marker 恰好落入窗口也只作为诊断候选,不提升正式 mapping。
验收
- E2:测试证明 stop 调用先于消费者取消,post-stop chunk 会写盘,结束通知或 2 秒静默才关闭 drain。
- E4:iOS 17、iOS 18 各执行 willFinish 300ms 与 didFinish 300ms smoke。
- 必须同时满足 identity verified、drop=0、marker 完整、timebase 一致、insideCoreWindow、drain=end-of-stream。
- smoke 通过后再跑 3×3 因果批次;否则保持
null/—并记录协议阻塞点。
回滚
移除 CoreProfile 专用 drain 协调,恢复统一取消任务后关闭 channel。历史 Session 通过 coreProfileDrainStatus 和 streamPhase 可区分。