Refactor email queue worker and interface cleanup
Removed `InitAsync` from `IOutgoingEmailQueue` to decouple RabbitMQ initialization from the interface. Replaced `AsyncIniteWorker` with the correctly named `AsyncInitWorker` in `DependencyInjection.cs` and introduced a new, improved implementation of `AsyncInitWorker`. The new `AsyncInitWorker` class initializes the outgoing email queue consumer using an event-driven RabbitMQ approach, with enhanced logging and error handling. Removed the outdated `AsyncIniteWorker` class to streamline the codebase. These changes improve code clarity, maintainability, and correctness.
This commit is contained in:
@@ -11,10 +11,4 @@ public interface IOutgoingEmailQueue
|
||||
Task EnqueueAsync(OutgoingEmailEvent outgoingEmailEvent, CancellationToken cancellationToken = default);
|
||||
|
||||
Task<int> GetQueueDepthAsync(CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Initialize RabbitMQ connection, channel, exchanges, and queues asynchronously.
|
||||
/// Called lazily on first use via EnsureInitializedAsync.
|
||||
/// </summary>
|
||||
Task InitAsync(CancellationToken cancellationToken = default);
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ public static class DependencyInjection
|
||||
.SetApplicationName("EmailProfiler");
|
||||
|
||||
// Register Background Workers
|
||||
services.AddHostedService<AsyncIniteWorker>();
|
||||
services.AddHostedService<AsyncInitWorker>();
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
using DigitalData.EmailProfiler.Application.Common.Interfaces;
|
||||
using DigitalData.EmailProfiler.Infrastructure.Queue;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace DigitalData.EmailProfiler.Infrastructure.Services.Background;
|
||||
|
||||
/// <summary>
|
||||
/// A hosted background service responsible for initializing the outgoing email queue consumer.
|
||||
/// Leverages a push-based, event-driven RabbitMQ consumer to eliminate polling overhead.
|
||||
/// Email account configuration is resolved exclusively from application settings; no database access is performed.
|
||||
/// </summary>
|
||||
public class AsyncInitWorker(IOutgoingEmailQueue EmailQueue, ILogger<AsyncInitWorker> Logger) : BackgroundService
|
||||
{
|
||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
{
|
||||
Logger.LogInformation("Outgoing email queue worker is starting. Initializing event-driven RabbitMQ consumer.");
|
||||
|
||||
try
|
||||
{
|
||||
// Initialize the RabbitMQ push-based consumer. This call is non-blocking;
|
||||
// message processing is handled asynchronously via registered event callbacks.
|
||||
if (EmailQueue is OutgoingEmailQueue outgoingEmailQueue)
|
||||
await outgoingEmailQueue.InitAsync(stoppingToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError(ex, "A critical error occurred while initializing the outgoing email queue consumer. The worker cannot proceed.");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
using DigitalData.EmailProfiler.Application.Common.Interfaces;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace DigitalData.EmailProfiler.Infrastructure.Services.Background;
|
||||
|
||||
/// <summary>
|
||||
/// Background worker that processes outgoing emails from RabbitMQ queue.
|
||||
/// Uses event-driven RabbitMQ consumer (push-based) instead of polling.
|
||||
/// NO database operations - email account configuration comes from appsettings.
|
||||
/// </summary>
|
||||
public class AsyncIniteWorker(
|
||||
IOutgoingEmailQueue EmailQueue,
|
||||
ILogger<AsyncIniteWorker> Logger) : BackgroundService
|
||||
{
|
||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
{
|
||||
Logger.LogInformation("EmailSenderWorker started (event-driven RabbitMQ consumer)");
|
||||
|
||||
try
|
||||
{
|
||||
// Start RabbitMQ consumer (event-driven, non-blocking)
|
||||
await EmailQueue.InitAsync(stoppingToken);
|
||||
|
||||
// Keep worker alive until cancellation
|
||||
// await Task.Delay(Timeout.Infinite, stoppingToken);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
Logger.LogInformation("EmailSenderWorker is stopping");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError(ex, "EmailSenderWorker failed to start");
|
||||
throw;
|
||||
}
|
||||
|
||||
// Logger.LogInformation("EmailSenderWorker stopped");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user