1 // 2 // 3 // Copyright 2016 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 #ifndef GRPC_SRC_CPP_SERVER_HEALTH_DEFAULT_HEALTH_CHECK_SERVICE_H 20 #define GRPC_SRC_CPP_SERVER_HEALTH_DEFAULT_HEALTH_CHECK_SERVICE_H 21 22 #include <stddef.h> 23 24 #include <map> 25 #include <memory> 26 #include <string> 27 28 #include "absl/base/thread_annotations.h" 29 30 #include <grpcpp/grpcpp.h> 31 #include <grpcpp/health_check_service_interface.h> 32 #include <grpcpp/impl/service_type.h> 33 #include <grpcpp/impl/sync.h> 34 #include <grpcpp/support/byte_buffer.h> 35 #include <grpcpp/support/server_callback.h> 36 #include <grpcpp/support/status.h> 37 38 #include "src/core/lib/gprpp/ref_counted.h" 39 #include "src/core/lib/gprpp/ref_counted_ptr.h" 40 41 namespace grpc { 42 43 // Default implementation of HealthCheckServiceInterface. Server will create and 44 // own it. 45 class DefaultHealthCheckService final : public HealthCheckServiceInterface { 46 public: 47 enum ServingStatus { NOT_FOUND, SERVING, NOT_SERVING }; 48 49 // The service impl to register with the server. 50 class HealthCheckServiceImpl : public Service { 51 public: 52 // Reactor for handling Watch streams. 53 class WatchReactor : public ServerWriteReactor<ByteBuffer>, 54 public grpc_core::RefCounted<WatchReactor> { 55 public: 56 WatchReactor(HealthCheckServiceImpl* service, const ByteBuffer* request); 57 58 void SendHealth(ServingStatus status); 59 60 void OnWriteDone(bool ok) override; 61 void OnCancel() override; 62 void OnDone() override; 63 64 private: 65 void SendHealthLocked(ServingStatus status) 66 ABSL_EXCLUSIVE_LOCKS_REQUIRED(&mu_); 67 68 void MaybeFinishLocked(Status status) ABSL_EXCLUSIVE_LOCKS_REQUIRED(&mu_); 69 70 HealthCheckServiceImpl* service_; 71 std::string service_name_; 72 ByteBuffer response_; 73 74 grpc::internal::Mutex mu_; 75 bool write_pending_ ABSL_GUARDED_BY(mu_) = false; 76 ServingStatus pending_status_ ABSL_GUARDED_BY(mu_) = NOT_FOUND; 77 bool finish_called_ ABSL_GUARDED_BY(mu_) = false; 78 }; 79 80 explicit HealthCheckServiceImpl(DefaultHealthCheckService* database); 81 82 ~HealthCheckServiceImpl() override; 83 84 private: 85 // Request handler for Check method. 86 static ServerUnaryReactor* HandleCheckRequest( 87 DefaultHealthCheckService* database, CallbackServerContext* context, 88 const ByteBuffer* request, ByteBuffer* response); 89 90 // Returns true on success. 91 static bool DecodeRequest(const ByteBuffer& request, 92 std::string* service_name); 93 static bool EncodeResponse(ServingStatus status, ByteBuffer* response); 94 95 DefaultHealthCheckService* database_; 96 97 grpc::internal::Mutex mu_; 98 grpc::internal::CondVar shutdown_condition_; 99 bool shutdown_ ABSL_GUARDED_BY(mu_) = false; 100 size_t num_watches_ ABSL_GUARDED_BY(mu_) = 0; 101 }; 102 103 DefaultHealthCheckService(); 104 105 void SetServingStatus(const std::string& service_name, bool serving) override; 106 void SetServingStatus(bool serving) override; 107 108 void Shutdown() override; 109 110 ServingStatus GetServingStatus(const std::string& service_name) const; 111 112 HealthCheckServiceImpl* GetHealthCheckService(); 113 114 private: 115 // Stores the current serving status of a service and any call 116 // handlers registered for updates when the service's status changes. 117 class ServiceData { 118 public: 119 void SetServingStatus(ServingStatus status); GetServingStatus()120 ServingStatus GetServingStatus() const { return status_; } 121 void AddWatch( 122 grpc_core::RefCountedPtr<HealthCheckServiceImpl::WatchReactor> watcher); 123 void RemoveWatch(HealthCheckServiceImpl::WatchReactor* watcher); Unused()124 bool Unused() const { return watchers_.empty() && status_ == NOT_FOUND; } 125 126 private: 127 ServingStatus status_ = NOT_FOUND; 128 std::map<HealthCheckServiceImpl::WatchReactor*, 129 grpc_core::RefCountedPtr<HealthCheckServiceImpl::WatchReactor>> 130 watchers_; 131 }; 132 133 void RegisterWatch( 134 const std::string& service_name, 135 grpc_core::RefCountedPtr<HealthCheckServiceImpl::WatchReactor> watcher); 136 137 void UnregisterWatch(const std::string& service_name, 138 HealthCheckServiceImpl::WatchReactor* watcher); 139 140 mutable grpc::internal::Mutex mu_; 141 bool shutdown_ ABSL_GUARDED_BY(&mu_) = false; 142 std::map<std::string, ServiceData> services_map_ ABSL_GUARDED_BY(&mu_); 143 std::unique_ptr<HealthCheckServiceImpl> impl_; 144 }; 145 146 } // namespace grpc 147 148 #endif // GRPC_SRC_CPP_SERVER_HEALTH_DEFAULT_HEALTH_CHECK_SERVICE_H 149