1919using Grpc . Core ;
2020using Grpc . Core . Utils ;
2121using Grpc . Health . V1 ;
22+ using Microsoft . Extensions . Hosting ;
2223
2324namespace Grpc . AspNetCore . HealthChecks ;
2425
@@ -32,7 +33,7 @@ namespace Grpc.AspNetCore.HealthChecks;
3233/// server.AddServiceDefinition(Grpc.Health.V1.Health.BindService(serviceImpl));
3334/// </code>
3435/// </summary>
35- public class HealthServiceImpl : Grpc . Health . V1 . Health . HealthBase
36+ public class HealthServiceImpl ( IHostApplicationLifetime applicationLifetime ) : Grpc . Health . V1 . Health . HealthBase
3637{
3738 // The maximum number of statuses to buffer on the server.
3839 internal const int MaxStatusBufferSize = 5 ;
@@ -192,15 +193,22 @@ public override async Task Watch(HealthCheckRequest request, IServerStreamWriter
192193 HealthCheckResponse response = GetHealthCheckResponse ( service , throwOnNotFound : false ) ;
193194 await responseStream . WriteAsync ( response ) . ConfigureAwait ( false ) ;
194195
195- // Read messages. WaitToReadAsync will wait until new messages are available.
196- // Loop will exit when the call is canceled and the writer is marked as complete.
197- while ( await channel . Reader . WaitToReadAsync ( ) . ConfigureAwait ( false ) )
196+ try
198197 {
199- if ( channel . Reader . TryRead ( out HealthCheckResponse ? item ) )
198+ // Read messages. WaitToReadAsync will wait until new messages are available.
199+ // Loop will exit when the call is canceled and the writer is marked as complete or when the application is stopping.
200+ while ( await channel . Reader . WaitToReadAsync ( applicationLifetime . ApplicationStopping ) . ConfigureAwait ( false ) )
200201 {
201- await responseStream . WriteAsync ( item ) . ConfigureAwait ( false ) ;
202+ if ( channel . Reader . TryRead ( out HealthCheckResponse ? item ) )
203+ {
204+ await responseStream . WriteAsync ( item ) . ConfigureAwait ( false ) ;
205+ }
202206 }
203207 }
208+ catch ( OperationCanceledException )
209+ {
210+ await responseStream . WriteAsync ( new HealthCheckResponse { Status = HealthCheckResponse . Types . ServingStatus . NotServing } ) ;
211+ }
204212 }
205213
206214 private void NotifyStatus ( string service , HealthCheckResponse . Types . ServingStatus status )
0 commit comments