Enhance ChannelDebugCollector and LibraryDebugCollector for improved data handling
ci / build-backend (push) Successful in 1m51s
ci / build-frontend (push) Successful in 50s
ci / tests (push) Successful in 1m33s
ci / sonar (push) Successful in 4m29s

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.
This commit is contained in:
Leonid Pershin
2026-07-31 04:27:06 +03:00
parent 375e0a810b
commit bd3ced3637
2 changed files with 39 additions and 34 deletions
@@ -33,6 +33,17 @@ public sealed class ChannelDebugCollector(
/// <summary>Сколько прошлого класть в дамп: сдвиги и повторы объясняются вчерашним эфиром.</summary>
private const int PastDays = 2;
/// <summary>
/// Координаты прогона: чей канал, по какому шаблону, на какой момент и на сколько суток вперёд.
/// Ездят вместе через всю сборку, поэтому и передаются вместе.
/// </summary>
private sealed record RunScope(
Channel Channel,
ScheduleTemplate Template,
DateTimeOffset Now,
int HorizonDays
);
public async Task<IReadOnlyList<DebugFile>> 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<ScheduleEntry> 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,
@@ -24,10 +24,13 @@ public sealed class LibraryDebugCollector(
{
public async Task<IReadOnlyList<DebugFile>> 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,
};
});