playlist retry-exhaustion handling

This commit is contained in:
Dmitry Sergeev
2026-09-01 23:35:41 +03:00
parent abdfc8e2de
commit 179768ca4a
9 changed files with 346 additions and 45 deletions
+47 -1
View File
@@ -7,10 +7,22 @@ import (
"time"
)
type PlaylistReadiness struct {
type PlaylistEventKind uint8
const (
PlaylistEventReady PlaylistEventKind = iota
PlaylistEventFailed
)
type PlaylistEvent struct {
Revision uint64
Kind PlaylistEventKind
}
// PlaylistReadiness is retained as an alias for callers that only publish
// ready events. Its zero Kind is PlaylistEventReady.
type PlaylistReadiness = PlaylistEvent
type playlistTimer interface {
C() <-chan time.Time
Stop() bool
@@ -162,6 +174,40 @@ func (c *PlaylistController) Run(
readiness = nil
continue
}
if ready.Kind == PlaylistEventFailed {
if ready.Revision != revision {
continue
}
stopTimer()
// A failed entry must not retain a live or apparently active
// duration clock, even when the policy is to wait.
timing = NewPlaylistTiming(revision, timing.Duration)
if c.playlist.OnFailure != PlaylistFailureNext {
c.publish(state, revision, timing)
continue
}
next, sessionCommand, apply, err := ApplyPlaylistSelection(
c.playlist,
state,
PlaylistCommand{Kind: PlaylistNext},
c.retry,
)
if err != nil || !apply {
c.publish(state, revision, timing)
continue
}
select {
case <-ctx.Done():
return ctx.Err()
case c.sessions <- sessionCommand:
}
revision++
state = next
entry, _ := next.Entry(c.playlist)
timing = NewPlaylistTiming(revision, entry.Duration)
c.publish(state, revision, timing)
continue
}
if timing.Paused &&
ready.Revision == timing.Revision &&
timing.Duration > 0 &&