Files
Print_server/Inspectron.Epson/PrintServer/DiscoveredPrintersReceiver/InsinTelemetryDiscoveredPrintersReceiver.cs

72 lines
2.3 KiB
C#

using Inspectron.Epson;
using Inspectron.Epson.PrintServer.Telemetry;
namespace EpsonPrintService;
public sealed class InsinTelemetryDiscoveredPrintersReceiver : IDiscoveredPrintersReceiver
{
private readonly IDiscoveredPrintersReceiver _inner;
private readonly IInsinTelemetry _telemetry;
private readonly HashSet<string> _seenIps = new();
private readonly Dictionary<string, bool> _present = new();
private readonly object _stateLock = new();
public InsinTelemetryDiscoveredPrintersReceiver(
IDiscoveredPrintersReceiver inner,
IInsinTelemetry telemetry)
{
_inner = inner;
_telemetry = telemetry;
}
public async Task OnPrintersDiscoveredAsync(IReadOnlyList<DiscoveredPrinter> printers)
{
await _inner.OnPrintersDiscoveredAsync(printers);
List<(string kind, string message)> toEmit;
lock (_stateLock)
{
toEmit = ComputeEvents(printers);
}
foreach (var (kind, message) in toEmit)
{
try { _telemetry.Emit(kind, message); }
catch { /* swallow: telemetry must never break discovery */ }
}
}
private List<(string, string)> ComputeEvents(IReadOnlyList<DiscoveredPrinter> printers)
{
var events = new List<(string, string)>();
var currentIps = new HashSet<string>();
foreach (var p in printers)
{
if (string.IsNullOrEmpty(p.IPAddress)) continue;
currentIps.Add(p.IPAddress);
if (_seenIps.Add(p.IPAddress))
events.Add((InsinEventKinds.PrinterDiscovered,
InsinMessageFormatter.Format(("printer", p.IPAddress), ("model", p.ModelName))));
if (!_present.TryGetValue(p.IPAddress, out var wasPresent) || !wasPresent)
events.Add((InsinEventKinds.PrinterOnline,
InsinMessageFormatter.Format(("printer", p.IPAddress))));
_present[p.IPAddress] = true;
}
foreach (var kv in _present.ToList())
{
if (kv.Value && !currentIps.Contains(kv.Key))
{
events.Add((InsinEventKinds.PrinterOffline,
InsinMessageFormatter.Format(("printer", kv.Key))));
_present[kv.Key] = false;
}
}
return events;
}
}