using InboxIntel.Infrastructure.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; namespace InboxIntel.Infrastructure.Retention; /// /// Daily driver for (AUDIT H-3). Exits immediately when both /// retention knobs are 0 (the default) so existing deployments see no behaviour change. /// public class RetentionWorker : BackgroundService { private readonly IServiceScopeFactory _scopeFactory; private readonly DataRetentionOptions _options; private readonly ILogger _logger; public RetentionWorker(IServiceScopeFactory scopeFactory, IOptions options, ILogger logger) { _scopeFactory = scopeFactory; _options = options.Value; _logger = logger; } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { if (_options.PurgeTrashedAfterDays <= 0 && _options.PurgeAllAfterDays <= 0) { _logger.LogDebug("RetentionWorker idle: retention is disabled (all knobs 0)."); return; } _logger.LogInformation("RetentionWorker started; trashed>{Trashed}d, all>{All}d", _options.PurgeTrashedAfterDays, _options.PurgeAllAfterDays); while (!stoppingToken.IsCancellationRequested) { try { using var scope = _scopeFactory.CreateScope(); var service = scope.ServiceProvider.GetRequiredService(); await service.PurgeAsync(stoppingToken); } catch (OperationCanceledException) when (stoppingToken.IsCancellationRequested) { break; } catch (Exception ex) { _logger.LogError(ex, "Retention purge failed; will retry next cycle."); } await Task.Delay(TimeSpan.FromHours(24), stoppingToken); } } }