Files
scadalink-design/src/ScadaLink.Host/Actors/DeadLetterMonitorActor.cs
Joseph Doherty d38356efdb Phase 1 WP-11–22: Host infrastructure, Blazor Server UI, and integration tests
Host infrastructure (WP-11–17):
- StartupValidator with 19 validation rules
- /health/ready endpoint with DB + Akka health checks
- Akka.NET bootstrap via AkkaHostedService (HOCON config, cluster, remoting, SBR)
- Serilog with SiteId/NodeHostname/NodeRole enrichment
- DeadLetterMonitorActor with count tracking
- CoordinatedShutdown wiring (no Environment.Exit)
- Windows Service support (UseWindowsService)

Central UI (WP-18–21):
- Blazor Server shell with Bootstrap 5, role-aware NavMenu
- Login/logout flow (LDAP auth → JWT → HTTP-only cookie)
- CookieAuthenticationStateProvider with idle timeout
- LDAP group mapping CRUD page (Admin role)
- Route guards with Authorize attributes per role
- SignalR reconnection overlay for failover

Integration tests (WP-22):
- Startup validation, auth flow, audit transactions, readiness gating
186 tests pass (1 skipped: LDAP integration), zero warnings.
2026-03-16 19:50:59 -04:00

54 lines
1.4 KiB
C#

using Akka.Actor;
using Akka.Event;
using Microsoft.Extensions.Logging;
namespace ScadaLink.Host.Actors;
/// <summary>
/// Subscribes to Akka.NET dead letter events, logs them, and tracks count
/// for health monitoring integration.
/// </summary>
public class DeadLetterMonitorActor : ReceiveActor
{
private long _deadLetterCount;
public DeadLetterMonitorActor(ILogger<DeadLetterMonitorActor> logger)
{
Receive<DeadLetter>(dl =>
{
_deadLetterCount++;
logger.LogWarning(
"Dead letter: {MessageType} from {Sender} to {Recipient}",
dl.Message.GetType().Name,
dl.Sender,
dl.Recipient);
});
Receive<GetDeadLetterCount>(_ => Sender.Tell(new DeadLetterCountResponse(_deadLetterCount)));
}
protected override void PreStart()
{
Context.System.EventStream.Subscribe(Self, typeof(DeadLetter));
}
protected override void PostStop()
{
Context.System.EventStream.Unsubscribe(Self, typeof(DeadLetter));
}
}
/// <summary>
/// Message to request the current dead letter count.
/// </summary>
public sealed class GetDeadLetterCount
{
public static readonly GetDeadLetterCount Instance = new();
private GetDeadLetterCount() { }
}
/// <summary>
/// Response containing the current dead letter count.
/// </summary>
public sealed record DeadLetterCountResponse(long Count);