using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
namespace Cleanuparr.Infrastructure.Health;
///
/// Service that broadcasts health status changes via SignalR
///
public class HealthStatusBroadcaster : IHostedService
{
private readonly ILogger _logger;
private readonly IHealthCheckService _healthCheckService;
private readonly IHubContext _hubContext;
///
/// Initializes a new instance of the class
///
/// The logger
/// The health check service
/// The SignalR hub context
public HealthStatusBroadcaster(
ILogger logger,
IHealthCheckService healthCheckService,
IHubContext hubContext)
{
_logger = logger;
_healthCheckService = healthCheckService;
_hubContext = hubContext;
}
///
public Task StartAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Health status broadcaster starting");
// Subscribe to health status change events
_healthCheckService.ClientHealthChanged += OnClientHealthChanged;
return Task.CompletedTask;
}
///
public Task StopAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Health status broadcaster stopping");
// Unsubscribe from health status change events
_healthCheckService.ClientHealthChanged -= OnClientHealthChanged;
return Task.CompletedTask;
}
private async void OnClientHealthChanged(object? sender, ClientHealthChangedEventArgs e)
{
try
{
_logger.LogDebug("Broadcasting health status change for client {clientId}", e.ClientId);
// Broadcast to all clients
await _hubContext.Clients.All.SendAsync("HealthStatusChanged", e.Status);
// Send degradation messages
if (e.IsDegraded)
{
_logger.LogWarning("Client {clientId} health degraded", e.ClientId);
await _hubContext.Clients.All.SendAsync("ClientDegraded", e.Status);
}
// Send recovery messages
if (e.IsRecovered)
{
_logger.LogInformation("Client {clientId} health recovered", e.ClientId);
await _hubContext.Clients.All.SendAsync("ClientRecovered", e.Status);
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Error broadcasting health status change for client {clientId}", e.ClientId);
}
}
}