fix playout build loop that was recently introduced (#1318)

This commit is contained in:
Jason Dove
2023-06-22 09:40:20 -05:00
committed by GitHub
parent 1fc461e476
commit 015f5e9798
11 changed files with 62 additions and 55 deletions
@@ -4,5 +4,5 @@ public class CollectionEnumeratorState
{
public int Seed { get; set; }
public int Index { get; set; }
public CollectionEnumeratorState Clone() => new CollectionEnumeratorState { Seed = Seed, Index = Index };
public CollectionEnumeratorState Clone() => new() { Seed = Seed, Index = Index };
}
@@ -4,7 +4,7 @@ namespace ErsatzTV.Core.Interfaces.Scheduling;
public interface IMediaCollectionEnumerator
{
IMediaCollectionEnumerator Clone(CollectionEnumeratorState state, CancellationToken cancellationToken);
void ResetState(CollectionEnumeratorState state);
CollectionEnumeratorState State { get; }
Option<MediaItem> Current { get; }
void MoveNext();
@@ -31,9 +31,10 @@ public sealed class ChronologicalMediaCollectionEnumerator : IMediaCollectionEnu
}
}
public IMediaCollectionEnumerator Clone(CollectionEnumeratorState state, CancellationToken cancellationToken)
public void ResetState(CollectionEnumeratorState state)
{
return new ChronologicalMediaCollectionEnumerator(_sortedMediaItems, state);
// seed doesn't matter in chronological
State.Index = state.Index;
}
public CollectionEnumeratorState State { get; }
@@ -35,9 +35,10 @@ public class CustomOrderCollectionEnumerator : IMediaCollectionEnumerator
}
}
public IMediaCollectionEnumerator Clone(CollectionEnumeratorState state, CancellationToken cancellationToken)
public void ResetState(CollectionEnumeratorState state)
{
return new CustomOrderCollectionEnumerator(_collection, _mediaItems, state);
// seed doesn't matter here
State.Index = state.Index;
}
public CollectionEnumeratorState State { get; }
@@ -122,16 +122,15 @@ public class PlayoutModeSchedulerDuration : PlayoutModeSchedulerBase<ProgramSche
DateTimeOffset durationFinish = nextState.DurationFinish.IfNone(SystemTime.MaxValueUtc);
var enumeratorClones = new Dictionary<CollectionKey, IMediaCollectionEnumerator>();
var enumeratorStates = new Dictionary<CollectionKey, CollectionEnumeratorState>();
foreach ((CollectionKey key, IMediaCollectionEnumerator enumerator) in collectionEnumerators)
{
IMediaCollectionEnumerator clone = enumerator.Clone(enumerator.State.Clone(), cancellationToken);
enumeratorClones.Add(key, clone);
enumeratorStates.Add(key, enumerator.State.Clone());
}
List<PlayoutItem> maybePlayoutItems = AddFiller(
nextState,
enumeratorClones,
collectionEnumerators,
scheduleItem,
playoutItem,
itemChapters,
@@ -147,16 +146,6 @@ public class PlayoutModeSchedulerDuration : PlayoutModeSchedulerBase<ProgramSche
// LogScheduledItem(scheduleItem, mediaItem, itemStartTime);
playoutItems.AddRange(maybePlayoutItems);
// update original enumerators
foreach ((CollectionKey key, IMediaCollectionEnumerator enumerator) in collectionEnumerators)
{
IMediaCollectionEnumerator clone = enumeratorClones[key];
while (enumerator.State.Seed != clone.State.Seed || enumerator.State.Index != clone.State.Index)
{
enumerator.MoveNext();
}
}
nextState = nextState with
{
CurrentTime = itemEndTimeWithFiller,
@@ -171,6 +160,12 @@ public class PlayoutModeSchedulerDuration : PlayoutModeSchedulerBase<ProgramSche
}
else
{
// reset enumerators
foreach ((CollectionKey key, IMediaCollectionEnumerator enumerator) in collectionEnumerators)
{
enumerator.ResetState(enumeratorStates[key]);
}
TimeSpan durationBlock = itemEndTimeWithFiller - itemStartTime;
if (itemEndTimeWithFiller - itemStartTime > scheduleItem.PlayoutDuration)
{
@@ -74,16 +74,15 @@ public class PlayoutModeSchedulerFlood : PlayoutModeSchedulerBase<ProgramSchedul
? GetStartTimeAfter(nextState with { InFlood = false }, peekScheduleItem)
: DateTimeOffset.MaxValue;
var enumeratorClones = new Dictionary<CollectionKey, IMediaCollectionEnumerator>();
var enumeratorStates = new Dictionary<CollectionKey, CollectionEnumeratorState>();
foreach ((CollectionKey key, IMediaCollectionEnumerator enumerator) in collectionEnumerators)
{
IMediaCollectionEnumerator clone = enumerator.Clone(enumerator.State.Clone(), cancellationToken);
enumeratorClones.Add(key, clone);
enumeratorStates.Add(key, enumerator.State.Clone());
}
List<PlayoutItem> maybePlayoutItems = AddFiller(
nextState,
enumeratorClones,
collectionEnumerators,
scheduleItem,
playoutItem,
itemChapters,
@@ -102,16 +101,6 @@ public class PlayoutModeSchedulerFlood : PlayoutModeSchedulerBase<ProgramSchedul
playoutItems.AddRange(maybePlayoutItems);
// LogScheduledItem(scheduleItem, mediaItem, itemStartTime);
// update original enumerators
foreach ((CollectionKey key, IMediaCollectionEnumerator enumerator) in collectionEnumerators)
{
IMediaCollectionEnumerator clone = enumeratorClones[key];
while (enumerator.State.Seed != clone.State.Seed || enumerator.State.Index != clone.State.Index)
{
enumerator.MoveNext();
}
}
nextState = nextState with
{
CurrentTime = itemEndTimeWithFiller,
@@ -125,6 +114,14 @@ public class PlayoutModeSchedulerFlood : PlayoutModeSchedulerBase<ProgramSchedul
contentEnumerator.MoveNext();
}
else
{
// reset enumerators
foreach ((CollectionKey key, IMediaCollectionEnumerator enumerator) in collectionEnumerators)
{
enumerator.ResetState(enumeratorStates[key]);
}
}
}
// _logger.LogDebug(
@@ -27,9 +27,10 @@ public class RandomizedMediaCollectionEnumerator : IMediaCollectionEnumerator
}
}
public IMediaCollectionEnumerator Clone(CollectionEnumeratorState state, CancellationToken cancellationToken)
public void ResetState(CollectionEnumeratorState state)
{
return new RandomizedMediaCollectionEnumerator(_mediaItems, state);
// seed never changes here, no need to reset
State.Index = state.Index;
}
public CollectionEnumeratorState State { get; }
@@ -31,9 +31,10 @@ public sealed class SeasonEpisodeMediaCollectionEnumerator : IMediaCollectionEnu
}
}
public IMediaCollectionEnumerator Clone(CollectionEnumeratorState state, CancellationToken cancellationToken)
public void ResetState(CollectionEnumeratorState state)
{
return new SeasonEpisodeMediaCollectionEnumerator(_sortedMediaItems, state);
// seed doesn't matter here
State.Index = state.Index;
}
public CollectionEnumeratorState State { get; }
@@ -43,9 +43,16 @@ public class ShuffleInOrderCollectionEnumerator : IMediaCollectionEnumerator
}
}
public IMediaCollectionEnumerator Clone(CollectionEnumeratorState state, CancellationToken cancellationToken)
public void ResetState(CollectionEnumeratorState state)
{
return new ShuffleInOrderCollectionEnumerator(_collections, state, _randomStartPoint, cancellationToken);
// only re-shuffle if needed
if (State.Seed != state.Seed)
{
_random = new Random(state.Seed);
_shuffled = Shuffle(_collections, _random);
}
State.Index = state.Index;
}
public CollectionEnumeratorState State { get; }
@@ -40,9 +40,16 @@ public class ShuffledMediaCollectionEnumerator : IMediaCollectionEnumerator
}
}
public IMediaCollectionEnumerator Clone(CollectionEnumeratorState state, CancellationToken cancellationToken)
public void ResetState(CollectionEnumeratorState state)
{
return new ShuffledMediaCollectionEnumerator(_mediaItems, state, cancellationToken);
// only re-shuffle if needed
if (State.Seed != state.Seed)
{
_random = new CloneableRandom(state.Seed);
_shuffled = Shuffle(_mediaItems, _random);
}
State.Index = state.Index;
}
public CollectionEnumeratorState State { get; }
@@ -10,8 +10,6 @@ namespace ErsatzTV.Infrastructure.Scheduling;
public class MultiEpisodeShuffleCollectionEnumerator : IMediaCollectionEnumerator
{
private readonly CancellationToken _cancellationToken;
private readonly IList<MediaItem> _mediaItems;
private readonly IScriptEngine _scriptEngine;
private readonly ILogger _logger;
private readonly int _mediaItemCount;
private readonly Dictionary<int, List<MediaItem>> _mediaItemGroups;
@@ -21,15 +19,13 @@ public class MultiEpisodeShuffleCollectionEnumerator : IMediaCollectionEnumerato
private readonly Lazy<Option<TimeSpan>> _lazyMinimumDuration;
public MultiEpisodeShuffleCollectionEnumerator(
IList<MediaItem> mediaItems,
ICollection<MediaItem> mediaItems,
CollectionEnumeratorState state,
IScriptEngine scriptEngine,
string scriptFile,
ILogger logger,
CancellationToken cancellationToken)
{
_mediaItems = mediaItems;
_scriptEngine = scriptEngine;
_logger = logger;
_cancellationToken = cancellationToken;
@@ -91,15 +87,16 @@ public class MultiEpisodeShuffleCollectionEnumerator : IMediaCollectionEnumerato
}
}
public IMediaCollectionEnumerator Clone(CollectionEnumeratorState state, CancellationToken cancellationToken)
public void ResetState(CollectionEnumeratorState state)
{
return new MultiEpisodeShuffleCollectionEnumerator(
_mediaItems,
state,
_scriptEngine,
null,
_logger,
cancellationToken);
// only re-shuffle if needed
if (State.Seed != state.Seed)
{
_random = new CloneableRandom(state.Seed);
_shuffled = Shuffle(_random);
}
State.Index = state.Index;
}
public CollectionEnumeratorState State { get; }