using Microsoft.Extensions.DependencyInjection; using System.Threading; using NCrontab; using LCU.API.Internal.Operations.IncentiveApiLib.Persistence; using LCU.Library.Internal.LCUHostedService.LCUBackgroundService; using LCU.API.Internal.Operations.IncentiveApi.Configuration; using LCU.API.Internal.Operations.IncentiveApi.Utilities; namespace LCU.API.Internal.Operations.IncentiveApi.HostedServices; public class ApplicationDbIntegrityHostedService : LCUBackgroundService, IApplicationDbIntegrityHostedService { private readonly ApiConfiguration _apiConfiguration; private readonly IServiceScopeFactory _scopeFactory; private readonly CrontabSchedule _applicationDbIntegritySchedule; private DateTime _nextScheduleRun; public const string DefaultErrorMonitoringCronPattern = "0 0 * * *"; private CancellationToken _cancellationToken; public ApplicationDbIntegrityHostedService(IServiceScopeFactory scopeFactory, ApiConfiguration apiConfiguration) { _scopeFactory = scopeFactory; _apiConfiguration = apiConfiguration; _applicationDbIntegritySchedule = CronHelpers.SetCronSchedule(_apiConfiguration.ApplicationDbIntegrityCronSchedule, DefaultErrorMonitoringCronPattern); _nextScheduleRun = _applicationDbIntegritySchedule.GetNextOccurrence(DateTime.Now); _cancellationToken = new CancellationToken(); } protected override async Task ExecuteAsync(CancellationToken cancellationToken) { Log.Debug("ApplicationDbIntegrity Hosted Service is starting."); try { while (!cancellationToken.IsCancellationRequested) { await Task.Delay(UntilNextExecution(), cancellationToken); using (var scope = _scopeFactory.CreateScope()) { Log.Debug("Running ApplicationDbIntegrity Service"); await scope.ServiceProvider.GetRequiredService().AppUserIdIntegrityMaintenanceSucceeded(_cancellationToken); } _nextScheduleRun = _applicationDbIntegritySchedule.GetNextOccurrence(DateTime.Now); } } catch (OperationCanceledException taskCanceledEx) { Log.Error(taskCanceledEx, $"Manual start/stop of ApplicationDbIntegrity Hosted Service was initiated."); } catch (Exception exception) { Log.Error(exception, "Error trying to startup main thread for ApplicationDbIntegrity Hosted Service"); } Log.Debug("ApplicationDbIntegrity Hosted Service is stopping."); } private int UntilNextExecution() => Math.Max(0, (int)_nextScheduleRun.Subtract(DateTime.Now).TotalMilliseconds); }