- Cleaned up whitespace in Directory.Build.props and Directory.Packages.props for consistency. - Reformatted project file references in PnvPanel.Api.csproj for better clarity. - Enhanced code readability in various endpoint files by adjusting line breaks and indentation. - Standardized method signatures and improved formatting in ResultExtensions and multiple endpoint classes for better maintainability.
63 lines
2.1 KiB
C#
63 lines
2.1 KiB
C#
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Hosting;
|
|
using Microsoft.Extensions.Logging;
|
|
using PnvPanel.Application.Common.Interfaces;
|
|
using PnvPanel.Domain.Nodes;
|
|
using PnvPanel.Infrastructure.Persistence;
|
|
|
|
namespace PnvPanel.Infrastructure.BackgroundJobs;
|
|
|
|
public sealed class NodeHealthCheckService(
|
|
IServiceScopeFactory scopeFactory,
|
|
ILogger<NodeHealthCheckService> logger
|
|
) : BackgroundService
|
|
{
|
|
private static readonly TimeSpan Interval = TimeSpan.FromMinutes(2);
|
|
|
|
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
|
{
|
|
using var timer = new PeriodicTimer(Interval);
|
|
do
|
|
{
|
|
try
|
|
{
|
|
await CheckAllAsync(stoppingToken);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger.LogError(ex, "Node health-check failed");
|
|
}
|
|
} while (await timer.WaitForNextTickAsync(stoppingToken));
|
|
}
|
|
|
|
private async Task CheckAllAsync(CancellationToken cancellationToken)
|
|
{
|
|
await using var scope = scopeFactory.CreateAsyncScope();
|
|
var dbContext = scope.ServiceProvider.GetRequiredService<AppDbContext>();
|
|
var gateway = scope.ServiceProvider.GetRequiredService<IXuiPanelGateway>();
|
|
var notifier = scope.ServiceProvider.GetRequiredService<IRealtimeNotifier>();
|
|
|
|
var nodes = await dbContext.Nodes.Where(n => n.IsEnabled).ToListAsync(cancellationToken);
|
|
|
|
foreach (var node in nodes)
|
|
{
|
|
var probe = await gateway.ProbeAsync(node, cancellationToken);
|
|
var newStatus = probe.IsReachable ? NodeStatus.Online : NodeStatus.Offline;
|
|
|
|
if (node.Status != newStatus)
|
|
{
|
|
node.UpdateStatus(newStatus);
|
|
await notifier.NotifyNodeStatusChangedAsync(
|
|
node.Id,
|
|
newStatus,
|
|
node.LastSyncAt,
|
|
cancellationToken
|
|
);
|
|
}
|
|
}
|
|
|
|
await dbContext.SaveChangesAsync(cancellationToken);
|
|
}
|
|
}
|