Allow cancellation to propagate

This commit is contained in:
Ryan Nowak 2018-09-19 21:22:48 -07:00
parent 4259b65c16
commit 8fb6c2a50a
2 changed files with 34 additions and 3 deletions

View File

@ -77,7 +77,9 @@ namespace Microsoft.Extensions.Diagnostics.HealthChecks
Log.HealthCheckEnd(_logger, registration, entry, stopwatch.GetElapsedTime()); Log.HealthCheckEnd(_logger, registration, entry, stopwatch.GetElapsedTime());
} }
catch (Exception ex)
// Allow cancellation to propagate.
catch (Exception ex) when (ex as OperationCanceledException == null)
{ {
entry = new HealthReportEntry(HealthStatus.Failed, ex.Message, ex, data: null); entry = new HealthReportEntry(HealthStatus.Failed, ex.Message, ex, data: null);
Log.HealthCheckError(_logger, registration, ex, stopwatch.GetElapsedTime()); Log.HealthCheckError(_logger, registration, ex, stopwatch.GetElapsedTime());

View File

@ -33,7 +33,7 @@ namespace Microsoft.Extensions.Diagnostics.HealthChecks
.AddCheck("Baz", new DelegateHealthCheck(_ => Task.FromResult(HealthCheckResult.Passed()))); .AddCheck("Baz", new DelegateHealthCheck(_ => Task.FromResult(HealthCheckResult.Passed())));
var services = serviceCollection.BuildServiceProvider(); var services = serviceCollection.BuildServiceProvider();
var scopeFactory = services.GetRequiredService<IServiceScopeFactory>(); var scopeFactory = services.GetRequiredService<IServiceScopeFactory>();
var options = services.GetRequiredService<IOptions<HealthCheckServiceOptions>>(); var options = services.GetRequiredService<IOptions<HealthCheckServiceOptions>>();
var logger = services.GetRequiredService<ILogger<DefaultHealthCheckService>>(); var logger = services.GetRequiredService<ILogger<DefaultHealthCheckService>>();
@ -188,6 +188,35 @@ namespace Microsoft.Extensions.Diagnostics.HealthChecks
}); });
} }
[Fact]
public async Task CheckHealthAsync_Cancellation_CanPropagate()
{
// Arrange
var insideCheck = new TaskCompletionSource<object>();
var service = CreateHealthChecksService(b =>
{
b.AddAsyncCheck("cancels", async ct =>
{
insideCheck.SetResult(null);
await Task.Delay(10000, ct);
return HealthCheckResult.Failed();
});
});
var cancel = new CancellationTokenSource();
var task = service.CheckHealthAsync(cancel.Token);
// After this returns we know the check has started
await insideCheck.Task;
cancel.Cancel();
// Act & Assert
await Assert.ThrowsAsync<TaskCanceledException>(async () => await task);
}
[Fact] [Fact]
public async Task CheckHealthAsync_ConvertsExceptionInHealthCheckToFailedResultAsync() public async Task CheckHealthAsync_ConvertsExceptionInHealthCheckToFailedResultAsync()
{ {
@ -366,7 +395,7 @@ namespace Microsoft.Extensions.Diagnostics.HealthChecks
public CheckWithServiceDependency(AnotherService _) public CheckWithServiceDependency(AnotherService _)
{ {
} }
public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default) public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
{ {
return Task.FromResult(HealthCheckResult.Passed()); return Task.FromResult(HealthCheckResult.Passed());