Skip to content

fix(remote-hls): give the bypass a terminal state and act on a settled carriage verdict (#334) - #335

Merged
superuser404notfound merged 1 commit into
mainfrom
fix/issue-334-bypass-readiness-terminal-state
Aug 8, 2026
Merged

fix(remote-hls): give the bypass a terminal state and act on a settled carriage verdict (#334)#335
superuser404notfound merged 1 commit into
mainfrom
fix/issue-334-bypass-readiness-terminal-state

Conversation

@superuser404notfound

Copy link
Copy Markdown
Owner

Re #334. Found while verifying #321 against a synthetic live master.

A nativeRemoteHLS session whose item never reaches readyToPlay had no way out. The lean bypass runs without a readiness watchdog on purpose and leaves a dead upstream to AVPlayer's own "gave up" signal, which covers an origin that stops answering. It does not cover one that answers everything while AVFoundation builds no track from what it serves: nothing fails, nothing becomes ready, state stays .loading.

The carriage machinery could not rescue it, because all of it hangs off the same anchor: the #293 probe settled hevcInMPEGTS and the verdict was then only read by a loop that arms at readyToPlay, and the deferred segment-head probe waited out its 20 s readiness ceiling and returned without reading the one thing that could judge the source.

Three changes

  1. A settled verdict reroutes on its own. It is read off the source's playlists or PMT and needs no grace. A video track that does exist still outranks it, so a source contradicting the probe keeps its native session.
  2. The deferred probe reads the segment head when the ceiling expires instead of abandoning the case. Deferring existed so the read would not compete with the mount; a mount that has not settled in 20 s is not competing for anything.
  3. The bypass gets a ceiling on silence. 45 s with no readiness, no reroute and no failure publishes a real error. Readiness at any point, a reroute, or an AVPlayer failure disarm it, so a slow IPTV handshake or a Jellyfin transcode spin-up never meets it. The budget also clears the deferred probe's own 20 s ceiling plus its segment read, which is asserted in a test rather than left to a comment.

Verification

12 new tests (verdict-acts-without-readiness table, deadline table), 1618 tests in 240 suites green, -strict-concurrency=complete clean, tvOS Simulator BUILD SUCCEEDED.

Each layer was also run against a synthetic live master carrying HEVC in MPEG-TS with no audio track, which is the shape that produced the hang:

Fixture Before After
CODECS="hvc1..." 25 s in state=loading, verdict logged and unused reroutes ~1 s in, state=playing
no CODECS same hang, segment head never read ceiling log, head read, reroute at ~20 s, plays
CODECS="avc1..." while carrying HEVC hang with nothing able to judge it terminal .error at 45 s

Internal surface only (RemoteHLSReadinessDeadline and the new load(readinessDeadline:) parameter are not public), so this is a patch-level behaviour fix: sessions that used to hang now either play or fail.

🤖 Generated with Claude Code

https://claude.ai/code/session_01HX5zV3Fcf7Nzq4DYGdXvQE

…d carriage verdict (#334)

A nativeRemoteHLS session whose item never reaches readyToPlay had no way out.
The lean bypass deliberately runs without a readiness watchdog and leaves a dead
upstream to AVPlayer's own "gave up" signal, which covers an origin that stops
answering. It does not cover one that answers everything while AVFoundation can
build no track from what it serves: nothing fails, nothing becomes ready, and
state stays .loading for as long as the host leaves it there.

The carriage machinery could not rescue it either, because all of it hangs off
the same anchor. The #293 probe settled hevcInMPEGTS from the playlists and the
verdict was then read only by a loop that arms at readyToPlay, and the deferred
segment-head probe waited out its 20 s readiness ceiling and returned without
reading the one thing that could have judged the source.

Three changes. A settled verdict now reroutes on its own: it is read off the
source's own playlists or PMT, needs no grace, and a video track that does exist
still outranks it. The deferred probe reads the segment head when the ceiling
expires, since a mount that has not settled in 20 s is not competing with it for
anything. And the bypass gets a ceiling on silence: 45 s with no readiness, no
reroute and no failure publishes a real error instead of an endless spinner.
Readiness at any point, a reroute, or an AVPlayer failure disarm it, so the
budget is only ever spent by a session that was going to hang.

Verified against a synthetic live master carrying HEVC in MPEG-TS with no audio
track, the shape that produced the hang: with CODECS present it now reroutes
about a second in and plays; with CODECS absent the deferred probe reads the
segment head at the ceiling and reroutes at ~20 s; and a master that advertises
avc1 while carrying HEVC, which nothing can judge, ends in a terminal error at
45 s instead of loading forever.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HX5zV3Fcf7Nzq4DYGdXvQE
@superuser404notfound
superuser404notfound merged commit 5b9c533 into main Aug 8, 2026
3 checks passed
@superuser404notfound
superuser404notfound deleted the fix/issue-334-bypass-readiness-terminal-state branch August 8, 2026 03:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant