AetherEngine 5.19.1
Patch release: recovery for a VOD producer that dies mid-session at the tail (#169, round 2).
Fixed
A VOD session whose producer dies mid-session now recovers instead of parking into -12889 (1ba1b8c)
Reported by @rrgomes with a decisive trace (4K HEVC DV P8.1 MKV, direct play over LAN, Apple TV 4K): near the end of the file the source reader stopped for good after reconnect churn, the final segment (seg719) was never produced, and the request for it re-armed a 30 s backpressure wait indefinitely (cache miss after 30005ms (cache=46 restarted=false) x11) until AVPlayer collapsed with CoreMediaErrorDomain -12889.
Three defects lined up:
- A mid-session VOD
readErrorpump exit had no recovery arm at all. Only the nothing-ever-produced case surfaced as fatal (#126); the rest was assumed covered by the scrub/wedge arms, but the backpressure wedge detector runs inside the pump and died with it. - The forward-wait branch judged "will this arrive?" by index distance to the producer's march front alone (the mechanism the reporter identified, confirmed verbatim). A dead producer freezes the front just below the request, so the wait re-armed forever. The final segment is maximally exposed: there is nothing beyond it for the march to advance into.
- Even an escalated restart would have been vetoed: the restart loop's producerCovers guard reads the dead producer's still-installed base, which covers the requested index.
Three-layer fix, defense in depth (VOD only; live keeps its pump watchdogs and reopen machinery):
- Event-driven revive: a mid-session
readErrorexit gets a bounded revive (2 attempts) aimed at the pending seek target or AVPlayer's real position, and the demuxer whose read just threw is replaced with a fresh connection via the existing #79 path instead of being re-seeked. - Liveness-aware forward wait: a FINISHED pump skips the backpressure wait entirely and restarts immediately; a pump that never exits (blocked in a read) escalates once a full wait burned with zero march-front progress for the same index. An advancing front resets the record, preserving the #141/#93 patience for slow-but-alive sources.
- producerCovers bypass: both proofs override the veto so the escalated restart actually fires.
Retest log signatures: #169 VOD pump died mid-session (readError N); rebuilding producer on a fresh demuxer at ... (pump-exit path) or seg719: #169 forward-wait march dead (front=718 frozen across a full wait); escalating to restart (silent-stop path).
Covered by Issue169DeadProducerEscalationTests (7 tests). Full suite 965/965 green; strict-concurrency and tvOS Simulator builds clean.
Thanks to @rrgomes for removing their host mitigation to isolate the engine behavior, for the memprobe evidence that the producer was provably stopped, and for the exact code-level mechanism in VideoSegmentProvider, which this release confirms and fixes.