using Inspectron.Epson.PrintServer.Hooks; using Inspectron.Epson.PrintServer.PrintServices; using Inspectron.Epson.Queue; using Microsoft.Extensions.Logging; namespace Inspectron.Epson.PrintServer; public class PrintLoop { private readonly global::Inspectron.Epson.Queue.PrintServer _printServer; private readonly IPrintService _printService; private readonly IPrintJobSource _jobSource; private readonly IReadOnlyList _arrivedHandlers; private readonly ILogger _logger; private CancellationTokenSource? _cancellationSource; private CancellationToken _cancellationToken; public PrintLoop(global::Inspectron.Epson.Queue.PrintServer printServer, IPrintService printService, IPrintJobSource jobSource, ILogger logger, IEnumerable? arrivedHandlers = null) { _printServer = printServer; _printService = printService; _jobSource = jobSource; _arrivedHandlers = arrivedHandlers?.ToList() ?? (IReadOnlyList)Array.Empty(); _logger = logger; } public Task StartAsync() { _cancellationSource = new CancellationTokenSource(); _cancellationToken = _cancellationSource.Token; _= Task.Run(Loop); return Task.CompletedTask; } public async Task Loop() { while (!_cancellationSource!.Token.IsCancellationRequested) { var job = await _jobSource.GetNextJobAsync(_cancellationToken); if (_arrivedHandlers.Count > 0) { var ctx = new PrintJobArrivedContext(job); foreach (var handler in _arrivedHandlers) { try { await handler(ctx, _cancellationToken); } catch (Exception ex) { _logger.LogError(ex, "Print job arrived hook threw (job {JobId})", job.JobId); } } } _printServer.SubmitJob(job.IP, job); } } public Task StopAsync() { _cancellationSource!.Cancel(); return Task.CompletedTask; } }