using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; namespace Big.Infrastructure; /// /// The hosted polling loop of the beoordeling-escalation worker (S-14, ADR-0015): on an interval it /// resolves a scoped and asks it to drain the parked /// BeoordelingEscaleren jobs. A deliberately thin shell — all acquire/reassign/complete logic /// lives in the processor, which is unit-tested; this class only owns the timer, the per-tick scope, /// and loop resilience. Structurally identical to . /// public sealed class BeoordelingEscalatiePump( IServiceScopeFactory scopeFactory, FlowableOptions options, ILogger logger) : BackgroundService { protected override async Task ExecuteAsync(CancellationToken stoppingToken) { while (!stoppingToken.IsCancellationRequested) { try { using var scope = scopeFactory.CreateScope(); var processor = scope.ServiceProvider.GetRequiredService(); await processor.PumpOnceAsync(options.MaxJobsPerPoll, stoppingToken); } catch (OperationCanceledException) when (stoppingToken.IsCancellationRequested) { break; } catch (Exception ex) { // A transient fault (e.g. Flowable briefly unreachable) must not kill the loop. logger.LogError(ex, "BeoordelingEscaleren job poll failed; retrying after the poll interval."); } try { await Task.Delay(options.PollInterval, stoppingToken); } catch (OperationCanceledException) when (stoppingToken.IsCancellationRequested) { break; } } } }