using EnvelopeGenerator.Application.Common.Configurations; using EnvelopeGenerator.Application.Envelopes.Queries; using EnvelopeGenerator.Application.Pdf; using EnvelopeGenerator.Domain.Constants; using MediatR; using Microsoft.Extensions.Options; using Quartz; namespace EnvelopeGenerator.Finalizer.Job { public class FinishEnvelopeJob : IJob { private readonly ILogger _logger; private readonly IMediator _mediator; private readonly PDFBurnerParams _options; public FinishEnvelopeJob(ILogger logger, IMediator mediator, IOptions options) { _logger = logger; _mediator = mediator; _options = options.Value; } public async Task Execute(IJobExecutionContext context) { var cancel = context.CancellationToken; var envelopes = await _mediator.Send(new ReadEnvelopeQuery() { Status = new() { Include = [ EnvelopeStatus.EnvelopeCompletelySigned ] }, HasDocResult = false }, cancel); using var semaphore = new SemaphoreSlim(_options.ConcurrencyLimit); await Task.WhenAll(envelopes.Select(async envelope => { await semaphore.WaitAsync(cancel); try { await _mediator.BurnPdf(envelope.Id, cancel); } catch (Exception ex) { _logger.LogError(ex, "Error burning envelope {EnvelopeId}", envelope.Id); } finally { semaphore.Release(); } })); var envelopeCount = envelopes.Count(); if (envelopeCount > 0) { _logger.LogInformation( "Job '{JobName}' executed at {Timestamp}. {EnvelopeCount} envelope(s) successfully finalized. UUID(s): {EnvelopeUuids}", context.JobDetail.Key.Name, context.FireTimeUtc.ToLocalTime(), envelopeCount, string.Join(", ", envelopes.Select(e => e.Uuid)) ); } else _logger.LogInformation("Job '{JobName}' executed successfully at {Timestamp}. No envelopes were finalized.", context.JobDetail.Key.Name, context.FireTimeUtc.ToLocalTime() ); } } }