using WebDrop.Core; namespace WebDrop.Api; /// 定期清理过期条目、下载达上限的条目、过期频道,并低频清理孤立 blob。 public sealed class SweepWorker(ChannelService service, ShareService shares, WebDropOptions options, ILogger logger) : BackgroundService { private const int OrphanSweepEvery = 20; protected override async Task ExecuteAsync(CancellationToken stoppingToken) { var interval = TimeSpan.FromSeconds(Math.Max(1, options.SweepIntervalSeconds)); using var timer = new PeriodicTimer(interval); int round = 0; do { try { bool orphans = round++ % OrphanSweepEvery == 0; int removed = await Task.Run(() => service.Sweep(orphans) + shares.Sweep(), stoppingToken).ConfigureAwait(false); if (removed > 0) logger.LogInformation("清理了 {Count} 个过期条目或频道", removed); } catch (OperationCanceledException) when (stoppingToken.IsCancellationRequested) { break; } catch (Exception e) { // 只记录异常类型,不记录可能含频道 id 的细节 logger.LogError("清理任务失败:{Type}", e.GetType().Name); } } while (await WaitAsync(timer, stoppingToken).ConfigureAwait(false)); } private static async Task WaitAsync(PeriodicTimer timer, CancellationToken ct) { try { return await timer.WaitForNextTickAsync(ct).ConfigureAwait(false); } catch (OperationCanceledException) { return false; } } }