Implement parallel health checks

\n\nCommit migrated from f14a45e096
This commit is contained in:
Nathanael Marchand 2019-02-18 15:48:45 +01:00 committed by Ryan Nowak
parent 58ea57e63f
commit d805cf3b2e
1 changed files with 71 additions and 66 deletions

View File

@ -39,23 +39,8 @@ namespace Microsoft.Extensions.Diagnostics.HealthChecks
Func<HealthCheckRegistration, bool> predicate, Func<HealthCheckRegistration, bool> predicate,
CancellationToken cancellationToken = default) CancellationToken cancellationToken = default)
{ {
var registrations = _options.Value.Registrations; async Task<(string registrationName, HealthReportEntry result)> RunCheckAsync(IServiceScope scope, HealthCheckRegistration registration)
using (var scope = _scopeFactory.CreateScope())
{ {
var context = new HealthCheckContext();
var entries = new Dictionary<string, HealthReportEntry>(StringComparer.OrdinalIgnoreCase);
var totalTime = ValueStopwatch.StartNew();
Log.HealthCheckProcessingBegin(_logger);
foreach (var registration in registrations)
{
if (predicate != null && !predicate(registration))
{
continue;
}
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
var healthCheck = registration.Factory(scope.ServiceProvider); var healthCheck = registration.Factory(scope.ServiceProvider);
@ -65,7 +50,7 @@ namespace Microsoft.Extensions.Diagnostics.HealthChecks
using (_logger.BeginScope(new HealthCheckLogScope(registration.Name))) using (_logger.BeginScope(new HealthCheckLogScope(registration.Name)))
{ {
var stopwatch = ValueStopwatch.StartNew(); var stopwatch = ValueStopwatch.StartNew();
context.Registration = registration; var context = new HealthCheckContext { Registration = registration };
Log.HealthCheckBegin(_logger, registration); Log.HealthCheckBegin(_logger, registration);
@ -100,16 +85,36 @@ namespace Microsoft.Extensions.Diagnostics.HealthChecks
Log.HealthCheckError(_logger, registration, ex, duration); Log.HealthCheckError(_logger, registration, ex, duration);
} }
entries[registration.Name] = entry; return (registration.Name, entry);
} }
} }
IEnumerable<HealthCheckRegistration> registrations = _options.Value.Registrations;
if (predicate != null)
{
registrations = registrations.Where(predicate);
}
var totalTime = ValueStopwatch.StartNew();
Log.HealthCheckProcessingBegin(_logger);
(string registrationName, HealthReportEntry result)[] results;
using (var scope = _scopeFactory.CreateScope())
{
results = await Task.WhenAll(registrations.Select(r => RunCheckAsync(scope, r)));
}
var entries = new Dictionary<string, HealthReportEntry>(StringComparer.OrdinalIgnoreCase);
foreach (var (registrationName, result) in results)
{
entries[registrationName] = result;
}
var totalElapsedTime = totalTime.GetElapsedTime(); var totalElapsedTime = totalTime.GetElapsedTime();
var report = new HealthReport(entries, totalElapsedTime); var report = new HealthReport(entries, totalElapsedTime);
Log.HealthCheckProcessingEnd(_logger, report.Status, totalElapsedTime); Log.HealthCheckProcessingEnd(_logger, report.Status, totalElapsedTime);
return report; return report;
} }
}
private static void ValidateRegistrations(IEnumerable<HealthCheckRegistration> registrations) private static void ValidateRegistrations(IEnumerable<HealthCheckRegistration> registrations)
{ {