constellation-api/CH.CQRS/Query/Health/HealthQuery.cs

51 lines
1.6 KiB
C#
Raw Normal View History

using OpenHarbor.CQRS.Abstractions;
using System.Diagnostics;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Memory;
using CH.Dal;
namespace CH.CQRS.Query.Health;
public class HealthQuery
{
}
public class HealthQueryHandler(CHDbContext dbContext, IMemoryCache memoryCache) : IQueryHandler<HealthQuery, HealthQueryResult>
{
private const string HealthCheckCacheKey = "HealthStatus";
private const int CacheDurationInSeconds = 60;
public async Task<HealthQueryResult> HandleAsync(HealthQuery query, CancellationToken cancellationToken = new CancellationToken())
{
if (memoryCache.TryGetValue(HealthCheckCacheKey, out var memory))
{
return (HealthQueryResult)memory;
}
var (databaseStatus, databaseLatency) = await MeasureLatencyAsync(CheckDatabaseHealthAsync);
var healthCheckResult = new HealthQueryResult
{
ApiStatus = true,
DatabaseStatus = databaseStatus,
DatabaseLatency = $"{databaseLatency}ms",
};
memoryCache.Set(HealthCheckCacheKey, healthCheckResult, TimeSpan.FromSeconds(CacheDurationInSeconds));
return healthCheckResult;
}
public static async Task<(bool isHealthy, long latencyMs)> MeasureLatencyAsync(Func<Task<bool>> healthCheckAction)
{
var stopwatch = Stopwatch.StartNew();
var isHealthy = await healthCheckAction();
stopwatch.Stop();
return (isHealthy, stopwatch.ElapsedMilliseconds);
}
private async Task<bool> CheckDatabaseHealthAsync()
{
try
{
await dbContext.Database.ExecuteSqlRawAsync("SELECT 1");
return true;
}
catch
{
return false;
}
}
}