• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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