Skip to content

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 增加:

字段含义
streamPhaseactivepost-stop-drain
endOfStream空结束通知为 true,普通 chunk 为 false

Session 结果增加 coreProfileDrainStatusnot-requiredend-of-streamquiescenttimeoutfailed,并记录 coreProfilePostStopChunkCountcoreProfileDrainIdleSeconds=2coreProfileDrainMaxSeconds=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 <= toleranceMs

CoreProfile 协议未承诺 stop 后一定发送空结束通知,因此 quiescent 定义为:stop 已发出,已有消费者持续排空,最后一条 post-stop 消息后连续 2 秒无新消息,且总等待不超过 6 秒。若达到总超时,即使 marker 恰好落入窗口也只作为诊断候选,不提升正式 mapping。

验收

  1. E2:测试证明 stop 调用先于消费者取消,post-stop chunk 会写盘,结束通知或 2 秒静默才关闭 drain。
  2. E4:iOS 17、iOS 18 各执行 willFinish 300ms 与 didFinish 300ms smoke。
  3. 必须同时满足 identity verified、drop=0、marker 完整、timebase 一致、insideCoreWindow、drain=end-of-stream。
  4. smoke 通过后再跑 3×3 因果批次;否则保持 null/— 并记录协议阻塞点。

回滚

移除 CoreProfile 专用 drain 协调,恢复统一取消任务后关闭 channel。历史 Session 通过 coreProfileDrainStatusstreamPhase 可区分。

Perfowl · Performance Observer