using Inspectron.Epson; using Inspectron.Epson.PrintServer.ConfigurationSources; using Microsoft.Extensions.Logging; namespace EpsonPrintService; /// /// Background task that periodically discovers printers and notifies receivers when changes occur /// public class PrinterDiscoveryBackgroundTask { private readonly IDiscoveryService _discoveryService; private readonly IDiscoveredPrintersReceiver _receiver; private readonly ILogger _logger; private readonly TimeSpan _interval; private readonly TimeSpan _discoveryTimeout; private HashSet _lastDiscoveredPrinterIps = new(); private List _lastDiscoveredPrinters = new(); public PrinterDiscoveryBackgroundTask( IDiscoveryService discoveryService, IDiscoveredPrintersReceiver receiver, ILogger logger) { _discoveryService = discoveryService; _receiver = receiver; _logger = logger; _interval = TimeSpan.FromSeconds(30); _discoveryTimeout = TimeSpan.FromSeconds(3); } /// /// Starts the background discovery task /// /// Token to cancel the background task public async Task StartAsync(CancellationToken cancellationToken) { _logger.LogInformation("Starting printer discovery background task (interval: {Interval}s)", _interval.TotalSeconds); // Run immediately on start await DiscoverAndNotifyAsync(); // Then run periodically while (!cancellationToken.IsCancellationRequested) { try { await Task.Delay(_interval, cancellationToken); await DiscoverAndNotifyAsync(); } catch (TaskCanceledException) { break; } catch (Exception ex) { _logger.LogError(ex, "Error during printer discovery"); } } _logger.LogInformation("Printer discovery background task stopped"); } private async Task DiscoverAndNotifyAsync() { try { var printers = await _discoveryService.DiscoverPrintersAsync(_discoveryTimeout); printers.Add(new DiscoveredPrinter() { IPAddress = "127.0.0.1", ModelName = "TM-T30III", }); var currentIps = printers.Select(p => p.IPAddress).ToHashSet(); if (HasConfigurationChanged(currentIps)) { _logger.LogInformation("Discovered printer configuration changed: {Count} printer(s)", printers.Count); _lastDiscoveredPrinterIps = currentIps; _lastDiscoveredPrinters = printers; await _receiver.OnPrintersDiscoveredAsync(printers.AsReadOnly()); } } catch (Exception ex) { _logger.LogWarning(ex, "Failed to discover printers"); } } private bool HasConfigurationChanged(HashSet currentIps) { if (currentIps.Count != _lastDiscoveredPrinterIps.Count) return true; return !currentIps.SetEquals(_lastDiscoveredPrinterIps); } }