Conversation
radamhub
force-pushed
the
fix/stream-transient-retry
branch
from
July 30, 2026 15:50
b904375 to
4745eee
Compare
7 tasks
…tuses
StreamError carries a Retryable field that is set in three places in
stream.go, but nothing ever reads it. customerror.IsRetriableError probes
for a selfRetryable interface (IsRetryable() bool), which StreamError does
not implement, so the field has no effect on any decision. One call site
even builds StreamError{..., Retryable: true} and immediately wraps it in
retry.Unrecoverable, which is self-contradictory.
Add the missing IsRetryable() method so the field reaches the retry loops
in pkg/mount/dfs/vfs/downloaders.go, and stop classifying transient
upstream statuses as unrecoverable while streaming: 429/500/502/503/504
are routine under load on debrid providers. Aborting on them ends playback
for the whole session, because ffmpeg sees an I/O error and the player
keeps requesting segments that never arrive.
Adds a unit test covering both directions of the retryability decision.
radamhub
force-pushed
the
fix/stream-transient-retry
branch
from
July 30, 2026 15:58
4745eee to
65e49e8
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
📌 Description
StreamErrorhas aRetryablefield that nothing ever reads, so transient upstream statuses end playback instead of being retried.Reported in #345.
Target Branch Check (IMPORTANT)
Expected target:
Changes Made
StreamError.IsRetryable().customerror.IsRetriableErrorprobes for aselfRetryableinterface (IsRetryable() bool, seeinternal/customerror/retry.go).StreamErrordid not implement it, so theRetryablefield had no effect on any decision: it is set in three places instream.goand read in none. One of those call sites buildsStreamError{..., Retryable: true}and immediately wraps it inretry.Unrecoverable(...), which is self-contradictory.streamHTTP, stop classifying transient upstream statuses as unrecoverable.429,500,502,503and504now return a retryableStreamErrorso the existing retry loops inpkg/mount/dfs/vfs/downloaders.go(DownloadWithRetry,downloadChunkWithRetry) can back off and try again. Every other unexpected status keeps the previousretry.Unrecoverablebehaviour.pkg/manager/stream_retry_test.goasserting both directions of the decision.Testing
Steps:
go test ./pkg/manager/ -run TestStreamErrorRetryabilityIsHonoured -vpasses with the change, and fails without it (the retryable case is reported as non-retriable).stream error, retrying ... attempt=1and playback continues.416still terminates the stream immediately.Risks / Notes
IsRetryable()makes the field meaningful, so it also changes behaviour at one pre-existing call site:StreamError{Err: ..., Retryable: true}returned after "connection retry exhausted" is now seen as retriable by the outer loop. That looks intended (the inner loop exhausting its own attempts does not mean the outer layer should give up), but it is a behaviour change worth a second opinion, and I am happy to gate that one differently if you prefer.Checklist