From becb6083312b532c8984c53a8185e2946590c9b1 Mon Sep 17 00:00:00 2001 From: TekH Date: Mon, 27 Jul 2026 16:55:31 +0200 Subject: [PATCH] Make OutgoingEmailConsumer more robust and maintainable - Added null-safety checks (`?.`) for `ILogger` usage in `OutgoingEmailConsumer`. - Removed unused `AsyncEventingBasicConsumer` and `_lazyInit` fields. - Updated `DisposeAsync` to check `_lazyChannel.IsValueCreated` before accessing it. - Added infinite delay in `AsyncInitWorker` to keep the background service active until cancellation. - Improved overall maintainability and reduced potential runtime issues. --- .../Queue/OutgoingEmailConsumer.cs | 11 ++++++----- .../Services/Background/AsyncInitWorker.cs | 2 ++ 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/DigitalData.MessagingService.Infrastructure/Queue/OutgoingEmailConsumer.cs b/src/DigitalData.MessagingService.Infrastructure/Queue/OutgoingEmailConsumer.cs index cd334df..5516511 100644 --- a/src/DigitalData.MessagingService.Infrastructure/Queue/OutgoingEmailConsumer.cs +++ b/src/DigitalData.MessagingService.Infrastructure/Queue/OutgoingEmailConsumer.cs @@ -21,8 +21,6 @@ public sealed class OutgoingEmailConsumer : IAsyncDisposable private readonly Lazy> _lazyChannel; - private readonly AsyncEventingBasicConsumer? consumer; - private readonly Lazy _lazyInit; private readonly ILogger? _logger; @@ -60,13 +58,13 @@ public sealed class OutgoingEmailConsumer : IAsyncDisposable } else { - logger.LogWarning("Failed to deserialize email message: DeliveryTag={DeliveryTag}", args.DeliveryTag); + logger?.LogWarning("Failed to deserialize email message: DeliveryTag={DeliveryTag}", args.DeliveryTag); await channel.BasicNackAsync(args.DeliveryTag, false, false, args.CancellationToken); // Don't requeue invalid messages } } catch (Exception ex) { - logger.LogError(ex, "Failed to process email [To={To}, Subject={Subject}] message: DeliveryTag={DeliveryTag}. Moving to DLQ (NO retry).", oMailEvent?.Recipient, oMailEvent?.Subject, args.DeliveryTag); + logger?.LogError(ex, "Failed to process email [To={To}, Subject={Subject}] message: DeliveryTag={DeliveryTag}. Moving to DLQ (NO retry).", oMailEvent?.Recipient, oMailEvent?.Subject, args.DeliveryTag); // TODO: Error Reporting Strategy // Option 1: Separate RabbitMQ Queue (emailprofiler.errors) @@ -100,7 +98,7 @@ public sealed class OutgoingEmailConsumer : IAsyncDisposable consumer: consumer, cancellationToken: CnnFactory.CancellationToken); - logger.LogInformation("RabbitMQ consumer started for queue: {QueueName}", _config.QueueName); + logger?.LogInformation("RabbitMQ consumer started for queue: {QueueName}", _config.QueueName); }); } @@ -119,6 +117,9 @@ public sealed class OutgoingEmailConsumer : IAsyncDisposable public async ValueTask DisposeAsync() { + if (!_lazyChannel.IsValueCreated) + return; + var channel = await _lazyChannel.Value; if (channel is not null) { diff --git a/src/DigitalData.MessagingService.Infrastructure/Services/Background/AsyncInitWorker.cs b/src/DigitalData.MessagingService.Infrastructure/Services/Background/AsyncInitWorker.cs index 175f1d7..de569c1 100644 --- a/src/DigitalData.MessagingService.Infrastructure/Services/Background/AsyncInitWorker.cs +++ b/src/DigitalData.MessagingService.Infrastructure/Services/Background/AsyncInitWorker.cs @@ -14,5 +14,7 @@ public class AsyncInitWorker(OutgoingEmailConsumer EmailConsumer) : BackgroundSe protected override async Task ExecuteAsync(CancellationToken stoppingToken) { await EmailConsumer.InitAsync(); + + await Task.Delay(Timeout.Infinite, stoppingToken).ConfigureAwait(ConfigureAwaitOptions.SuppressThrowing); } } \ No newline at end of file