110 lines
3.2 KiB
C#
110 lines
3.2 KiB
C#
using Microsoft.Extensions.Hosting;
|
|
using Microsoft.Extensions.Logging;
|
|
using System.Timers;
|
|
using e_suite.Scheduler.Jobs;
|
|
using e_suite.Scheduler.Scheduler;
|
|
using eSuite.Core.Clock;
|
|
|
|
namespace e_suite.Scheduler;
|
|
|
|
public class TimedHostedService : IHostedService
|
|
{
|
|
private readonly List<ScheduledJob> _jobs = [];
|
|
private readonly ILogger _logger;
|
|
private readonly IServiceProvider _serviceProvider;
|
|
private readonly IClock _clock;
|
|
private readonly System.Timers.Timer _timer;
|
|
|
|
public TimedHostedService(ILogger logger, IServiceProvider serviceProvider, IClock clock )
|
|
{
|
|
_timer = new System.Timers.Timer
|
|
{
|
|
Interval = 10000,
|
|
AutoReset = true,
|
|
};
|
|
|
|
_timer.Elapsed += ExecuteTimer;
|
|
|
|
_logger = logger;
|
|
_serviceProvider = serviceProvider;
|
|
_clock = clock;
|
|
}
|
|
|
|
public Task StartAsync(CancellationToken cancellationToken)
|
|
{
|
|
_logger.LogInformation("Timed Background Service is starting.");
|
|
|
|
RegisterJobs();
|
|
|
|
_timer.Enabled = true;
|
|
ExecuteTimer(_timer, null!);
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
private void RegisterJobs()
|
|
{
|
|
RegisterJob<NightlyCleanUp>();
|
|
RegisterJob<NightlySigmaImport>();
|
|
}
|
|
|
|
private void RegisterJob<T>() where T : IJob
|
|
{
|
|
var schedule = GetSchedule(typeof(T));
|
|
|
|
var scheduledJob = new ScheduledJob(_clock)
|
|
{
|
|
Schedule = schedule,
|
|
#pragma warning disable CS8601 //Null reference is checked for so no need to worry about it here.
|
|
Job = _serviceProvider.GetService(typeof(T)) as IJob,
|
|
#pragma warning restore CS8601
|
|
LastExecuted = _clock.GetNow
|
|
};
|
|
|
|
if (scheduledJob.Job == null)
|
|
throw new ArgumentNullException(nameof(scheduledJob.Job), "job cannot be null");
|
|
|
|
_jobs.Add(scheduledJob);
|
|
}
|
|
|
|
private static ISchedule GetSchedule(Type type)
|
|
{
|
|
var attributes = type.GetCustomAttributes(false);
|
|
|
|
foreach (var attribute in attributes)
|
|
{
|
|
if (attribute is ISchedule schedule)
|
|
return schedule;
|
|
}
|
|
|
|
throw new InvalidOperationException($"{type.FullName} does not contain a valid Schedule attribute");
|
|
}
|
|
|
|
private void ExecuteTimer(object? sender, ElapsedEventArgs e)
|
|
{
|
|
var now = _clock.GetNow;
|
|
|
|
var taskList = new List<Task>();
|
|
foreach (var job in _jobs.Where(job => job.NextScheduledExecution <= now))
|
|
{
|
|
job.LastExecuted = now;
|
|
taskList.Add(ExecuteJobAsync(job.Job));
|
|
}
|
|
|
|
Task.WhenAll(taskList).GetAwaiter().GetResult();
|
|
}
|
|
|
|
private async Task ExecuteJobAsync(IJob job)
|
|
{
|
|
_logger.LogInformation("Executing {FullName}", job.GetType().FullName);
|
|
await job.ExecuteAsync();
|
|
_logger.LogInformation("Executing {FullName} - Completed", job.GetType().FullName);
|
|
}
|
|
|
|
public Task StopAsync(CancellationToken cancellationToken)
|
|
{
|
|
_logger.LogInformation("Timed Background Service is stopping.");
|
|
|
|
_jobs.Clear();
|
|
return Task.CompletedTask;
|
|
}
|
|
} |