From bd3ced3637ca7d247796bf4683f5cf5d0439bb6d Mon Sep 17 00:00:00 2001 From: Leonid Pershin Date: Fri, 31 Jul 2026 04:27:06 +0300 Subject: [PATCH] Enhance ChannelDebugCollector and LibraryDebugCollector for improved data handling Refactored the ChannelDebugCollector to introduce a new RunScope record, consolidating channel, template, and time horizon data for better readability and maintainability. Updated methods to utilize the new RunScope structure, enhancing the clarity of debug file generation. In the LibraryDebugCollector, added AsSplitQuery to optimize database queries and improve performance. Cleaned up unused parameters and ensured consistent handling of asset statuses. These changes aim to streamline debug data collection and improve overall efficiency. --- .../DebugExport/ChannelDebugCollector.cs | 60 ++++++++++--------- .../DebugExport/LibraryDebugCollector.cs | 13 ++-- 2 files changed, 39 insertions(+), 34 deletions(-) diff --git a/backend/src/TeleWave.Application/Programming/Planning/DebugExport/ChannelDebugCollector.cs b/backend/src/TeleWave.Application/Programming/Planning/DebugExport/ChannelDebugCollector.cs index 45713c9..d2dcd23 100644 --- a/backend/src/TeleWave.Application/Programming/Planning/DebugExport/ChannelDebugCollector.cs +++ b/backend/src/TeleWave.Application/Programming/Planning/DebugExport/ChannelDebugCollector.cs @@ -33,6 +33,17 @@ public sealed class ChannelDebugCollector( /// Сколько прошлого класть в дамп: сдвиги и повторы объясняются вчерашним эфиром. private const int PastDays = 2; + /// + /// Координаты прогона: чей канал, по какому шаблону, на какой момент и на сколько суток вперёд. + /// Ездят вместе через всю сборку, поэтому и передаются вместе. + /// + private sealed record RunScope( + Channel Channel, + ScheduleTemplate Template, + DateTimeOffset Now, + int HorizonDays + ); + public async Task> CollectAsync( Channel channel, ScheduleTemplate template, @@ -41,6 +52,7 @@ public sealed class ChannelDebugCollector( ) { var horizonDays = Math.Max(1, _options.HorizonDays); + var scope = new RunScope(channel, template, now, horizonDays); var from = now.AddDays(-PastDays); var to = now.AddDays(horizonDays); @@ -108,11 +120,8 @@ public sealed class ChannelDebugCollector( return [ - new DebugFile("README.md", Readme(channel, now, horizonDays)), - new DebugFile( - "summary.json", - Summary(channel, template, now, horizonDays, grid, entries, preview, drift) - ), + new DebugFile("README.md", Readme(scope)), + new DebugFile("summary.json", Summary(scope, grid, entries, preview, drift)), new DebugFile("drift.json", DriftFacts(drift)), new DebugFile("channel.json", ChannelFacts(channel)), new DebugFile("template.json", TemplateFacts(template, groupNames, junctionNames)), @@ -239,11 +248,11 @@ public sealed class ChannelDebugCollector( }; } - private static string Readme(Channel channel, DateTimeOffset now, int horizonDays) => + private static string Readme(RunScope scope) => $""" - # Отладочный дамп канала «{channel.Name}» + # Отладочный дамп канала «{scope.Channel.Name}» - Собран: {now:yyyy-MM-dd HH:mm:ss} UTC. Горизонт планирования: {horizonDays} сут., + Собран: {scope.Now:yyyy-MM-dd HH:mm:ss} UTC. Горизонт планирования: {scope.HorizonDays} сут., прошлое в дампе: {PastDays} сут. - `summary.json` — что за канал, сколько чего собралось, свод предупреждений. @@ -276,16 +285,13 @@ public sealed class ChannelDebugCollector( пошло меньше». `groups.json` рядом — только те группы, что участвуют в этом канале. Времена везде UTC. Время канала = UTC{( - channel.UtcOffsetMinutes < 0 ? "-" : "+" - )}{Math.Abs(channel.UtcOffsetMinutes) / 60:00}:{Math.Abs(channel.UtcOffsetMinutes) + scope.Channel.UtcOffsetMinutes < 0 ? "-" : "+" + )}{Math.Abs(scope.Channel.UtcOffsetMinutes) / 60:00}:{Math.Abs(scope.Channel.UtcOffsetMinutes) % 60:00}. """; private object Summary( - Channel channel, - ScheduleTemplate template, - DateTimeOffset now, - int horizonDays, + RunScope scope, EffectiveGrid grid, IReadOnlyList entries, PlanningResult? preview, @@ -293,27 +299,27 @@ public sealed class ChannelDebugCollector( ) => new { - CollectedAtUtc = now, + CollectedAtUtc = scope.Now, Channel = new { - channel.Id, - channel.Name, - channel.Slug, - channel.IsEnabled, + scope.Channel.Id, + scope.Channel.Name, + scope.Channel.Slug, + scope.Channel.IsEnabled, }, Scheduler = new { - HorizonDays = horizonDays, + scope.HorizonDays, _options.RetentionDays, _options.TickMinutes, }, Template = new { - template.Id, - template.Revision, - template.HasPendingChanges, - Layers = template.Layers.Count, - Slots = template.Layers.Sum(l => l.Slots.Count), + scope.Template.Id, + scope.Template.Revision, + scope.Template.HasPendingChanges, + Layers = scope.Template.Layers.Count, + Slots = scope.Template.Layers.Sum(l => l.Slots.Count), }, Grid = new { Instances = grid.Slots.Count, Background = grid.Background.Count }, Drift = DriftSummary(drift), @@ -436,7 +442,7 @@ public sealed class ChannelDebugCollector( scheduled.Slot.Id, scheduled.Slot.Title, scheduled.BroadcastDate, - StartUtc = scheduled.StartUtc, + scheduled.StartUtc, EndUtc = scheduled.StartUtc.AddMinutes(scheduled.Slot.TargetDurationMinutes), scheduled.Slot.TargetDurationMinutes, scheduled.Slot.SlotKind, @@ -561,7 +567,7 @@ public sealed class ChannelDebugCollector( Slot = w.SlotId is { } id ? slotTitles.GetValueOrDefault(id) : null, w.Details, }), - Cursors = preview.Cursors, + preview.Cursors, Items = preview.Items.Select(item => new { item.StartsAtUtc, diff --git a/backend/src/TeleWave.Application/Programming/Planning/DebugExport/LibraryDebugCollector.cs b/backend/src/TeleWave.Application/Programming/Planning/DebugExport/LibraryDebugCollector.cs index 0335dd7..6d4430a 100644 --- a/backend/src/TeleWave.Application/Programming/Planning/DebugExport/LibraryDebugCollector.cs +++ b/backend/src/TeleWave.Application/Programming/Planning/DebugExport/LibraryDebugCollector.cs @@ -24,10 +24,13 @@ public sealed class LibraryDebugCollector( { public async Task> CollectAsync(CancellationToken cancellationToken) { + // Раздельными запросами: у шоу и серии, и жанры, и в одном join строки перемножились бы — + // 788 серий на три жанра дают 2364 строки вместо 791 на одном только сериале. var shows = await dbContext .Shows.AsNoTracking() .Include(s => s.Episodes) .Include(s => s.Genres) + .AsSplitQuery() .ToListAsync(cancellationToken); var genres = await dbContext @@ -42,8 +45,6 @@ public sealed class LibraryDebugCollector( a.Status, a.Duration, a.SegmentCount, - a.Width, - a.Height, a.ErrorMessage )) .ToDictionaryAsync(a => a.Id, cancellationToken); @@ -168,7 +169,7 @@ public sealed class LibraryDebugCollector( s.Group.Name, CachedUnits = s.Group.UnitCount, ActualUnits = s.Units, - PlayableUnits = s.PlayableUnits, + s.PlayableUnits, s.Group.StatsComputedAt, }), }; @@ -181,8 +182,6 @@ public sealed class LibraryDebugCollector( MediaAssetStatus Status, TimeSpan? Duration, int? SegmentCount, - int? Width, - int? Height, string? ErrorMessage ); @@ -251,7 +250,7 @@ public sealed class LibraryDebugCollector( episode.AirDate, episode.MediaAssetId, File = asset?.OriginalFileName, - Status = asset?.Status, + asset?.Status, Minutes = asset?.Duration is { } duration ? Math.Round(duration.TotalMinutes, 2) : (double?)null, @@ -334,7 +333,7 @@ public sealed class LibraryDebugCollector( Seconds = asset?.Duration is { } duration ? Math.Round(duration.TotalSeconds, 1) : (double?)null, - Status = asset?.Status, + asset?.Status, File = asset?.OriginalFileName, }; });