using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; namespace TeleWave.Infrastructure.Media; /// /// Расписание уборки uploads/ (сама уборка — ): проход на старте /// и раз в час. Удаление недописанного файла на месте /// () закрывает штатные обрывы, этот сервис — /// страховка от аварийного рестарта посреди заливки. /// public sealed class UploadsCleanupBackgroundService( MediaPathResolver paths, IOptions options, ILogger logger ) : BackgroundService { /// Как часто заглядывать в каталог. Порог измеряется часами — чаще незачем. private static readonly TimeSpan Period = TimeSpan.FromHours(1); private readonly StorageOptions _storage = options.Value; protected override async Task ExecuteAsync(CancellationToken stoppingToken) { if (_storage.StaleUploadHours <= 0) { logger.LogInformation("Уборка uploads/ выключена (Storage:StaleUploadHours = 0)."); return; } var retention = TimeSpan.FromHours(_storage.StaleUploadHours); paths.EnsureDirectories(); // Первый проход сразу: после аварийного рестарта недописанное лежит с прошлого запуска. UploadsCleaner.Sweep(paths, retention, logger); using var timer = new PeriodicTimer(Period); while (await timer.WaitForNextTickAsync(stoppingToken)) UploadsCleaner.Sweep(paths, retention, logger); } }