add print-job-arrived hook system
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
using Inspectron.Epson;
|
using Inspectron.Epson;
|
||||||
using Inspectron.Epson.PrintServer;
|
using Inspectron.Epson.PrintServer;
|
||||||
using Inspectron.Epson.PrintServer.ConfigurationSources;
|
using Inspectron.Epson.PrintServer.ConfigurationSources;
|
||||||
|
using Inspectron.Epson.PrintServer.Hooks;
|
||||||
using Inspectron.Epson.PrintServer.JobSources;
|
using Inspectron.Epson.PrintServer.JobSources;
|
||||||
using Inspectron.Epson.PrintServer.JobStatusReporters;
|
using Inspectron.Epson.PrintServer.JobStatusReporters;
|
||||||
using Inspectron.Epson.PrintServer.PrinterAssinment;
|
using Inspectron.Epson.PrintServer.PrinterAssinment;
|
||||||
@@ -17,6 +18,7 @@ public class PrintServerBootstrapper
|
|||||||
{
|
{
|
||||||
private readonly EpsonPrintServiceConfiguration _config;
|
private readonly EpsonPrintServiceConfiguration _config;
|
||||||
private readonly CancellationTokenSource _cts;
|
private readonly CancellationTokenSource _cts;
|
||||||
|
private readonly List<PrintJobArrivedHandler> _arrivedHandlers = new();
|
||||||
private StandardKernel? _kernel;
|
private StandardKernel? _kernel;
|
||||||
|
|
||||||
public bool IsRunning { get; private set; }
|
public bool IsRunning { get; private set; }
|
||||||
@@ -27,6 +29,17 @@ public class PrintServerBootstrapper
|
|||||||
_cts = cts;
|
_cts = cts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Register a handler that fires once per print job as it arrives from the job source,
|
||||||
|
/// before it's enqueued on the printer queue. Register all handlers before calling <see cref="StartAsync"/>.
|
||||||
|
/// Handler exceptions are logged and swallowed; they never block a print.
|
||||||
|
/// </summary>
|
||||||
|
public void OnPrintJobArrived(PrintJobArrivedHandler handler)
|
||||||
|
{
|
||||||
|
if (IsRunning) throw new InvalidOperationException("Register hooks before StartAsync().");
|
||||||
|
_arrivedHandlers.Add(handler);
|
||||||
|
}
|
||||||
|
|
||||||
public async Task StartAsync()
|
public async Task StartAsync()
|
||||||
{
|
{
|
||||||
_kernel = new StandardKernel();
|
_kernel = new StandardKernel();
|
||||||
@@ -80,6 +93,10 @@ public class PrintServerBootstrapper
|
|||||||
_kernel.Bind<IReceiptConverterFactory>().To<ReceiptConverterFactory>().InSingletonScope();
|
_kernel.Bind<IReceiptConverterFactory>().To<ReceiptConverterFactory>().InSingletonScope();
|
||||||
_kernel.Bind<IJobStatusReporter>().To<JamesStatusReporter>();
|
_kernel.Bind<IJobStatusReporter>().To<JamesStatusReporter>();
|
||||||
_kernel.Bind<PrintServer>().ToSelf().InSingletonScope();
|
_kernel.Bind<PrintServer>().ToSelf().InSingletonScope();
|
||||||
|
foreach (var handler in _arrivedHandlers)
|
||||||
|
{
|
||||||
|
_kernel.Bind<PrintJobArrivedHandler>().ToConstant(handler);
|
||||||
|
}
|
||||||
_kernel.Bind<IDiscoveredPrintersReceiver>().To<JamesDiscoveredPrintersReceiver>().InSingletonScope();
|
_kernel.Bind<IDiscoveredPrintersReceiver>().To<JamesDiscoveredPrintersReceiver>().InSingletonScope();
|
||||||
_kernel.Bind<PrinterDiscoveryBackgroundTask>().ToSelf().InSingletonScope();
|
_kernel.Bind<PrinterDiscoveryBackgroundTask>().ToSelf().InSingletonScope();
|
||||||
_kernel.Bind<HeartbeatBackgroundTask>().ToSelf().InSingletonScope();
|
_kernel.Bind<HeartbeatBackgroundTask>().ToSelf().InSingletonScope();
|
||||||
|
|||||||
75
Inspectron.Epson/PrintServer/Hooks/PrintJobArrivedHandler.cs
Normal file
75
Inspectron.Epson/PrintServer/Hooks/PrintJobArrivedHandler.cs
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
using System.Text.Json;
|
||||||
|
using Inspectron.Epson.PrintServer.Printers.Utils;
|
||||||
|
using Inspectron.Epson.Queue;
|
||||||
|
using FinalReceiptModel = Inspectron.Epson.PrintServer.Printers.Utils.FinalRecipe.FinalReceipt;
|
||||||
|
using InvoiceReceiptModel = Inspectron.Epson.PrintServer.Printers.Utils.InvoiceReceipt.InvoiceReceipt;
|
||||||
|
using KitchenReceiptModel = Inspectron.Epson.PrintServer.Printers.Utils.KitchenReceipt.KitchenReceipt;
|
||||||
|
using OrderItemsReceiptModel = Inspectron.Epson.PrintServer.Printers.Utils.OrderItems.OrderItemsReceipt;
|
||||||
|
|
||||||
|
namespace Inspectron.Epson.PrintServer.Hooks;
|
||||||
|
|
||||||
|
public delegate Task PrintJobArrivedHandler(PrintJobArrivedContext ctx, CancellationToken cancellationToken);
|
||||||
|
|
||||||
|
public sealed class PrintJobArrivedContext
|
||||||
|
{
|
||||||
|
private KitchenReceiptModel? _kitchen;
|
||||||
|
private FinalReceiptModel? _final;
|
||||||
|
private InvoiceReceiptModel? _invoice;
|
||||||
|
private OrderItemsReceiptModel? _orderItems;
|
||||||
|
private bool _kitchenParsed, _finalParsed, _invoiceParsed, _orderItemsParsed;
|
||||||
|
|
||||||
|
public PrintJob Job { get; }
|
||||||
|
public int ReceiptTypeId => Job.Document.ReceiptType;
|
||||||
|
public ReceiptConverterFactory.EReceiptType ReceiptType => (ReceiptConverterFactory.EReceiptType)Job.Document.ReceiptType;
|
||||||
|
public string ContentJson => Job.Document.Content;
|
||||||
|
|
||||||
|
public PrintJobArrivedContext(PrintJob job)
|
||||||
|
{
|
||||||
|
Job = job;
|
||||||
|
}
|
||||||
|
|
||||||
|
public KitchenReceiptModel? AsKitchen()
|
||||||
|
{
|
||||||
|
if (_kitchenParsed) return _kitchen;
|
||||||
|
_kitchenParsed = true;
|
||||||
|
if (ReceiptType is ReceiptConverterFactory.EReceiptType.WorkareaTicket
|
||||||
|
or ReceiptConverterFactory.EReceiptType.NextCourse)
|
||||||
|
{
|
||||||
|
_kitchen = JsonSerializer.Deserialize<KitchenReceiptModel>(ContentJson);
|
||||||
|
}
|
||||||
|
return _kitchen;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FinalReceiptModel? AsFinal()
|
||||||
|
{
|
||||||
|
if (_finalParsed) return _final;
|
||||||
|
_finalParsed = true;
|
||||||
|
if (ReceiptType == ReceiptConverterFactory.EReceiptType.Receipt)
|
||||||
|
{
|
||||||
|
_final = JsonSerializer.Deserialize<FinalReceiptModel>(ContentJson);
|
||||||
|
}
|
||||||
|
return _final;
|
||||||
|
}
|
||||||
|
|
||||||
|
public InvoiceReceiptModel? AsInvoice()
|
||||||
|
{
|
||||||
|
if (_invoiceParsed) return _invoice;
|
||||||
|
_invoiceParsed = true;
|
||||||
|
if (ReceiptType == ReceiptConverterFactory.EReceiptType.Invoice)
|
||||||
|
{
|
||||||
|
_invoice = JsonSerializer.Deserialize<InvoiceReceiptModel>(ContentJson);
|
||||||
|
}
|
||||||
|
return _invoice;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OrderItemsReceiptModel? AsOrderItems()
|
||||||
|
{
|
||||||
|
if (_orderItemsParsed) return _orderItems;
|
||||||
|
_orderItemsParsed = true;
|
||||||
|
if (ReceiptType == ReceiptConverterFactory.EReceiptType.OrdersOverview)
|
||||||
|
{
|
||||||
|
_orderItems = JsonSerializer.Deserialize<OrderItemsReceiptModel>(ContentJson);
|
||||||
|
}
|
||||||
|
return _orderItems;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using Inspectron.Epson.PrintServer.PrintServices;
|
using Inspectron.Epson.PrintServer.Hooks;
|
||||||
|
using Inspectron.Epson.PrintServer.PrintServices;
|
||||||
using Inspectron.Epson.Queue;
|
using Inspectron.Epson.Queue;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
@@ -9,17 +10,19 @@ public class PrintLoop
|
|||||||
private readonly global::Inspectron.Epson.Queue.PrintServer _printServer;
|
private readonly global::Inspectron.Epson.Queue.PrintServer _printServer;
|
||||||
private readonly IPrintService _printService;
|
private readonly IPrintService _printService;
|
||||||
private readonly IPrintJobSource _jobSource;
|
private readonly IPrintJobSource _jobSource;
|
||||||
|
private readonly IReadOnlyList<PrintJobArrivedHandler> _arrivedHandlers;
|
||||||
|
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
private CancellationTokenSource? _cancellationSource;
|
private CancellationTokenSource? _cancellationSource;
|
||||||
private CancellationToken _cancellationToken;
|
private CancellationToken _cancellationToken;
|
||||||
|
|
||||||
public PrintLoop(global::Inspectron.Epson.Queue.PrintServer printServer,IPrintService printService, IPrintJobSource jobSource, ILogger logger)
|
public PrintLoop(global::Inspectron.Epson.Queue.PrintServer printServer, IPrintService printService, IPrintJobSource jobSource, ILogger logger, IEnumerable<PrintJobArrivedHandler>? arrivedHandlers = null)
|
||||||
{
|
{
|
||||||
_printServer = printServer;
|
_printServer = printServer;
|
||||||
_printService = printService;
|
_printService = printService;
|
||||||
_jobSource = jobSource;
|
_jobSource = jobSource;
|
||||||
|
_arrivedHandlers = arrivedHandlers?.ToList() ?? (IReadOnlyList<PrintJobArrivedHandler>)Array.Empty<PrintJobArrivedHandler>();
|
||||||
|
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,7 +38,23 @@ public class PrintLoop
|
|||||||
while (!_cancellationSource!.Token.IsCancellationRequested)
|
while (!_cancellationSource!.Token.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
var job = await _jobSource.GetNextJobAsync(_cancellationToken);
|
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);
|
_printServer.SubmitJob(job.IP, job);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user