Initial project import
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
using MiaoJiZhang.Infrastructure.Persistence;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace MiaoJiZhang.Api.Services;
|
||||
|
||||
public class RecycleBinCleanupService(
|
||||
IServiceScopeFactory scopeFactory,
|
||||
ILogger<RecycleBinCleanupService> logger) : BackgroundService
|
||||
{
|
||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
{
|
||||
await Cleanup(stoppingToken);
|
||||
using var timer = new PeriodicTimer(TimeSpan.FromHours(24));
|
||||
while (await timer.WaitForNextTickAsync(stoppingToken))
|
||||
await Cleanup(stoppingToken);
|
||||
}
|
||||
|
||||
private async Task Cleanup(CancellationToken ct)
|
||||
{
|
||||
try
|
||||
{
|
||||
using var scope = scopeFactory.CreateScope();
|
||||
var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
|
||||
var cutoff = DateTime.UtcNow.AddDays(-30);
|
||||
var ids = await db.Transactions.IgnoreQueryFilters()
|
||||
.Where(t => t.IsDeleted && t.DeletedAt < cutoff)
|
||||
.Select(t => t.Id)
|
||||
.ToListAsync(ct);
|
||||
if (ids.Count == 0) return;
|
||||
|
||||
await db.ChatMessages
|
||||
.Where(message =>
|
||||
message.TransactionId.HasValue &&
|
||||
ids.Contains(message.TransactionId.Value))
|
||||
.ExecuteUpdateAsync(setters => setters
|
||||
.SetProperty(message => message.TransactionId, (long?)null)
|
||||
.SetProperty(message => message.Content, """{"deleted":true}"""), ct);
|
||||
await db.Transactions.IgnoreQueryFilters()
|
||||
.Where(t => ids.Contains(t.Id))
|
||||
.ExecuteDeleteAsync(ct);
|
||||
logger.LogInformation(
|
||||
"Permanently removed {Count} transactions after recycle-bin retention",
|
||||
ids.Count);
|
||||
}
|
||||
catch (OperationCanceledException) when (ct.IsCancellationRequested)
|
||||
{
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
logger.LogError(exception, "Recycle-bin cleanup failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user