ProfileWorker changes: - Implement IHealthCheck interface - Replace _workCount with DateTime-based tracking - Track _lastSuccessfulRun, _consecutiveFailures, _lastException - Graceful shutdown handling (OperationCanceledException) - Health states: Healthy, Degraded (1-2 failures), Unhealthy (3x interval) DependencyInjection changes: - Register ProfileWorker as singleton (for health check access) - Use factory pattern for IHostedService registration Program.cs changes: - Add health check service with ProfileWorker - Map /health endpoint (full JSON response with all checks) - Map /health/ready endpoint (filtered by 'ready' tag) - Custom JSON response writer with detailed metrics
47 lines
1.6 KiB
C#
47 lines
1.6 KiB
C#
using Microsoft.Extensions.Options;
|
|
|
|
namespace ECMJobRunner.WebCron.ProfileWorker;
|
|
|
|
public static class DependencyInjection
|
|
{
|
|
public static IServiceCollection AddProfileWorker(this IServiceCollection services, IConfiguration configuration)
|
|
{
|
|
// Configure ProfileWorker options from appsettings.json
|
|
services.Configure<ProfileWorkerOptions>(
|
|
configuration.GetSection(ProfileWorkerOptions.SectionName));
|
|
|
|
// Validate options at startup
|
|
services.AddSingleton<IValidateOptions<ProfileWorkerOptions>, ProfileWorkerOptionsValidator>();
|
|
|
|
// Register ProfileWorker as both HostedService and singleton (for health check access)
|
|
services.AddSingleton<ProfileWorker>();
|
|
services.AddHostedService(sp => sp.GetRequiredService<ProfileWorker>());
|
|
|
|
services.AddSingleton<ProfileCache>();
|
|
services.AddScoped<ProfileWork>();
|
|
|
|
return services;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validates ProfileWorkerOptions configuration at startup.
|
|
/// </summary>
|
|
internal class ProfileWorkerOptionsValidator : IValidateOptions<ProfileWorkerOptions>
|
|
{
|
|
public ValidateOptionsResult Validate(string? name, ProfileWorkerOptions options)
|
|
{
|
|
if (options.IntervalMS <= 0)
|
|
{
|
|
return ValidateOptionsResult.Fail("ProfileWorker:IntervalMs must be greater than 0");
|
|
}
|
|
|
|
if (options.IntervalMS < 100)
|
|
{
|
|
return ValidateOptionsResult.Fail("ProfileWorker:IntervalMs should be at least 100ms to avoid excessive CPU usage");
|
|
}
|
|
|
|
return ValidateOptionsResult.Success;
|
|
}
|
|
}
|