playlist retry-exhaustion handling
This commit is contained in:
@@ -89,7 +89,8 @@ func (c *PlaylistReadinessCoordinator) Run(ctx context.Context) error {
|
||||
ticker := c.newTicker(c.interval)
|
||||
defer ticker.Stop()
|
||||
|
||||
var emittedRevision uint64
|
||||
var emittedReadyRevision uint64
|
||||
var emittedFailedRevision uint64
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
@@ -99,11 +100,7 @@ func (c *PlaylistReadinessCoordinator) Run(ctx context.Context) error {
|
||||
playlistSnapshot, ok := c.playlist.Snapshot()
|
||||
if !ok ||
|
||||
!playlistSnapshot.State.HasSelection ||
|
||||
playlistSnapshot.Revision == 0 ||
|
||||
playlistSnapshot.Entry.Duration <= 0 ||
|
||||
playlistSnapshot.Timing.Started ||
|
||||
playlistSnapshot.Timing.Paused ||
|
||||
playlistSnapshot.Revision == emittedRevision {
|
||||
playlistSnapshot.Revision == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -114,7 +111,30 @@ func (c *PlaylistReadinessCoordinator) Run(ctx context.Context) error {
|
||||
) {
|
||||
continue
|
||||
}
|
||||
if !IsSessionPlaying(sessionSnapshot, c.statuses.SnapshotAll()) {
|
||||
statuses := c.statuses.SnapshotAll()
|
||||
if IsSessionFailed(sessionSnapshot, statuses) {
|
||||
if playlistSnapshot.Revision == emittedFailedRevision {
|
||||
continue
|
||||
}
|
||||
failed := PlaylistEvent{
|
||||
Revision: playlistSnapshot.Revision,
|
||||
Kind: PlaylistEventFailed,
|
||||
}
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
case c.output <- failed:
|
||||
emittedFailedRevision = playlistSnapshot.Revision
|
||||
}
|
||||
continue
|
||||
}
|
||||
if playlistSnapshot.Entry.Duration <= 0 ||
|
||||
playlistSnapshot.Timing.Started ||
|
||||
playlistSnapshot.Timing.Paused ||
|
||||
playlistSnapshot.Revision == emittedReadyRevision {
|
||||
continue
|
||||
}
|
||||
if !IsSessionPlaying(sessionSnapshot, statuses) {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -123,7 +143,7 @@ func (c *PlaylistReadinessCoordinator) Run(ctx context.Context) error {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
case c.output <- ready:
|
||||
emittedRevision = playlistSnapshot.Revision
|
||||
emittedReadyRevision = playlistSnapshot.Revision
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -193,6 +213,38 @@ func IsSessionPlaying(
|
||||
}
|
||||
}
|
||||
|
||||
func IsSessionFailed(
|
||||
session SessionSnapshot,
|
||||
statuses PlaybackStatusSnapshot,
|
||||
) bool {
|
||||
if statuses.Generation != session.Generation {
|
||||
return false
|
||||
}
|
||||
|
||||
switch session.Plan.Topology {
|
||||
case TopologyIndependent:
|
||||
return (session.Plan.Video.Active && statusIsFailed(
|
||||
statuses.Video, statuses.HasVideo, session.Generation, session.Plan.Video,
|
||||
)) || (session.Plan.Audio.Active && statusIsFailed(
|
||||
statuses.Audio, statuses.HasAudio, session.Generation, session.Plan.Audio,
|
||||
))
|
||||
case TopologySynchronized:
|
||||
return statuses.HasSync &&
|
||||
statuses.Sync.Generation == session.Generation &&
|
||||
statuses.Sync.State == StateFailed &&
|
||||
sameSyncSource(statuses.Sync.Pair, session.Plan.Sync)
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func statusIsFailed(status Status, present bool, generation uint64, feed FeedConfig) bool {
|
||||
return present &&
|
||||
status.Generation == generation &&
|
||||
status.State == StateFailed &&
|
||||
sameFeedSource(status.Feed, feed)
|
||||
}
|
||||
|
||||
func statusIsPlaying(
|
||||
status Status,
|
||||
present bool,
|
||||
|
||||
Reference in New Issue
Block a user