Refactor various classes to initialize lists with empty array syntax for improved clarity and consistency. Update Program.cs to remove unnecessary partial class declaration due to changes in ASP.NET Core 10. Enhance MediaPathResolver by making AssetRelativePath static for better accessibility. Adjust MediaClaimingBackgroundService to centralize idle polling logic. Improve SignalQueue's WaitAsync method for clearer intent in signal draining.
This commit is contained in:
@@ -109,7 +109,7 @@ public sealed class FfmpegBumperRenderer(
|
||||
segmentCount,
|
||||
spec.Width,
|
||||
spec.Height,
|
||||
paths.AssetRelativePath(assetId)
|
||||
MediaPathResolver.AssetRelativePath(assetId)
|
||||
);
|
||||
}
|
||||
finally
|
||||
|
||||
@@ -81,7 +81,7 @@ public sealed class FfmpegMediaProcessor(
|
||||
outHeight,
|
||||
"h264",
|
||||
"aac",
|
||||
paths.AssetRelativePath(assetId)
|
||||
MediaPathResolver.AssetRelativePath(assetId)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -26,8 +26,10 @@ internal abstract class MediaClaimingBackgroundService<TJob>(
|
||||
) : BackgroundService
|
||||
where TJob : class
|
||||
{
|
||||
// Периодически перепроверяем БД, даже если сигнал не пришёл — страховка на любой случай.
|
||||
private static readonly TimeSpan IdlePoll = TimeSpan.FromSeconds(30);
|
||||
// Период опроса вынесен в неродовой класс: статическое поле обобщённого типа существует
|
||||
// отдельной копией на каждую замкнутую специализацию, то есть выглядит общей константой,
|
||||
// не будучи ею. Здесь значение одинаковое и вреда нет, но читателя это вводит в заблуждение.
|
||||
private static TimeSpan IdlePoll => MediaClaimingDefaults.IdlePoll;
|
||||
|
||||
/// <summary>true — воркер обслуживает только сгенерированные ассеты, false — только остальные.</summary>
|
||||
protected abstract bool HandlesGenerated { get; }
|
||||
@@ -238,3 +240,10 @@ internal abstract class MediaClaimingBackgroundService<TJob>(
|
||||
? x => x.Status == status && x.Source == MediaSource.Generated
|
||||
: x => x.Status == status && x.Source != MediaSource.Generated;
|
||||
}
|
||||
|
||||
/// <summary>Общие для всех воркеров значения — одно на процесс, а не на специализацию.</summary>
|
||||
internal static class MediaClaimingDefaults
|
||||
{
|
||||
/// <summary>Периодически перепроверяем БД, даже если сигнал не пришёл — страховка на любой случай.</summary>
|
||||
public static readonly TimeSpan IdlePoll = TimeSpan.FromSeconds(30);
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ public sealed class MediaPathResolver
|
||||
public string AssetDir(Guid assetId) =>
|
||||
EnsureWithinRoot(Path.Combine(AssetsDir, assetId.ToString("N")));
|
||||
|
||||
public string AssetRelativePath(Guid assetId) => $"assets/{assetId:N}";
|
||||
public static string AssetRelativePath(Guid assetId) => $"assets/{assetId:N}";
|
||||
|
||||
/// <summary>Путь к файлу сегмента внутри каталога ассета (имя файла проверяется на traversal).</summary>
|
||||
public string SegmentPath(Guid assetId, string fileName)
|
||||
|
||||
@@ -20,7 +20,10 @@ public abstract class SignalQueue
|
||||
public async ValueTask WaitAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
await _channel.Reader.ReadAsync(cancellationToken);
|
||||
// Сдренировать накопившиеся сигналы — работу всё равно берём из БД пачкой.
|
||||
while (_channel.Reader.TryRead(out _)) { }
|
||||
while (_channel.Reader.TryRead(out _))
|
||||
{
|
||||
// Тело пустое намеренно: сигналы дренируются ради побочного эффекта чтения — работу
|
||||
// обработчик всё равно берёт из БД пачкой, и сами значения не нужны.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace TeleWave.Infrastructure.Metadata;
|
||||
public sealed class MetadataProviderResolver : IMetadataProviderResolver
|
||||
{
|
||||
private readonly Dictionary<string, IMetadataProvider> _byKey;
|
||||
private readonly List<string> _available = new();
|
||||
private readonly List<string> _available = [];
|
||||
|
||||
public MetadataProviderResolver(
|
||||
IEnumerable<IMetadataProvider> providers,
|
||||
|
||||
Reference in New Issue
Block a user