89 lines
2.9 KiB
C#
89 lines
2.9 KiB
C#
using System;
|
|
using Svrnty.CQRS.Events.Configuration;
|
|
using Svrnty.CQRS.Events.Abstractions.Storage;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.Extensions.Hosting;
|
|
using Microsoft.Extensions.Logging;
|
|
using Microsoft.Extensions.Options;
|
|
using Svrnty.CQRS.Events.Abstractions;
|
|
|
|
namespace Svrnty.CQRS.Events.Services;
|
|
|
|
/// <summary>
|
|
/// Background service that periodically cleans up old read receipts.
|
|
/// </summary>
|
|
public class ReadReceiptCleanupService : BackgroundService
|
|
{
|
|
private readonly IReadReceiptStore _readReceiptStore;
|
|
private readonly ILogger<ReadReceiptCleanupService> _logger;
|
|
private readonly ReadReceiptOptions _options;
|
|
|
|
public ReadReceiptCleanupService(
|
|
IReadReceiptStore readReceiptStore,
|
|
ILogger<ReadReceiptCleanupService> logger,
|
|
IOptions<ReadReceiptOptions> options)
|
|
{
|
|
_readReceiptStore = readReceiptStore ?? throw new ArgumentNullException(nameof(readReceiptStore));
|
|
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
|
_options = options?.Value ?? throw new ArgumentNullException(nameof(options));
|
|
}
|
|
|
|
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
|
{
|
|
if (!_options.EnableAutoCleanup)
|
|
{
|
|
_logger.LogInformation("Read receipt auto-cleanup is disabled");
|
|
return;
|
|
}
|
|
|
|
_logger.LogInformation(
|
|
"Read receipt cleanup service started (Interval: {Interval}, Retention: {Retention})",
|
|
_options.CleanupInterval,
|
|
_options.RetentionPeriod);
|
|
|
|
while (!stoppingToken.IsCancellationRequested)
|
|
{
|
|
try
|
|
{
|
|
await Task.Delay(_options.CleanupInterval, stoppingToken);
|
|
|
|
if (stoppingToken.IsCancellationRequested)
|
|
break;
|
|
|
|
await PerformCleanupAsync(stoppingToken);
|
|
}
|
|
catch (OperationCanceledException) when (stoppingToken.IsCancellationRequested)
|
|
{
|
|
// Normal shutdown
|
|
break;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error during read receipt cleanup");
|
|
// Continue running despite errors
|
|
}
|
|
}
|
|
|
|
_logger.LogInformation("Read receipt cleanup service stopped");
|
|
}
|
|
|
|
private async Task PerformCleanupAsync(CancellationToken cancellationToken)
|
|
{
|
|
var olderThan = DateTimeOffset.UtcNow.Subtract(_options.RetentionPeriod);
|
|
|
|
_logger.LogDebug("Starting read receipt cleanup (deleting receipts older than {OlderThan})", olderThan);
|
|
|
|
var deletedCount = await _readReceiptStore.CleanupAsync(olderThan, cancellationToken);
|
|
|
|
if (deletedCount > 0)
|
|
{
|
|
_logger.LogInformation("Cleaned up {DeletedCount} old read receipts", deletedCount);
|
|
}
|
|
else
|
|
{
|
|
_logger.LogDebug("No old read receipts to clean up");
|
|
}
|
|
}
|
|
}
|