feat(engine): RetentionService — hourly executions sweep

This commit is contained in:
Claude
2026-08-28 15:07:58 +00:00
parent 0895dc5f8f
commit 5137591b8a
3 changed files with 101 additions and 0 deletions

View File

@@ -0,0 +1,52 @@
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using VolcanicCore.Persistence.Repositories;
namespace VolcanicCore.Api.Engine;
public sealed class RetentionService : BackgroundService
{
private static readonly TimeSpan SweepInterval = TimeSpan.FromHours(1);
private readonly ExecutionRepository _executions;
private readonly int _retentionDays;
private readonly int _keepPerWorkflow;
private readonly ILogger<RetentionService> _log;
public RetentionService(
ExecutionRepository executions, int retentionDays, int keepPerWorkflow, ILogger<RetentionService> log)
{
_executions = executions;
_retentionDays = retentionDays;
_keepPerWorkflow = keepPerWorkflow;
_log = log;
}
// Public so tests can invoke it deterministically.
public void RunSweep()
{
try
{
var oldCutoff = DateTimeOffset.UtcNow.AddDays(-_retentionDays);
var byAge = _executions.PruneOlderThan(oldCutoff);
var overCap = _executions.PruneOldestPerWorkflow(_keepPerWorkflow);
_log.LogInformation("retention sweep: pruned {ByAge} by age, {OverCap} by per-workflow cap",
byAge, overCap);
}
catch (Exception ex)
{
_log.LogError(ex, "retention sweep failed");
}
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
RunSweep();
while (!stoppingToken.IsCancellationRequested)
{
try { await Task.Delay(SweepInterval, stoppingToken); }
catch (TaskCanceledException) { break; }
RunSweep();
}
}
}

View File

@@ -125,6 +125,12 @@ builder.Services.AddSingleton<TriggerHost>();
builder.Services.AddSingleton<IWorkflowLifecycle>(sp => sp.GetRequiredService<TriggerHost>());
builder.Services.AddHostedService(sp => sp.GetRequiredService<TriggerHost>());
builder.Services.AddHostedService(sp => new RetentionService(
sp.GetRequiredService<ExecutionRepository>(),
settings.ExecutionRetentionDays,
settings.ExecutionKeepPerWorkflow,
sp.GetRequiredService<ILogger<RetentionService>>()));
var app = builder.Build();
// Apply migrations at boot.