elsa-core/src/modules/Elsa.Retention/HostedServices/CleanupHostedService.cs
Sverre Winkelmans d899b674dc
Retention Module (#5344)
* Retention module

* Remove unused batch size

* Use ISystemClock instead of DateTime.Now

* Remove TargetFramework

* Use WorkflowInstanceManager

* Update using statement, remove cloneable from WorkflowInstanceFilter.cs

* Update project description and remove unnecessary properties

* Move to BackgroundService

* Generic retention module

---------

Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
2024-10-28 19:44:23 +01:00

55 lines
2.1 KiB
C#

using Elsa.Retention.Jobs;
using Elsa.Retention.Options;
using Medallion.Threading;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
namespace Elsa.Retention.HostedServices;
/// <summary>
/// Periodically wipes workflow instances and their execution logs.
/// </summary>
public class CleanupHostedService : BackgroundService
{
private readonly TimeSpan _interval;
private readonly ILogger<CleanupHostedService> _logger;
private readonly IServiceScopeFactory _serviceScopeFactory;
/// <summary>
/// Creates new Cleanup hosted service
/// </summary>
/// <param name="options"></param>
/// <param name="serviceScopeFactory"></param>
/// <param name="logger"></param>
public CleanupHostedService(IOptions<CleanupOptions> options, IServiceScopeFactory serviceScopeFactory, ILogger<CleanupHostedService> logger)
{
_serviceScopeFactory = serviceScopeFactory;
_logger = logger;
_interval = options.Value.SweepInterval;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
using IServiceScope scope = _serviceScopeFactory.CreateScope();
CleanupJob job = scope.ServiceProvider.GetRequiredService<CleanupJob>();
IDistributedLockProvider distributedLockProvider = scope.ServiceProvider.GetRequiredService<IDistributedLockProvider>();
await Task.Delay(_interval, stoppingToken);
await using IDistributedSynchronizationHandle handle = await distributedLockProvider.AcquireLockAsync(nameof(CleanupHostedService), cancellationToken: stoppingToken);
try
{
await job.ExecuteAsync(stoppingToken);
}
catch (Exception e)
{
_logger.LogError(e, "Failed to perform cleanup this time around. Next cleanup attempt will happen in {Interval}", _interval);
}
}
}
}