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; }
}
}