43 lines
1.6 KiB
C#
43 lines
1.6 KiB
C#
using WebDrop.Core;
|
|
|
|
namespace WebDrop.Api;
|
|
|
|
/// <summary>定期清理过期条目、下载达上限的条目、过期频道,并低频清理孤立 blob。</summary>
|
|
public sealed class SweepWorker(ChannelService service, ShareService shares, WebDropOptions options, ILogger<SweepWorker> 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<bool> WaitAsync(PeriodicTimer timer, CancellationToken ct)
|
|
{
|
|
try { return await timer.WaitForNextTickAsync(ct).ConfigureAwait(false); }
|
|
catch (OperationCanceledException) { return false; }
|
|
}
|
|
}
|