Browse Source

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

pull/1319/head
Jason Dove 2 years ago committed by GitHub
parent
commit
015f5e9798
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      ErsatzTV.Core/Domain/CollectionEnumeratorState.cs
  2. 2
      ErsatzTV.Core/Interfaces/Scheduling/IMediaCollectionEnumerator.cs
  3. 5
      ErsatzTV.Core/Scheduling/ChronologicalMediaCollectionEnumerator.cs
  4. 5
      ErsatzTV.Core/Scheduling/CustomOrderCollectionEnumerator.cs
  5. 23
      ErsatzTV.Core/Scheduling/PlayoutModeSchedulerDuration.cs
  6. 25
      ErsatzTV.Core/Scheduling/PlayoutModeSchedulerFlood.cs
  7. 5
      ErsatzTV.Core/Scheduling/RandomizedMediaCollectionEnumerator.cs
  8. 5
      ErsatzTV.Core/Scheduling/SeasonEpisodeMediaCollectionEnumerator.cs
  9. 11
      ErsatzTV.Core/Scheduling/ShuffleInOrderCollectionEnumerator.cs
  10. 11
      ErsatzTV.Core/Scheduling/ShuffledMediaCollectionEnumerator.cs
  11. 23
      ErsatzTV.Infrastructure/Scheduling/MultiEpisodeShuffleCollectionEnumerator.cs

2
ErsatzTV.Core/Domain/CollectionEnumeratorState.cs

@ -4,5 +4,5 @@ public class CollectionEnumeratorState @@ -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 };
}

2
ErsatzTV.Core/Interfaces/Scheduling/IMediaCollectionEnumerator.cs

@ -4,7 +4,7 @@ namespace ErsatzTV.Core.Interfaces.Scheduling; @@ -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();

5
ErsatzTV.Core/Scheduling/ChronologicalMediaCollectionEnumerator.cs

@ -31,9 +31,10 @@ public sealed class ChronologicalMediaCollectionEnumerator : IMediaCollectionEnu @@ -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; }

5
ErsatzTV.Core/Scheduling/CustomOrderCollectionEnumerator.cs

@ -35,9 +35,10 @@ public class CustomOrderCollectionEnumerator : IMediaCollectionEnumerator @@ -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; }

23
ErsatzTV.Core/Scheduling/PlayoutModeSchedulerDuration.cs

@ -122,16 +122,15 @@ public class PlayoutModeSchedulerDuration : PlayoutModeSchedulerBase<ProgramSche @@ -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 @@ -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 @@ -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)
{

25
ErsatzTV.Core/Scheduling/PlayoutModeSchedulerFlood.cs

@ -74,16 +74,15 @@ public class PlayoutModeSchedulerFlood : PlayoutModeSchedulerBase<ProgramSchedul @@ -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 @@ -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 @@ -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(

5
ErsatzTV.Core/Scheduling/RandomizedMediaCollectionEnumerator.cs

@ -27,9 +27,10 @@ public class RandomizedMediaCollectionEnumerator : IMediaCollectionEnumerator @@ -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; }

5
ErsatzTV.Core/Scheduling/SeasonEpisodeMediaCollectionEnumerator.cs

@ -31,9 +31,10 @@ public sealed class SeasonEpisodeMediaCollectionEnumerator : IMediaCollectionEnu @@ -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; }

11
ErsatzTV.Core/Scheduling/ShuffleInOrderCollectionEnumerator.cs

@ -43,9 +43,16 @@ public class ShuffleInOrderCollectionEnumerator : IMediaCollectionEnumerator @@ -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; }

11
ErsatzTV.Core/Scheduling/ShuffledMediaCollectionEnumerator.cs

@ -40,9 +40,16 @@ public class ShuffledMediaCollectionEnumerator : IMediaCollectionEnumerator @@ -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; }

23
ErsatzTV.Infrastructure/Scheduling/MultiEpisodeShuffleCollectionEnumerator.cs

@ -10,8 +10,6 @@ namespace ErsatzTV.Infrastructure.Scheduling; @@ -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 @@ -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 @@ -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; }

Loading…
Cancel
Save