@@ -50,16 +50,15 @@ public override async Task<HealthReport> CheckHealthAsync(
5050
5151 var tasks = new Task < HealthReportEntry > [ registrations . Count ] ;
5252 var index = 0 ;
53- using ( var scope = _scopeFactory . CreateScope ( ) )
54- {
55- foreach ( var registration in registrations )
56- {
57- tasks [ index ++ ] = Task . Run ( ( ) => RunCheckAsync ( scope , registration , cancellationToken ) , cancellationToken ) ;
58- }
5953
60- await Task . WhenAll ( tasks ) . ConfigureAwait ( false ) ;
54+ foreach ( var registration in registrations )
55+ {
56+ tasks [ index ++ ] = Task . Run ( ( ) => RunCheckAsync ( registration , cancellationToken ) , cancellationToken ) ;
6157 }
6258
59+ await Task . WhenAll ( tasks ) . ConfigureAwait ( false ) ;
60+
61+
6362 index = 0 ;
6463 var entries = new Dictionary < string , HealthReportEntry > ( StringComparer . OrdinalIgnoreCase ) ;
6564 foreach ( var registration in registrations )
@@ -73,85 +72,88 @@ public override async Task<HealthReport> CheckHealthAsync(
7372 return report ;
7473 }
7574
76- private async Task < HealthReportEntry > RunCheckAsync ( IServiceScope scope , HealthCheckRegistration registration , CancellationToken cancellationToken )
75+ private async Task < HealthReportEntry > RunCheckAsync ( HealthCheckRegistration registration , CancellationToken cancellationToken )
7776 {
7877 cancellationToken . ThrowIfCancellationRequested ( ) ;
7978
80- var healthCheck = registration . Factory ( scope . ServiceProvider ) ;
81-
82- // If the health check does things like make Database queries using EF or backend HTTP calls,
83- // it may be valuable to know that logs it generates are part of a health check. So we start a scope.
84- using ( _logger . BeginScope ( new HealthCheckLogScope ( registration . Name ) ) )
79+ using ( var scope = _scopeFactory . CreateScope ( ) )
8580 {
86- var stopwatch = ValueStopwatch . StartNew ( ) ;
87- var context = new HealthCheckContext { Registration = registration } ;
88-
89- Log . HealthCheckBegin ( _logger , registration ) ;
81+ var healthCheck = registration . Factory ( scope . ServiceProvider ) ;
9082
91- HealthReportEntry entry ;
92- CancellationTokenSource ? timeoutCancellationTokenSource = null ;
93- try
83+ // If the health check does things like make Database queries using EF or backend HTTP calls,
84+ // it may be valuable to know that logs it generates are part of a health check. So we start a scope.
85+ using ( _logger . BeginScope ( new HealthCheckLogScope ( registration . Name ) ) )
9486 {
95- HealthCheckResult result ;
87+ var stopwatch = ValueStopwatch . StartNew ( ) ;
88+ var context = new HealthCheckContext { Registration = registration } ;
9689
97- var checkCancellationToken = cancellationToken ;
98- if ( registration . Timeout > TimeSpan . Zero )
90+ Log . HealthCheckBegin ( _logger , registration ) ;
91+
92+ HealthReportEntry entry ;
93+ CancellationTokenSource ? timeoutCancellationTokenSource = null ;
94+ try
9995 {
100- timeoutCancellationTokenSource = CancellationTokenSource . CreateLinkedTokenSource ( cancellationToken ) ;
101- timeoutCancellationTokenSource . CancelAfter ( registration . Timeout ) ;
102- checkCancellationToken = timeoutCancellationTokenSource . Token ;
96+ HealthCheckResult result ;
97+
98+ var checkCancellationToken = cancellationToken ;
99+ if ( registration . Timeout > TimeSpan . Zero )
100+ {
101+ timeoutCancellationTokenSource = CancellationTokenSource . CreateLinkedTokenSource ( cancellationToken ) ;
102+ timeoutCancellationTokenSource . CancelAfter ( registration . Timeout ) ;
103+ checkCancellationToken = timeoutCancellationTokenSource . Token ;
104+ }
105+
106+ result = await healthCheck . CheckHealthAsync ( context , checkCancellationToken ) . ConfigureAwait ( false ) ;
107+
108+ var duration = stopwatch . GetElapsedTime ( ) ;
109+
110+ entry = new HealthReportEntry (
111+ status : result . Status ,
112+ description : result . Description ,
113+ duration : duration ,
114+ exception : result . Exception ,
115+ data : result . Data ,
116+ tags : registration . Tags ) ;
117+
118+ Log . HealthCheckEnd ( _logger , registration , entry , duration ) ;
119+ Log . HealthCheckData ( _logger , registration , entry ) ;
120+ }
121+ catch ( OperationCanceledException ex ) when ( ! cancellationToken . IsCancellationRequested )
122+ {
123+ var duration = stopwatch . GetElapsedTime ( ) ;
124+ entry = new HealthReportEntry (
125+ status : registration . FailureStatus ,
126+ description : "A timeout occurred while running check." ,
127+ duration : duration ,
128+ exception : ex ,
129+ data : null ,
130+ tags : registration . Tags ) ;
131+
132+ Log . HealthCheckError ( _logger , registration , ex , duration ) ;
103133 }
104134
105- result = await healthCheck . CheckHealthAsync ( context , checkCancellationToken ) . ConfigureAwait ( false ) ;
106-
107- var duration = stopwatch . GetElapsedTime ( ) ;
108-
109- entry = new HealthReportEntry (
110- status : result . Status ,
111- description : result . Description ,
112- duration : duration ,
113- exception : result . Exception ,
114- data : result . Data ,
115- tags : registration . Tags ) ;
116-
117- Log . HealthCheckEnd ( _logger , registration , entry , duration ) ;
118- Log . HealthCheckData ( _logger , registration , entry ) ;
119- }
120- catch ( OperationCanceledException ex ) when ( ! cancellationToken . IsCancellationRequested )
121- {
122- var duration = stopwatch . GetElapsedTime ( ) ;
123- entry = new HealthReportEntry (
124- status : registration . FailureStatus ,
125- description : "A timeout occurred while running check." ,
126- duration : duration ,
127- exception : ex ,
128- data : null ,
129- tags : registration . Tags ) ;
130-
131- Log . HealthCheckError ( _logger , registration , ex , duration ) ;
132- }
135+ // Allow cancellation to propagate if it's not a timeout.
136+ catch ( Exception ex ) when ( ex as OperationCanceledException == null )
137+ {
138+ var duration = stopwatch . GetElapsedTime ( ) ;
139+ entry = new HealthReportEntry (
140+ status : registration . FailureStatus ,
141+ description : ex . Message ,
142+ duration : duration ,
143+ exception : ex ,
144+ data : null ,
145+ tags : registration . Tags ) ;
146+
147+ Log . HealthCheckError ( _logger , registration , ex , duration ) ;
148+ }
133149
134- // Allow cancellation to propagate if it's not a timeout.
135- catch ( Exception ex ) when ( ex as OperationCanceledException == null )
136- {
137- var duration = stopwatch . GetElapsedTime ( ) ;
138- entry = new HealthReportEntry (
139- status : registration . FailureStatus ,
140- description : ex . Message ,
141- duration : duration ,
142- exception : ex ,
143- data : null ,
144- tags : registration . Tags ) ;
145-
146- Log . HealthCheckError ( _logger , registration , ex , duration ) ;
147- }
150+ finally
151+ {
152+ timeoutCancellationTokenSource ? . Dispose ( ) ;
153+ }
148154
149- finally
150- {
151- timeoutCancellationTokenSource ? . Dispose ( ) ;
155+ return entry ;
152156 }
153-
154- return entry ;
155157 }
156158 }
157159
0 commit comments