using LCU.Api.Internal.Dispatcher.Configurations; using LCU.Api.Internal.DispatcherSharedLib.Utilities; using LCU.Api.Internal.Dispatcher.Services.DispatcherOperationServices; using Microsoft.Extensions.DependencyInjection; using NCrontab; using System.Threading; using LCU.Library.Internal.LCUHostedService.LCUBackgroundService; namespace LCU.Api.Internal.Dispatcher.HostedServices; public class CleanUpJobsHostedService : LCUBackgroundService, ICleanUpJobsHostedService { private readonly ApiConfiguration _apiConfiguration; private readonly IServiceScopeFactory _scopeFactory; private readonly CrontabSchedule _cleanUpJobSchedule; private DateTime _nextScheduleRun; public const string DefaultCleanUpJobCronPattern = "* 22 * * *"; private CancellationToken _cancellationToken; public CleanUpJobsHostedService(IServiceScopeFactory scopeFactory, ApiConfiguration apiConfiguration) { _scopeFactory = scopeFactory; _apiConfiguration = apiConfiguration; _cleanUpJobSchedule = CronHelpers.SetCronSchedule(_apiConfiguration.CleanUpJobsCronSchedule, DefaultCleanUpJobCronPattern); _nextScheduleRun = _cleanUpJobSchedule.GetNextOccurrence(DateTime.Now); _cancellationToken = new CancellationToken(); } protected override async Task ExecuteAsync(CancellationToken cancellationToken) { if (!_apiConfiguration.FeatureFlags.RunCleanUpJobsHostedService) { Log.Error("Clean Up Job Hosted Service is disabled by feature flag. Service not started."); return; } Log.Debug("Dispatcher's Clean Up Job Hosted Service is starting."); try { while (!cancellationToken.IsCancellationRequested) { await Task.Delay(UntilNextExecution(), cancellationToken); // wait until next time using (var scope = _scopeFactory.CreateAsyncScope()) { Log.Debug("Running Clean Up Job Service"); await scope.ServiceProvider.GetRequiredService().PerformCleanUpJobs(_cancellationToken); } _nextScheduleRun = _cleanUpJobSchedule.GetNextOccurrence(DateTime.Now); } } catch(OperationCanceledException taskCanceledEx) { Log.Error(taskCanceledEx, $"Manual start/stop of Dispatcher's Clean Up Job Hosted Service was initiated."); } catch (Exception exception) { Log.Error(exception, "Error trying to startup main thread for Dispatcher's Clean Up Job Hosted Service"); } Log.Debug("Dispatcher's Clean Up Job Hosted Service is stopping."); } private int UntilNextExecution() => Math.Max(0, (int)_nextScheduleRun.Subtract(DateTime.Now).TotalMilliseconds); }