@@ -40,7 +40,10 @@ pub struct HealthReporter {
40
40
41
41
impl HealthReporter {
42
42
fn new ( ) -> Self {
43
- let statuses = Arc :: new ( RwLock :: new ( HashMap :: new ( ) ) ) ;
43
+ // According to the gRPC Health Check specification, the empty service "" corresponds to the overall server health
44
+ let server_status = ( "" . to_string ( ) , watch:: channel ( ServingStatus :: Serving ) ) ;
45
+
46
+ let statuses = Arc :: new ( RwLock :: new ( HashMap :: from ( [ server_status] ) ) ) ;
44
47
45
48
HealthReporter { statuses }
46
49
}
@@ -166,9 +169,7 @@ mod tests {
166
169
use crate :: proto:: HealthCheckRequest ;
167
170
use crate :: server:: { HealthReporter , HealthService } ;
168
171
use crate :: ServingStatus ;
169
- use std:: collections:: HashMap ;
170
- use std:: sync:: Arc ;
171
- use tokio:: sync:: { watch, RwLock } ;
172
+ use tokio:: sync:: watch;
172
173
use tokio_stream:: StreamExt ;
173
174
use tonic:: { Code , Request , Status } ;
174
175
@@ -183,23 +184,35 @@ mod tests {
183
184
}
184
185
185
186
async fn make_test_service ( ) -> ( HealthReporter , HealthService ) {
186
- let state = Arc :: new ( RwLock :: new ( HashMap :: new ( ) ) ) ;
187
- state. write ( ) . await . insert (
188
- "TestService" . to_string ( ) ,
189
- watch:: channel ( ServingStatus :: Unknown ) ,
190
- ) ;
191
- (
192
- HealthReporter {
193
- statuses : state. clone ( ) ,
194
- } ,
195
- HealthService :: new ( state. clone ( ) ) ,
196
- )
187
+ let health_reporter = HealthReporter :: new ( ) ;
188
+
189
+ // insert test value
190
+ {
191
+ let mut statuses = health_reporter. statuses . write ( ) . await ;
192
+ statuses. insert (
193
+ "TestService" . to_string ( ) ,
194
+ watch:: channel ( ServingStatus :: Unknown ) ,
195
+ ) ;
196
+ }
197
+
198
+ let health_service = HealthService :: new ( health_reporter. statuses . clone ( ) ) ;
199
+ ( health_reporter, health_service)
197
200
}
198
201
199
202
#[ tokio:: test]
200
203
async fn test_service_check ( ) {
201
204
let ( mut reporter, service) = make_test_service ( ) . await ;
202
205
206
+ // Overall server health
207
+ let resp = service
208
+ . check ( Request :: new ( HealthCheckRequest {
209
+ service : "" . to_string ( ) ,
210
+ } ) )
211
+ . await ;
212
+ assert ! ( resp. is_ok( ) ) ;
213
+ let resp = resp. unwrap ( ) . into_inner ( ) ;
214
+ assert_serving_status ( resp. status , ServingStatus :: Serving ) ;
215
+
203
216
// Unregistered service
204
217
let resp = service
205
218
. check ( Request :: new ( HealthCheckRequest {
@@ -237,6 +250,21 @@ mod tests {
237
250
async fn test_service_watch ( ) {
238
251
let ( mut reporter, service) = make_test_service ( ) . await ;
239
252
253
+ // Overall server health
254
+ let resp = service
255
+ . watch ( Request :: new ( HealthCheckRequest {
256
+ service : "" . to_string ( ) ,
257
+ } ) )
258
+ . await ;
259
+ assert ! ( resp. is_ok( ) ) ;
260
+ let mut resp = resp. unwrap ( ) . into_inner ( ) ;
261
+ let item = resp
262
+ . next ( )
263
+ . await
264
+ . expect ( "streamed response is Some" )
265
+ . expect ( "response is ok" ) ;
266
+ assert_serving_status ( item. status , ServingStatus :: Serving ) ;
267
+
240
268
// Unregistered service
241
269
let resp = service
242
270
. watch ( Request :: new ( HealthCheckRequest {
0 commit comments