xref: /aosp_15_r20/external/grpc-grpc/test/cpp/end2end/test_health_check_service_impl.cc (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1 //
2 //
3 // Copyright 2018 gRPC authors.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 //
18 
19 #include "test/cpp/end2end/test_health_check_service_impl.h"
20 
21 #include <grpc/grpc.h>
22 
23 using grpc::health::v1::HealthCheckRequest;
24 using grpc::health::v1::HealthCheckResponse;
25 
26 namespace grpc {
27 namespace testing {
28 
Check(ServerContext *,const HealthCheckRequest * request,HealthCheckResponse * response)29 Status HealthCheckServiceImpl::Check(ServerContext* /*context*/,
30                                      const HealthCheckRequest* request,
31                                      HealthCheckResponse* response) {
32   std::lock_guard<std::mutex> lock(mu_);
33   auto iter = status_map_.find(request->service());
34   if (iter == status_map_.end()) {
35     return Status(StatusCode::NOT_FOUND, "");
36   }
37   response->set_status(iter->second);
38   return Status::OK;
39 }
40 
Watch(ServerContext * context,const HealthCheckRequest * request,grpc::ServerWriter<HealthCheckResponse> * writer)41 Status HealthCheckServiceImpl::Watch(
42     ServerContext* context, const HealthCheckRequest* request,
43     grpc::ServerWriter<HealthCheckResponse>* writer) {
44   auto last_state = HealthCheckResponse::UNKNOWN;
45   while (!context->IsCancelled()) {
46     {
47       std::lock_guard<std::mutex> lock(mu_);
48       HealthCheckResponse response;
49       auto iter = status_map_.find(request->service());
50       if (iter == status_map_.end()) {
51         response.set_status(response.SERVICE_UNKNOWN);
52       } else {
53         response.set_status(iter->second);
54       }
55       if (response.status() != last_state) {
56         writer->Write(response, grpc::WriteOptions());
57         last_state = response.status();
58       }
59     }
60     gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
61                                  gpr_time_from_millis(1000, GPR_TIMESPAN)));
62   }
63   return Status::OK;
64 }
65 
SetStatus(const std::string & service_name,HealthCheckResponse::ServingStatus status)66 void HealthCheckServiceImpl::SetStatus(
67     const std::string& service_name,
68     HealthCheckResponse::ServingStatus status) {
69   std::lock_guard<std::mutex> lock(mu_);
70   if (shutdown_) {
71     status = HealthCheckResponse::NOT_SERVING;
72   }
73   status_map_[service_name] = status;
74 }
75 
SetAll(HealthCheckResponse::ServingStatus status)76 void HealthCheckServiceImpl::SetAll(HealthCheckResponse::ServingStatus status) {
77   std::lock_guard<std::mutex> lock(mu_);
78   if (shutdown_) {
79     return;
80   }
81   for (auto iter = status_map_.begin(); iter != status_map_.end(); ++iter) {
82     iter->second = status;
83   }
84 }
85 
Shutdown()86 void HealthCheckServiceImpl::Shutdown() {
87   std::lock_guard<std::mutex> lock(mu_);
88   if (shutdown_) {
89     return;
90   }
91   shutdown_ = true;
92   for (auto iter = status_map_.begin(); iter != status_map_.end(); ++iter) {
93     iter->second = HealthCheckResponse::NOT_SERVING;
94   }
95 }
96 
97 }  // namespace testing
98 }  // namespace grpc
99