mirror of
https://github.com/Sea-Haven-Industries/shoc-backend.git
synced 2026-09-30 03:43:11 +00:00
85 lines
3.3 KiB
C#
85 lines
3.3 KiB
C#
using Microsoft.Extensions.Options;
|
|
using SeaHaven.Services.Configuration;
|
|
using SeaHaven.Services.Interfaces;
|
|
|
|
namespace Api.SeaHavenIndustries.HostedServices
|
|
{
|
|
public sealed class WorkOrderReconciliationHostedService : BackgroundService
|
|
{
|
|
private readonly IServiceScopeFactory _scopeFactory;
|
|
private readonly IOptionsMonitor<WorkOrderReconciliationOptions> _options;
|
|
private readonly TimeProvider _timeProvider;
|
|
private readonly ILogger<WorkOrderReconciliationHostedService> _logger;
|
|
|
|
public WorkOrderReconciliationHostedService(
|
|
IServiceScopeFactory scopeFactory,
|
|
IOptionsMonitor<WorkOrderReconciliationOptions> options,
|
|
TimeProvider timeProvider,
|
|
ILogger<WorkOrderReconciliationHostedService> logger)
|
|
{
|
|
_scopeFactory = scopeFactory;
|
|
_options = options;
|
|
_timeProvider = timeProvider;
|
|
_logger = logger;
|
|
}
|
|
|
|
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
|
{
|
|
var nextScheduledAt = _timeProvider.GetUtcNow();
|
|
if (_options.CurrentValue.Enabled && _options.CurrentValue.RunOnStartup)
|
|
{
|
|
await TriggerAsync("startup", stoppingToken);
|
|
nextScheduledAt = _timeProvider.GetUtcNow().AddMinutes(_options.CurrentValue.ScheduleMinutes);
|
|
}
|
|
|
|
while (!stoppingToken.IsCancellationRequested)
|
|
{
|
|
var options = _options.CurrentValue;
|
|
if (options.Enabled)
|
|
{
|
|
var now = _timeProvider.GetUtcNow();
|
|
if (now >= nextScheduledAt)
|
|
{
|
|
await TriggerAsync("schedule", stoppingToken);
|
|
nextScheduledAt = now.AddMinutes(options.ScheduleMinutes);
|
|
}
|
|
|
|
await RunPendingAsync(stoppingToken);
|
|
}
|
|
|
|
await Task.Delay(
|
|
TimeSpan.FromSeconds(Math.Clamp(options.PollSeconds, 1, 300)),
|
|
_timeProvider,
|
|
stoppingToken);
|
|
}
|
|
}
|
|
|
|
private async Task TriggerAsync(string reason, CancellationToken cancellationToken)
|
|
{
|
|
try
|
|
{
|
|
await using var scope = _scopeFactory.CreateAsyncScope();
|
|
var runner = scope.ServiceProvider.GetRequiredService<IWorkOrderReconciliationRunner>();
|
|
await runner.TriggerAsync(reason, cancellationToken);
|
|
}
|
|
catch (Exception ex) when (ex is not OperationCanceledException)
|
|
{
|
|
_logger.LogError(ex, "Could not queue procurement reconciliation.");
|
|
}
|
|
}
|
|
|
|
private async Task RunPendingAsync(CancellationToken cancellationToken)
|
|
{
|
|
try
|
|
{
|
|
await using var scope = _scopeFactory.CreateAsyncScope();
|
|
var runner = scope.ServiceProvider.GetRequiredService<IWorkOrderReconciliationRunner>();
|
|
await runner.RunPendingAsync(cancellationToken);
|
|
}
|
|
catch (Exception ex) when (ex is not OperationCanceledException)
|
|
{
|
|
_logger.LogError(ex, "Could not execute procurement reconciliation.");
|
|
}
|
|
}
|
|
}
|
|
}
|