health_check_client.cc
Go to the documentation of this file.
1 //
2 // Copyright 2018 gRPC authors.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
18 
20 
21 #include <stdint.h>
22 #include <stdio.h>
23 #include <string.h>
24 
25 #include <memory>
26 #include <utility>
27 
28 #include "absl/memory/memory.h"
29 #include "absl/status/status.h"
30 #include "absl/status/statusor.h"
31 #include "absl/strings/string_view.h"
32 #include "upb/upb.h"
33 #include "upb/upb.hpp"
34 
36 #include <grpc/slice.h>
37 #include <grpc/status.h>
38 #include <grpc/support/log.h>
39 
44 
45 namespace grpc_core {
46 
47 TraceFlag grpc_health_check_client_trace(false, "health_check_client");
48 
49 namespace {
50 
51 class HealthStreamEventHandler
52  : public SubchannelStreamClient::CallEventHandler {
53  public:
54  HealthStreamEventHandler(
55  std::string service_name,
56  RefCountedPtr<channelz::SubchannelNode> channelz_node,
57  RefCountedPtr<ConnectivityStateWatcherInterface> watcher)
58  : service_name_(std::move(service_name)),
59  channelz_node_(std::move(channelz_node)),
60  watcher_(std::move(watcher)) {}
61 
62  Slice GetPathLocked() override {
63  return Slice::FromStaticString("/grpc.health.v1.Health/Watch");
64  }
65 
66  void OnCallStartLocked(SubchannelStreamClient* client) override {
67  SetHealthStatusLocked(client, GRPC_CHANNEL_CONNECTING,
68  "starting health watch");
69  }
70 
71  void OnRetryTimerStartLocked(SubchannelStreamClient* client) override {
72  SetHealthStatusLocked(client, GRPC_CHANNEL_TRANSIENT_FAILURE,
73  "health check call failed; will retry after backoff");
74  }
75 
76  grpc_slice EncodeSendMessageLocked() override {
78  grpc_health_v1_HealthCheckRequest* request_struct =
81  request_struct, upb_StringView_FromDataAndSize(service_name_.data(),
82  service_name_.size()));
83  size_t buf_length;
85  request_struct, arena.ptr(), &buf_length);
86  grpc_slice request_slice = GRPC_SLICE_MALLOC(buf_length);
87  memcpy(GRPC_SLICE_START_PTR(request_slice), buf, buf_length);
88  return request_slice;
89  }
90 
91  absl::Status RecvMessageReadyLocked(
92  SubchannelStreamClient* client,
93  absl::string_view serialized_message) override {
94  auto healthy = DecodeResponse(serialized_message);
95  if (!healthy.ok()) {
96  SetHealthStatusLocked(client, GRPC_CHANNEL_TRANSIENT_FAILURE,
97  healthy.status().ToString().c_str());
98  return healthy.status();
99  }
100  if (!*healthy) {
101  SetHealthStatusLocked(client, GRPC_CHANNEL_TRANSIENT_FAILURE,
102  "backend unhealthy");
103  } else {
104  SetHealthStatusLocked(client, GRPC_CHANNEL_READY, "OK");
105  }
106  return absl::OkStatus();
107  }
108 
109  void RecvTrailingMetadataReadyLocked(SubchannelStreamClient* client,
110  grpc_status_code status) override {
112  static const char kErrorMessage[] =
113  "health checking Watch method returned UNIMPLEMENTED; "
114  "disabling health checks but assuming server is healthy";
116  if (channelz_node_ != nullptr) {
117  channelz_node_->AddTraceEvent(
120  }
121  SetHealthStatusLocked(client, GRPC_CHANNEL_READY, kErrorMessage);
122  }
123  }
124 
125  private:
126  // Returns true if healthy.
127  static absl::StatusOr<bool> DecodeResponse(
128  absl::string_view serialized_message) {
129  // Deserialize message.
132  serialized_message.data(), serialized_message.size(), arena.ptr());
133  if (response == nullptr) {
134  // Can't parse message; assume unhealthy.
135  return absl::InvalidArgumentError("cannot parse health check response");
136  }
139  }
140 
141  void SetHealthStatusLocked(SubchannelStreamClient* client,
143  const char* reason) {
145  gpr_log(GPR_INFO, "HealthCheckClient %p: setting state=%s reason=%s",
147  }
149  ? absl::UnavailableError(reason)
150  : absl::Status());
151  }
152 
154  RefCountedPtr<channelz::SubchannelNode> channelz_node_;
155  RefCountedPtr<ConnectivityStateWatcherInterface> watcher_;
156 };
157 
158 } // namespace
159 
161  std::string service_name,
162  RefCountedPtr<ConnectedSubchannel> connected_subchannel,
163  grpc_pollset_set* interested_parties,
166  return MakeOrphanable<SubchannelStreamClient>(
167  std::move(connected_subchannel), interested_parties,
168  absl::make_unique<HealthStreamEventHandler>(std::move(service_name),
169  std::move(channelz_node),
170  std::move(watcher)),
172  ? "HealthCheckClient"
173  : nullptr);
174 }
175 
176 } // namespace grpc_core
trace.h
absl::InvalidArgumentError
Status InvalidArgumentError(absl::string_view message)
Definition: third_party/abseil-cpp/absl/status/status.cc:351
slice.h
GPR_INFO
#define GPR_INFO
Definition: include/grpc/impl/codegen/log.h:56
GRPC_CHANNEL_READY
@ GRPC_CHANNEL_READY
Definition: include/grpc/impl/codegen/connectivity_state.h:36
channelz_node_
RefCountedPtr< channelz::SubchannelNode > channelz_node_
Definition: health_check_client.cc:154
log.h
grpc_core::MakeHealthCheckClient
OrphanablePtr< SubchannelStreamClient > MakeHealthCheckClient(std::string service_name, RefCountedPtr< ConnectedSubchannel > connected_subchannel, grpc_pollset_set *interested_parties, RefCountedPtr< channelz::SubchannelNode > channelz_node, RefCountedPtr< ConnectivityStateWatcherInterface > watcher)
Definition: health_check_client.cc:160
slice.h
grpc_health_v1_HealthCheckRequest_new
UPB_INLINE grpc_health_v1_HealthCheckRequest * grpc_health_v1_HealthCheckRequest_new(upb_Arena *arena)
Definition: health.upb.h:41
grpc_core
Definition: call_metric_recorder.h:31
client
Definition: examples/python/async_streaming/client.py:1
grpc_core::channelz::ChannelTrace::Error
@ Error
Definition: channel_trace.h:55
grpc_pollset_set
struct grpc_pollset_set grpc_pollset_set
Definition: iomgr_fwd.h:23
string.h
grpc_core::slice_detail::StaticConstructors< Slice >::FromStaticString
static Slice FromStaticString(const char *s)
Definition: src/core/lib/slice/slice.h:201
buf
voidpf void * buf
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
absl::string_view
Definition: abseil-cpp/absl/strings/string_view.h:167
GRPC_SLICE_MALLOC
#define GRPC_SLICE_MALLOC(len)
Definition: include/grpc/slice.h:70
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
grpc_status_code
grpc_status_code
Definition: include/grpc/impl/codegen/status.h:28
GRPC_CHANNEL_TRANSIENT_FAILURE
@ GRPC_CHANNEL_TRANSIENT_FAILURE
Definition: include/grpc/impl/codegen/connectivity_state.h:38
absl::OkStatus
Status OkStatus()
Definition: third_party/abseil-cpp/absl/status/status.h:882
status
absl::Status status
Definition: rls.cc:251
health_check_client.h
GRPC_TRACE_FLAG_ENABLED
#define GRPC_TRACE_FLAG_ENABLED(f)
Definition: debug/trace.h:114
grpc_health_v1_HealthCheckRequest_serialize
UPB_INLINE char * grpc_health_v1_HealthCheckRequest_serialize(const grpc_health_v1_HealthCheckRequest *msg, upb_Arena *arena, size_t *len)
Definition: health.upb.h:63
arena
grpc_core::ScopedArenaPtr arena
Definition: binder_transport_test.cc:237
grpc_connectivity_state
grpc_connectivity_state
Definition: include/grpc/impl/codegen/connectivity_state.h:30
status.h
grpc_health_v1_HealthCheckResponse_SERVING
@ grpc_health_v1_HealthCheckResponse_SERVING
Definition: health.upb.h:32
memcpy
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
grpc_health_v1_HealthCheckResponse_parse
UPB_INLINE grpc_health_v1_HealthCheckResponse * grpc_health_v1_HealthCheckResponse_parse(const char *buf, size_t size, upb_Arena *arena)
Definition: health.upb.h:86
grpc_core::RefCountedPtr
Definition: ref_counted_ptr.h:35
absl::move
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
Definition: abseil-cpp/absl/utility/utility.h:221
grpc_core::grpc_health_check_client_trace
TraceFlag grpc_health_check_client_trace(false, "health_check_client")
absl::string_view::size
constexpr size_type size() const noexcept
Definition: abseil-cpp/absl/strings/string_view.h:277
upb.h
gpr_log
GPRAPI void gpr_log(const char *file, int line, gpr_log_severity severity, const char *format,...) GPR_PRINT_FORMAT_CHECK(4
service_name_
std::string service_name_
Definition: health_check_client.cc:153
connectivity_state.h
GRPC_SLICE_START_PTR
#define GRPC_SLICE_START_PTR(slice)
Definition: include/grpc/impl/codegen/slice.h:101
grpc_slice_from_static_string
GPRAPI grpc_slice grpc_slice_from_static_string(const char *source)
Definition: slice/slice.cc:89
grpc_slice
Definition: include/grpc/impl/codegen/slice.h:65
watcher_
RefCountedPtr< ConnectivityStateWatcherInterface > watcher_
Definition: health_check_client.cc:155
GPR_ERROR
#define GPR_ERROR
Definition: include/grpc/impl/codegen/log.h:57
stdint.h
GRPC_CHANNEL_CONNECTING
@ GRPC_CHANNEL_CONNECTING
Definition: include/grpc/impl/codegen/connectivity_state.h:34
upb::Arena
Definition: upb.hpp:68
grpc_core::ConnectivityStateName
const char * ConnectivityStateName(grpc_connectivity_state state)
Definition: connectivity_state.cc:38
grpc_core::testing::kErrorMessage
constexpr const char * kErrorMessage
Definition: grpc_tls_certificate_distributor_test.cc:51
upb.hpp
absl::Status
Definition: third_party/abseil-cpp/absl/status/status.h:424
grpc_health_v1_HealthCheckResponse_status
UPB_INLINE int32_t grpc_health_v1_HealthCheckResponse_status(const grpc_health_v1_HealthCheckResponse *msg)
Definition: health.upb.h:115
grpc_core::OrphanablePtr
std::unique_ptr< T, Deleter > OrphanablePtr
Definition: orphanable.h:64
asyncio_get_stats.response
response
Definition: asyncio_get_stats.py:28
std
Definition: grpcpp/impl/codegen/async_unary_call.h:407
upb_StringView_FromDataAndSize
UPB_INLINE upb_StringView upb_StringView_FromDataAndSize(const char *data, size_t size)
Definition: upb/upb/upb.h:77
health.upb.h
state
Definition: bloaty/third_party/zlib/contrib/blast/blast.c:41
grpc_health_v1_HealthCheckRequest_set_service
UPB_INLINE void grpc_health_v1_HealthCheckRequest_set_service(grpc_health_v1_HealthCheckRequest *msg, upb_StringView value)
Definition: health.upb.h:77
absl::UnavailableError
Status UnavailableError(absl::string_view message)
Definition: third_party/abseil-cpp/absl/status/status.cc:375
grpc_health_v1_HealthCheckRequest
struct grpc_health_v1_HealthCheckRequest grpc_health_v1_HealthCheckRequest
Definition: health.upb.h:25
watcher
ClusterWatcher * watcher
Definition: cds.cc:148
GRPC_STATUS_UNIMPLEMENTED
@ GRPC_STATUS_UNIMPLEMENTED
Definition: include/grpc/impl/codegen/status.h:124
absl::StatusOr
Definition: abseil-cpp/absl/status/statusor.h:187
channel_trace.h
int32_t
signed int int32_t
Definition: stdint-msvc2008.h:77
absl::string_view::data
constexpr const_pointer data() const noexcept
Definition: abseil-cpp/absl/strings/string_view.h:336
port_platform.h


grpc
Author(s):
autogenerated on Fri May 16 2025 02:59:01