using Microsoft.Extensions.Options; using QMax.Api.Configuration; namespace QMax.Api.Services; public sealed class MaxOutboxWorker( IServiceScopeFactory scopeFactory, IOptions options, ILogger logger) : BackgroundService { private readonly QMaxOptions _options = options.Value; protected override async Task ExecuteAsync(CancellationToken stoppingToken) { var delay = TimeSpan.FromSeconds(Math.Max(1, _options.MaxOutboxPollIntervalSeconds)); using var timer = new PeriodicTimer(delay); while (!stoppingToken.IsCancellationRequested) { try { await timer.WaitForNextTickAsync(stoppingToken); } catch (OperationCanceledException) { break; } try { await using var scope = scopeFactory.CreateAsyncScope(); var outbox = scope.ServiceProvider.GetRequiredService(); await outbox.ProcessOnceAsync(stoppingToken); } catch (Exception ex) { logger.LogWarning(ex, "QMAX outbox tick failed."); } } } }