using System.Collections.Concurrent; using Microsoft.Extensions.Logging; public class PrintServer { private readonly IPrintService _printService; private readonly ILogger _logger; private readonly ConcurrentDictionary _printerQueues; private readonly ReaderWriterLockSlim _printDiscoveryLock = new(); public PrintServer(IPrintService printService, ILogger logger) { _printService = printService; _logger = logger; _printerQueues = new ConcurrentDictionary(); } /// /// Acquires a read lock for print operations. Multiple print operations can run concurrently. /// public void EnterPrintLock() => _printDiscoveryLock.EnterReadLock(); /// /// Releases the read lock after a print operation completes. /// public void ExitPrintLock() => _printDiscoveryLock.ExitReadLock(); /// /// Acquires a write lock for discovery operations. This blocks until all print operations complete /// and prevents new print operations from starting. /// public void EnterDiscoveryLock() => _printDiscoveryLock.EnterWriteLock(); /// /// Releases the write lock after discovery completes. /// public void ExitDiscoveryLock() => _printDiscoveryLock.ExitWriteLock(); public void RegisterPrinter(string printerIp) { var queue = new PrinterQueue(printerIp, _printService, _logger, this); if (_printerQueues.TryAdd(printerIp, queue)) { queue.Start(); Console.WriteLine($"Printer {printerIp} registered"); } } public void UnregisterPrinter(string printerIp) { if (_printerQueues.TryRemove(printerIp, out var queue)) { queue.StopAsync().Wait(); Console.WriteLine($"Printer {printerIp} unregistered"); } } public void SubmitJob(string printerIp, PrintJob job) { if (_printerQueues.TryGetValue(printerIp, out var queue)) { queue.Enqueue(job); } else { _logger.LogWarning( $"Printer {printerIp} not found. Job cannot be submitted."); } } public Dictionary GetQueueStatus() { var status = new Dictionary(); foreach (var kvp in _printerQueues) { status[kvp.Key] = kvp.Value.QueueLength; } return status; } public async Task ShutdownAsync() { var stopTasks = _printerQueues.Values.Select(q => q.StopAsync()); await Task.WhenAll(stopTasks); Console.WriteLine("Print server shut down"); } }