Refactor GridScheduleGenerator and related models for improved repeat slot handling
Updated the GridScheduleGenerator to utilize a new PlanningRepeatWindow structure for managing repeat slots, enhancing the logic for loading repeat units. The LoadRepeatUnitsAsync method was modified to accept a channel ID and repeat window, ensuring accurate retrieval of past entries. Additionally, the PlanningSlot record was updated to include the new RepeatWindow property, and the SchedulePlanner was adjusted to collect repeat units based on the updated logic. Enhanced unit tests to verify the correct behavior of repeat slot functionality, ensuring that overlaps and elastic start times are handled appropriately.
This commit is contained in:
@@ -379,10 +379,11 @@ public sealed class GridScheduleGenerator(
|
||||
? groupElements
|
||||
: [];
|
||||
|
||||
var repeatUnits =
|
||||
slot.SlotKind == SlotKind.Repeat
|
||||
? await LoadRepeatUnitsAsync(channel, slot, item, cancellationToken)
|
||||
: null;
|
||||
var repeatWindow =
|
||||
slot.SlotKind == SlotKind.Repeat ? BuildRepeatWindow(channel, slot, item) : null;
|
||||
var repeatUnits = repeatWindow is null
|
||||
? null
|
||||
: await LoadRepeatUnitsAsync(channel.Id, repeatWindow, startUtc, cancellationToken);
|
||||
|
||||
var strategy = ToPlanningStrategy(SlotStrategy.FromJson(slot.StrategyJson));
|
||||
var cursor = states.TryGetValue(slot.Id, out var state)
|
||||
@@ -410,6 +411,7 @@ public sealed class GridScheduleGenerator(
|
||||
elements,
|
||||
cursor,
|
||||
repeatUnits,
|
||||
repeatWindow,
|
||||
BuildJunction(
|
||||
slot.JunctionBetweenId,
|
||||
junctions,
|
||||
@@ -579,20 +581,16 @@ public sealed class GridScheduleGenerator(
|
||||
: null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Что играло в точке, на которую ссылается слот-повтор. Читается уже записанная лента того же
|
||||
/// канала — стратегий и состояния повтору не нужно.
|
||||
/// </summary>
|
||||
private async Task<IReadOnlyList<PlanningUnit>> LoadRepeatUnitsAsync(
|
||||
/// <summary>Отрезок ленты, на который ссылается слот-повтор, в UTC.</summary>
|
||||
private static PlanningRepeatWindow? BuildRepeatWindow(
|
||||
Channel channel,
|
||||
Slot slot,
|
||||
ScheduledSlot scheduled,
|
||||
CancellationToken cancellationToken
|
||||
ScheduledSlot scheduled
|
||||
)
|
||||
{
|
||||
var source = RepeatSource.FromJson(slot.RepeatSourceJson);
|
||||
if (source is null)
|
||||
return [];
|
||||
return null;
|
||||
|
||||
var offset = TimeSpan.FromMinutes(channel.UtcOffsetMinutes);
|
||||
var sourceDate = scheduled.BroadcastDate.AddDays(-Math.Max(1, source.DaysAgo));
|
||||
@@ -602,15 +600,36 @@ public sealed class GridScheduleGenerator(
|
||||
offset,
|
||||
channel.DayStartTime
|
||||
);
|
||||
var to = from.AddMinutes(Math.Max(1, source.DurationMinutes));
|
||||
|
||||
return new PlanningRepeatWindow(from, from.AddMinutes(Math.Max(1, source.DurationMinutes)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Что играло в точке, на которую ссылается слот-повтор, по уже записанной ленте. Берётся только
|
||||
/// прошлое до начала прогона: всё, что позже, планировщик найдёт в собственной ленте, и без этой
|
||||
/// границы предпросмотр складывал бы реальный эфир с симулированным.
|
||||
///
|
||||
/// Условие — пересечение с окном, а не попадание старта в него: старты эластичные, и фильм,
|
||||
/// начавшийся на десять минут раньше объявленного времени, по старту не нашёлся бы.
|
||||
/// </summary>
|
||||
private async Task<IReadOnlyList<PlanningUnit>> LoadRepeatUnitsAsync(
|
||||
Guid channelId,
|
||||
PlanningRepeatWindow window,
|
||||
DateTimeOffset startUtc,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
var from = window.FromUtc;
|
||||
var to = window.ToUtc;
|
||||
|
||||
var entries = await dbContext
|
||||
.ScheduleEntries.AsNoTracking()
|
||||
.Where(e =>
|
||||
e.ChannelId == channel.Id
|
||||
e.ChannelId == channelId
|
||||
&& e.Kind == ScheduleEntryKind.Program
|
||||
&& e.StartsAtUtc >= from
|
||||
&& e.StartsAtUtc < to
|
||||
&& e.EndsAtUtc > from
|
||||
&& e.StartsAtUtc < startUtc
|
||||
)
|
||||
.OrderBy(e => e.StartsAtUtc)
|
||||
.Select(e => new
|
||||
|
||||
Reference in New Issue
Block a user