158 lines
5.3 KiB
C#
158 lines
5.3 KiB
C#
using PrintService.Models;
|
|
using PrintService.Services;
|
|
|
|
namespace PrintService;
|
|
|
|
/// <summary>
|
|
/// Main worker service that coordinates all components
|
|
/// </summary>
|
|
public class Worker : BackgroundService
|
|
{
|
|
private readonly ILogger<Worker> _logger;
|
|
private readonly PrintQueueService _queueService;
|
|
private readonly FileMonitorService _fileMonitorService;
|
|
private readonly PrinterService _printerService;
|
|
private readonly DocumentProcessor _documentProcessor;
|
|
private readonly IpcService _ipcService;
|
|
|
|
public Worker(
|
|
ILogger<Worker> logger,
|
|
PrintQueueService queueService,
|
|
FileMonitorService fileMonitorService,
|
|
PrinterService printerService,
|
|
DocumentProcessor documentProcessor,
|
|
IpcService ipcService)
|
|
{
|
|
_logger = logger;
|
|
_queueService = queueService;
|
|
_fileMonitorService = fileMonitorService;
|
|
_printerService = printerService;
|
|
_documentProcessor = documentProcessor;
|
|
_ipcService = ipcService;
|
|
}
|
|
|
|
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
|
{
|
|
_logger.LogInformation("LAAPC Print Service starting at: {time}", DateTimeOffset.Now);
|
|
|
|
try
|
|
{
|
|
// Start IPC server for CLI communication
|
|
_ipcService.Start();
|
|
|
|
// Start file monitoring (optional - mainly using IPC for job creation)
|
|
// _fileMonitorService.Start();
|
|
|
|
_logger.LogInformation("Print service started successfully");
|
|
_logger.LogInformation("Queue has {Count} pending jobs", _queueService.Count);
|
|
|
|
// Main processing loop
|
|
while (!stoppingToken.IsCancellationRequested)
|
|
{
|
|
try
|
|
{
|
|
if (_queueService.TryDequeue(out var job) && job != null)
|
|
{
|
|
await ProcessJob(job, stoppingToken);
|
|
}
|
|
else
|
|
{
|
|
// No jobs in queue, wait a bit
|
|
await Task.Delay(500, stoppingToken);
|
|
}
|
|
}
|
|
catch (OperationCanceledException)
|
|
{
|
|
// Expected during shutdown, exit gracefully
|
|
break;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error in processing loop");
|
|
try
|
|
{
|
|
await Task.Delay(1000, stoppingToken);
|
|
}
|
|
catch (OperationCanceledException)
|
|
{
|
|
// Shutdown requested during error delay
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (OperationCanceledException)
|
|
{
|
|
// Expected during shutdown
|
|
_logger.LogInformation("Service shutdown requested");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogCritical(ex, "Fatal error in worker service");
|
|
throw;
|
|
}
|
|
finally
|
|
{
|
|
_logger.LogInformation("Print service stopping");
|
|
_ipcService.Stop();
|
|
_fileMonitorService.Stop();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Process a single print job
|
|
/// </summary>
|
|
private async Task ProcessJob(PrintJob job, CancellationToken cancellationToken)
|
|
{
|
|
_logger.LogInformation("Processing job {JobId} (Type: {DocType}, Order: {OrderNum})",
|
|
job.Id, job.DocumentType, job.OrderNumber ?? "N/A");
|
|
|
|
job.Status = PrintJobStatus.Processing;
|
|
job.UpdatedAt = DateTime.Now;
|
|
|
|
try
|
|
{
|
|
// Get document configuration from printer-config.json
|
|
var config = _documentProcessor.GetDocumentConfig(job.DocumentType);
|
|
if (config == null)
|
|
{
|
|
throw new InvalidOperationException($"No configuration found for document type '{job.DocumentType}' in printer-config.json");
|
|
}
|
|
|
|
// Read file content
|
|
if (!File.Exists(job.QueuedFilePath))
|
|
{
|
|
throw new FileNotFoundException($"Queued file not found: {job.QueuedFilePath}");
|
|
}
|
|
|
|
var content = _documentProcessor.ReadFile(job.QueuedFilePath);
|
|
|
|
// Process/transform content
|
|
var processedContent = _documentProcessor.ProcessDocument(content, config);
|
|
|
|
// Print to Windows queue
|
|
await Task.Run(() => _printerService.Print(processedContent, config, job.OriginalFilename), cancellationToken);
|
|
|
|
// Post-process (archive or delete)
|
|
_documentProcessor.PostProcess(job, config);
|
|
|
|
// Mark as completed
|
|
job.Status = PrintJobStatus.Completed;
|
|
job.UpdatedAt = DateTime.Now;
|
|
|
|
_logger.LogInformation("Job {JobId} completed successfully", job.Id);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Failed to process job {JobId}", job.Id);
|
|
|
|
job.LastError = ex.Message;
|
|
job.UpdatedAt = DateTime.Now;
|
|
|
|
// Requeue for retry
|
|
_queueService.Requeue(job);
|
|
}
|
|
}
|
|
}
|
|
|