using Data; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; namespace Infrastructure.Events; /// /// Background service that periodically cleans up old events /// public class EventCleanupService : BackgroundService { private readonly IServiceProvider _serviceProvider; private readonly ILogger _logger; private readonly TimeSpan _cleanupInterval = TimeSpan.FromHours(4); // Run every 4 hours private readonly int _retentionDays = 30; // Keep events for 30 days public EventCleanupService(IServiceProvider serviceProvider, ILogger logger) { _serviceProvider = serviceProvider; _logger = logger; } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { _logger.LogInformation("Event cleanup service started. Interval: {interval}, Retention: {retention} days", _cleanupInterval, _retentionDays); while (!stoppingToken.IsCancellationRequested) { try { if (stoppingToken.IsCancellationRequested) { break; } await PerformCleanupAsync(); await Task.Delay(_cleanupInterval, stoppingToken); } catch (OperationCanceledException) { // Service is stopping break; } catch (Exception ex) { _logger.LogError(ex, "Error during event cleanup"); } } _logger.LogInformation("Event cleanup service stopped"); } private async Task PerformCleanupAsync() { try { using var scope = _serviceProvider.CreateScope(); var context = scope.ServiceProvider.GetRequiredService(); var cutoffDate = DateTime.UtcNow.AddDays(-_retentionDays); await context.Events .Where(e => e.Timestamp < cutoffDate) .ExecuteDeleteAsync(); } catch (Exception ex) { _logger.LogError(ex, "Failed to perform event cleanup"); } } public override async Task StopAsync(CancellationToken cancellationToken) { _logger.LogInformation("Event cleanup service stopping..."); await base.StopAsync(cancellationToken); } }