Make IHealthCheckService work in ST-sync-context
\n\nCommit migrated from 2b673c89c2
This commit is contained in:
parent
ffc4b00764
commit
2849483895
|
|
@ -54,7 +54,7 @@ namespace Microsoft.Extensions.Diagnostics.HealthChecks
|
||||||
{
|
{
|
||||||
foreach (var registration in registrations)
|
foreach (var registration in registrations)
|
||||||
{
|
{
|
||||||
tasks[index++] = RunCheckAsync(scope, registration, cancellationToken);
|
tasks[index++] = Task.Run(() => RunCheckAsync(scope, registration, cancellationToken), cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
await Task.WhenAll(tasks).ConfigureAwait(false);
|
await Task.WhenAll(tasks).ConfigureAwait(false);
|
||||||
|
|
@ -75,8 +75,6 @@ namespace Microsoft.Extensions.Diagnostics.HealthChecks
|
||||||
|
|
||||||
private async Task<HealthReportEntry> RunCheckAsync(IServiceScope scope, HealthCheckRegistration registration, CancellationToken cancellationToken)
|
private async Task<HealthReportEntry> RunCheckAsync(IServiceScope scope, HealthCheckRegistration registration, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
await Task.Yield();
|
|
||||||
|
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
var healthCheck = registration.Factory(scope.ServiceProvider);
|
var healthCheck = registration.Factory(scope.ServiceProvider);
|
||||||
|
|
@ -104,7 +102,7 @@ namespace Microsoft.Extensions.Diagnostics.HealthChecks
|
||||||
checkCancellationToken = timeoutCancellationTokenSource.Token;
|
checkCancellationToken = timeoutCancellationTokenSource.Token;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = await healthCheck.CheckHealthAsync(context, checkCancellationToken);
|
result = await healthCheck.CheckHealthAsync(context, checkCancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
var duration = stopwatch.GetElapsedTime();
|
var duration = stopwatch.GetElapsedTime();
|
||||||
|
|
||||||
|
|
@ -118,7 +116,6 @@ namespace Microsoft.Extensions.Diagnostics.HealthChecks
|
||||||
Log.HealthCheckEnd(_logger, registration, entry, duration);
|
Log.HealthCheckEnd(_logger, registration, entry, duration);
|
||||||
Log.HealthCheckData(_logger, registration, entry);
|
Log.HealthCheckData(_logger, registration, entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (OperationCanceledException ex) when (!cancellationToken.IsCancellationRequested)
|
catch (OperationCanceledException ex) when (!cancellationToken.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
var duration = stopwatch.GetElapsedTime();
|
var duration = stopwatch.GetElapsedTime();
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Testing;
|
using Microsoft.AspNetCore.Testing;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Internal;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Logging.Testing;
|
using Microsoft.Extensions.Logging.Testing;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
|
|
@ -450,6 +451,39 @@ namespace Microsoft.Extensions.Diagnostics.HealthChecks
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void CheckHealthAsync_WorksInSingleThreadedSyncContext()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var service = CreateHealthChecksService(b =>
|
||||||
|
{
|
||||||
|
b.AddAsyncCheck("test", async () =>
|
||||||
|
{
|
||||||
|
await Task.Delay(1).ConfigureAwait(false);
|
||||||
|
return HealthCheckResult.Healthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
var hangs = true;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(3)))
|
||||||
|
{
|
||||||
|
var token = cts.Token;
|
||||||
|
token.Register(() => throw new OperationCanceledException(token));
|
||||||
|
|
||||||
|
SingleThreadedSynchronizationContext.Run(() =>
|
||||||
|
{
|
||||||
|
// Act
|
||||||
|
service.CheckHealthAsync(token).GetAwaiter().GetResult();
|
||||||
|
hangs = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.False(hangs);
|
||||||
|
}
|
||||||
|
|
||||||
private static DefaultHealthCheckService CreateHealthChecksService(Action<IHealthChecksBuilder> configure)
|
private static DefaultHealthCheckService CreateHealthChecksService(Action<IHealthChecksBuilder> configure)
|
||||||
{
|
{
|
||||||
var services = new ServiceCollection();
|
var services = new ServiceCollection();
|
||||||
|
|
|
||||||
|
|
@ -12,4 +12,8 @@
|
||||||
<Reference Include="Microsoft.Extensions.Logging.Testing" />
|
<Reference Include="Microsoft.Extensions.Logging.Testing" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="..\..\..\Shared\test\SingleThreadedSynchronizationContext.cs" Link="Shared\SingleThreadedSynchronizationContext.cs"/>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue