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