feat(server): implement sealed share lifecycle

Signed-off-by: JustMe <mr.toing@outlook.com>
This commit is contained in:
justme committed 2026-10-02 00:59:56 +08:00
1 parent e02e024605
commit 42b93ae2d8
45 files changed
+6327

No files matched your search

+42
View File
@@ -0,0 +1,42 @@
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; }
}
}