< Summary

Information
Class: ProjectTemplate.Web.Services.ApplicationAuditReconciliationHostedService
Assembly: ProjectTemplate.Web
File(s): /home/runner/work/NetCoreApplicationTemplate/NetCoreApplicationTemplate/src/ProjectTemplate.Web/Services/ApplicationAuditReconciliationHostedService.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 38
Coverable lines: 38
Total lines: 69
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 18
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)0%110100%
ExecuteAsync()0%7280%

File(s)

/home/runner/work/NetCoreApplicationTemplate/NetCoreApplicationTemplate/src/ProjectTemplate.Web/Services/ApplicationAuditReconciliationHostedService.cs

#LineLine coverage
 1using Microsoft.Extensions.Options;
 2using ProjectTemplate.Infrastructure.Data.Auditing;
 3
 4namespace ProjectTemplate.Web.Services;
 5
 06public sealed partial class ApplicationAuditReconciliationHostedService(
 07    IServiceScopeFactory scopeFactory,
 08    IOptions<ApplicationAuditReconciliationOptions> options,
 09    TimeProvider timeProvider,
 010    ILogger<ApplicationAuditReconciliationHostedService> logger)
 11    : BackgroundService
 12{
 013    private readonly IServiceScopeFactory _scopeFactory =
 014        scopeFactory ?? throw new ArgumentNullException(nameof(scopeFactory));
 015    private readonly ApplicationAuditReconciliationOptions _options =
 016        options?.Value ?? throw new ArgumentNullException(nameof(options));
 017    private readonly TimeProvider _timeProvider =
 018        timeProvider ?? throw new ArgumentNullException(nameof(timeProvider));
 019    private readonly ILogger<ApplicationAuditReconciliationHostedService> _logger =
 020        logger ?? throw new ArgumentNullException(nameof(logger));
 21
 22    [LoggerMessage(
 23        EventId = 19110,
 24        Level = LogLevel.Error,
 25        Message = "The audit reconciliation cycle failed and will be retried.")]
 26    private static partial void LogReconciliationFailure(ILogger logger, Exception exception);
 27
 28    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
 29    {
 030        if (!_options.Enabled || !_options.RunWorker)
 31        {
 032            return;
 33        }
 34
 035        while (!stoppingToken.IsCancellationRequested)
 36        {
 37            try
 38            {
 039                using IServiceScope scope = _scopeFactory.CreateScope();
 040                IApplicationAuditReconciler reconciler = scope.ServiceProvider
 041                    .GetRequiredService<IApplicationAuditReconciler>();
 042                _ = await reconciler.ReconcileAsync(stoppingToken).ConfigureAwait(false);
 43
 044                IApplicationAuditCompletionOutboxQuery? outboxQuery = scope.ServiceProvider
 045                    .GetService<IApplicationAuditCompletionOutboxQuery>();
 046                if (outboxQuery is not null)
 47                {
 048                    ApplicationAuditCompletionOutboxHealth deliveryHealth = await outboxQuery
 049                        .GetHealthAsync(stoppingToken)
 050                        .ConfigureAwait(false);
 051                    scope.ServiceProvider
 052                        .GetRequiredService<ApplicationAuditReconciliationMetrics>()
 053                        .UpdateDelivery(deliveryHealth);
 54                }
 055            }
 056            catch (OperationCanceledException) when (stoppingToken.IsCancellationRequested)
 57            {
 058                break;
 59            }
 060            catch (Exception exception)
 61            {
 062                LogReconciliationFailure(_logger, exception);
 063            }
 64
 065            await Task.Delay(_options.Interval, _timeProvider, stoppingToken)
 066                .ConfigureAwait(false);
 67        }
 068    }
 69}