Client-side health checking support.

pull/16507/head
Mark D. Roth 6 years ago
parent 55906e4d23
commit f85fd026e3
  1. 1
      .clang_complete
  2. 21
      BUILD
  3. 44
      CMakeLists.txt
  4. 44
      Makefile
  5. 13
      build.yaml
  6. 3
      config.m4
  7. 3
      config.w32
  8. 1
      doc/environment_variables.md
  9. 8
      gRPC-C++.podspec
  10. 13
      gRPC-Core.podspec
  11. 4
      grpc.gemspec
  12. 30
      grpc.gyp
  13. 3
      include/grpc/impl/codegen/grpc_types.h
  14. 4
      package.xml
  15. 3
      src/core/ext/filters/client_channel/client_channel_channelz.cc
  16. 2
      src/core/ext/filters/client_channel/health/health.pb.c
  17. 0
      src/core/ext/filters/client_channel/health/health.pb.h
  18. 646
      src/core/ext/filters/client_channel/health/health_check_client.cc
  19. 173
      src/core/ext/filters/client_channel/health/health_check_client.h
  20. 10
      src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc
  21. 7
      src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
  22. 25
      src/core/ext/filters/client_channel/lb_policy/subchannel_list.h
  23. 393
      src/core/ext/filters/client_channel/subchannel.cc
  24. 7
      src/core/ext/filters/client_channel/subchannel.h
  25. 446
      src/core/lib/transport/static_metadata.cc
  26. 145
      src/core/lib/transport/static_metadata.h
  27. 38
      src/cpp/server/health/default_health_check_service.cc
  28. 4
      src/cpp/server/health/default_health_check_service.h
  29. 2
      src/python/grpcio/grpc_core_dependencies.py
  30. 1
      test/core/end2end/fuzzers/hpack.dictionary
  31. 157
      test/cpp/end2end/client_lb_end2end_test.cc
  32. 1
      tools/codegen/core/gen_static_metadata.py
  33. 4
      tools/distrib/check_copyright.py
  34. 1
      tools/distrib/check_include_guards.py
  35. 4
      tools/distrib/check_nanopb_output.sh
  36. 7
      tools/doxygen/Doxyfile.c++.internal
  37. 4
      tools/doxygen/Doxyfile.core.internal
  38. 27
      tools/run_tests/generated/sources_and_headers.json

@ -14,4 +14,5 @@
-Ithird_party/cares
-Ithird_party/googletest/googletest/include
-Ithird_party/googletest/googlemock/include
-Ithird_party/nanopb

21
BUILD

@ -131,7 +131,6 @@ GRPCXX_SRCS = [
"src/cpp/server/create_default_thread_pool.cc",
"src/cpp/server/dynamic_thread_pool.cc",
"src/cpp/server/health/default_health_check_service.cc",
"src/cpp/server/health/health.pb.c",
"src/cpp/server/health/health_check_service.cc",
"src/cpp/server/health/health_check_service_server_builder_option.cc",
"src/cpp/server/server_builder.cc",
@ -151,7 +150,6 @@ GRPCXX_HDRS = [
"src/cpp/common/channel_filter.h",
"src/cpp/server/dynamic_thread_pool.h",
"src/cpp/server/health/default_health_check_service.h",
"src/cpp/server/health/health.pb.h",
"src/cpp/server/thread_pool_interface.h",
"src/cpp/thread_manager/thread_manager.h",
]
@ -1040,6 +1038,7 @@ grpc_cc_library(
"src/core/ext/filters/client_channel/client_channel_factory.cc",
"src/core/ext/filters/client_channel/client_channel_plugin.cc",
"src/core/ext/filters/client_channel/connector.cc",
"src/core/ext/filters/client_channel/health/health_check_client.cc",
"src/core/ext/filters/client_channel/http_connect_handshaker.cc",
"src/core/ext/filters/client_channel/http_proxy.cc",
"src/core/ext/filters/client_channel/lb_policy.cc",
@ -1062,6 +1061,7 @@ grpc_cc_library(
"src/core/ext/filters/client_channel/client_channel_channelz.h",
"src/core/ext/filters/client_channel/client_channel_factory.h",
"src/core/ext/filters/client_channel/connector.h",
"src/core/ext/filters/client_channel/health/health_check_client.h",
"src/core/ext/filters/client_channel/http_connect_handshaker.h",
"src/core/ext/filters/client_channel/http_proxy.h",
"src/core/ext/filters/client_channel/lb_policy.h",
@ -1089,6 +1089,7 @@ grpc_cc_library(
"orphanable",
"ref_counted",
"ref_counted_ptr",
"health_proto",
],
)
@ -1200,6 +1201,20 @@ grpc_cc_library(
],
)
grpc_cc_library(
name = "health_proto",
srcs = [
"src/core/ext/filters/client_channel/health/health.pb.c",
],
hdrs = [
"src/core/ext/filters/client_channel/health/health.pb.h",
],
external_deps = [
"nanopb",
],
language = "c++",
)
grpc_cc_library(
name = "grpclb_proto",
srcs = [
@ -1987,6 +2002,7 @@ grpc_cc_library(
deps = [
"grpc",
"grpc++_codegen_base",
"health_proto",
],
)
@ -1999,6 +2015,7 @@ grpc_cc_library(
deps = [
"grpc++_codegen_base",
"grpc_unsecure",
"health_proto",
],
)

@ -1229,6 +1229,7 @@ add_library(grpc
src/core/ext/filters/client_channel/client_channel_factory.cc
src/core/ext/filters/client_channel/client_channel_plugin.cc
src/core/ext/filters/client_channel/connector.cc
src/core/ext/filters/client_channel/health/health_check_client.cc
src/core/ext/filters/client_channel/http_connect_handshaker.cc
src/core/ext/filters/client_channel/http_proxy.cc
src/core/ext/filters/client_channel/lb_policy.cc
@ -1245,6 +1246,7 @@ add_library(grpc
src/core/ext/filters/client_channel/subchannel_index.cc
src/core/ext/filters/client_channel/uri_parser.cc
src/core/ext/filters/deadline/deadline_filter.cc
src/core/ext/filters/client_channel/health/health.pb.c
src/core/tsi/alts_transport_security.cc
src/core/tsi/fake_transport_security.cc
src/core/tsi/local_transport_security.cc
@ -1579,6 +1581,7 @@ add_library(grpc_cronet
src/core/ext/filters/client_channel/client_channel_factory.cc
src/core/ext/filters/client_channel/client_channel_plugin.cc
src/core/ext/filters/client_channel/connector.cc
src/core/ext/filters/client_channel/health/health_check_client.cc
src/core/ext/filters/client_channel/http_connect_handshaker.cc
src/core/ext/filters/client_channel/http_proxy.cc
src/core/ext/filters/client_channel/lb_policy.cc
@ -1595,6 +1598,10 @@ add_library(grpc_cronet
src/core/ext/filters/client_channel/subchannel_index.cc
src/core/ext/filters/client_channel/uri_parser.cc
src/core/ext/filters/deadline/deadline_filter.cc
src/core/ext/filters/client_channel/health/health.pb.c
third_party/nanopb/pb_common.c
third_party/nanopb/pb_decode.c
third_party/nanopb/pb_encode.c
src/core/lib/http/httpcli_security_connector.cc
src/core/lib/security/context/security_context.cc
src/core/lib/security/credentials/alts/alts_credentials.cc
@ -1656,9 +1663,6 @@ add_library(grpc_cronet
src/core/tsi/alts/handshaker/altscontext.pb.c
src/core/tsi/alts/handshaker/handshaker.pb.c
src/core/tsi/alts/handshaker/transport_security_common.pb.c
third_party/nanopb/pb_common.c
third_party/nanopb/pb_decode.c
third_party/nanopb/pb_encode.c
src/core/tsi/transport_security.cc
src/core/ext/transport/chttp2/client/insecure/channel_create.cc
src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc
@ -1946,6 +1950,7 @@ add_library(grpc_test_util
src/core/ext/filters/client_channel/client_channel_factory.cc
src/core/ext/filters/client_channel/client_channel_plugin.cc
src/core/ext/filters/client_channel/connector.cc
src/core/ext/filters/client_channel/health/health_check_client.cc
src/core/ext/filters/client_channel/http_connect_handshaker.cc
src/core/ext/filters/client_channel/http_proxy.cc
src/core/ext/filters/client_channel/lb_policy.cc
@ -1962,6 +1967,10 @@ add_library(grpc_test_util
src/core/ext/filters/client_channel/subchannel_index.cc
src/core/ext/filters/client_channel/uri_parser.cc
src/core/ext/filters/deadline/deadline_filter.cc
src/core/ext/filters/client_channel/health/health.pb.c
third_party/nanopb/pb_common.c
third_party/nanopb/pb_decode.c
third_party/nanopb/pb_encode.c
src/core/ext/transport/chttp2/transport/bin_decoder.cc
src/core/ext/transport/chttp2/transport/bin_encoder.cc
src/core/ext/transport/chttp2/transport/chttp2_plugin.cc
@ -2260,6 +2269,7 @@ add_library(grpc_test_util_unsecure
src/core/ext/filters/client_channel/client_channel_factory.cc
src/core/ext/filters/client_channel/client_channel_plugin.cc
src/core/ext/filters/client_channel/connector.cc
src/core/ext/filters/client_channel/health/health_check_client.cc
src/core/ext/filters/client_channel/http_connect_handshaker.cc
src/core/ext/filters/client_channel/http_proxy.cc
src/core/ext/filters/client_channel/lb_policy.cc
@ -2276,6 +2286,10 @@ add_library(grpc_test_util_unsecure
src/core/ext/filters/client_channel/subchannel_index.cc
src/core/ext/filters/client_channel/uri_parser.cc
src/core/ext/filters/deadline/deadline_filter.cc
src/core/ext/filters/client_channel/health/health.pb.c
third_party/nanopb/pb_common.c
third_party/nanopb/pb_decode.c
third_party/nanopb/pb_encode.c
src/core/ext/transport/chttp2/transport/bin_decoder.cc
src/core/ext/transport/chttp2/transport/bin_encoder.cc
src/core/ext/transport/chttp2/transport/chttp2_plugin.cc
@ -2587,6 +2601,7 @@ add_library(grpc_unsecure
src/core/ext/filters/client_channel/client_channel_factory.cc
src/core/ext/filters/client_channel/client_channel_plugin.cc
src/core/ext/filters/client_channel/connector.cc
src/core/ext/filters/client_channel/health/health_check_client.cc
src/core/ext/filters/client_channel/http_connect_handshaker.cc
src/core/ext/filters/client_channel/http_proxy.cc
src/core/ext/filters/client_channel/lb_policy.cc
@ -2603,6 +2618,10 @@ add_library(grpc_unsecure
src/core/ext/filters/client_channel/subchannel_index.cc
src/core/ext/filters/client_channel/uri_parser.cc
src/core/ext/filters/deadline/deadline_filter.cc
src/core/ext/filters/client_channel/health/health.pb.c
third_party/nanopb/pb_common.c
third_party/nanopb/pb_decode.c
third_party/nanopb/pb_encode.c
src/core/ext/transport/inproc/inproc_plugin.cc
src/core/ext/transport/inproc/inproc_transport.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
@ -2621,9 +2640,6 @@ add_library(grpc_unsecure
src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc
src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc
src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc
third_party/nanopb/pb_common.c
third_party/nanopb/pb_decode.c
third_party/nanopb/pb_encode.c
src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c
src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c
src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c
@ -2857,7 +2873,6 @@ add_library(grpc++
src/cpp/server/create_default_thread_pool.cc
src/cpp/server/dynamic_thread_pool.cc
src/cpp/server/health/default_health_check_service.cc
src/cpp/server/health/health.pb.c
src/cpp/server/health/health_check_service.cc
src/cpp/server/health/health_check_service_server_builder_option.cc
src/cpp/server/server_builder.cc
@ -2870,6 +2885,10 @@ add_library(grpc++
src/cpp/util/status.cc
src/cpp/util/string_ref.cc
src/cpp/util/time_cc.cc
src/core/ext/filters/client_channel/health/health.pb.c
third_party/nanopb/pb_common.c
third_party/nanopb/pb_decode.c
third_party/nanopb/pb_encode.c
src/cpp/codegen/codegen_init.cc
)
@ -3218,7 +3237,6 @@ add_library(grpc++_cronet
src/cpp/server/create_default_thread_pool.cc
src/cpp/server/dynamic_thread_pool.cc
src/cpp/server/health/default_health_check_service.cc
src/cpp/server/health/health.pb.c
src/cpp/server/health/health_check_service.cc
src/cpp/server/health/health_check_service_server_builder_option.cc
src/cpp/server/server_builder.cc
@ -3231,6 +3249,10 @@ add_library(grpc++_cronet
src/cpp/util/status.cc
src/cpp/util/string_ref.cc
src/cpp/util/time_cc.cc
src/core/ext/filters/client_channel/health/health.pb.c
third_party/nanopb/pb_common.c
third_party/nanopb/pb_decode.c
third_party/nanopb/pb_encode.c
src/cpp/codegen/codegen_init.cc
src/core/ext/transport/chttp2/client/insecure/channel_create.cc
src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc
@ -3421,6 +3443,7 @@ add_library(grpc++_cronet
src/core/ext/filters/client_channel/client_channel_factory.cc
src/core/ext/filters/client_channel/client_channel_plugin.cc
src/core/ext/filters/client_channel/connector.cc
src/core/ext/filters/client_channel/health/health_check_client.cc
src/core/ext/filters/client_channel/http_connect_handshaker.cc
src/core/ext/filters/client_channel/http_proxy.cc
src/core/ext/filters/client_channel/lb_policy.cc
@ -4341,7 +4364,6 @@ add_library(grpc++_unsecure
src/cpp/server/create_default_thread_pool.cc
src/cpp/server/dynamic_thread_pool.cc
src/cpp/server/health/default_health_check_service.cc
src/cpp/server/health/health.pb.c
src/cpp/server/health/health_check_service.cc
src/cpp/server/health/health_check_service_server_builder_option.cc
src/cpp/server/server_builder.cc
@ -4354,6 +4376,10 @@ add_library(grpc++_unsecure
src/cpp/util/status.cc
src/cpp/util/string_ref.cc
src/cpp/util/time_cc.cc
src/core/ext/filters/client_channel/health/health.pb.c
third_party/nanopb/pb_common.c
third_party/nanopb/pb_decode.c
third_party/nanopb/pb_encode.c
src/cpp/codegen/codegen_init.cc
)

@ -3697,6 +3697,7 @@ LIBGRPC_SRC = \
src/core/ext/filters/client_channel/client_channel_factory.cc \
src/core/ext/filters/client_channel/client_channel_plugin.cc \
src/core/ext/filters/client_channel/connector.cc \
src/core/ext/filters/client_channel/health/health_check_client.cc \
src/core/ext/filters/client_channel/http_connect_handshaker.cc \
src/core/ext/filters/client_channel/http_proxy.cc \
src/core/ext/filters/client_channel/lb_policy.cc \
@ -3713,6 +3714,7 @@ LIBGRPC_SRC = \
src/core/ext/filters/client_channel/subchannel_index.cc \
src/core/ext/filters/client_channel/uri_parser.cc \
src/core/ext/filters/deadline/deadline_filter.cc \
src/core/ext/filters/client_channel/health/health.pb.c \
src/core/tsi/alts_transport_security.cc \
src/core/tsi/fake_transport_security.cc \
src/core/tsi/local_transport_security.cc \
@ -4041,6 +4043,7 @@ LIBGRPC_CRONET_SRC = \
src/core/ext/filters/client_channel/client_channel_factory.cc \
src/core/ext/filters/client_channel/client_channel_plugin.cc \
src/core/ext/filters/client_channel/connector.cc \
src/core/ext/filters/client_channel/health/health_check_client.cc \
src/core/ext/filters/client_channel/http_connect_handshaker.cc \
src/core/ext/filters/client_channel/http_proxy.cc \
src/core/ext/filters/client_channel/lb_policy.cc \
@ -4057,6 +4060,10 @@ LIBGRPC_CRONET_SRC = \
src/core/ext/filters/client_channel/subchannel_index.cc \
src/core/ext/filters/client_channel/uri_parser.cc \
src/core/ext/filters/deadline/deadline_filter.cc \
src/core/ext/filters/client_channel/health/health.pb.c \
third_party/nanopb/pb_common.c \
third_party/nanopb/pb_decode.c \
third_party/nanopb/pb_encode.c \
src/core/lib/http/httpcli_security_connector.cc \
src/core/lib/security/context/security_context.cc \
src/core/lib/security/credentials/alts/alts_credentials.cc \
@ -4118,9 +4125,6 @@ LIBGRPC_CRONET_SRC = \
src/core/tsi/alts/handshaker/altscontext.pb.c \
src/core/tsi/alts/handshaker/handshaker.pb.c \
src/core/tsi/alts/handshaker/transport_security_common.pb.c \
third_party/nanopb/pb_common.c \
third_party/nanopb/pb_decode.c \
third_party/nanopb/pb_encode.c \
src/core/tsi/transport_security.cc \
src/core/ext/transport/chttp2/client/insecure/channel_create.cc \
src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc \
@ -4401,6 +4405,7 @@ LIBGRPC_TEST_UTIL_SRC = \
src/core/ext/filters/client_channel/client_channel_factory.cc \
src/core/ext/filters/client_channel/client_channel_plugin.cc \
src/core/ext/filters/client_channel/connector.cc \
src/core/ext/filters/client_channel/health/health_check_client.cc \
src/core/ext/filters/client_channel/http_connect_handshaker.cc \
src/core/ext/filters/client_channel/http_proxy.cc \
src/core/ext/filters/client_channel/lb_policy.cc \
@ -4417,6 +4422,10 @@ LIBGRPC_TEST_UTIL_SRC = \
src/core/ext/filters/client_channel/subchannel_index.cc \
src/core/ext/filters/client_channel/uri_parser.cc \
src/core/ext/filters/deadline/deadline_filter.cc \
src/core/ext/filters/client_channel/health/health.pb.c \
third_party/nanopb/pb_common.c \
third_party/nanopb/pb_decode.c \
third_party/nanopb/pb_encode.c \
src/core/ext/transport/chttp2/transport/bin_decoder.cc \
src/core/ext/transport/chttp2/transport/bin_encoder.cc \
src/core/ext/transport/chttp2/transport/chttp2_plugin.cc \
@ -4701,6 +4710,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \
src/core/ext/filters/client_channel/client_channel_factory.cc \
src/core/ext/filters/client_channel/client_channel_plugin.cc \
src/core/ext/filters/client_channel/connector.cc \
src/core/ext/filters/client_channel/health/health_check_client.cc \
src/core/ext/filters/client_channel/http_connect_handshaker.cc \
src/core/ext/filters/client_channel/http_proxy.cc \
src/core/ext/filters/client_channel/lb_policy.cc \
@ -4717,6 +4727,10 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \
src/core/ext/filters/client_channel/subchannel_index.cc \
src/core/ext/filters/client_channel/uri_parser.cc \
src/core/ext/filters/deadline/deadline_filter.cc \
src/core/ext/filters/client_channel/health/health.pb.c \
third_party/nanopb/pb_common.c \
third_party/nanopb/pb_decode.c \
third_party/nanopb/pb_encode.c \
src/core/ext/transport/chttp2/transport/bin_decoder.cc \
src/core/ext/transport/chttp2/transport/bin_encoder.cc \
src/core/ext/transport/chttp2/transport/chttp2_plugin.cc \
@ -5001,6 +5015,7 @@ LIBGRPC_UNSECURE_SRC = \
src/core/ext/filters/client_channel/client_channel_factory.cc \
src/core/ext/filters/client_channel/client_channel_plugin.cc \
src/core/ext/filters/client_channel/connector.cc \
src/core/ext/filters/client_channel/health/health_check_client.cc \
src/core/ext/filters/client_channel/http_connect_handshaker.cc \
src/core/ext/filters/client_channel/http_proxy.cc \
src/core/ext/filters/client_channel/lb_policy.cc \
@ -5017,6 +5032,10 @@ LIBGRPC_UNSECURE_SRC = \
src/core/ext/filters/client_channel/subchannel_index.cc \
src/core/ext/filters/client_channel/uri_parser.cc \
src/core/ext/filters/deadline/deadline_filter.cc \
src/core/ext/filters/client_channel/health/health.pb.c \
third_party/nanopb/pb_common.c \
third_party/nanopb/pb_decode.c \
third_party/nanopb/pb_encode.c \
src/core/ext/transport/inproc/inproc_plugin.cc \
src/core/ext/transport/inproc/inproc_transport.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc \
@ -5035,9 +5054,6 @@ LIBGRPC_UNSECURE_SRC = \
src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc \
src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc \
src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc \
third_party/nanopb/pb_common.c \
third_party/nanopb/pb_decode.c \
third_party/nanopb/pb_encode.c \
src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c \
src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c \
src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \
@ -5236,7 +5252,6 @@ LIBGRPC++_SRC = \
src/cpp/server/create_default_thread_pool.cc \
src/cpp/server/dynamic_thread_pool.cc \
src/cpp/server/health/default_health_check_service.cc \
src/cpp/server/health/health.pb.c \
src/cpp/server/health/health_check_service.cc \
src/cpp/server/health/health_check_service_server_builder_option.cc \
src/cpp/server/server_builder.cc \
@ -5249,6 +5264,10 @@ LIBGRPC++_SRC = \
src/cpp/util/status.cc \
src/cpp/util/string_ref.cc \
src/cpp/util/time_cc.cc \
src/core/ext/filters/client_channel/health/health.pb.c \
third_party/nanopb/pb_common.c \
third_party/nanopb/pb_decode.c \
third_party/nanopb/pb_encode.c \
src/cpp/codegen/codegen_init.cc \
PUBLIC_HEADERS_CXX += \
@ -5607,7 +5626,6 @@ LIBGRPC++_CRONET_SRC = \
src/cpp/server/create_default_thread_pool.cc \
src/cpp/server/dynamic_thread_pool.cc \
src/cpp/server/health/default_health_check_service.cc \
src/cpp/server/health/health.pb.c \
src/cpp/server/health/health_check_service.cc \
src/cpp/server/health/health_check_service_server_builder_option.cc \
src/cpp/server/server_builder.cc \
@ -5620,6 +5638,10 @@ LIBGRPC++_CRONET_SRC = \
src/cpp/util/status.cc \
src/cpp/util/string_ref.cc \
src/cpp/util/time_cc.cc \
src/core/ext/filters/client_channel/health/health.pb.c \
third_party/nanopb/pb_common.c \
third_party/nanopb/pb_decode.c \
third_party/nanopb/pb_encode.c \
src/cpp/codegen/codegen_init.cc \
src/core/ext/transport/chttp2/client/insecure/channel_create.cc \
src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc \
@ -5810,6 +5832,7 @@ LIBGRPC++_CRONET_SRC = \
src/core/ext/filters/client_channel/client_channel_factory.cc \
src/core/ext/filters/client_channel/client_channel_plugin.cc \
src/core/ext/filters/client_channel/connector.cc \
src/core/ext/filters/client_channel/health/health_check_client.cc \
src/core/ext/filters/client_channel/http_connect_handshaker.cc \
src/core/ext/filters/client_channel/http_proxy.cc \
src/core/ext/filters/client_channel/lb_policy.cc \
@ -6695,7 +6718,6 @@ LIBGRPC++_UNSECURE_SRC = \
src/cpp/server/create_default_thread_pool.cc \
src/cpp/server/dynamic_thread_pool.cc \
src/cpp/server/health/default_health_check_service.cc \
src/cpp/server/health/health.pb.c \
src/cpp/server/health/health_check_service.cc \
src/cpp/server/health/health_check_service_server_builder_option.cc \
src/cpp/server/server_builder.cc \
@ -6708,6 +6730,10 @@ LIBGRPC++_UNSECURE_SRC = \
src/cpp/util/status.cc \
src/cpp/util/string_ref.cc \
src/cpp/util/time_cc.cc \
src/core/ext/filters/client_channel/health/health.pb.c \
third_party/nanopb/pb_common.c \
third_party/nanopb/pb_decode.c \
third_party/nanopb/pb_encode.c \
src/cpp/codegen/codegen_init.cc \
PUBLIC_HEADERS_CXX += \

@ -572,6 +572,7 @@ filegroups:
- src/core/ext/filters/client_channel/client_channel_channelz.h
- src/core/ext/filters/client_channel/client_channel_factory.h
- src/core/ext/filters/client_channel/connector.h
- src/core/ext/filters/client_channel/health/health_check_client.h
- src/core/ext/filters/client_channel/http_connect_handshaker.h
- src/core/ext/filters/client_channel/http_proxy.h
- src/core/ext/filters/client_channel/lb_policy.h
@ -596,6 +597,7 @@ filegroups:
- src/core/ext/filters/client_channel/client_channel_factory.cc
- src/core/ext/filters/client_channel/client_channel_plugin.cc
- src/core/ext/filters/client_channel/connector.cc
- src/core/ext/filters/client_channel/health/health_check_client.cc
- src/core/ext/filters/client_channel/http_connect_handshaker.cc
- src/core/ext/filters/client_channel/http_proxy.cc
- src/core/ext/filters/client_channel/lb_policy.cc
@ -615,6 +617,7 @@ filegroups:
uses:
- grpc_base
- grpc_deadline_filter
- health_proto
- name: grpc_codegen
public_headers:
- include/grpc/impl/codegen/byte_buffer.h
@ -1107,6 +1110,13 @@ filegroups:
- src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c
uses:
- nanopb
- name: health_proto
headers:
- src/core/ext/filters/client_channel/health/health.pb.h
src:
- src/core/ext/filters/client_channel/health/health.pb.c
uses:
- nanopb
- name: nanopb
src:
- third_party/nanopb/pb_common.c
@ -1354,7 +1364,6 @@ filegroups:
- src/cpp/common/channel_filter.h
- src/cpp/server/dynamic_thread_pool.h
- src/cpp/server/health/default_health_check_service.h
- src/cpp/server/health/health.pb.h
- src/cpp/server/thread_pool_interface.h
- src/cpp/thread_manager/thread_manager.h
src:
@ -1378,7 +1387,6 @@ filegroups:
- src/cpp/server/create_default_thread_pool.cc
- src/cpp/server/dynamic_thread_pool.cc
- src/cpp/server/health/default_health_check_service.cc
- src/cpp/server/health/health.pb.c
- src/cpp/server/health/health_check_service.cc
- src/cpp/server/health/health_check_service_server_builder_option.cc
- src/cpp/server/server_builder.cc
@ -1397,6 +1405,7 @@ filegroups:
- grpc_transport_inproc_headers
- grpc++_codegen_base
- nanopb_headers
- health_proto
- name: grpc++_config_proto
language: c++
public_headers:

@ -339,6 +339,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/filters/client_channel/client_channel_factory.cc \
src/core/ext/filters/client_channel/client_channel_plugin.cc \
src/core/ext/filters/client_channel/connector.cc \
src/core/ext/filters/client_channel/health/health_check_client.cc \
src/core/ext/filters/client_channel/http_connect_handshaker.cc \
src/core/ext/filters/client_channel/http_proxy.cc \
src/core/ext/filters/client_channel/lb_policy.cc \
@ -355,6 +356,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/filters/client_channel/subchannel_index.cc \
src/core/ext/filters/client_channel/uri_parser.cc \
src/core/ext/filters/deadline/deadline_filter.cc \
src/core/ext/filters/client_channel/health/health.pb.c \
src/core/tsi/alts_transport_security.cc \
src/core/tsi/fake_transport_security.cc \
src/core/tsi/local_transport_security.cc \
@ -667,6 +669,7 @@ if test "$PHP_GRPC" != "no"; then
PHP_ADD_BUILD_DIR($ext_builddir/src/boringssl)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/census)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/health)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/grpclb)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf)

@ -314,6 +314,7 @@ if (PHP_GRPC != "no") {
"src\\core\\ext\\filters\\client_channel\\client_channel_factory.cc " +
"src\\core\\ext\\filters\\client_channel\\client_channel_plugin.cc " +
"src\\core\\ext\\filters\\client_channel\\connector.cc " +
"src\\core\\ext\\filters\\client_channel\\health\\health_check_client.cc " +
"src\\core\\ext\\filters\\client_channel\\http_connect_handshaker.cc " +
"src\\core\\ext\\filters\\client_channel\\http_proxy.cc " +
"src\\core\\ext\\filters\\client_channel\\lb_policy.cc " +
@ -330,6 +331,7 @@ if (PHP_GRPC != "no") {
"src\\core\\ext\\filters\\client_channel\\subchannel_index.cc " +
"src\\core\\ext\\filters\\client_channel\\uri_parser.cc " +
"src\\core\\ext\\filters\\deadline\\deadline_filter.cc " +
"src\\core\\ext\\filters\\client_channel\\health\\health.pb.c " +
"src\\core\\tsi\\alts_transport_security.cc " +
"src\\core\\tsi\\fake_transport_security.cc " +
"src\\core\\tsi\\local_transport_security.cc " +
@ -672,6 +674,7 @@ if (PHP_GRPC != "no") {
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\census");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\health");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\proto");

@ -52,6 +52,7 @@ some configuration as environment variables that can be set.
traces epoll-fd creation/close calls for epollex polling engine
- glb - traces the grpclb load balancer
- handshaker - traces handshaking state
- health_check_client - traces health checking client code
- http - traces state in the http2 transport engine
- http2_stream_state - traces all http2 stream state mutations.
- http1 - traces HTTP/1.x operations performed by gRPC

@ -173,7 +173,6 @@ Pod::Spec.new do |s|
'src/cpp/common/channel_filter.h',
'src/cpp/server/dynamic_thread_pool.h',
'src/cpp/server/health/default_health_check_service.h',
'src/cpp/server/health/health.pb.h',
'src/cpp/server/thread_pool_interface.h',
'src/cpp/thread_manager/thread_manager.h',
'src/cpp/client/insecure_credentials.cc',
@ -204,7 +203,6 @@ Pod::Spec.new do |s|
'src/cpp/server/create_default_thread_pool.cc',
'src/cpp/server/dynamic_thread_pool.cc',
'src/cpp/server/health/default_health_check_service.cc',
'src/cpp/server/health/health.pb.c',
'src/cpp/server/health/health_check_service.cc',
'src/cpp/server/health/health_check_service_server_builder_option.cc',
'src/cpp/server/server_builder.cc',
@ -329,6 +327,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/client_channel_channelz.h',
'src/core/ext/filters/client_channel/client_channel_factory.h',
'src/core/ext/filters/client_channel/connector.h',
'src/core/ext/filters/client_channel/health/health_check_client.h',
'src/core/ext/filters/client_channel/http_connect_handshaker.h',
'src/core/ext/filters/client_channel/http_proxy.h',
'src/core/ext/filters/client_channel/lb_policy.h',
@ -346,6 +345,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/subchannel_index.h',
'src/core/ext/filters/client_channel/uri_parser.h',
'src/core/ext/filters/deadline/deadline_filter.h',
'src/core/ext/filters/client_channel/health/health.pb.h',
'src/core/tsi/alts_transport_security.h',
'src/core/tsi/fake_transport_security.h',
'src/core/tsi/local_transport_security.h',
@ -520,7 +520,6 @@ Pod::Spec.new do |s|
'src/cpp/common/channel_filter.h',
'src/cpp/server/dynamic_thread_pool.h',
'src/cpp/server/health/default_health_check_service.h',
'src/cpp/server/health/health.pb.h',
'src/cpp/server/thread_pool_interface.h',
'src/cpp/thread_manager/thread_manager.h',
'src/core/lib/gpr/alloc.h',
@ -684,7 +683,8 @@ Pod::Spec.new do |s|
'src/core/lib/transport/transport.h',
'src/core/lib/transport/transport_impl.h',
'src/core/lib/debug/trace.h',
'src/core/ext/transport/inproc/inproc_transport.h'
'src/core/ext/transport/inproc/inproc_transport.h',
'src/core/ext/filters/client_channel/health/health.pb.h'
end
s.subspec 'Protobuf' do |ss|

@ -336,6 +336,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/client_channel_channelz.h',
'src/core/ext/filters/client_channel/client_channel_factory.h',
'src/core/ext/filters/client_channel/connector.h',
'src/core/ext/filters/client_channel/health/health_check_client.h',
'src/core/ext/filters/client_channel/http_connect_handshaker.h',
'src/core/ext/filters/client_channel/http_proxy.h',
'src/core/ext/filters/client_channel/lb_policy.h',
@ -353,6 +354,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/subchannel_index.h',
'src/core/ext/filters/client_channel/uri_parser.h',
'src/core/ext/filters/deadline/deadline_filter.h',
'src/core/ext/filters/client_channel/health/health.pb.h',
'src/core/tsi/alts_transport_security.h',
'src/core/tsi/fake_transport_security.h',
'src/core/tsi/local_transport_security.h',
@ -771,6 +773,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/client_channel_factory.cc',
'src/core/ext/filters/client_channel/client_channel_plugin.cc',
'src/core/ext/filters/client_channel/connector.cc',
'src/core/ext/filters/client_channel/health/health_check_client.cc',
'src/core/ext/filters/client_channel/http_connect_handshaker.cc',
'src/core/ext/filters/client_channel/http_proxy.cc',
'src/core/ext/filters/client_channel/lb_policy.cc',
@ -787,6 +790,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/subchannel_index.cc',
'src/core/ext/filters/client_channel/uri_parser.cc',
'src/core/ext/filters/deadline/deadline_filter.cc',
'src/core/ext/filters/client_channel/health/health.pb.c',
'src/core/tsi/alts_transport_security.cc',
'src/core/tsi/fake_transport_security.cc',
'src/core/tsi/local_transport_security.cc',
@ -945,6 +949,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/client_channel_channelz.h',
'src/core/ext/filters/client_channel/client_channel_factory.h',
'src/core/ext/filters/client_channel/connector.h',
'src/core/ext/filters/client_channel/health/health_check_client.h',
'src/core/ext/filters/client_channel/http_connect_handshaker.h',
'src/core/ext/filters/client_channel/http_proxy.h',
'src/core/ext/filters/client_channel/lb_policy.h',
@ -962,6 +967,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/subchannel_index.h',
'src/core/ext/filters/client_channel/uri_parser.h',
'src/core/ext/filters/deadline/deadline_filter.h',
'src/core/ext/filters/client_channel/health/health.pb.h',
'src/core/tsi/alts_transport_security.h',
'src/core/tsi/fake_transport_security.h',
'src/core/tsi/local_transport_security.h',
@ -1207,6 +1213,9 @@ Pod::Spec.new do |s|
'test/core/util/tracer_util.cc',
'test/core/util/trickle_endpoint.cc',
'test/core/util/cmdline.cc',
'third_party/nanopb/pb_common.c',
'third_party/nanopb/pb_decode.c',
'third_party/nanopb/pb_encode.c',
'test/core/end2end/data/ssl_test_data.h',
'test/core/security/oauth2_utils.h',
'test/core/end2end/cq_verifier.h',
@ -1228,6 +1237,10 @@ Pod::Spec.new do |s|
'test/core/util/tracer_util.h',
'test/core/util/trickle_endpoint.h',
'test/core/util/cmdline.h',
'third_party/nanopb/pb.h',
'third_party/nanopb/pb_common.h',
'third_party/nanopb/pb_decode.h',
'third_party/nanopb/pb_encode.h',
'test/core/end2end/end2end_tests.cc',
'test/core/end2end/end2end_test_utils.cc',
'test/core/end2end/tests/authority_not_supported.cc',

@ -272,6 +272,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/filters/client_channel/client_channel_channelz.h )
s.files += %w( src/core/ext/filters/client_channel/client_channel_factory.h )
s.files += %w( src/core/ext/filters/client_channel/connector.h )
s.files += %w( src/core/ext/filters/client_channel/health/health_check_client.h )
s.files += %w( src/core/ext/filters/client_channel/http_connect_handshaker.h )
s.files += %w( src/core/ext/filters/client_channel/http_proxy.h )
s.files += %w( src/core/ext/filters/client_channel/lb_policy.h )
@ -289,6 +290,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/filters/client_channel/subchannel_index.h )
s.files += %w( src/core/ext/filters/client_channel/uri_parser.h )
s.files += %w( src/core/ext/filters/deadline/deadline_filter.h )
s.files += %w( src/core/ext/filters/client_channel/health/health.pb.h )
s.files += %w( src/core/tsi/alts_transport_security.h )
s.files += %w( src/core/tsi/fake_transport_security.h )
s.files += %w( src/core/tsi/local_transport_security.h )
@ -710,6 +712,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/filters/client_channel/client_channel_factory.cc )
s.files += %w( src/core/ext/filters/client_channel/client_channel_plugin.cc )
s.files += %w( src/core/ext/filters/client_channel/connector.cc )
s.files += %w( src/core/ext/filters/client_channel/health/health_check_client.cc )
s.files += %w( src/core/ext/filters/client_channel/http_connect_handshaker.cc )
s.files += %w( src/core/ext/filters/client_channel/http_proxy.cc )
s.files += %w( src/core/ext/filters/client_channel/lb_policy.cc )
@ -726,6 +729,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/filters/client_channel/subchannel_index.cc )
s.files += %w( src/core/ext/filters/client_channel/uri_parser.cc )
s.files += %w( src/core/ext/filters/deadline/deadline_filter.cc )
s.files += %w( src/core/ext/filters/client_channel/health/health.pb.c )
s.files += %w( src/core/tsi/alts_transport_security.cc )
s.files += %w( src/core/tsi/fake_transport_security.cc )
s.files += %w( src/core/tsi/local_transport_security.cc )

@ -531,6 +531,7 @@
'src/core/ext/filters/client_channel/client_channel_factory.cc',
'src/core/ext/filters/client_channel/client_channel_plugin.cc',
'src/core/ext/filters/client_channel/connector.cc',
'src/core/ext/filters/client_channel/health/health_check_client.cc',
'src/core/ext/filters/client_channel/http_connect_handshaker.cc',
'src/core/ext/filters/client_channel/http_proxy.cc',
'src/core/ext/filters/client_channel/lb_policy.cc',
@ -547,6 +548,7 @@
'src/core/ext/filters/client_channel/subchannel_index.cc',
'src/core/ext/filters/client_channel/uri_parser.cc',
'src/core/ext/filters/deadline/deadline_filter.cc',
'src/core/ext/filters/client_channel/health/health.pb.c',
'src/core/tsi/alts_transport_security.cc',
'src/core/tsi/fake_transport_security.cc',
'src/core/tsi/local_transport_security.cc',
@ -789,6 +791,7 @@
'src/core/ext/filters/client_channel/client_channel_factory.cc',
'src/core/ext/filters/client_channel/client_channel_plugin.cc',
'src/core/ext/filters/client_channel/connector.cc',
'src/core/ext/filters/client_channel/health/health_check_client.cc',
'src/core/ext/filters/client_channel/http_connect_handshaker.cc',
'src/core/ext/filters/client_channel/http_proxy.cc',
'src/core/ext/filters/client_channel/lb_policy.cc',
@ -805,6 +808,10 @@
'src/core/ext/filters/client_channel/subchannel_index.cc',
'src/core/ext/filters/client_channel/uri_parser.cc',
'src/core/ext/filters/deadline/deadline_filter.cc',
'src/core/ext/filters/client_channel/health/health.pb.c',
'third_party/nanopb/pb_common.c',
'third_party/nanopb/pb_decode.c',
'third_party/nanopb/pb_encode.c',
'src/core/ext/transport/chttp2/transport/bin_decoder.cc',
'src/core/ext/transport/chttp2/transport/bin_encoder.cc',
'src/core/ext/transport/chttp2/transport/chttp2_plugin.cc',
@ -1023,6 +1030,7 @@
'src/core/ext/filters/client_channel/client_channel_factory.cc',
'src/core/ext/filters/client_channel/client_channel_plugin.cc',
'src/core/ext/filters/client_channel/connector.cc',
'src/core/ext/filters/client_channel/health/health_check_client.cc',
'src/core/ext/filters/client_channel/http_connect_handshaker.cc',
'src/core/ext/filters/client_channel/http_proxy.cc',
'src/core/ext/filters/client_channel/lb_policy.cc',
@ -1039,6 +1047,10 @@
'src/core/ext/filters/client_channel/subchannel_index.cc',
'src/core/ext/filters/client_channel/uri_parser.cc',
'src/core/ext/filters/deadline/deadline_filter.cc',
'src/core/ext/filters/client_channel/health/health.pb.c',
'third_party/nanopb/pb_common.c',
'third_party/nanopb/pb_decode.c',
'third_party/nanopb/pb_encode.c',
'src/core/ext/transport/chttp2/transport/bin_decoder.cc',
'src/core/ext/transport/chttp2/transport/bin_encoder.cc',
'src/core/ext/transport/chttp2/transport/chttp2_plugin.cc',
@ -1269,6 +1281,7 @@
'src/core/ext/filters/client_channel/client_channel_factory.cc',
'src/core/ext/filters/client_channel/client_channel_plugin.cc',
'src/core/ext/filters/client_channel/connector.cc',
'src/core/ext/filters/client_channel/health/health_check_client.cc',
'src/core/ext/filters/client_channel/http_connect_handshaker.cc',
'src/core/ext/filters/client_channel/http_proxy.cc',
'src/core/ext/filters/client_channel/lb_policy.cc',
@ -1285,6 +1298,10 @@
'src/core/ext/filters/client_channel/subchannel_index.cc',
'src/core/ext/filters/client_channel/uri_parser.cc',
'src/core/ext/filters/deadline/deadline_filter.cc',
'src/core/ext/filters/client_channel/health/health.pb.c',
'third_party/nanopb/pb_common.c',
'third_party/nanopb/pb_decode.c',
'third_party/nanopb/pb_encode.c',
'src/core/ext/transport/inproc/inproc_plugin.cc',
'src/core/ext/transport/inproc/inproc_transport.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc',
@ -1303,9 +1320,6 @@
'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc',
'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc',
'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc',
'third_party/nanopb/pb_common.c',
'third_party/nanopb/pb_decode.c',
'third_party/nanopb/pb_encode.c',
'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c',
'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c',
'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c',
@ -1387,7 +1401,6 @@
'src/cpp/server/create_default_thread_pool.cc',
'src/cpp/server/dynamic_thread_pool.cc',
'src/cpp/server/health/default_health_check_service.cc',
'src/cpp/server/health/health.pb.c',
'src/cpp/server/health/health_check_service.cc',
'src/cpp/server/health/health_check_service_server_builder_option.cc',
'src/cpp/server/server_builder.cc',
@ -1400,6 +1413,10 @@
'src/cpp/util/status.cc',
'src/cpp/util/string_ref.cc',
'src/cpp/util/time_cc.cc',
'src/core/ext/filters/client_channel/health/health.pb.c',
'third_party/nanopb/pb_common.c',
'third_party/nanopb/pb_decode.c',
'third_party/nanopb/pb_encode.c',
'src/cpp/codegen/codegen_init.cc',
],
},
@ -1534,7 +1551,6 @@
'src/cpp/server/create_default_thread_pool.cc',
'src/cpp/server/dynamic_thread_pool.cc',
'src/cpp/server/health/default_health_check_service.cc',
'src/cpp/server/health/health.pb.c',
'src/cpp/server/health/health_check_service.cc',
'src/cpp/server/health/health_check_service_server_builder_option.cc',
'src/cpp/server/server_builder.cc',
@ -1547,6 +1563,10 @@
'src/cpp/util/status.cc',
'src/cpp/util/string_ref.cc',
'src/cpp/util/time_cc.cc',
'src/core/ext/filters/client_channel/health/health.pb.c',
'third_party/nanopb/pb_common.c',
'third_party/nanopb/pb_decode.c',
'third_party/nanopb/pb_encode.c',
'src/cpp/codegen/codegen_init.cc',
],
},

@ -347,6 +347,9 @@ typedef struct {
/** If set to non zero, surfaces the user agent string to the server. User
agent is surfaced by default. */
#define GRPC_ARG_SURFACE_USER_AGENT "grpc.surface_user_agent"
/** If set, inhibits health checking (which may be enabled via the
* service config.) */
#define GRPC_ARG_INHIBIT_HEALTH_CHECKING "grpc.inhibit_health_checking"
/** \} */
/** Result of a grpc call. If the caller satisfies the prerequisites of a

@ -277,6 +277,7 @@
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/client_channel_channelz.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/client_channel_factory.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/connector.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/health/health_check_client.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/http_connect_handshaker.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/http_proxy.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy.h" role="src" />
@ -294,6 +295,7 @@
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/subchannel_index.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/uri_parser.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/deadline/deadline_filter.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/health/health.pb.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts_transport_security.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/fake_transport_security.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/local_transport_security.h" role="src" />
@ -715,6 +717,7 @@
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/client_channel_factory.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/client_channel_plugin.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/connector.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/health/health_check_client.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/http_connect_handshaker.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/http_proxy.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy.cc" role="src" />
@ -731,6 +734,7 @@
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/subchannel_index.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/uri_parser.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/deadline/deadline_filter.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/health/health.pb.c" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts_transport_security.cc" role="src" />
<file baseinstalldir="/" name="src/core/tsi/fake_transport_security.cc" role="src" />
<file baseinstalldir="/" name="src/core/tsi/local_transport_security.cc" role="src" />

@ -128,7 +128,8 @@ void SubchannelNode::PopulateConnectivityState(grpc_json* json) {
if (subchannel_ == nullptr) {
state = GRPC_CHANNEL_SHUTDOWN;
} else {
state = grpc_subchannel_check_connectivity(subchannel_, nullptr);
state = grpc_subchannel_check_connectivity(
subchannel_, nullptr, true /* inhibit_health_checking */);
}
json = grpc_json_create_child(nullptr, json, "state", nullptr,
GRPC_JSON_OBJECT, false);

@ -1,7 +1,7 @@
/* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.3.7-dev */
#include "src/cpp/server/health/health.pb.h"
#include "src/core/ext/filters/client_channel/health/health.pb.h"
/* @@protoc_insertion_point(includes) */
#if PB_PROTO_HEADER_VERSION != 30
#error Regenerate this file with the current version of nanopb generator.

@ -0,0 +1,646 @@
/*
*
* Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <grpc/support/port_platform.h>
#include <stdint.h>
#include "src/core/ext/filters/client_channel/health/health_check_client.h"
#include "pb_decode.h"
#include "pb_encode.h"
#include "src/core/ext/filters/client_channel/health/health.pb.h"
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/gprpp/mutex_lock.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/transport/error_utils.h"
#include "src/core/lib/transport/status_metadata.h"
#define HEALTH_CHECK_INITIAL_CONNECT_BACKOFF_SECONDS 1
#define HEALTH_CHECK_RECONNECT_BACKOFF_MULTIPLIER 1.6
#define HEALTH_CHECK_RECONNECT_MAX_BACKOFF_SECONDS 120
#define HEALTH_CHECK_RECONNECT_JITTER 0.2
grpc_core::TraceFlag grpc_health_check_client_trace(false,
"health_check_client");
namespace grpc_core {
//
// HealthCheckClient
//
HealthCheckClient::HealthCheckClient(
const char* service_name,
RefCountedPtr<ConnectedSubchannel> connected_subchannel,
grpc_pollset_set* interested_parties,
grpc_core::RefCountedPtr<grpc_core::channelz::SubchannelNode> channelz_node)
: InternallyRefCountedWithTracing<HealthCheckClient>(
&grpc_health_check_client_trace),
service_name_(service_name),
connected_subchannel_(std::move(connected_subchannel)),
interested_parties_(interested_parties),
channelz_node_(std::move(channelz_node)),
retry_backoff_(
BackOff::Options()
.set_initial_backoff(
HEALTH_CHECK_INITIAL_CONNECT_BACKOFF_SECONDS * 1000)
.set_multiplier(HEALTH_CHECK_RECONNECT_BACKOFF_MULTIPLIER)
.set_jitter(HEALTH_CHECK_RECONNECT_JITTER)
.set_max_backoff(HEALTH_CHECK_RECONNECT_MAX_BACKOFF_SECONDS *
1000)) {
if (grpc_health_check_client_trace.enabled()) {
gpr_log(GPR_INFO, "created HealthCheckClient %p", this);
}
GRPC_CLOSURE_INIT(&retry_timer_callback_, OnRetryTimer, this,
grpc_schedule_on_exec_ctx);
gpr_mu_init(&mu_);
StartCall();
}
HealthCheckClient::~HealthCheckClient() {
if (grpc_health_check_client_trace.enabled()) {
gpr_log(GPR_INFO, "destroying HealthCheckClient %p", this);
}
GRPC_ERROR_UNREF(error_);
gpr_mu_destroy(&mu_);
}
void HealthCheckClient::NotifyOnHealthChange(grpc_connectivity_state* state,
grpc_closure* closure) {
MutexLock lock(&mu_);
GPR_ASSERT(notify_state_ == nullptr);
if (*state != state_) {
*state = state_;
GRPC_CLOSURE_SCHED(closure, GRPC_ERROR_REF(error_));
return;
}
notify_state_ = state;
on_health_changed_ = closure;
}
void HealthCheckClient::SetHealthStatus(grpc_connectivity_state state,
grpc_error* error) {
MutexLock lock(&mu_);
SetHealthStatusLocked(state, error);
}
void HealthCheckClient::SetHealthStatusLocked(grpc_connectivity_state state,
grpc_error* error) {
if (grpc_health_check_client_trace.enabled()) {
gpr_log(GPR_INFO, "HealthCheckClient %p: setting state=%d error=%s", this,
state, grpc_error_string(error));
}
if (notify_state_ != nullptr && *notify_state_ != state) {
*notify_state_ = state;
notify_state_ = nullptr;
GRPC_CLOSURE_SCHED(on_health_changed_, GRPC_ERROR_REF(error));
on_health_changed_ = nullptr;
}
state_ = state;
GRPC_ERROR_UNREF(error_);
error_ = error;
}
void HealthCheckClient::Orphan() {
if (grpc_health_check_client_trace.enabled()) {
gpr_log(GPR_INFO, "HealthCheckClient %p: shutting down", this);
}
{
MutexLock lock(&mu_);
if (on_health_changed_ != nullptr) {
*notify_state_ = GRPC_CHANNEL_SHUTDOWN;
notify_state_ = nullptr;
GRPC_CLOSURE_SCHED(on_health_changed_, GRPC_ERROR_NONE);
on_health_changed_ = nullptr;
}
shutting_down_ = true;
call_state_.reset();
if (retry_timer_callback_pending_) {
grpc_timer_cancel(&retry_timer_);
}
}
Unref(DEBUG_LOCATION, "orphan");
}
void HealthCheckClient::StartCall() {
MutexLock lock(&mu_);
StartCallLocked();
}
void HealthCheckClient::StartCallLocked() {
if (shutting_down_) return;
GPR_ASSERT(call_state_ == nullptr);
SetHealthStatusLocked(GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE);
call_state_ = MakeOrphanable<CallState>(Ref(), interested_parties_);
if (grpc_health_check_client_trace.enabled()) {
gpr_log(GPR_INFO, "HealthCheckClient %p: created CallState %p", this,
call_state_.get());
}
call_state_->StartCall();
}
void HealthCheckClient::StartRetryTimer() {
MutexLock lock(&mu_);
SetHealthStatusLocked(
GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"health check call failed; will retry after backoff"));
grpc_millis next_try = retry_backoff_.NextAttemptTime();
if (grpc_health_check_client_trace.enabled()) {
gpr_log(GPR_INFO, "HealthCheckClient %p: health check call lost...", this);
grpc_millis timeout = next_try - ExecCtx::Get()->Now();
if (timeout > 0) {
gpr_log(GPR_INFO,
"HealthCheckClient %p: ... will retry in %" PRId64 "ms.", this,
timeout);
} else {
gpr_log(GPR_INFO, "HealthCheckClient %p: ... retrying immediately.",
this);
}
}
// Ref for callback, tracked manually.
Ref(DEBUG_LOCATION, "health_retry_timer").release();
retry_timer_callback_pending_ = true;
grpc_timer_init(&retry_timer_, next_try, &retry_timer_callback_);
}
void HealthCheckClient::OnRetryTimer(void* arg, grpc_error* error) {
HealthCheckClient* self = static_cast<HealthCheckClient*>(arg);
{
MutexLock lock(&self->mu_);
self->retry_timer_callback_pending_ = false;
if (!self->shutting_down_ && error == GRPC_ERROR_NONE &&
self->call_state_ == nullptr) {
if (grpc_health_check_client_trace.enabled()) {
gpr_log(GPR_INFO, "HealthCheckClient %p: restarting health check call",
self);
}
self->StartCallLocked();
}
}
self->Unref(DEBUG_LOCATION, "health_retry_timer");
}
//
// protobuf helpers
//
namespace {
void EncodeRequest(const char* service_name,
ManualConstructor<SliceBufferByteStream>* send_message) {
grpc_health_v1_HealthCheckRequest request_struct;
request_struct.has_service = true;
snprintf(request_struct.service, sizeof(request_struct.service), "%s",
service_name);
pb_ostream_t ostream;
memset(&ostream, 0, sizeof(ostream));
pb_encode(&ostream, grpc_health_v1_HealthCheckRequest_fields,
&request_struct);
grpc_slice request_slice = GRPC_SLICE_MALLOC(ostream.bytes_written);
ostream = pb_ostream_from_buffer(GRPC_SLICE_START_PTR(request_slice),
GRPC_SLICE_LENGTH(request_slice));
GPR_ASSERT(pb_encode(&ostream, grpc_health_v1_HealthCheckRequest_fields,
&request_struct) != 0);
grpc_slice_buffer slice_buffer;
grpc_slice_buffer_init(&slice_buffer);
grpc_slice_buffer_add(&slice_buffer, request_slice);
send_message->Init(&slice_buffer, 0);
grpc_slice_buffer_destroy_internal(&slice_buffer);
}
// Returns true if healthy.
// If there was an error parsing the response, sets *error and returns false.
bool DecodeResponse(grpc_slice_buffer* slice_buffer, grpc_error** error) {
// If message is empty, assume unhealthy.
if (slice_buffer->length == 0) {
*error =
GRPC_ERROR_CREATE_FROM_STATIC_STRING("health check response was empty");
return false;
}
// Concatenate the slices to form a single string.
UniquePtr<uint8_t> recv_message_deleter;
uint8_t* recv_message;
if (slice_buffer->count == 1) {
recv_message = GRPC_SLICE_START_PTR(slice_buffer->slices[0]);
} else {
recv_message = static_cast<uint8_t*>(gpr_malloc(slice_buffer->length));
recv_message_deleter.reset(recv_message);
size_t offset = 0;
for (size_t i = 0; i < slice_buffer->count; ++i) {
memcpy(recv_message + offset,
GRPC_SLICE_START_PTR(slice_buffer->slices[i]),
GRPC_SLICE_LENGTH(slice_buffer->slices[i]));
offset += GRPC_SLICE_LENGTH(slice_buffer->slices[i]);
}
}
// Deserialize message.
grpc_health_v1_HealthCheckResponse response_struct;
pb_istream_t istream =
pb_istream_from_buffer(recv_message, slice_buffer->length);
if (!pb_decode(&istream, grpc_health_v1_HealthCheckResponse_fields,
&response_struct)) {
// Can't parse message; assume unhealthy.
*error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"cannot parse health check response");
return false;
}
if (!response_struct.has_status) {
// Field not present; assume unhealthy.
*error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"status field not present in health check response");
return false;
}
return response_struct.status ==
grpc_health_v1_HealthCheckResponse_ServingStatus_SERVING;
}
} // namespace
//
// HealthCheckClient::CallState
//
HealthCheckClient::CallState::CallState(
RefCountedPtr<HealthCheckClient> health_check_client,
grpc_pollset_set* interested_parties)
: InternallyRefCountedWithTracing<CallState>(
&grpc_health_check_client_trace),
health_check_client_(std::move(health_check_client)),
pollent_(grpc_polling_entity_create_from_pollset_set(interested_parties)),
arena_(gpr_arena_create(health_check_client_->connected_subchannel_
->GetInitialCallSizeEstimate(0))) {
memset(&call_combiner_, 0, sizeof(call_combiner_));
grpc_call_combiner_init(&call_combiner_);
memset(context_, 0, sizeof(context_));
gpr_atm_rel_store(&seen_response_, static_cast<gpr_atm>(0));
}
HealthCheckClient::CallState::~CallState() {
if (grpc_health_check_client_trace.enabled()) {
gpr_log(GPR_INFO, "HealthCheckClient %p: destroying CallState %p",
health_check_client_.get(), this);
}
if (call_ != nullptr) GRPC_SUBCHANNEL_CALL_UNREF(call_, "call_ended");
// Unset the call combiner cancellation closure. This has the
// effect of scheduling the previously set cancellation closure, if
// any, so that it can release any internal references it may be
// holding to the call stack. Also flush the closures on exec_ctx so that
// filters that schedule cancel notification closures on exec_ctx do not
// need to take a ref of the call stack to guarantee closure liveness.
grpc_call_combiner_set_notify_on_cancel(&call_combiner_, nullptr);
grpc_core::ExecCtx::Get()->Flush();
grpc_call_combiner_destroy(&call_combiner_);
gpr_arena_destroy(arena_);
}
void HealthCheckClient::CallState::Orphan() {
grpc_call_combiner_cancel(&call_combiner_, GRPC_ERROR_CANCELLED);
Cancel();
}
void HealthCheckClient::CallState::StartCall() {
ConnectedSubchannel::CallArgs args = {
&pollent_,
GRPC_MDSTR_SLASH_GRPC_DOT_HEALTH_DOT_V1_DOT_HEALTH_SLASH_WATCH,
gpr_now(GPR_CLOCK_MONOTONIC), // start_time
GRPC_MILLIS_INF_FUTURE, // deadline
arena_,
context_,
&call_combiner_,
0, // parent_data_size
};
grpc_error* error =
health_check_client_->connected_subchannel_->CreateCall(args, &call_);
if (error != GRPC_ERROR_NONE) {
gpr_log(GPR_ERROR,
"HealthCheckClient %p CallState %p: error creating health "
"checking call on subchannel (%s); will retry",
health_check_client_.get(), this, grpc_error_string(error));
GRPC_ERROR_UNREF(error);
// Schedule instead of running directly, since we must not be
// holding health_check_client_->mu_ when CallEnded() is called.
Ref(DEBUG_LOCATION, "call_end_closure").release();
GRPC_CLOSURE_SCHED(
GRPC_CLOSURE_INIT(&batch_.handler_private.closure, CallEndedRetry, this,
grpc_schedule_on_exec_ctx),
GRPC_ERROR_NONE);
return;
}
// Initialize payload and batch.
memset(&batch_, 0, sizeof(batch_));
batch_.payload = &payload_;
// on_complete callback takes ref, handled manually.
Ref(DEBUG_LOCATION, "on_complete").release();
batch_.on_complete = GRPC_CLOSURE_INIT(&on_complete_, OnComplete, this,
grpc_schedule_on_exec_ctx);
// Add send_initial_metadata op.
grpc_metadata_batch_init(&send_initial_metadata_);
error = grpc_metadata_batch_add_head(
&send_initial_metadata_, &path_metadata_storage_,
grpc_mdelem_from_slices(
GRPC_MDSTR_PATH,
GRPC_MDSTR_SLASH_GRPC_DOT_HEALTH_DOT_V1_DOT_HEALTH_SLASH_WATCH));
GPR_ASSERT(error == GRPC_ERROR_NONE);
payload_.send_initial_metadata.send_initial_metadata =
&send_initial_metadata_;
payload_.send_initial_metadata.send_initial_metadata_flags = 0;
payload_.send_initial_metadata.peer_string = nullptr;
batch_.send_initial_metadata = true;
// Add send_message op.
EncodeRequest(health_check_client_->service_name_, &send_message_);
payload_.send_message.send_message.reset(send_message_.get());
batch_.send_message = true;
// Add send_trailing_metadata op.
grpc_metadata_batch_init(&send_trailing_metadata_);
payload_.send_trailing_metadata.send_trailing_metadata =
&send_trailing_metadata_;
batch_.send_trailing_metadata = true;
// Add recv_initial_metadata op.
grpc_metadata_batch_init(&recv_initial_metadata_);
payload_.recv_initial_metadata.recv_initial_metadata =
&recv_initial_metadata_;
payload_.recv_initial_metadata.recv_flags = nullptr;
payload_.recv_initial_metadata.trailing_metadata_available = nullptr;
payload_.recv_initial_metadata.peer_string = nullptr;
// recv_initial_metadata_ready callback takes ref, handled manually.
Ref(DEBUG_LOCATION, "recv_initial_metadata_ready").release();
payload_.recv_initial_metadata.recv_initial_metadata_ready =
GRPC_CLOSURE_INIT(&recv_initial_metadata_ready_, RecvInitialMetadataReady,
this, grpc_schedule_on_exec_ctx);
batch_.recv_initial_metadata = true;
// Add recv_message op.
payload_.recv_message.recv_message = &recv_message_;
// recv_message callback takes ref, handled manually.
Ref(DEBUG_LOCATION, "recv_message_ready").release();
payload_.recv_message.recv_message_ready = GRPC_CLOSURE_INIT(
&recv_message_ready_, RecvMessageReady, this, grpc_schedule_on_exec_ctx);
batch_.recv_message = true;
// Start batch.
StartBatch(&batch_);
// Initialize recv_trailing_metadata batch.
memset(&recv_trailing_metadata_batch_, 0,
sizeof(recv_trailing_metadata_batch_));
recv_trailing_metadata_batch_.payload = &payload_;
// Add recv_trailing_metadata op.
grpc_metadata_batch_init(&recv_trailing_metadata_);
payload_.recv_trailing_metadata.recv_trailing_metadata =
&recv_trailing_metadata_;
payload_.recv_trailing_metadata.collect_stats = &collect_stats_;
// This callback signals the end of the call, so it relies on the
// initial ref instead of taking a new ref. When it's invoked, the
// initial ref is released.
payload_.recv_trailing_metadata.recv_trailing_metadata_ready =
GRPC_CLOSURE_INIT(&recv_trailing_metadata_ready_,
RecvTrailingMetadataReady, this,
grpc_schedule_on_exec_ctx);
recv_trailing_metadata_batch_.recv_trailing_metadata = true;
// Start recv_trailing_metadata batch.
StartBatch(&recv_trailing_metadata_batch_);
}
void HealthCheckClient::CallState::StartBatchInCallCombiner(void* arg,
grpc_error* error) {
grpc_transport_stream_op_batch* batch =
static_cast<grpc_transport_stream_op_batch*>(arg);
grpc_subchannel_call* call =
static_cast<grpc_subchannel_call*>(batch->handler_private.extra_arg);
grpc_subchannel_call_process_op(call, batch);
}
void HealthCheckClient::CallState::StartBatch(
grpc_transport_stream_op_batch* batch) {
batch->handler_private.extra_arg = call_;
GRPC_CLOSURE_INIT(&batch->handler_private.closure, StartBatchInCallCombiner,
batch, grpc_schedule_on_exec_ctx);
GRPC_CALL_COMBINER_START(&call_combiner_, &batch->handler_private.closure,
GRPC_ERROR_NONE, "start_subchannel_batch");
}
void HealthCheckClient::CallState::OnCancelComplete(void* arg,
grpc_error* error) {
HealthCheckClient::CallState* self =
static_cast<HealthCheckClient::CallState*>(arg);
GRPC_CALL_COMBINER_STOP(&self->call_combiner_, "health_cancel");
self->Unref(DEBUG_LOCATION, "cancel");
}
void HealthCheckClient::CallState::StartCancel(void* arg, grpc_error* error) {
HealthCheckClient::CallState* self =
static_cast<HealthCheckClient::CallState*>(arg);
auto* batch = grpc_make_transport_stream_op(
GRPC_CLOSURE_CREATE(OnCancelComplete, self, grpc_schedule_on_exec_ctx));
batch->cancel_stream = true;
batch->payload->cancel_stream.cancel_error = GRPC_ERROR_CANCELLED;
grpc_subchannel_call_process_op(self->call_, batch);
}
void HealthCheckClient::CallState::Cancel() {
if (call_ != nullptr) {
Ref(DEBUG_LOCATION, "cancel").release();
GRPC_CALL_COMBINER_START(
&call_combiner_,
GRPC_CLOSURE_CREATE(StartCancel, this, grpc_schedule_on_exec_ctx),
GRPC_ERROR_NONE, "health_cancel");
}
}
void HealthCheckClient::CallState::OnComplete(void* arg, grpc_error* error) {
HealthCheckClient::CallState* self =
static_cast<HealthCheckClient::CallState*>(arg);
GRPC_CALL_COMBINER_STOP(&self->call_combiner_, "on_complete");
grpc_metadata_batch_destroy(&self->send_initial_metadata_);
grpc_metadata_batch_destroy(&self->send_trailing_metadata_);
self->Unref(DEBUG_LOCATION, "on_complete");
}
void HealthCheckClient::CallState::RecvInitialMetadataReady(void* arg,
grpc_error* error) {
HealthCheckClient::CallState* self =
static_cast<HealthCheckClient::CallState*>(arg);
GRPC_CALL_COMBINER_STOP(&self->call_combiner_, "recv_initial_metadata_ready");
grpc_metadata_batch_destroy(&self->recv_initial_metadata_);
self->Unref(DEBUG_LOCATION, "recv_initial_metadata_ready");
}
void HealthCheckClient::CallState::DoneReadingRecvMessage(grpc_error* error) {
recv_message_.reset();
if (error != GRPC_ERROR_NONE) {
GRPC_ERROR_UNREF(error);
Cancel();
grpc_slice_buffer_destroy_internal(&recv_message_buffer_);
Unref(DEBUG_LOCATION, "recv_message_ready");
return;
}
const bool healthy = DecodeResponse(&recv_message_buffer_, &error);
const grpc_connectivity_state state =
healthy ? GRPC_CHANNEL_READY : GRPC_CHANNEL_TRANSIENT_FAILURE;
if (error == GRPC_ERROR_NONE && !healthy) {
error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("backend unhealthy");
}
health_check_client_->SetHealthStatus(state, error);
gpr_atm_rel_store(&seen_response_, static_cast<gpr_atm>(1));
grpc_slice_buffer_destroy_internal(&recv_message_buffer_);
// Start another recv_message batch.
// This re-uses the ref we're holding.
// Note: Can't just reuse batch_ here, since we don't know that all
// callbacks from the original batch have completed yet.
memset(&recv_message_batch_, 0, sizeof(recv_message_batch_));
recv_message_batch_.payload = &payload_;
payload_.recv_message.recv_message = &recv_message_;
payload_.recv_message.recv_message_ready = GRPC_CLOSURE_INIT(
&recv_message_ready_, RecvMessageReady, this, grpc_schedule_on_exec_ctx);
recv_message_batch_.recv_message = true;
StartBatch(&recv_message_batch_);
}
grpc_error* HealthCheckClient::CallState::PullSliceFromRecvMessage() {
grpc_slice slice;
grpc_error* error = recv_message_->Pull(&slice);
if (error == GRPC_ERROR_NONE) {
grpc_slice_buffer_add(&recv_message_buffer_, slice);
}
return error;
}
void HealthCheckClient::CallState::ContinueReadingRecvMessage() {
while (recv_message_->Next(SIZE_MAX, &recv_message_ready_)) {
grpc_error* error = PullSliceFromRecvMessage();
if (error != GRPC_ERROR_NONE) {
DoneReadingRecvMessage(error);
return;
}
if (recv_message_buffer_.length == recv_message_->length()) {
DoneReadingRecvMessage(GRPC_ERROR_NONE);
break;
}
}
}
void HealthCheckClient::CallState::OnByteStreamNext(void* arg,
grpc_error* error) {
HealthCheckClient::CallState* self =
static_cast<HealthCheckClient::CallState*>(arg);
if (error != GRPC_ERROR_NONE) {
self->DoneReadingRecvMessage(GRPC_ERROR_REF(error));
return;
}
error = self->PullSliceFromRecvMessage();
if (error != GRPC_ERROR_NONE) {
self->DoneReadingRecvMessage(error);
return;
}
if (self->recv_message_buffer_.length == self->recv_message_->length()) {
self->DoneReadingRecvMessage(GRPC_ERROR_NONE);
} else {
self->ContinueReadingRecvMessage();
}
}
void HealthCheckClient::CallState::RecvMessageReady(void* arg,
grpc_error* error) {
HealthCheckClient::CallState* self =
static_cast<HealthCheckClient::CallState*>(arg);
GRPC_CALL_COMBINER_STOP(&self->call_combiner_, "recv_message_ready");
if (self->recv_message_ == nullptr) {
self->Unref(DEBUG_LOCATION, "recv_message_ready");
return;
}
grpc_slice_buffer_init(&self->recv_message_buffer_);
GRPC_CLOSURE_INIT(&self->recv_message_ready_, OnByteStreamNext, self,
grpc_schedule_on_exec_ctx);
self->ContinueReadingRecvMessage();
// Ref will continue to be held until we finish draining the byte stream.
}
void HealthCheckClient::CallState::RecvTrailingMetadataReady(
void* arg, grpc_error* error) {
HealthCheckClient::CallState* self =
static_cast<HealthCheckClient::CallState*>(arg);
GRPC_CALL_COMBINER_STOP(&self->call_combiner_,
"recv_trailing_metadata_ready");
// Get call status.
grpc_status_code status = GRPC_STATUS_UNKNOWN;
if (error != GRPC_ERROR_NONE) {
grpc_error_get_status(error, GRPC_MILLIS_INF_FUTURE, &status,
nullptr /* slice */, nullptr /* http_error */,
nullptr /* error_string */);
} else if (self->recv_trailing_metadata_.idx.named.grpc_status != nullptr) {
status = grpc_get_status_code_from_metadata(
self->recv_trailing_metadata_.idx.named.grpc_status->md);
}
if (grpc_health_check_client_trace.enabled()) {
gpr_log(GPR_INFO,
"HealthCheckClient %p CallState %p: health watch failed with "
"status %d",
self->health_check_client_.get(), self, status);
}
// Clean up.
grpc_metadata_batch_destroy(&self->recv_trailing_metadata_);
// For status UNIMPLEMENTED, give up and assume always healthy.
bool retry = true;
if (status == GRPC_STATUS_UNIMPLEMENTED) {
static const char kErrorMessage[] =
"health checking Watch method returned UNIMPLEMENTED; "
"disabling health checks but assuming server is healthy";
gpr_log(GPR_ERROR, kErrorMessage);
if (self->health_check_client_->channelz_node_ != nullptr) {
self->health_check_client_->channelz_node_->AddTraceEvent(
channelz::ChannelTrace::Error,
grpc_slice_from_static_string(kErrorMessage));
}
self->health_check_client_->SetHealthStatus(GRPC_CHANNEL_READY,
GRPC_ERROR_NONE);
retry = false;
}
self->CallEnded(retry);
}
void HealthCheckClient::CallState::CallEndedRetry(void* arg,
grpc_error* error) {
HealthCheckClient::CallState* self =
static_cast<HealthCheckClient::CallState*>(arg);
self->CallEnded(true /* retry */);
self->Unref(DEBUG_LOCATION, "call_end_closure");
}
void HealthCheckClient::CallState::CallEnded(bool retry) {
// If this CallState is still in use, this call ended because of a failure,
// so we need to stop using it and optionally create a new one.
// Otherwise, we have deliberately ended this call, and no further action
// is required.
if (this == health_check_client_->call_state_.get()) {
health_check_client_->call_state_.reset();
if (retry) {
GPR_ASSERT(!health_check_client_->shutting_down_);
if (static_cast<bool>(gpr_atm_acq_load(&seen_response_))) {
// If the call fails after we've gotten a successful response, reset
// the backoff and restart the call immediately.
health_check_client_->retry_backoff_.Reset();
health_check_client_->StartCall();
} else {
// If the call failed without receiving any messages, retry later.
health_check_client_->StartRetryTimer();
}
}
}
Unref(DEBUG_LOCATION, "call_ended");
}
} // namespace grpc_core

@ -0,0 +1,173 @@
/*
*
* Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_HEALTH_HEALTH_CHECK_CLIENT_H
#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_HEALTH_HEALTH_CHECK_CLIENT_H
#include <grpc/support/port_platform.h>
#include <grpc/grpc.h>
#include <grpc/support/atm.h>
#include <grpc/support/sync.h>
#include "src/core/ext/filters/client_channel/client_channel_channelz.h"
#include "src/core/ext/filters/client_channel/subchannel.h"
#include "src/core/lib/backoff/backoff.h"
#include "src/core/lib/gpr/arena.h"
#include "src/core/lib/gprpp/orphanable.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/iomgr/call_combiner.h"
#include "src/core/lib/iomgr/closure.h"
#include "src/core/lib/iomgr/polling_entity.h"
#include "src/core/lib/iomgr/timer.h"
#include "src/core/lib/transport/byte_stream.h"
#include "src/core/lib/transport/metadata_batch.h"
#include "src/core/lib/transport/transport.h"
namespace grpc_core {
class HealthCheckClient
: public InternallyRefCountedWithTracing<HealthCheckClient> {
public:
HealthCheckClient(const char* service_name,
RefCountedPtr<ConnectedSubchannel> connected_subchannel,
grpc_pollset_set* interested_parties,
RefCountedPtr<channelz::SubchannelNode> channelz_node);
~HealthCheckClient();
// When the health state changes from *state, sets *state to the new
// value and schedules closure.
// Only one closure can be outstanding at a time.
void NotifyOnHealthChange(grpc_connectivity_state* state,
grpc_closure* closure);
void Orphan() override;
private:
// Contains a call to the backend and all the data related to the call.
class CallState : public InternallyRefCountedWithTracing<CallState> {
public:
CallState(RefCountedPtr<HealthCheckClient> health_check_client,
grpc_pollset_set* interested_parties_);
~CallState();
void Orphan() override;
void StartCall();
private:
void Cancel();
void StartBatch(grpc_transport_stream_op_batch* batch);
static void StartBatchInCallCombiner(void* arg, grpc_error* error);
static void CallEndedRetry(void* arg, grpc_error* error);
void CallEnded(bool retry);
static void OnComplete(void* arg, grpc_error* error);
static void RecvInitialMetadataReady(void* arg, grpc_error* error);
static void RecvMessageReady(void* arg, grpc_error* error);
static void RecvTrailingMetadataReady(void* arg, grpc_error* error);
static void StartCancel(void* arg, grpc_error* error);
static void OnCancelComplete(void* arg, grpc_error* error);
static void OnByteStreamNext(void* arg, grpc_error* error);
void ContinueReadingRecvMessage();
grpc_error* PullSliceFromRecvMessage();
void DoneReadingRecvMessage(grpc_error* error);
RefCountedPtr<HealthCheckClient> health_check_client_;
grpc_polling_entity pollent_;
gpr_arena* arena_;
grpc_call_combiner call_combiner_;
grpc_call_context_element context_[GRPC_CONTEXT_COUNT];
// The streaming call to the backend. Always non-NULL.
grpc_subchannel_call* call_;
grpc_transport_stream_op_batch_payload payload_;
grpc_transport_stream_op_batch batch_;
grpc_transport_stream_op_batch recv_message_batch_;
grpc_transport_stream_op_batch recv_trailing_metadata_batch_;
grpc_closure on_complete_;
// send_initial_metadata
grpc_metadata_batch send_initial_metadata_;
grpc_linked_mdelem path_metadata_storage_;
// send_message
ManualConstructor<SliceBufferByteStream> send_message_;
// send_trailing_metadata
grpc_metadata_batch send_trailing_metadata_;
// recv_initial_metadata
grpc_metadata_batch recv_initial_metadata_;
grpc_closure recv_initial_metadata_ready_;
// recv_message
OrphanablePtr<ByteStream> recv_message_;
grpc_closure recv_message_ready_;
grpc_slice_buffer recv_message_buffer_;
gpr_atm seen_response_;
// recv_trailing_metadata
grpc_metadata_batch recv_trailing_metadata_;
grpc_transport_stream_stats collect_stats_;
grpc_closure recv_trailing_metadata_ready_;
};
void StartCall();
void StartCallLocked(); // Requires holding mu_.
void StartRetryTimer();
static void OnRetryTimer(void* arg, grpc_error* error);
void SetHealthStatus(grpc_connectivity_state state, grpc_error* error);
void SetHealthStatusLocked(grpc_connectivity_state state,
grpc_error* error); // Requires holding mu_.
const char* service_name_; // Do not own.
RefCountedPtr<ConnectedSubchannel> connected_subchannel_;
grpc_pollset_set* interested_parties_; // Do not own.
RefCountedPtr<channelz::SubchannelNode> channelz_node_;
gpr_mu mu_;
grpc_connectivity_state state_ = GRPC_CHANNEL_CONNECTING;
grpc_error* error_ = GRPC_ERROR_NONE;
grpc_connectivity_state* notify_state_ = nullptr;
grpc_closure* on_health_changed_ = nullptr;
bool shutting_down_ = false;
// The data associated with the current health check call. It holds a ref
// to this HealthCheckClient object.
OrphanablePtr<CallState> call_state_;
// Call retry state.
BackOff retry_backoff_;
grpc_timer retry_timer_;
grpc_closure retry_timer_callback_;
bool retry_timer_callback_pending_ = false;
};
} // namespace grpc_core
#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_HEALTH_HEALTH_CHECK_CLIENT_H */

@ -1699,7 +1699,7 @@ grpc_channel_args* GrpcLb::CreateRoundRobinPolicyArgsLocked() {
// Replace the LB addresses in the channel args that we pass down to
// the subchannel.
static const char* keys_to_remove[] = {GRPC_ARG_LB_ADDRESSES};
const grpc_arg args_to_add[] = {
grpc_arg args_to_add[3] = {
grpc_lb_addresses_create_channel_arg(addresses),
// A channel arg indicating if the target is a backend inferred from a
// grpclb load balancer.
@ -1708,9 +1708,15 @@ grpc_channel_args* GrpcLb::CreateRoundRobinPolicyArgsLocked() {
GRPC_ARG_ADDRESS_IS_BACKEND_FROM_GRPCLB_LOAD_BALANCER),
is_backend_from_grpclb_load_balancer),
};
size_t num_args_to_add = 2;
if (is_backend_from_grpclb_load_balancer) {
args_to_add[2] = grpc_channel_arg_integer_create(
const_cast<char*>(GRPC_ARG_INHIBIT_HEALTH_CHECKING), 1);
++num_args_to_add;
}
grpc_channel_args* args = grpc_channel_args_copy_and_add_and_remove(
args_, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), args_to_add,
GPR_ARRAY_SIZE(args_to_add));
num_args_to_add);
grpc_lb_addresses_destroy(addresses);
return args;
}

@ -359,9 +359,14 @@ void PickFirst::UpdateLocked(const grpc_channel_args& args) {
"Pick First %p received update with %" PRIuPTR " addresses", this,
addresses->num_addresses);
}
grpc_arg new_arg = grpc_channel_arg_integer_create(
const_cast<char*>(GRPC_ARG_INHIBIT_HEALTH_CHECKING), 1);
grpc_channel_args* new_args =
grpc_channel_args_copy_and_add(&args, &new_arg, 1);
auto subchannel_list = MakeOrphanable<PickFirstSubchannelList>(
this, &grpc_lb_pick_first_trace, addresses, combiner(),
client_channel_factory(), args);
client_channel_factory(), *new_args);
grpc_channel_args_destroy(new_args);
if (subchannel_list->num_subchannels() == 0) {
// Empty update or no valid subchannels. Unsubscribe from all current
// subchannels and put the channel in TRANSIENT_FAILURE.

@ -102,8 +102,8 @@ class SubchannelData {
// ProcessConnectivityChangeLocked()).
grpc_connectivity_state CheckConnectivityStateLocked(grpc_error** error) {
GPR_ASSERT(!connectivity_notification_pending_);
pending_connectivity_state_unsafe_ =
grpc_subchannel_check_connectivity(subchannel(), error);
pending_connectivity_state_unsafe_ = grpc_subchannel_check_connectivity(
subchannel(), error, subchannel_list_->inhibit_health_checking());
UpdateConnectedSubchannelLocked();
return pending_connectivity_state_unsafe_;
}
@ -216,6 +216,7 @@ class SubchannelList
// Accessors.
LoadBalancingPolicy* policy() const { return policy_; }
TraceFlag* tracer() const { return tracer_; }
bool inhibit_health_checking() const { return inhibit_health_checking_; }
// Resets connection backoff of all subchannels.
// TODO(roth): We will probably need to rethink this as part of moving
@ -254,6 +255,8 @@ class SubchannelList
TraceFlag* tracer_;
bool inhibit_health_checking_;
grpc_combiner* combiner_;
// The list of subchannels.
@ -340,7 +343,8 @@ void SubchannelData<SubchannelListType,
subchannel_list()->Ref(DEBUG_LOCATION, "connectivity_watch").release();
grpc_subchannel_notify_on_state_change(
subchannel_, subchannel_list_->policy()->interested_parties(),
&pending_connectivity_state_unsafe_, &connectivity_changed_closure_);
&pending_connectivity_state_unsafe_, &connectivity_changed_closure_,
subchannel_list_->inhibit_health_checking());
}
template <typename SubchannelListType, typename SubchannelDataType>
@ -359,7 +363,8 @@ void SubchannelData<SubchannelListType,
GPR_ASSERT(connectivity_notification_pending_);
grpc_subchannel_notify_on_state_change(
subchannel_, subchannel_list_->policy()->interested_parties(),
&pending_connectivity_state_unsafe_, &connectivity_changed_closure_);
&pending_connectivity_state_unsafe_, &connectivity_changed_closure_,
subchannel_list_->inhibit_health_checking());
}
template <typename SubchannelListType, typename SubchannelDataType>
@ -390,8 +395,9 @@ void SubchannelData<SubchannelListType, SubchannelDataType>::
subchannel_, reason);
}
GPR_ASSERT(connectivity_notification_pending_);
grpc_subchannel_notify_on_state_change(subchannel_, nullptr, nullptr,
&connectivity_changed_closure_);
grpc_subchannel_notify_on_state_change(
subchannel_, nullptr, nullptr, &connectivity_changed_closure_,
subchannel_list_->inhibit_health_checking());
}
template <typename SubchannelListType, typename SubchannelDataType>
@ -499,8 +505,13 @@ SubchannelList<SubchannelListType, SubchannelDataType>::SubchannelList(
subchannels_.reserve(addresses->num_addresses);
// We need to remove the LB addresses in order to be able to compare the
// subchannel keys of subchannels from a different batch of addresses.
// We also remove the inhibit-health-checking arg, since we are
// handling that here.
inhibit_health_checking_ = grpc_channel_arg_get_bool(
grpc_channel_args_find(&args, GRPC_ARG_INHIBIT_HEALTH_CHECKING), false);
static const char* keys_to_remove[] = {GRPC_ARG_SUBCHANNEL_ADDRESS,
GRPC_ARG_LB_ADDRESSES};
GRPC_ARG_LB_ADDRESSES,
GRPC_ARG_INHIBIT_HEALTH_CHECKING};
// Create a subchannel for each address.
grpc_subchannel_args sc_args;
for (size_t i = 0; i < addresses->num_addresses; i++) {

@ -30,6 +30,7 @@
#include <grpc/support/string_util.h>
#include "src/core/ext/filters/client_channel/client_channel.h"
#include "src/core/ext/filters/client_channel/health/health_check_client.h"
#include "src/core/ext/filters/client_channel/parse_address.h"
#include "src/core/ext/filters/client_channel/proxy_mapper_registry.h"
#include "src/core/ext/filters/client_channel/subchannel_index.h"
@ -41,6 +42,7 @@
#include "src/core/lib/gpr/alloc.h"
#include "src/core/lib/gprpp/debug_location.h"
#include "src/core/lib/gprpp/manual_constructor.h"
#include "src/core/lib/gprpp/mutex_lock.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
#include "src/core/lib/iomgr/timer.h"
@ -50,6 +52,7 @@
#include "src/core/lib/surface/channel_init.h"
#include "src/core/lib/transport/connectivity_state.h"
#include "src/core/lib/transport/error_utils.h"
#include "src/core/lib/transport/service_config.h"
#include "src/core/lib/transport/status_metadata.h"
#define INTERNAL_REF_BITS 16
@ -66,6 +69,10 @@ struct state_watcher {
grpc_closure closure;
grpc_subchannel* subchannel;
grpc_connectivity_state connectivity_state;
grpc_connectivity_state last_connectivity_state;
grpc_core::OrphanablePtr<grpc_core::HealthCheckClient> health_check_client;
grpc_closure health_check_closure;
grpc_connectivity_state health_state;
};
} // namespace
@ -78,6 +85,12 @@ typedef struct external_state_watcher {
struct external_state_watcher* prev;
} external_state_watcher;
namespace grpc_core {
class ConnectedSubchannelStateWatcher;
} // namespace grpc_core
struct grpc_subchannel {
grpc_connector* connector;
@ -109,19 +122,24 @@ struct grpc_subchannel {
being setup */
grpc_pollset_set* pollset_set;
grpc_core::UniquePtr<char> health_check_service_name;
/** mutex protecting remaining elements */
gpr_mu mu;
/** active connection, or null; of type grpc_core::ConnectedSubchannel
*/
/** active connection, or null */
grpc_core::RefCountedPtr<grpc_core::ConnectedSubchannel> connected_subchannel;
grpc_core::OrphanablePtr<grpc_core::ConnectedSubchannelStateWatcher>
connected_subchannel_watcher;
/** have we seen a disconnection? */
bool disconnected;
/** are we connecting */
bool connecting;
/** connectivity state tracking */
grpc_connectivity_state_tracker state_tracker;
grpc_connectivity_state_tracker state_and_health_tracker;
external_state_watcher root_external_state_watcher;
@ -153,6 +171,171 @@ struct grpc_subchannel_call {
grpc_millis deadline;
};
static void maybe_start_connecting_locked(grpc_subchannel* c);
static const char* subchannel_connectivity_state_change_string(
grpc_connectivity_state state) {
switch (state) {
case GRPC_CHANNEL_IDLE:
return "Subchannel state change to IDLE";
case GRPC_CHANNEL_CONNECTING:
return "Subchannel state change to CONNECTING";
case GRPC_CHANNEL_READY:
return "Subchannel state change to READY";
case GRPC_CHANNEL_TRANSIENT_FAILURE:
return "Subchannel state change to TRANSIENT_FAILURE";
case GRPC_CHANNEL_SHUTDOWN:
return "Subchannel state change to SHUTDOWN";
}
GPR_UNREACHABLE_CODE(return "UNKNOWN");
}
static void set_subchannel_connectivity_state_locked(
grpc_subchannel* c, grpc_connectivity_state state, grpc_error* error,
const char* reason) {
if (c->channelz_subchannel != nullptr) {
c->channelz_subchannel->AddTraceEvent(
grpc_core::channelz::ChannelTrace::Severity::Info,
grpc_slice_from_static_string(
subchannel_connectivity_state_change_string(state)));
}
grpc_connectivity_state_set(&c->state_tracker, state, error, reason);
}
namespace grpc_core {
class ConnectedSubchannelStateWatcher
: public InternallyRefCounted<ConnectedSubchannelStateWatcher> {
public:
// Must be instantiated while holding c->mu.
explicit ConnectedSubchannelStateWatcher(grpc_subchannel* c)
: subchannel_(c) {
// Steal subchannel ref for connecting.
GRPC_SUBCHANNEL_WEAK_REF(subchannel_, "state_watcher");
GRPC_SUBCHANNEL_WEAK_UNREF(subchannel_, "connecting");
// Start watching for connectivity state changes.
// Callback uses initial ref to this.
GRPC_CLOSURE_INIT(&on_connectivity_changed_, OnConnectivityChanged, this,
grpc_schedule_on_exec_ctx);
c->connected_subchannel->NotifyOnStateChange(c->pollset_set,
&pending_connectivity_state_,
&on_connectivity_changed_);
// Start health check if needed.
grpc_connectivity_state health_state = GRPC_CHANNEL_READY;
if (c->health_check_service_name != nullptr) {
health_check_client_ = grpc_core::MakeOrphanable<HealthCheckClient>(
c->health_check_service_name.get(), c->connected_subchannel,
c->pollset_set, c->channelz_subchannel);
GRPC_CLOSURE_INIT(&on_health_changed_, OnHealthChanged, this,
grpc_schedule_on_exec_ctx);
Ref().release(); // Ref for health callback tracked manually.
health_check_client_->NotifyOnHealthChange(&health_state_,
&on_health_changed_);
health_state = GRPC_CHANNEL_CONNECTING;
}
// Report initial state.
set_subchannel_connectivity_state_locked(
c, GRPC_CHANNEL_READY, GRPC_ERROR_NONE, "subchannel_connected");
grpc_connectivity_state_set(&c->state_and_health_tracker, health_state,
GRPC_ERROR_NONE, "subchannel_connected");
}
~ConnectedSubchannelStateWatcher() {
GRPC_SUBCHANNEL_WEAK_UNREF(subchannel_, "state_watcher");
}
void Orphan() override { health_check_client_.reset(); }
private:
static void OnConnectivityChanged(void* arg, grpc_error* error) {
auto* self = static_cast<ConnectedSubchannelStateWatcher*>(arg);
grpc_subchannel* c = self->subchannel_;
{
MutexLock lock(&c->mu);
switch (self->pending_connectivity_state_) {
case GRPC_CHANNEL_TRANSIENT_FAILURE:
case GRPC_CHANNEL_SHUTDOWN: {
if (!c->disconnected && c->connected_subchannel != nullptr) {
if (grpc_trace_stream_refcount.enabled()) {
gpr_log(GPR_INFO,
"Connected subchannel %p of subchannel %p has gone into "
"%s. Attempting to reconnect.",
c->connected_subchannel.get(), c,
grpc_connectivity_state_name(
self->pending_connectivity_state_));
}
c->connected_subchannel.reset();
c->connected_subchannel_watcher.reset();
self->last_connectivity_state_ = GRPC_CHANNEL_TRANSIENT_FAILURE;
set_subchannel_connectivity_state_locked(
c, GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error),
"reflect_child");
grpc_connectivity_state_set(&c->state_and_health_tracker,
GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_ERROR_REF(error), "reflect_child");
c->backoff_begun = false;
c->backoff->Reset();
maybe_start_connecting_locked(c);
} else {
self->last_connectivity_state_ = GRPC_CHANNEL_SHUTDOWN;
}
self->health_check_client_.reset();
break;
}
default: {
// In principle, this should never happen. We should not get
// a callback for READY, because that was the state we started
// this watch from. And a connected subchannel should never go
// from READY to CONNECTING or IDLE.
self->last_connectivity_state_ = self->pending_connectivity_state_;
set_subchannel_connectivity_state_locked(
c, self->pending_connectivity_state_, GRPC_ERROR_REF(error),
"reflect_child");
if (self->pending_connectivity_state_ != GRPC_CHANNEL_READY) {
grpc_connectivity_state_set(&c->state_and_health_tracker,
self->pending_connectivity_state_,
GRPC_ERROR_REF(error), "reflect_child");
}
c->connected_subchannel->NotifyOnStateChange(
nullptr, &self->pending_connectivity_state_,
&self->on_connectivity_changed_);
self = nullptr; // So we don't unref below.
}
}
}
// Don't unref until we've released the lock, because this might
// cause the subchannel (which contains the lock) to be destroyed.
if (self != nullptr) self->Unref();
}
static void OnHealthChanged(void* arg, grpc_error* error) {
auto* self = static_cast<ConnectedSubchannelStateWatcher*>(arg);
if (self->health_state_ == GRPC_CHANNEL_SHUTDOWN) {
self->Unref();
return;
}
grpc_subchannel* c = self->subchannel_;
MutexLock lock(&c->mu);
if (self->last_connectivity_state_ == GRPC_CHANNEL_READY) {
grpc_connectivity_state_set(&c->state_and_health_tracker,
self->health_state_, GRPC_ERROR_REF(error),
"health_changed");
}
self->health_check_client_->NotifyOnHealthChange(&self->health_state_,
&self->on_health_changed_);
}
grpc_subchannel* subchannel_;
grpc_closure on_connectivity_changed_;
grpc_connectivity_state pending_connectivity_state_ = GRPC_CHANNEL_READY;
grpc_connectivity_state last_connectivity_state_ = GRPC_CHANNEL_READY;
grpc_core::OrphanablePtr<grpc_core::HealthCheckClient> health_check_client_;
grpc_closure on_health_changed_;
grpc_connectivity_state health_state_ = GRPC_CHANNEL_CONNECTING;
};
} // namespace grpc_core
#define SUBCHANNEL_CALL_TO_CALL_STACK(call) \
(grpc_call_stack*)((char*)(call) + GPR_ROUND_UP_TO_ALIGNMENT_SIZE( \
sizeof(grpc_subchannel_call)))
@ -198,8 +381,10 @@ static void subchannel_destroy(void* arg, grpc_error* error) {
c->channelz_subchannel.reset();
}
gpr_free((void*)c->filters);
c->health_check_service_name.reset();
grpc_channel_args_destroy(c->args);
grpc_connectivity_state_destroy(&c->state_tracker);
grpc_connectivity_state_destroy(&c->state_and_health_tracker);
grpc_connector_unref(c->connector);
grpc_pollset_set_destroy(c->pollset_set);
grpc_subchannel_key_destroy(c->key);
@ -262,6 +447,7 @@ static void disconnect(grpc_subchannel* c) {
grpc_connector_shutdown(c->connector, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Subchannel disconnected"));
c->connected_subchannel.reset();
c->connected_subchannel_watcher.reset();
gpr_mu_unlock(&c->mu);
}
@ -337,6 +523,31 @@ static void parse_args_for_backoff_values(
.set_max_backoff(max_backoff_ms);
}
namespace grpc_core {
namespace {
struct HealthCheckParams {
UniquePtr<char> service_name;
static void Parse(const grpc_json* field, HealthCheckParams* params) {
if (strcmp(field->key, "healthCheckConfig") == 0) {
if (field->type != GRPC_JSON_OBJECT) return;
for (grpc_json* sub_field = field->child; sub_field != nullptr;
sub_field = sub_field->next) {
if (sub_field->key == nullptr) return;
if (strcmp(sub_field->key, "serviceName") == 0) {
if (params->service_name != nullptr) return; // Duplicate.
if (sub_field->type != GRPC_JSON_STRING) return;
params->service_name.reset(gpr_strdup(sub_field->value));
}
}
}
}
};
} // namespace
} // namespace grpc_core
grpc_subchannel* grpc_subchannel_create(grpc_connector* connector,
const grpc_subchannel_args* args) {
grpc_subchannel_key* key = grpc_subchannel_key_create(args);
@ -387,12 +598,28 @@ grpc_subchannel* grpc_subchannel_create(grpc_connector* connector,
grpc_schedule_on_exec_ctx);
grpc_connectivity_state_init(&c->state_tracker, GRPC_CHANNEL_IDLE,
"subchannel");
grpc_connectivity_state_init(&c->state_and_health_tracker, GRPC_CHANNEL_IDLE,
"subchannel");
grpc_core::BackOff::Options backoff_options;
parse_args_for_backoff_values(args->args, &backoff_options,
&c->min_connect_timeout_ms);
c->backoff.Init(backoff_options);
gpr_mu_init(&c->mu);
// Check whether we should enable health checking.
const char* service_config_json = grpc_channel_arg_get_string(
grpc_channel_args_find(c->args, GRPC_ARG_SERVICE_CONFIG));
if (service_config_json != nullptr) {
grpc_core::UniquePtr<grpc_core::ServiceConfig> service_config =
grpc_core::ServiceConfig::Create(service_config_json);
if (service_config != nullptr) {
grpc_core::HealthCheckParams params;
service_config->ParseGlobalParams(grpc_core::HealthCheckParams::Parse,
&params);
c->health_check_service_name = std::move(params.service_name);
}
}
const grpc_arg* arg =
grpc_channel_args_find(c->args, GRPC_ARG_ENABLE_CHANNELZ);
bool channelz_enabled =
@ -428,35 +655,6 @@ intptr_t grpc_subchannel_get_child_socket_uuid(grpc_subchannel* subchannel) {
}
}
static const char* subchannel_connectivity_state_change_string(
grpc_connectivity_state state) {
switch (state) {
case GRPC_CHANNEL_IDLE:
return "Subchannel state change to IDLE";
case GRPC_CHANNEL_CONNECTING:
return "Subchannel state change to CONNECTING";
case GRPC_CHANNEL_READY:
return "Subchannel state change to READY";
case GRPC_CHANNEL_TRANSIENT_FAILURE:
return "Subchannel state change to TRANSIENT_FAILURE";
case GRPC_CHANNEL_SHUTDOWN:
return "Subchannel state change to SHUTDOWN";
}
GPR_UNREACHABLE_CODE(return "UNKNOWN");
}
static void set_subchannel_connectivity_state_locked(
grpc_subchannel* c, grpc_connectivity_state state, grpc_error* error,
const char* reason) {
if (c->channelz_subchannel != nullptr) {
c->channelz_subchannel->AddTraceEvent(
grpc_core::channelz::ChannelTrace::Severity::Info,
grpc_slice_from_static_string(
subchannel_connectivity_state_change_string(state)));
}
grpc_connectivity_state_set(&c->state_tracker, state, error, reason);
}
static void continue_connect_locked(grpc_subchannel* c) {
grpc_connect_in_args args;
args.interested_parties = c->pollset_set;
@ -467,15 +665,19 @@ static void continue_connect_locked(grpc_subchannel* c) {
args.channel_args = c->args;
set_subchannel_connectivity_state_locked(c, GRPC_CHANNEL_CONNECTING,
GRPC_ERROR_NONE, "connecting");
grpc_connectivity_state_set(&c->state_and_health_tracker,
GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE,
"connecting");
grpc_connector_connect(c->connector, &args, &c->connecting_result,
&c->on_connected);
}
grpc_connectivity_state grpc_subchannel_check_connectivity(grpc_subchannel* c,
grpc_error** error) {
grpc_connectivity_state state;
grpc_connectivity_state grpc_subchannel_check_connectivity(
grpc_subchannel* c, grpc_error** error, bool inhibit_health_checks) {
gpr_mu_lock(&c->mu);
state = grpc_connectivity_state_get(&c->state_tracker, error);
grpc_connectivity_state_tracker* tracker =
inhibit_health_checks ? &c->state_tracker : &c->state_and_health_tracker;
grpc_connectivity_state state = grpc_connectivity_state_get(tracker, error);
gpr_mu_unlock(&c->mu);
return state;
}
@ -533,7 +735,8 @@ static void maybe_start_connecting_locked(grpc_subchannel* c) {
/* Already connected: don't restart */
return;
}
if (!grpc_connectivity_state_has_watchers(&c->state_tracker)) {
if (!grpc_connectivity_state_has_watchers(&c->state_tracker) &&
!grpc_connectivity_state_has_watchers(&c->state_and_health_tracker)) {
/* Nobody is interested in connecting: so don't just yet */
return;
}
@ -560,16 +763,18 @@ static void maybe_start_connecting_locked(grpc_subchannel* c) {
void grpc_subchannel_notify_on_state_change(
grpc_subchannel* c, grpc_pollset_set* interested_parties,
grpc_connectivity_state* state, grpc_closure* notify) {
grpc_connectivity_state* state, grpc_closure* notify,
bool inhibit_health_checks) {
grpc_connectivity_state_tracker* tracker =
inhibit_health_checks ? &c->state_tracker : &c->state_and_health_tracker;
external_state_watcher* w;
if (state == nullptr) {
gpr_mu_lock(&c->mu);
for (w = c->root_external_state_watcher.next;
w != &c->root_external_state_watcher; w = w->next) {
if (w->notify == notify) {
grpc_connectivity_state_notify_on_state_change(&c->state_tracker,
nullptr, &w->closure);
grpc_connectivity_state_notify_on_state_change(tracker, nullptr,
&w->closure);
}
}
gpr_mu_unlock(&c->mu);
@ -588,62 +793,12 @@ void grpc_subchannel_notify_on_state_change(
w->next = &c->root_external_state_watcher;
w->prev = w->next->prev;
w->next->prev = w->prev->next = w;
grpc_connectivity_state_notify_on_state_change(&c->state_tracker, state,
&w->closure);
grpc_connectivity_state_notify_on_state_change(tracker, state, &w->closure);
maybe_start_connecting_locked(c);
gpr_mu_unlock(&c->mu);
}
}
static void on_connected_subchannel_connectivity_changed(void* p,
grpc_error* error) {
state_watcher* connected_subchannel_watcher = static_cast<state_watcher*>(p);
grpc_subchannel* c = connected_subchannel_watcher->subchannel;
gpr_mu* mu = &c->mu;
gpr_mu_lock(mu);
switch (connected_subchannel_watcher->connectivity_state) {
case GRPC_CHANNEL_TRANSIENT_FAILURE:
case GRPC_CHANNEL_SHUTDOWN: {
if (!c->disconnected && c->connected_subchannel != nullptr) {
if (grpc_trace_stream_refcount.enabled()) {
gpr_log(GPR_INFO,
"Connected subchannel %p of subchannel %p has gone into %s. "
"Attempting to reconnect.",
c->connected_subchannel.get(), c,
grpc_connectivity_state_name(
connected_subchannel_watcher->connectivity_state));
}
c->connected_subchannel.reset();
set_subchannel_connectivity_state_locked(
c, GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error),
"reflect_child");
c->backoff_begun = false;
c->backoff->Reset();
maybe_start_connecting_locked(c);
} else {
connected_subchannel_watcher->connectivity_state =
GRPC_CHANNEL_SHUTDOWN;
}
break;
}
default: {
set_subchannel_connectivity_state_locked(
c, connected_subchannel_watcher->connectivity_state,
GRPC_ERROR_REF(error), "reflect_child");
GRPC_SUBCHANNEL_WEAK_REF(c, "state_watcher");
c->connected_subchannel->NotifyOnStateChange(
nullptr, &connected_subchannel_watcher->connectivity_state,
&connected_subchannel_watcher->closure);
connected_subchannel_watcher = nullptr;
}
}
gpr_mu_unlock(mu);
GRPC_SUBCHANNEL_WEAK_UNREF(c, "state_watcher");
gpr_free(connected_subchannel_watcher);
}
static bool publish_transport_locked(grpc_subchannel* c) {
/* construct channel stack */
grpc_channel_stack_builder* builder = grpc_channel_stack_builder_create();
@ -670,17 +825,7 @@ static bool publish_transport_locked(grpc_subchannel* c) {
intptr_t socket_uuid = c->connecting_result.socket_uuid;
memset(&c->connecting_result, 0, sizeof(c->connecting_result));
/* initialize state watcher */
state_watcher* connected_subchannel_watcher = static_cast<state_watcher*>(
gpr_zalloc(sizeof(*connected_subchannel_watcher)));
connected_subchannel_watcher->subchannel = c;
connected_subchannel_watcher->connectivity_state = GRPC_CHANNEL_READY;
GRPC_CLOSURE_INIT(&connected_subchannel_watcher->closure,
on_connected_subchannel_connectivity_changed,
connected_subchannel_watcher, grpc_schedule_on_exec_ctx);
if (c->disconnected) {
gpr_free(connected_subchannel_watcher);
grpc_channel_stack_destroy(stk);
gpr_free(stk);
return false;
@ -692,17 +837,10 @@ static bool publish_transport_locked(grpc_subchannel* c) {
gpr_log(GPR_INFO, "New connected subchannel at %p for subchannel %p",
c->connected_subchannel.get(), c);
/* setup subchannel watching connected subchannel for changes; subchannel
ref for connecting is donated to the state watcher */
GRPC_SUBCHANNEL_WEAK_REF(c, "state_watcher");
GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting");
c->connected_subchannel->NotifyOnStateChange(
c->pollset_set, &connected_subchannel_watcher->connectivity_state,
&connected_subchannel_watcher->closure);
/* signal completion */
set_subchannel_connectivity_state_locked(c, GRPC_CHANNEL_READY,
GRPC_ERROR_NONE, "connected");
// Instantiate state watcher. Will clean itself up.
c->connected_subchannel_watcher =
grpc_core::MakeOrphanable<grpc_core::ConnectedSubchannelStateWatcher>(c);
return true;
}
@ -725,6 +863,12 @@ static void on_subchannel_connected(void* arg, grpc_error* error) {
"Connect Failed", &error, 1),
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE),
"connect_failed");
grpc_connectivity_state_set(
&c->state_and_health_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE,
grpc_error_set_int(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
"Connect Failed", &error, 1),
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE),
"connect_failed");
const char* errmsg = grpc_error_string(error);
gpr_log(GPR_INFO, "Connect failed: %s", errmsg);
@ -956,15 +1100,8 @@ void ConnectedSubchannel::Ping(grpc_closure* on_initiate,
grpc_error* ConnectedSubchannel::CreateCall(const CallArgs& args,
grpc_subchannel_call** call) {
size_t allocation_size =
GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_subchannel_call));
if (args.parent_data_size > 0) {
allocation_size +=
GPR_ROUND_UP_TO_ALIGNMENT_SIZE(channel_stack_->call_stack_size) +
args.parent_data_size;
} else {
allocation_size += channel_stack_->call_stack_size;
}
const size_t allocation_size =
GetInitialCallSizeEstimate(args.parent_data_size);
*call = static_cast<grpc_subchannel_call*>(
gpr_arena_alloc(args.arena, allocation_size));
grpc_call_stack* callstk = SUBCHANNEL_CALL_TO_CALL_STACK(*call);
@ -994,4 +1131,18 @@ grpc_error* ConnectedSubchannel::CreateCall(const CallArgs& args,
return GRPC_ERROR_NONE;
}
size_t ConnectedSubchannel::GetInitialCallSizeEstimate(
size_t parent_data_size) const {
size_t allocation_size =
GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_subchannel_call));
if (parent_data_size > 0) {
allocation_size +=
GPR_ROUND_UP_TO_ALIGNMENT_SIZE(channel_stack_->call_stack_size) +
parent_data_size;
} else {
allocation_size += channel_stack_->call_stack_size;
}
return allocation_size;
}
} // namespace grpc_core

@ -103,6 +103,8 @@ class ConnectedSubchannel : public RefCountedWithTracing<ConnectedSubchannel> {
}
intptr_t socket_uuid() { return socket_uuid_; }
size_t GetInitialCallSizeEstimate(size_t parent_data_size) const;
private:
grpc_channel_stack* channel_stack_;
// ref counted pointer to the channelz node in this connected subchannel's
@ -143,13 +145,14 @@ void* grpc_connected_subchannel_call_get_parent_data(
/** poll the current connectivity state of a channel */
grpc_connectivity_state grpc_subchannel_check_connectivity(
grpc_subchannel* channel, grpc_error** error);
grpc_subchannel* channel, grpc_error** error, bool inhibit_health_checking);
/** Calls notify when the connectivity state of a channel becomes different
from *state. Updates *state with the new state of the channel. */
void grpc_subchannel_notify_on_state_change(
grpc_subchannel* channel, grpc_pollset_set* interested_parties,
grpc_connectivity_state* state, grpc_closure* notify);
grpc_connectivity_state* state, grpc_closure* notify,
bool inhibit_health_checks);
/** retrieve the grpc_core::ConnectedSubchannel - or nullptr if not connected
* (which may happen before it initially connects or during transient failures)

@ -63,51 +63,53 @@ static uint8_t g_bytes[] = {
115, 115, 97, 103, 101, 95, 98, 121, 116, 101, 115, 47, 103, 114, 112,
99, 46, 108, 98, 46, 118, 49, 46, 76, 111, 97, 100, 66, 97, 108,
97, 110, 99, 101, 114, 47, 66, 97, 108, 97, 110, 99, 101, 76, 111,
97, 100, 100, 101, 102, 108, 97, 116, 101, 103, 122, 105, 112, 115, 116,
114, 101, 97, 109, 47, 103, 122, 105, 112, 71, 69, 84, 80, 79, 83,
84, 47, 47, 105, 110, 100, 101, 120, 46, 104, 116, 109, 108, 104, 116,
116, 112, 104, 116, 116, 112, 115, 50, 48, 48, 50, 48, 52, 50, 48,
54, 51, 48, 52, 52, 48, 48, 52, 48, 52, 53, 48, 48, 97, 99,
99, 101, 112, 116, 45, 99, 104, 97, 114, 115, 101, 116, 103, 122, 105,
112, 44, 32, 100, 101, 102, 108, 97, 116, 101, 97, 99, 99, 101, 112,
116, 45, 108, 97, 110, 103, 117, 97, 103, 101, 97, 99, 99, 101, 112,
116, 45, 114, 97, 110, 103, 101, 115, 97, 99, 99, 101, 112, 116, 97,
99, 99, 101, 115, 115, 45, 99, 111, 110, 116, 114, 111, 108, 45, 97,
108, 108, 111, 119, 45, 111, 114, 105, 103, 105, 110, 97, 103, 101, 97,
108, 108, 111, 119, 97, 117, 116, 104, 111, 114, 105, 122, 97, 116, 105,
111, 110, 99, 97, 99, 104, 101, 45, 99, 111, 110, 116, 114, 111, 108,
99, 111, 110, 116, 101, 110, 116, 45, 100, 105, 115, 112, 111, 115, 105,
116, 105, 111, 110, 99, 111, 110, 116, 101, 110, 116, 45, 108, 97, 110,
103, 117, 97, 103, 101, 99, 111, 110, 116, 101, 110, 116, 45, 108, 101,
110, 103, 116, 104, 99, 111, 110, 116, 101, 110, 116, 45, 108, 111, 99,
97, 116, 105, 111, 110, 99, 111, 110, 116, 101, 110, 116, 45, 114, 97,
110, 103, 101, 99, 111, 111, 107, 105, 101, 100, 97, 116, 101, 101, 116,
97, 103, 101, 120, 112, 101, 99, 116, 101, 120, 112, 105, 114, 101, 115,
102, 114, 111, 109, 105, 102, 45, 109, 97, 116, 99, 104, 105, 102, 45,
109, 111, 100, 105, 102, 105, 101, 100, 45, 115, 105, 110, 99, 101, 105,
102, 45, 110, 111, 110, 101, 45, 109, 97, 116, 99, 104, 105, 102, 45,
114, 97, 110, 103, 101, 105, 102, 45, 117, 110, 109, 111, 100, 105, 102,
105, 101, 100, 45, 115, 105, 110, 99, 101, 108, 97, 115, 116, 45, 109,
111, 100, 105, 102, 105, 101, 100, 108, 105, 110, 107, 108, 111, 99, 97,
116, 105, 111, 110, 109, 97, 120, 45, 102, 111, 114, 119, 97, 114, 100,
115, 112, 114, 111, 120, 121, 45, 97, 117, 116, 104, 101, 110, 116, 105,
99, 97, 116, 101, 112, 114, 111, 120, 121, 45, 97, 117, 116, 104, 111,
114, 105, 122, 97, 116, 105, 111, 110, 114, 97, 110, 103, 101, 114, 101,
102, 101, 114, 101, 114, 114, 101, 102, 114, 101, 115, 104, 114, 101, 116,
114, 121, 45, 97, 102, 116, 101, 114, 115, 101, 114, 118, 101, 114, 115,
101, 116, 45, 99, 111, 111, 107, 105, 101, 115, 116, 114, 105, 99, 116,
45, 116, 114, 97, 110, 115, 112, 111, 114, 116, 45, 115, 101, 99, 117,
114, 105, 116, 121, 116, 114, 97, 110, 115, 102, 101, 114, 45, 101, 110,
99, 111, 100, 105, 110, 103, 118, 97, 114, 121, 118, 105, 97, 119, 119,
119, 45, 97, 117, 116, 104, 101, 110, 116, 105, 99, 97, 116, 101, 48,
105, 100, 101, 110, 116, 105, 116, 121, 116, 114, 97, 105, 108, 101, 114,
115, 97, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 47, 103, 114,
112, 99, 103, 114, 112, 99, 80, 85, 84, 108, 98, 45, 99, 111, 115,
116, 45, 98, 105, 110, 105, 100, 101, 110, 116, 105, 116, 121, 44, 100,
101, 102, 108, 97, 116, 101, 105, 100, 101, 110, 116, 105, 116, 121, 44,
103, 122, 105, 112, 100, 101, 102, 108, 97, 116, 101, 44, 103, 122, 105,
112, 105, 100, 101, 110, 116, 105, 116, 121, 44, 100, 101, 102, 108, 97,
116, 101, 44, 103, 122, 105, 112};
97, 100, 47, 103, 114, 112, 99, 46, 104, 101, 97, 108, 116, 104, 46,
118, 49, 46, 72, 101, 97, 108, 116, 104, 47, 87, 97, 116, 99, 104,
100, 101, 102, 108, 97, 116, 101, 103, 122, 105, 112, 115, 116, 114, 101,
97, 109, 47, 103, 122, 105, 112, 71, 69, 84, 80, 79, 83, 84, 47,
47, 105, 110, 100, 101, 120, 46, 104, 116, 109, 108, 104, 116, 116, 112,
104, 116, 116, 112, 115, 50, 48, 48, 50, 48, 52, 50, 48, 54, 51,
48, 52, 52, 48, 48, 52, 48, 52, 53, 48, 48, 97, 99, 99, 101,
112, 116, 45, 99, 104, 97, 114, 115, 101, 116, 103, 122, 105, 112, 44,
32, 100, 101, 102, 108, 97, 116, 101, 97, 99, 99, 101, 112, 116, 45,
108, 97, 110, 103, 117, 97, 103, 101, 97, 99, 99, 101, 112, 116, 45,
114, 97, 110, 103, 101, 115, 97, 99, 99, 101, 112, 116, 97, 99, 99,
101, 115, 115, 45, 99, 111, 110, 116, 114, 111, 108, 45, 97, 108, 108,
111, 119, 45, 111, 114, 105, 103, 105, 110, 97, 103, 101, 97, 108, 108,
111, 119, 97, 117, 116, 104, 111, 114, 105, 122, 97, 116, 105, 111, 110,
99, 97, 99, 104, 101, 45, 99, 111, 110, 116, 114, 111, 108, 99, 111,
110, 116, 101, 110, 116, 45, 100, 105, 115, 112, 111, 115, 105, 116, 105,
111, 110, 99, 111, 110, 116, 101, 110, 116, 45, 108, 97, 110, 103, 117,
97, 103, 101, 99, 111, 110, 116, 101, 110, 116, 45, 108, 101, 110, 103,
116, 104, 99, 111, 110, 116, 101, 110, 116, 45, 108, 111, 99, 97, 116,
105, 111, 110, 99, 111, 110, 116, 101, 110, 116, 45, 114, 97, 110, 103,
101, 99, 111, 111, 107, 105, 101, 100, 97, 116, 101, 101, 116, 97, 103,
101, 120, 112, 101, 99, 116, 101, 120, 112, 105, 114, 101, 115, 102, 114,
111, 109, 105, 102, 45, 109, 97, 116, 99, 104, 105, 102, 45, 109, 111,
100, 105, 102, 105, 101, 100, 45, 115, 105, 110, 99, 101, 105, 102, 45,
110, 111, 110, 101, 45, 109, 97, 116, 99, 104, 105, 102, 45, 114, 97,
110, 103, 101, 105, 102, 45, 117, 110, 109, 111, 100, 105, 102, 105, 101,
100, 45, 115, 105, 110, 99, 101, 108, 97, 115, 116, 45, 109, 111, 100,
105, 102, 105, 101, 100, 108, 105, 110, 107, 108, 111, 99, 97, 116, 105,
111, 110, 109, 97, 120, 45, 102, 111, 114, 119, 97, 114, 100, 115, 112,
114, 111, 120, 121, 45, 97, 117, 116, 104, 101, 110, 116, 105, 99, 97,
116, 101, 112, 114, 111, 120, 121, 45, 97, 117, 116, 104, 111, 114, 105,
122, 97, 116, 105, 111, 110, 114, 97, 110, 103, 101, 114, 101, 102, 101,
114, 101, 114, 114, 101, 102, 114, 101, 115, 104, 114, 101, 116, 114, 121,
45, 97, 102, 116, 101, 114, 115, 101, 114, 118, 101, 114, 115, 101, 116,
45, 99, 111, 111, 107, 105, 101, 115, 116, 114, 105, 99, 116, 45, 116,
114, 97, 110, 115, 112, 111, 114, 116, 45, 115, 101, 99, 117, 114, 105,
116, 121, 116, 114, 97, 110, 115, 102, 101, 114, 45, 101, 110, 99, 111,
100, 105, 110, 103, 118, 97, 114, 121, 118, 105, 97, 119, 119, 119, 45,
97, 117, 116, 104, 101, 110, 116, 105, 99, 97, 116, 101, 48, 105, 100,
101, 110, 116, 105, 116, 121, 116, 114, 97, 105, 108, 101, 114, 115, 97,
112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 47, 103, 114, 112, 99,
103, 114, 112, 99, 80, 85, 84, 108, 98, 45, 99, 111, 115, 116, 45,
98, 105, 110, 105, 100, 101, 110, 116, 105, 116, 121, 44, 100, 101, 102,
108, 97, 116, 101, 105, 100, 101, 110, 116, 105, 116, 121, 44, 103, 122,
105, 112, 100, 101, 102, 108, 97, 116, 101, 44, 103, 122, 105, 112, 105,
100, 101, 110, 116, 105, 116, 121, 44, 100, 101, 102, 108, 97, 116, 101,
44, 103, 122, 105, 112};
static void static_ref(void* unused) {}
static void static_unref(void* unused) {}
@ -224,6 +226,7 @@ grpc_slice_refcount grpc_static_metadata_refcounts[GRPC_STATIC_MDSTR_COUNT] = {
{&grpc_static_metadata_vtable, &static_sub_refcnt},
{&grpc_static_metadata_vtable, &static_sub_refcnt},
{&grpc_static_metadata_vtable, &static_sub_refcnt},
{&grpc_static_metadata_vtable, &static_sub_refcnt},
};
const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT] = {
@ -262,76 +265,77 @@ const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT] = {
{&grpc_static_metadata_refcounts[32], {{g_bytes + 385, 30}}},
{&grpc_static_metadata_refcounts[33], {{g_bytes + 415, 31}}},
{&grpc_static_metadata_refcounts[34], {{g_bytes + 446, 36}}},
{&grpc_static_metadata_refcounts[35], {{g_bytes + 482, 7}}},
{&grpc_static_metadata_refcounts[36], {{g_bytes + 489, 4}}},
{&grpc_static_metadata_refcounts[37], {{g_bytes + 493, 11}}},
{&grpc_static_metadata_refcounts[38], {{g_bytes + 504, 3}}},
{&grpc_static_metadata_refcounts[39], {{g_bytes + 507, 4}}},
{&grpc_static_metadata_refcounts[40], {{g_bytes + 511, 1}}},
{&grpc_static_metadata_refcounts[41], {{g_bytes + 512, 11}}},
{&grpc_static_metadata_refcounts[42], {{g_bytes + 523, 4}}},
{&grpc_static_metadata_refcounts[43], {{g_bytes + 527, 5}}},
{&grpc_static_metadata_refcounts[44], {{g_bytes + 532, 3}}},
{&grpc_static_metadata_refcounts[45], {{g_bytes + 535, 3}}},
{&grpc_static_metadata_refcounts[46], {{g_bytes + 538, 3}}},
{&grpc_static_metadata_refcounts[47], {{g_bytes + 541, 3}}},
{&grpc_static_metadata_refcounts[48], {{g_bytes + 544, 3}}},
{&grpc_static_metadata_refcounts[49], {{g_bytes + 547, 3}}},
{&grpc_static_metadata_refcounts[50], {{g_bytes + 550, 3}}},
{&grpc_static_metadata_refcounts[51], {{g_bytes + 553, 14}}},
{&grpc_static_metadata_refcounts[52], {{g_bytes + 567, 13}}},
{&grpc_static_metadata_refcounts[53], {{g_bytes + 580, 15}}},
{&grpc_static_metadata_refcounts[54], {{g_bytes + 595, 13}}},
{&grpc_static_metadata_refcounts[55], {{g_bytes + 608, 6}}},
{&grpc_static_metadata_refcounts[56], {{g_bytes + 614, 27}}},
{&grpc_static_metadata_refcounts[57], {{g_bytes + 641, 3}}},
{&grpc_static_metadata_refcounts[58], {{g_bytes + 644, 5}}},
{&grpc_static_metadata_refcounts[59], {{g_bytes + 649, 13}}},
{&grpc_static_metadata_refcounts[60], {{g_bytes + 662, 13}}},
{&grpc_static_metadata_refcounts[61], {{g_bytes + 675, 19}}},
{&grpc_static_metadata_refcounts[62], {{g_bytes + 694, 16}}},
{&grpc_static_metadata_refcounts[63], {{g_bytes + 710, 14}}},
{&grpc_static_metadata_refcounts[64], {{g_bytes + 724, 16}}},
{&grpc_static_metadata_refcounts[65], {{g_bytes + 740, 13}}},
{&grpc_static_metadata_refcounts[66], {{g_bytes + 753, 6}}},
{&grpc_static_metadata_refcounts[67], {{g_bytes + 759, 4}}},
{&grpc_static_metadata_refcounts[68], {{g_bytes + 763, 4}}},
{&grpc_static_metadata_refcounts[69], {{g_bytes + 767, 6}}},
{&grpc_static_metadata_refcounts[70], {{g_bytes + 773, 7}}},
{&grpc_static_metadata_refcounts[71], {{g_bytes + 780, 4}}},
{&grpc_static_metadata_refcounts[72], {{g_bytes + 784, 8}}},
{&grpc_static_metadata_refcounts[73], {{g_bytes + 792, 17}}},
{&grpc_static_metadata_refcounts[74], {{g_bytes + 809, 13}}},
{&grpc_static_metadata_refcounts[75], {{g_bytes + 822, 8}}},
{&grpc_static_metadata_refcounts[76], {{g_bytes + 830, 19}}},
{&grpc_static_metadata_refcounts[77], {{g_bytes + 849, 13}}},
{&grpc_static_metadata_refcounts[78], {{g_bytes + 862, 4}}},
{&grpc_static_metadata_refcounts[79], {{g_bytes + 866, 8}}},
{&grpc_static_metadata_refcounts[80], {{g_bytes + 874, 12}}},
{&grpc_static_metadata_refcounts[81], {{g_bytes + 886, 18}}},
{&grpc_static_metadata_refcounts[82], {{g_bytes + 904, 19}}},
{&grpc_static_metadata_refcounts[83], {{g_bytes + 923, 5}}},
{&grpc_static_metadata_refcounts[84], {{g_bytes + 928, 7}}},
{&grpc_static_metadata_refcounts[85], {{g_bytes + 935, 7}}},
{&grpc_static_metadata_refcounts[86], {{g_bytes + 942, 11}}},
{&grpc_static_metadata_refcounts[87], {{g_bytes + 953, 6}}},
{&grpc_static_metadata_refcounts[88], {{g_bytes + 959, 10}}},
{&grpc_static_metadata_refcounts[89], {{g_bytes + 969, 25}}},
{&grpc_static_metadata_refcounts[90], {{g_bytes + 994, 17}}},
{&grpc_static_metadata_refcounts[91], {{g_bytes + 1011, 4}}},
{&grpc_static_metadata_refcounts[92], {{g_bytes + 1015, 3}}},
{&grpc_static_metadata_refcounts[93], {{g_bytes + 1018, 16}}},
{&grpc_static_metadata_refcounts[94], {{g_bytes + 1034, 1}}},
{&grpc_static_metadata_refcounts[95], {{g_bytes + 1035, 8}}},
{&grpc_static_metadata_refcounts[96], {{g_bytes + 1043, 8}}},
{&grpc_static_metadata_refcounts[97], {{g_bytes + 1051, 16}}},
{&grpc_static_metadata_refcounts[98], {{g_bytes + 1067, 4}}},
{&grpc_static_metadata_refcounts[99], {{g_bytes + 1071, 3}}},
{&grpc_static_metadata_refcounts[100], {{g_bytes + 1074, 11}}},
{&grpc_static_metadata_refcounts[101], {{g_bytes + 1085, 16}}},
{&grpc_static_metadata_refcounts[102], {{g_bytes + 1101, 13}}},
{&grpc_static_metadata_refcounts[103], {{g_bytes + 1114, 12}}},
{&grpc_static_metadata_refcounts[104], {{g_bytes + 1126, 21}}},
{&grpc_static_metadata_refcounts[35], {{g_bytes + 482, 28}}},
{&grpc_static_metadata_refcounts[36], {{g_bytes + 510, 7}}},
{&grpc_static_metadata_refcounts[37], {{g_bytes + 517, 4}}},
{&grpc_static_metadata_refcounts[38], {{g_bytes + 521, 11}}},
{&grpc_static_metadata_refcounts[39], {{g_bytes + 532, 3}}},
{&grpc_static_metadata_refcounts[40], {{g_bytes + 535, 4}}},
{&grpc_static_metadata_refcounts[41], {{g_bytes + 539, 1}}},
{&grpc_static_metadata_refcounts[42], {{g_bytes + 540, 11}}},
{&grpc_static_metadata_refcounts[43], {{g_bytes + 551, 4}}},
{&grpc_static_metadata_refcounts[44], {{g_bytes + 555, 5}}},
{&grpc_static_metadata_refcounts[45], {{g_bytes + 560, 3}}},
{&grpc_static_metadata_refcounts[46], {{g_bytes + 563, 3}}},
{&grpc_static_metadata_refcounts[47], {{g_bytes + 566, 3}}},
{&grpc_static_metadata_refcounts[48], {{g_bytes + 569, 3}}},
{&grpc_static_metadata_refcounts[49], {{g_bytes + 572, 3}}},
{&grpc_static_metadata_refcounts[50], {{g_bytes + 575, 3}}},
{&grpc_static_metadata_refcounts[51], {{g_bytes + 578, 3}}},
{&grpc_static_metadata_refcounts[52], {{g_bytes + 581, 14}}},
{&grpc_static_metadata_refcounts[53], {{g_bytes + 595, 13}}},
{&grpc_static_metadata_refcounts[54], {{g_bytes + 608, 15}}},
{&grpc_static_metadata_refcounts[55], {{g_bytes + 623, 13}}},
{&grpc_static_metadata_refcounts[56], {{g_bytes + 636, 6}}},
{&grpc_static_metadata_refcounts[57], {{g_bytes + 642, 27}}},
{&grpc_static_metadata_refcounts[58], {{g_bytes + 669, 3}}},
{&grpc_static_metadata_refcounts[59], {{g_bytes + 672, 5}}},
{&grpc_static_metadata_refcounts[60], {{g_bytes + 677, 13}}},
{&grpc_static_metadata_refcounts[61], {{g_bytes + 690, 13}}},
{&grpc_static_metadata_refcounts[62], {{g_bytes + 703, 19}}},
{&grpc_static_metadata_refcounts[63], {{g_bytes + 722, 16}}},
{&grpc_static_metadata_refcounts[64], {{g_bytes + 738, 14}}},
{&grpc_static_metadata_refcounts[65], {{g_bytes + 752, 16}}},
{&grpc_static_metadata_refcounts[66], {{g_bytes + 768, 13}}},
{&grpc_static_metadata_refcounts[67], {{g_bytes + 781, 6}}},
{&grpc_static_metadata_refcounts[68], {{g_bytes + 787, 4}}},
{&grpc_static_metadata_refcounts[69], {{g_bytes + 791, 4}}},
{&grpc_static_metadata_refcounts[70], {{g_bytes + 795, 6}}},
{&grpc_static_metadata_refcounts[71], {{g_bytes + 801, 7}}},
{&grpc_static_metadata_refcounts[72], {{g_bytes + 808, 4}}},
{&grpc_static_metadata_refcounts[73], {{g_bytes + 812, 8}}},
{&grpc_static_metadata_refcounts[74], {{g_bytes + 820, 17}}},
{&grpc_static_metadata_refcounts[75], {{g_bytes + 837, 13}}},
{&grpc_static_metadata_refcounts[76], {{g_bytes + 850, 8}}},
{&grpc_static_metadata_refcounts[77], {{g_bytes + 858, 19}}},
{&grpc_static_metadata_refcounts[78], {{g_bytes + 877, 13}}},
{&grpc_static_metadata_refcounts[79], {{g_bytes + 890, 4}}},
{&grpc_static_metadata_refcounts[80], {{g_bytes + 894, 8}}},
{&grpc_static_metadata_refcounts[81], {{g_bytes + 902, 12}}},
{&grpc_static_metadata_refcounts[82], {{g_bytes + 914, 18}}},
{&grpc_static_metadata_refcounts[83], {{g_bytes + 932, 19}}},
{&grpc_static_metadata_refcounts[84], {{g_bytes + 951, 5}}},
{&grpc_static_metadata_refcounts[85], {{g_bytes + 956, 7}}},
{&grpc_static_metadata_refcounts[86], {{g_bytes + 963, 7}}},
{&grpc_static_metadata_refcounts[87], {{g_bytes + 970, 11}}},
{&grpc_static_metadata_refcounts[88], {{g_bytes + 981, 6}}},
{&grpc_static_metadata_refcounts[89], {{g_bytes + 987, 10}}},
{&grpc_static_metadata_refcounts[90], {{g_bytes + 997, 25}}},
{&grpc_static_metadata_refcounts[91], {{g_bytes + 1022, 17}}},
{&grpc_static_metadata_refcounts[92], {{g_bytes + 1039, 4}}},
{&grpc_static_metadata_refcounts[93], {{g_bytes + 1043, 3}}},
{&grpc_static_metadata_refcounts[94], {{g_bytes + 1046, 16}}},
{&grpc_static_metadata_refcounts[95], {{g_bytes + 1062, 1}}},
{&grpc_static_metadata_refcounts[96], {{g_bytes + 1063, 8}}},
{&grpc_static_metadata_refcounts[97], {{g_bytes + 1071, 8}}},
{&grpc_static_metadata_refcounts[98], {{g_bytes + 1079, 16}}},
{&grpc_static_metadata_refcounts[99], {{g_bytes + 1095, 4}}},
{&grpc_static_metadata_refcounts[100], {{g_bytes + 1099, 3}}},
{&grpc_static_metadata_refcounts[101], {{g_bytes + 1102, 11}}},
{&grpc_static_metadata_refcounts[102], {{g_bytes + 1113, 16}}},
{&grpc_static_metadata_refcounts[103], {{g_bytes + 1129, 13}}},
{&grpc_static_metadata_refcounts[104], {{g_bytes + 1142, 12}}},
{&grpc_static_metadata_refcounts[105], {{g_bytes + 1154, 21}}},
};
uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] = {
@ -341,17 +345,17 @@ uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 4, 6, 6, 8, 8, 2, 4, 4};
static const int8_t elems_r[] = {
15, 9, -8, 0, 2, -44, -78, 17, 0, 6, -8, 0, 0, 0, 6,
-5, -10, 0, 0, -2, -3, -4, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, -63, 0, -46, -68, -69, -53, 0, 31, 30,
29, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 18,
17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3,
2, 3, 3, 2, 6, 0, 0, 0, 0, 0, 0, -5, 0};
16, 11, -8, 0, 3, -42, -81, -43, 0, 6, -8, 0, 0, 0, -7,
-3, -10, 0, 0, 0, -1, -2, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, -63, 0, -47, -68, -69, -70, 0, 33,
33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 20,
19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5,
4, 4, 4, 3, 10, 9, 0, 0, 0, 0, 0, 0, -3, 0};
static uint32_t elems_phash(uint32_t i) {
i -= 40;
uint32_t x = i % 103;
uint32_t y = i / 103;
i -= 41;
uint32_t x = i % 104;
uint32_t y = i / 104;
uint32_t h = x;
if (y < GPR_ARRAY_SIZE(elems_r)) {
uint32_t delta = (uint32_t)elems_r[y];
@ -361,29 +365,29 @@ static uint32_t elems_phash(uint32_t i) {
}
static const uint16_t elem_keys[] = {
254, 255, 256, 257, 258, 259, 260, 1085, 1086, 143, 144, 1709,
462, 463, 1604, 40, 41, 761, 1716, 980, 981, 1611, 621, 1499,
760, 2024, 2129, 2234, 5384, 5699, 5804, 6014, 6119, 6224, 1732, 6329,
6434, 6539, 6644, 6749, 6854, 6959, 7064, 7169, 7274, 7379, 7484, 7589,
5909, 5594, 7694, 7799, 7904, 8009, 8114, 8219, 8324, 8429, 8534, 8639,
8744, 8849, 8954, 9059, 9164, 9269, 9374, 1145, 518, 9479, 204, 9584,
9689, 1151, 1152, 1153, 1154, 1775, 9794, 1040, 1670, 10529, 0, 0,
1782, 829, 0, 0, 0, 0, 344, 1567, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0};
257, 258, 259, 260, 261, 262, 263, 1096, 1097, 1513, 1725, 145,
146, 467, 468, 1619, 41, 42, 1733, 990, 991, 767, 768, 1627,
627, 837, 2043, 2149, 2255, 5541, 5859, 5965, 6071, 6177, 1749, 6283,
6389, 6495, 6601, 6707, 6813, 6919, 7025, 7131, 7237, 7343, 7449, 7555,
7661, 5753, 7767, 7873, 7979, 8085, 8191, 8297, 8403, 8509, 8615, 8721,
8827, 8933, 9039, 9145, 9251, 9357, 9463, 1156, 9569, 523, 9675, 9781,
206, 1162, 1163, 1164, 1165, 1792, 1582, 1050, 9887, 9993, 1686, 10735,
1799, 0, 0, 0, 0, 0, 347, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0};
static const uint8_t elem_idxs[] = {
7, 8, 9, 10, 11, 12, 13, 77, 79, 1, 2, 71, 5, 6, 25, 3,
4, 63, 84, 66, 65, 73, 67, 30, 62, 57, 37, 74, 14, 17, 18, 20,
21, 22, 15, 23, 24, 26, 27, 28, 29, 31, 32, 33, 34, 35, 36, 38,
19, 16, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
53, 54, 55, 76, 69, 56, 70, 58, 59, 78, 80, 81, 82, 83, 60, 64,
72, 75, 255, 255, 85, 61, 255, 255, 255, 255, 0, 68};
7, 8, 9, 10, 11, 12, 13, 77, 79, 30, 71, 1, 2, 5, 6, 25,
3, 4, 84, 66, 65, 62, 63, 73, 67, 61, 57, 37, 74, 14, 17, 18,
19, 20, 15, 21, 22, 23, 24, 26, 27, 28, 29, 31, 32, 33, 34, 35,
36, 16, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
52, 53, 54, 76, 55, 69, 56, 58, 70, 78, 80, 81, 82, 83, 68, 64,
59, 60, 72, 75, 85, 255, 255, 255, 255, 255, 0};
grpc_mdelem grpc_static_mdelem_for_static_strings(int a, int b) {
if (a == -1 || b == -1) return GRPC_MDNULL;
uint32_t k = (uint32_t)(a * 105 + b);
uint32_t k = (uint32_t)(a * 106 + b);
uint32_t h = elems_phash(k);
return h < GPR_ARRAY_SIZE(elem_keys) && elem_keys[h] == k &&
elem_idxs[h] != 255
@ -396,175 +400,175 @@ grpc_mdelem_data grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT] = {
{{&grpc_static_metadata_refcounts[3], {{g_bytes + 19, 10}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}},
{&grpc_static_metadata_refcounts[38], {{g_bytes + 504, 3}}}},
{&grpc_static_metadata_refcounts[39], {{g_bytes + 532, 3}}}},
{{&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}},
{&grpc_static_metadata_refcounts[39], {{g_bytes + 507, 4}}}},
{&grpc_static_metadata_refcounts[40], {{g_bytes + 535, 4}}}},
{{&grpc_static_metadata_refcounts[0], {{g_bytes + 0, 5}}},
{&grpc_static_metadata_refcounts[40], {{g_bytes + 511, 1}}}},
{&grpc_static_metadata_refcounts[41], {{g_bytes + 539, 1}}}},
{{&grpc_static_metadata_refcounts[0], {{g_bytes + 0, 5}}},
{&grpc_static_metadata_refcounts[41], {{g_bytes + 512, 11}}}},
{&grpc_static_metadata_refcounts[42], {{g_bytes + 540, 11}}}},
{{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}},
{&grpc_static_metadata_refcounts[42], {{g_bytes + 523, 4}}}},
{&grpc_static_metadata_refcounts[43], {{g_bytes + 551, 4}}}},
{{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}},
{&grpc_static_metadata_refcounts[43], {{g_bytes + 527, 5}}}},
{&grpc_static_metadata_refcounts[44], {{g_bytes + 555, 5}}}},
{{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}},
{&grpc_static_metadata_refcounts[44], {{g_bytes + 532, 3}}}},
{&grpc_static_metadata_refcounts[45], {{g_bytes + 560, 3}}}},
{{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}},
{&grpc_static_metadata_refcounts[45], {{g_bytes + 535, 3}}}},
{&grpc_static_metadata_refcounts[46], {{g_bytes + 563, 3}}}},
{{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}},
{&grpc_static_metadata_refcounts[46], {{g_bytes + 538, 3}}}},
{&grpc_static_metadata_refcounts[47], {{g_bytes + 566, 3}}}},
{{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}},
{&grpc_static_metadata_refcounts[47], {{g_bytes + 541, 3}}}},
{&grpc_static_metadata_refcounts[48], {{g_bytes + 569, 3}}}},
{{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}},
{&grpc_static_metadata_refcounts[48], {{g_bytes + 544, 3}}}},
{&grpc_static_metadata_refcounts[49], {{g_bytes + 572, 3}}}},
{{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}},
{&grpc_static_metadata_refcounts[49], {{g_bytes + 547, 3}}}},
{&grpc_static_metadata_refcounts[50], {{g_bytes + 575, 3}}}},
{{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}},
{&grpc_static_metadata_refcounts[50], {{g_bytes + 550, 3}}}},
{{&grpc_static_metadata_refcounts[51], {{g_bytes + 553, 14}}},
{&grpc_static_metadata_refcounts[51], {{g_bytes + 578, 3}}}},
{{&grpc_static_metadata_refcounts[52], {{g_bytes + 581, 14}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}},
{&grpc_static_metadata_refcounts[52], {{g_bytes + 567, 13}}}},
{{&grpc_static_metadata_refcounts[53], {{g_bytes + 580, 15}}},
{&grpc_static_metadata_refcounts[53], {{g_bytes + 595, 13}}}},
{{&grpc_static_metadata_refcounts[54], {{g_bytes + 608, 15}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[54], {{g_bytes + 595, 13}}},
{{&grpc_static_metadata_refcounts[55], {{g_bytes + 623, 13}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[55], {{g_bytes + 608, 6}}},
{{&grpc_static_metadata_refcounts[56], {{g_bytes + 636, 6}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[56], {{g_bytes + 614, 27}}},
{{&grpc_static_metadata_refcounts[57], {{g_bytes + 642, 27}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[57], {{g_bytes + 641, 3}}},
{{&grpc_static_metadata_refcounts[58], {{g_bytes + 669, 3}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[58], {{g_bytes + 644, 5}}},
{{&grpc_static_metadata_refcounts[59], {{g_bytes + 672, 5}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[59], {{g_bytes + 649, 13}}},
{{&grpc_static_metadata_refcounts[60], {{g_bytes + 677, 13}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[60], {{g_bytes + 662, 13}}},
{{&grpc_static_metadata_refcounts[61], {{g_bytes + 690, 13}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[61], {{g_bytes + 675, 19}}},
{{&grpc_static_metadata_refcounts[62], {{g_bytes + 703, 19}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[15], {{g_bytes + 170, 16}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[62], {{g_bytes + 694, 16}}},
{{&grpc_static_metadata_refcounts[63], {{g_bytes + 722, 16}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[63], {{g_bytes + 710, 14}}},
{{&grpc_static_metadata_refcounts[64], {{g_bytes + 738, 14}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[64], {{g_bytes + 724, 16}}},
{{&grpc_static_metadata_refcounts[65], {{g_bytes + 752, 16}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[65], {{g_bytes + 740, 13}}},
{{&grpc_static_metadata_refcounts[66], {{g_bytes + 768, 13}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[14], {{g_bytes + 158, 12}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[66], {{g_bytes + 753, 6}}},
{{&grpc_static_metadata_refcounts[67], {{g_bytes + 781, 6}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[67], {{g_bytes + 759, 4}}},
{{&grpc_static_metadata_refcounts[68], {{g_bytes + 787, 4}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[68], {{g_bytes + 763, 4}}},
{{&grpc_static_metadata_refcounts[69], {{g_bytes + 791, 4}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[69], {{g_bytes + 767, 6}}},
{{&grpc_static_metadata_refcounts[70], {{g_bytes + 795, 6}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[70], {{g_bytes + 773, 7}}},
{{&grpc_static_metadata_refcounts[71], {{g_bytes + 801, 7}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[71], {{g_bytes + 780, 4}}},
{{&grpc_static_metadata_refcounts[72], {{g_bytes + 808, 4}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[20], {{g_bytes + 278, 4}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[72], {{g_bytes + 784, 8}}},
{{&grpc_static_metadata_refcounts[73], {{g_bytes + 812, 8}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[73], {{g_bytes + 792, 17}}},
{{&grpc_static_metadata_refcounts[74], {{g_bytes + 820, 17}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[74], {{g_bytes + 809, 13}}},
{{&grpc_static_metadata_refcounts[75], {{g_bytes + 837, 13}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[75], {{g_bytes + 822, 8}}},
{{&grpc_static_metadata_refcounts[76], {{g_bytes + 850, 8}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[76], {{g_bytes + 830, 19}}},
{{&grpc_static_metadata_refcounts[77], {{g_bytes + 858, 19}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[77], {{g_bytes + 849, 13}}},
{{&grpc_static_metadata_refcounts[78], {{g_bytes + 877, 13}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[78], {{g_bytes + 862, 4}}},
{{&grpc_static_metadata_refcounts[79], {{g_bytes + 890, 4}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[79], {{g_bytes + 866, 8}}},
{{&grpc_static_metadata_refcounts[80], {{g_bytes + 894, 8}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[80], {{g_bytes + 874, 12}}},
{{&grpc_static_metadata_refcounts[81], {{g_bytes + 902, 12}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[81], {{g_bytes + 886, 18}}},
{{&grpc_static_metadata_refcounts[82], {{g_bytes + 914, 18}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[82], {{g_bytes + 904, 19}}},
{{&grpc_static_metadata_refcounts[83], {{g_bytes + 932, 19}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[83], {{g_bytes + 923, 5}}},
{{&grpc_static_metadata_refcounts[84], {{g_bytes + 951, 5}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[84], {{g_bytes + 928, 7}}},
{{&grpc_static_metadata_refcounts[85], {{g_bytes + 956, 7}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[85], {{g_bytes + 935, 7}}},
{{&grpc_static_metadata_refcounts[86], {{g_bytes + 963, 7}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[86], {{g_bytes + 942, 11}}},
{{&grpc_static_metadata_refcounts[87], {{g_bytes + 970, 11}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[87], {{g_bytes + 953, 6}}},
{{&grpc_static_metadata_refcounts[88], {{g_bytes + 981, 6}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[88], {{g_bytes + 959, 10}}},
{{&grpc_static_metadata_refcounts[89], {{g_bytes + 987, 10}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[89], {{g_bytes + 969, 25}}},
{{&grpc_static_metadata_refcounts[90], {{g_bytes + 997, 25}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[90], {{g_bytes + 994, 17}}},
{{&grpc_static_metadata_refcounts[91], {{g_bytes + 1022, 17}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[19], {{g_bytes + 268, 10}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[91], {{g_bytes + 1011, 4}}},
{{&grpc_static_metadata_refcounts[92], {{g_bytes + 1039, 4}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[92], {{g_bytes + 1015, 3}}},
{{&grpc_static_metadata_refcounts[93], {{g_bytes + 1043, 3}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[93], {{g_bytes + 1018, 16}}},
{{&grpc_static_metadata_refcounts[94], {{g_bytes + 1046, 16}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}},
{&grpc_static_metadata_refcounts[94], {{g_bytes + 1034, 1}}}},
{&grpc_static_metadata_refcounts[95], {{g_bytes + 1062, 1}}}},
{{&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}},
{&grpc_static_metadata_refcounts[25], {{g_bytes + 350, 1}}}},
{{&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}},
{&grpc_static_metadata_refcounts[26], {{g_bytes + 351, 1}}}},
{{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}},
{&grpc_static_metadata_refcounts[95], {{g_bytes + 1035, 8}}}},
{&grpc_static_metadata_refcounts[96], {{g_bytes + 1063, 8}}}},
{{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}},
{&grpc_static_metadata_refcounts[36], {{g_bytes + 489, 4}}}},
{&grpc_static_metadata_refcounts[37], {{g_bytes + 517, 4}}}},
{{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}},
{&grpc_static_metadata_refcounts[35], {{g_bytes + 482, 7}}}},
{&grpc_static_metadata_refcounts[36], {{g_bytes + 510, 7}}}},
{{&grpc_static_metadata_refcounts[5], {{g_bytes + 36, 2}}},
{&grpc_static_metadata_refcounts[96], {{g_bytes + 1043, 8}}}},
{&grpc_static_metadata_refcounts[97], {{g_bytes + 1071, 8}}}},
{{&grpc_static_metadata_refcounts[14], {{g_bytes + 158, 12}}},
{&grpc_static_metadata_refcounts[97], {{g_bytes + 1051, 16}}}},
{&grpc_static_metadata_refcounts[98], {{g_bytes + 1079, 16}}}},
{{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}},
{&grpc_static_metadata_refcounts[98], {{g_bytes + 1067, 4}}}},
{&grpc_static_metadata_refcounts[99], {{g_bytes + 1095, 4}}}},
{{&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}},
{&grpc_static_metadata_refcounts[99], {{g_bytes + 1071, 3}}}},
{&grpc_static_metadata_refcounts[100], {{g_bytes + 1099, 3}}}},
{{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[15], {{g_bytes + 170, 16}}},
{&grpc_static_metadata_refcounts[95], {{g_bytes + 1035, 8}}}},
{&grpc_static_metadata_refcounts[96], {{g_bytes + 1063, 8}}}},
{{&grpc_static_metadata_refcounts[15], {{g_bytes + 170, 16}}},
{&grpc_static_metadata_refcounts[36], {{g_bytes + 489, 4}}}},
{&grpc_static_metadata_refcounts[37], {{g_bytes + 517, 4}}}},
{{&grpc_static_metadata_refcounts[21], {{g_bytes + 282, 8}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[100], {{g_bytes + 1074, 11}}},
{{&grpc_static_metadata_refcounts[101], {{g_bytes + 1102, 11}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}},
{&grpc_static_metadata_refcounts[95], {{g_bytes + 1035, 8}}}},
{&grpc_static_metadata_refcounts[96], {{g_bytes + 1063, 8}}}},
{{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}},
{&grpc_static_metadata_refcounts[35], {{g_bytes + 482, 7}}}},
{&grpc_static_metadata_refcounts[36], {{g_bytes + 510, 7}}}},
{{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}},
{&grpc_static_metadata_refcounts[101], {{g_bytes + 1085, 16}}}},
{&grpc_static_metadata_refcounts[102], {{g_bytes + 1113, 16}}}},
{{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}},
{&grpc_static_metadata_refcounts[36], {{g_bytes + 489, 4}}}},
{&grpc_static_metadata_refcounts[37], {{g_bytes + 517, 4}}}},
{{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}},
{&grpc_static_metadata_refcounts[102], {{g_bytes + 1101, 13}}}},
{&grpc_static_metadata_refcounts[103], {{g_bytes + 1129, 13}}}},
{{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}},
{&grpc_static_metadata_refcounts[103], {{g_bytes + 1114, 12}}}},
{&grpc_static_metadata_refcounts[104], {{g_bytes + 1142, 12}}}},
{{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}},
{&grpc_static_metadata_refcounts[104], {{g_bytes + 1126, 21}}}},
{&grpc_static_metadata_refcounts[105], {{g_bytes + 1154, 21}}}},
{{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}},
{&grpc_static_metadata_refcounts[95], {{g_bytes + 1035, 8}}}},
{&grpc_static_metadata_refcounts[96], {{g_bytes + 1063, 8}}}},
{{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}},
{&grpc_static_metadata_refcounts[36], {{g_bytes + 489, 4}}}},
{&grpc_static_metadata_refcounts[37], {{g_bytes + 517, 4}}}},
{{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}},
{&grpc_static_metadata_refcounts[102], {{g_bytes + 1101, 13}}}},
{&grpc_static_metadata_refcounts[103], {{g_bytes + 1129, 13}}}},
};
const uint8_t grpc_static_accept_encoding_metadata[8] = {0, 76, 77, 78,
79, 80, 81, 82};

@ -31,7 +31,7 @@
#include "src/core/lib/transport/metadata.h"
#define GRPC_STATIC_MDSTR_COUNT 105
#define GRPC_STATIC_MDSTR_COUNT 106
extern const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT];
/* ":path" */
#define GRPC_MDSTR_PATH (grpc_static_slice_table[0])
@ -107,147 +107,150 @@ extern const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT];
/* "/grpc.lb.v1.LoadBalancer/BalanceLoad" */
#define GRPC_MDSTR_SLASH_GRPC_DOT_LB_DOT_V1_DOT_LOADBALANCER_SLASH_BALANCELOAD \
(grpc_static_slice_table[34])
/* "/grpc.health.v1.Health/Watch" */
#define GRPC_MDSTR_SLASH_GRPC_DOT_HEALTH_DOT_V1_DOT_HEALTH_SLASH_WATCH \
(grpc_static_slice_table[35])
/* "deflate" */
#define GRPC_MDSTR_DEFLATE (grpc_static_slice_table[35])
#define GRPC_MDSTR_DEFLATE (grpc_static_slice_table[36])
/* "gzip" */
#define GRPC_MDSTR_GZIP (grpc_static_slice_table[36])
#define GRPC_MDSTR_GZIP (grpc_static_slice_table[37])
/* "stream/gzip" */
#define GRPC_MDSTR_STREAM_SLASH_GZIP (grpc_static_slice_table[37])
#define GRPC_MDSTR_STREAM_SLASH_GZIP (grpc_static_slice_table[38])
/* "GET" */
#define GRPC_MDSTR_GET (grpc_static_slice_table[38])
#define GRPC_MDSTR_GET (grpc_static_slice_table[39])
/* "POST" */
#define GRPC_MDSTR_POST (grpc_static_slice_table[39])
#define GRPC_MDSTR_POST (grpc_static_slice_table[40])
/* "/" */
#define GRPC_MDSTR_SLASH (grpc_static_slice_table[40])
#define GRPC_MDSTR_SLASH (grpc_static_slice_table[41])
/* "/index.html" */
#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (grpc_static_slice_table[41])
#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (grpc_static_slice_table[42])
/* "http" */
#define GRPC_MDSTR_HTTP (grpc_static_slice_table[42])
#define GRPC_MDSTR_HTTP (grpc_static_slice_table[43])
/* "https" */
#define GRPC_MDSTR_HTTPS (grpc_static_slice_table[43])
#define GRPC_MDSTR_HTTPS (grpc_static_slice_table[44])
/* "200" */
#define GRPC_MDSTR_200 (grpc_static_slice_table[44])
#define GRPC_MDSTR_200 (grpc_static_slice_table[45])
/* "204" */
#define GRPC_MDSTR_204 (grpc_static_slice_table[45])
#define GRPC_MDSTR_204 (grpc_static_slice_table[46])
/* "206" */
#define GRPC_MDSTR_206 (grpc_static_slice_table[46])
#define GRPC_MDSTR_206 (grpc_static_slice_table[47])
/* "304" */
#define GRPC_MDSTR_304 (grpc_static_slice_table[47])
#define GRPC_MDSTR_304 (grpc_static_slice_table[48])
/* "400" */
#define GRPC_MDSTR_400 (grpc_static_slice_table[48])
#define GRPC_MDSTR_400 (grpc_static_slice_table[49])
/* "404" */
#define GRPC_MDSTR_404 (grpc_static_slice_table[49])
#define GRPC_MDSTR_404 (grpc_static_slice_table[50])
/* "500" */
#define GRPC_MDSTR_500 (grpc_static_slice_table[50])
#define GRPC_MDSTR_500 (grpc_static_slice_table[51])
/* "accept-charset" */
#define GRPC_MDSTR_ACCEPT_CHARSET (grpc_static_slice_table[51])
#define GRPC_MDSTR_ACCEPT_CHARSET (grpc_static_slice_table[52])
/* "gzip, deflate" */
#define GRPC_MDSTR_GZIP_COMMA_DEFLATE (grpc_static_slice_table[52])
#define GRPC_MDSTR_GZIP_COMMA_DEFLATE (grpc_static_slice_table[53])
/* "accept-language" */
#define GRPC_MDSTR_ACCEPT_LANGUAGE (grpc_static_slice_table[53])
#define GRPC_MDSTR_ACCEPT_LANGUAGE (grpc_static_slice_table[54])
/* "accept-ranges" */
#define GRPC_MDSTR_ACCEPT_RANGES (grpc_static_slice_table[54])
#define GRPC_MDSTR_ACCEPT_RANGES (grpc_static_slice_table[55])
/* "accept" */
#define GRPC_MDSTR_ACCEPT (grpc_static_slice_table[55])
#define GRPC_MDSTR_ACCEPT (grpc_static_slice_table[56])
/* "access-control-allow-origin" */
#define GRPC_MDSTR_ACCESS_CONTROL_ALLOW_ORIGIN (grpc_static_slice_table[56])
#define GRPC_MDSTR_ACCESS_CONTROL_ALLOW_ORIGIN (grpc_static_slice_table[57])
/* "age" */
#define GRPC_MDSTR_AGE (grpc_static_slice_table[57])
#define GRPC_MDSTR_AGE (grpc_static_slice_table[58])
/* "allow" */
#define GRPC_MDSTR_ALLOW (grpc_static_slice_table[58])
#define GRPC_MDSTR_ALLOW (grpc_static_slice_table[59])
/* "authorization" */
#define GRPC_MDSTR_AUTHORIZATION (grpc_static_slice_table[59])
#define GRPC_MDSTR_AUTHORIZATION (grpc_static_slice_table[60])
/* "cache-control" */
#define GRPC_MDSTR_CACHE_CONTROL (grpc_static_slice_table[60])
#define GRPC_MDSTR_CACHE_CONTROL (grpc_static_slice_table[61])
/* "content-disposition" */
#define GRPC_MDSTR_CONTENT_DISPOSITION (grpc_static_slice_table[61])
#define GRPC_MDSTR_CONTENT_DISPOSITION (grpc_static_slice_table[62])
/* "content-language" */
#define GRPC_MDSTR_CONTENT_LANGUAGE (grpc_static_slice_table[62])
#define GRPC_MDSTR_CONTENT_LANGUAGE (grpc_static_slice_table[63])
/* "content-length" */
#define GRPC_MDSTR_CONTENT_LENGTH (grpc_static_slice_table[63])
#define GRPC_MDSTR_CONTENT_LENGTH (grpc_static_slice_table[64])
/* "content-location" */
#define GRPC_MDSTR_CONTENT_LOCATION (grpc_static_slice_table[64])
#define GRPC_MDSTR_CONTENT_LOCATION (grpc_static_slice_table[65])
/* "content-range" */
#define GRPC_MDSTR_CONTENT_RANGE (grpc_static_slice_table[65])
#define GRPC_MDSTR_CONTENT_RANGE (grpc_static_slice_table[66])
/* "cookie" */
#define GRPC_MDSTR_COOKIE (grpc_static_slice_table[66])
#define GRPC_MDSTR_COOKIE (grpc_static_slice_table[67])
/* "date" */
#define GRPC_MDSTR_DATE (grpc_static_slice_table[67])
#define GRPC_MDSTR_DATE (grpc_static_slice_table[68])
/* "etag" */
#define GRPC_MDSTR_ETAG (grpc_static_slice_table[68])
#define GRPC_MDSTR_ETAG (grpc_static_slice_table[69])
/* "expect" */
#define GRPC_MDSTR_EXPECT (grpc_static_slice_table[69])
#define GRPC_MDSTR_EXPECT (grpc_static_slice_table[70])
/* "expires" */
#define GRPC_MDSTR_EXPIRES (grpc_static_slice_table[70])
#define GRPC_MDSTR_EXPIRES (grpc_static_slice_table[71])
/* "from" */
#define GRPC_MDSTR_FROM (grpc_static_slice_table[71])
#define GRPC_MDSTR_FROM (grpc_static_slice_table[72])
/* "if-match" */
#define GRPC_MDSTR_IF_MATCH (grpc_static_slice_table[72])
#define GRPC_MDSTR_IF_MATCH (grpc_static_slice_table[73])
/* "if-modified-since" */
#define GRPC_MDSTR_IF_MODIFIED_SINCE (grpc_static_slice_table[73])
#define GRPC_MDSTR_IF_MODIFIED_SINCE (grpc_static_slice_table[74])
/* "if-none-match" */
#define GRPC_MDSTR_IF_NONE_MATCH (grpc_static_slice_table[74])
#define GRPC_MDSTR_IF_NONE_MATCH (grpc_static_slice_table[75])
/* "if-range" */
#define GRPC_MDSTR_IF_RANGE (grpc_static_slice_table[75])
#define GRPC_MDSTR_IF_RANGE (grpc_static_slice_table[76])
/* "if-unmodified-since" */
#define GRPC_MDSTR_IF_UNMODIFIED_SINCE (grpc_static_slice_table[76])
#define GRPC_MDSTR_IF_UNMODIFIED_SINCE (grpc_static_slice_table[77])
/* "last-modified" */
#define GRPC_MDSTR_LAST_MODIFIED (grpc_static_slice_table[77])
#define GRPC_MDSTR_LAST_MODIFIED (grpc_static_slice_table[78])
/* "link" */
#define GRPC_MDSTR_LINK (grpc_static_slice_table[78])
#define GRPC_MDSTR_LINK (grpc_static_slice_table[79])
/* "location" */
#define GRPC_MDSTR_LOCATION (grpc_static_slice_table[79])
#define GRPC_MDSTR_LOCATION (grpc_static_slice_table[80])
/* "max-forwards" */
#define GRPC_MDSTR_MAX_FORWARDS (grpc_static_slice_table[80])
#define GRPC_MDSTR_MAX_FORWARDS (grpc_static_slice_table[81])
/* "proxy-authenticate" */
#define GRPC_MDSTR_PROXY_AUTHENTICATE (grpc_static_slice_table[81])
#define GRPC_MDSTR_PROXY_AUTHENTICATE (grpc_static_slice_table[82])
/* "proxy-authorization" */
#define GRPC_MDSTR_PROXY_AUTHORIZATION (grpc_static_slice_table[82])
#define GRPC_MDSTR_PROXY_AUTHORIZATION (grpc_static_slice_table[83])
/* "range" */
#define GRPC_MDSTR_RANGE (grpc_static_slice_table[83])
#define GRPC_MDSTR_RANGE (grpc_static_slice_table[84])
/* "referer" */
#define GRPC_MDSTR_REFERER (grpc_static_slice_table[84])
#define GRPC_MDSTR_REFERER (grpc_static_slice_table[85])
/* "refresh" */
#define GRPC_MDSTR_REFRESH (grpc_static_slice_table[85])
#define GRPC_MDSTR_REFRESH (grpc_static_slice_table[86])
/* "retry-after" */
#define GRPC_MDSTR_RETRY_AFTER (grpc_static_slice_table[86])
#define GRPC_MDSTR_RETRY_AFTER (grpc_static_slice_table[87])
/* "server" */
#define GRPC_MDSTR_SERVER (grpc_static_slice_table[87])
#define GRPC_MDSTR_SERVER (grpc_static_slice_table[88])
/* "set-cookie" */
#define GRPC_MDSTR_SET_COOKIE (grpc_static_slice_table[88])
#define GRPC_MDSTR_SET_COOKIE (grpc_static_slice_table[89])
/* "strict-transport-security" */
#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (grpc_static_slice_table[89])
#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (grpc_static_slice_table[90])
/* "transfer-encoding" */
#define GRPC_MDSTR_TRANSFER_ENCODING (grpc_static_slice_table[90])
#define GRPC_MDSTR_TRANSFER_ENCODING (grpc_static_slice_table[91])
/* "vary" */
#define GRPC_MDSTR_VARY (grpc_static_slice_table[91])
#define GRPC_MDSTR_VARY (grpc_static_slice_table[92])
/* "via" */
#define GRPC_MDSTR_VIA (grpc_static_slice_table[92])
#define GRPC_MDSTR_VIA (grpc_static_slice_table[93])
/* "www-authenticate" */
#define GRPC_MDSTR_WWW_AUTHENTICATE (grpc_static_slice_table[93])
#define GRPC_MDSTR_WWW_AUTHENTICATE (grpc_static_slice_table[94])
/* "0" */
#define GRPC_MDSTR_0 (grpc_static_slice_table[94])
#define GRPC_MDSTR_0 (grpc_static_slice_table[95])
/* "identity" */
#define GRPC_MDSTR_IDENTITY (grpc_static_slice_table[95])
#define GRPC_MDSTR_IDENTITY (grpc_static_slice_table[96])
/* "trailers" */
#define GRPC_MDSTR_TRAILERS (grpc_static_slice_table[96])
#define GRPC_MDSTR_TRAILERS (grpc_static_slice_table[97])
/* "application/grpc" */
#define GRPC_MDSTR_APPLICATION_SLASH_GRPC (grpc_static_slice_table[97])
#define GRPC_MDSTR_APPLICATION_SLASH_GRPC (grpc_static_slice_table[98])
/* "grpc" */
#define GRPC_MDSTR_GRPC (grpc_static_slice_table[98])
#define GRPC_MDSTR_GRPC (grpc_static_slice_table[99])
/* "PUT" */
#define GRPC_MDSTR_PUT (grpc_static_slice_table[99])
#define GRPC_MDSTR_PUT (grpc_static_slice_table[100])
/* "lb-cost-bin" */
#define GRPC_MDSTR_LB_COST_BIN (grpc_static_slice_table[100])
#define GRPC_MDSTR_LB_COST_BIN (grpc_static_slice_table[101])
/* "identity,deflate" */
#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE (grpc_static_slice_table[101])
#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE (grpc_static_slice_table[102])
/* "identity,gzip" */
#define GRPC_MDSTR_IDENTITY_COMMA_GZIP (grpc_static_slice_table[102])
#define GRPC_MDSTR_IDENTITY_COMMA_GZIP (grpc_static_slice_table[103])
/* "deflate,gzip" */
#define GRPC_MDSTR_DEFLATE_COMMA_GZIP (grpc_static_slice_table[103])
#define GRPC_MDSTR_DEFLATE_COMMA_GZIP (grpc_static_slice_table[104])
/* "identity,deflate,gzip" */
#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE_COMMA_GZIP \
(grpc_static_slice_table[104])
(grpc_static_slice_table[105])
extern const grpc_slice_refcount_vtable grpc_static_metadata_vtable;
extern grpc_slice_refcount

@ -26,8 +26,8 @@
#include "pb_decode.h"
#include "pb_encode.h"
#include "src/core/ext/filters/client_channel/health/health.pb.h"
#include "src/cpp/server/health/default_health_check_service.h"
#include "src/cpp/server/health/health.pb.h"
namespace grpc {
@ -78,12 +78,12 @@ void DefaultHealthCheckService::RegisterCallHandler(
void DefaultHealthCheckService::UnregisterCallHandler(
const grpc::string& service_name,
std::shared_ptr<HealthCheckServiceImpl::CallHandler> handler) {
const std::shared_ptr<HealthCheckServiceImpl::CallHandler>& handler) {
std::unique_lock<std::mutex> lock(mu_);
auto it = services_map_.find(service_name);
if (it == services_map_.end()) return;
ServiceData& service_data = it->second;
service_data.RemoveCallHandler(std::move(handler));
service_data.RemoveCallHandler(handler);
if (service_data.Unused()) {
services_map_.erase(it);
}
@ -115,7 +115,7 @@ void DefaultHealthCheckService::ServiceData::AddCallHandler(
}
void DefaultHealthCheckService::ServiceData::RemoveCallHandler(
std::shared_ptr<HealthCheckServiceImpl::CallHandler> handler) {
const std::shared_ptr<HealthCheckServiceImpl::CallHandler>& handler) {
call_handlers_.erase(handler);
}
@ -184,16 +184,13 @@ bool DefaultHealthCheckService::HealthCheckServiceImpl::DecodeRequest(
std::vector<Slice> slices;
if (!request.Dump(&slices).ok()) return false;
uint8_t* request_bytes = nullptr;
bool request_bytes_owned = false;
size_t request_size = 0;
grpc_health_v1_HealthCheckRequest request_struct;
if (slices.empty()) {
request_struct.has_service = false;
} else if (slices.size() == 1) {
request_struct.has_service = false;
if (slices.size() == 1) {
request_bytes = const_cast<uint8_t*>(slices[0].begin());
request_size = slices[0].size();
} else {
request_bytes_owned = true;
} else if (slices.size() > 1) {
request_bytes = static_cast<uint8_t*>(gpr_malloc(request.Length()));
uint8_t* copy_to = request_bytes;
for (size_t i = 0; i < slices.size(); i++) {
@ -201,15 +198,13 @@ bool DefaultHealthCheckService::HealthCheckServiceImpl::DecodeRequest(
copy_to += slices[i].size();
}
}
if (request_bytes != nullptr) {
pb_istream_t istream = pb_istream_from_buffer(request_bytes, request_size);
bool decode_status = pb_decode(
&istream, grpc_health_v1_HealthCheckRequest_fields, &request_struct);
if (request_bytes_owned) {
gpr_free(request_bytes);
}
if (!decode_status) return false;
pb_istream_t istream = pb_istream_from_buffer(request_bytes, request_size);
bool decode_status = pb_decode(
&istream, grpc_health_v1_HealthCheckRequest_fields, &request_struct);
if (slices.size() > 1) {
gpr_free(request_bytes);
}
if (!decode_status) return false;
*service_name = request_struct.has_service ? request_struct.service : "";
return true;
}
@ -318,6 +313,7 @@ void DefaultHealthCheckService::HealthCheckServiceImpl::CheckCallHandler::
gpr_log(GPR_DEBUG, "[HCS %p] Health check call finished for handler %p",
service_, this);
}
self.reset(); // To appease clang-tidy.
}
//
@ -442,7 +438,7 @@ void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler::
SendFinish(std::shared_ptr<CallHandler> self, const Status& status) {
if (finish_called_) return;
std::unique_lock<std::mutex> cq_lock(service_->cq_shutdown_mu_);
if (!service_->shutdown_) return;
if (service_->shutdown_) return;
SendFinishLocked(std::move(self), status);
}
@ -464,6 +460,7 @@ void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler::
"handler: %p).",
service_, service_name_.c_str(), this);
}
self.reset(); // To appease clang-tidy.
}
// TODO(roth): This method currently assumes that there will be only one
@ -473,9 +470,10 @@ void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler::
OnDoneNotified(std::shared_ptr<CallHandler> self, bool ok) {
GPR_ASSERT(ok);
gpr_log(GPR_DEBUG,
"[HCS %p] Healt watch call is notified done (handler: %p, "
"[HCS %p] Health watch call is notified done (handler: %p, "
"is_cancelled: %d).",
service_, this, static_cast<int>(ctx_.IsCancelled()));
database_->UnregisterCallHandler(service_name_, self);
SendFinish(std::move(self), Status::CANCELLED);
}

@ -252,7 +252,7 @@ class DefaultHealthCheckService final : public HealthCheckServiceInterface {
void AddCallHandler(
std::shared_ptr<HealthCheckServiceImpl::CallHandler> handler);
void RemoveCallHandler(
std::shared_ptr<HealthCheckServiceImpl::CallHandler> handler);
const std::shared_ptr<HealthCheckServiceImpl::CallHandler>& handler);
bool Unused() const {
return call_handlers_.empty() && status_ == NOT_FOUND;
}
@ -269,7 +269,7 @@ class DefaultHealthCheckService final : public HealthCheckServiceInterface {
void UnregisterCallHandler(
const grpc::string& service_name,
std::shared_ptr<HealthCheckServiceImpl::CallHandler> handler);
const std::shared_ptr<HealthCheckServiceImpl::CallHandler>& handler);
mutable std::mutex mu_;
std::map<grpc::string, ServiceData> services_map_; // Guarded by mu_.

@ -313,6 +313,7 @@ CORE_SOURCE_FILES = [
'src/core/ext/filters/client_channel/client_channel_factory.cc',
'src/core/ext/filters/client_channel/client_channel_plugin.cc',
'src/core/ext/filters/client_channel/connector.cc',
'src/core/ext/filters/client_channel/health/health_check_client.cc',
'src/core/ext/filters/client_channel/http_connect_handshaker.cc',
'src/core/ext/filters/client_channel/http_proxy.cc',
'src/core/ext/filters/client_channel/lb_policy.cc',
@ -329,6 +330,7 @@ CORE_SOURCE_FILES = [
'src/core/ext/filters/client_channel/subchannel_index.cc',
'src/core/ext/filters/client_channel/uri_parser.cc',
'src/core/ext/filters/deadline/deadline_filter.cc',
'src/core/ext/filters/client_channel/health/health.pb.c',
'src/core/tsi/alts_transport_security.cc',
'src/core/tsi/fake_transport_security.cc',
'src/core/tsi/local_transport_security.cc',

@ -34,6 +34,7 @@
"\x1Egrpc.max_request_message_bytes"
"\x1Fgrpc.max_response_message_bytes"
"$/grpc.lb.v1.LoadBalancer/BalanceLoad"
"\x1C/grpc.health.v1.Health/Watch"
"\x07deflate"
"\x04gzip"
"\x0Bstream/gzip"

@ -31,6 +31,7 @@
#include <grpcpp/channel.h>
#include <grpcpp/client_context.h>
#include <grpcpp/create_channel.h>
#include <grpcpp/health_check_service_interface.h>
#include <grpcpp/server.h>
#include <grpcpp/server_builder.h>
@ -289,6 +290,10 @@ class ClientLbEnd2endTest : public ::testing::Test {
server_->Shutdown(grpc_timeout_milliseconds_to_deadline(0));
if (join) thread_->join();
}
void SetServingStatus(const grpc::string& service, bool serving) {
server_->GetHealthCheckService()->SetServingStatus(service, serving);
}
};
void ResetCounters() {
@ -320,6 +325,17 @@ class ClientLbEnd2endTest : public ::testing::Test {
return true;
}
bool WaitForChannelReady(Channel* channel, int timeout_seconds = 5) {
const gpr_timespec deadline =
grpc_timeout_seconds_to_deadline(timeout_seconds);
grpc_connectivity_state state;
while ((state = channel->GetState(true /* try_to_connect */)) !=
GRPC_CHANNEL_READY) {
if (!channel->WaitForStateChange(state, deadline)) return false;
}
return true;
}
bool SeenAllServers() {
for (const auto& server : servers_) {
if (server->service_.request_count() == 0) return false;
@ -359,11 +375,7 @@ TEST_F(ClientLbEnd2endTest, PickFirst) {
StartServers(kNumServers);
auto channel = BuildChannel(""); // test that pick first is the default.
auto stub = BuildStub(channel);
std::vector<int> ports;
for (size_t i = 0; i < servers_.size(); ++i) {
ports.emplace_back(servers_[i]->port_);
}
SetNextResolution(ports);
SetNextResolution(GetServersPorts());
for (size_t i = 0; i < servers_.size(); ++i) {
CheckRpcSendOk(stub, DEBUG_LOCATION);
}
@ -586,10 +598,7 @@ TEST_P(ClientLbEnd2endWithParamTest, PickFirstManyUpdates) {
StartServers(kNumServers);
auto channel = BuildChannel("pick_first");
auto stub = BuildStub(channel);
std::vector<int> ports;
for (size_t i = 0; i < servers_.size(); ++i) {
ports.emplace_back(servers_[i]->port_);
}
std::vector<int> ports = GetServersPorts();
for (size_t i = 0; i < 1000; ++i) {
std::shuffle(ports.begin(), ports.end(),
std::mt19937(std::random_device()()));
@ -719,11 +728,7 @@ TEST_F(ClientLbEnd2endTest, RoundRobin) {
StartServers(kNumServers);
auto channel = BuildChannel("round_robin");
auto stub = BuildStub(channel);
std::vector<int> ports;
for (const auto& server : servers_) {
ports.emplace_back(server->port_);
}
SetNextResolution(ports);
SetNextResolution(GetServersPorts());
// Wait until all backends are ready.
do {
CheckRpcSendOk(stub, DEBUG_LOCATION);
@ -885,10 +890,7 @@ TEST_F(ClientLbEnd2endTest, RoundRobinManyUpdates) {
StartServers(kNumServers);
auto channel = BuildChannel("round_robin");
auto stub = BuildStub(channel);
std::vector<int> ports;
for (size_t i = 0; i < servers_.size(); ++i) {
ports.emplace_back(servers_[i]->port_);
}
std::vector<int> ports = GetServersPorts();
for (size_t i = 0; i < 1000; ++i) {
std::shuffle(ports.begin(), ports.end(),
std::mt19937(std::random_device()()));
@ -998,6 +1000,125 @@ TEST_F(ClientLbEnd2endTest, RoundRobinSingleReconnect) {
WaitForServer(stub, 0, DEBUG_LOCATION);
}
// If health checking is required by client but health checking service
// is not running on the server, the channel should be treated as healthy.
TEST_F(ClientLbEnd2endTest,
RoundRobinServersHealthCheckingUnimplementedTreatedAsHealthy) {
StartServers(1); // Single server
ChannelArguments args;
args.SetServiceConfigJSON(
"{\"healthCheckConfig\": "
"{\"serviceName\": \"health_check_service_name\"}}");
auto channel = BuildChannel("round_robin", args);
auto stub = BuildStub(channel);
SetNextResolution({servers_[0]->port_});
EXPECT_TRUE(WaitForChannelReady(channel.get()));
CheckRpcSendOk(stub, DEBUG_LOCATION);
}
TEST_F(ClientLbEnd2endTest, RoundRobinWithHealthChecking) {
EnableDefaultHealthCheckService(true);
// Start servers.
const int kNumServers = 3;
StartServers(kNumServers);
ChannelArguments args;
args.SetServiceConfigJSON(
"{\"healthCheckConfig\": "
"{\"serviceName\": \"health_check_service_name\"}}");
auto channel = BuildChannel("round_robin", args);
auto stub = BuildStub(channel);
SetNextResolution(GetServersPorts());
// Channel should not become READY, because health checks should be failing.
gpr_log(GPR_INFO,
"*** initial state: unknown health check service name for "
"all servers");
EXPECT_FALSE(WaitForChannelReady(channel.get(), 1));
// Now set one of the servers to be healthy.
// The channel should become healthy and all requests should go to
// the healthy server.
gpr_log(GPR_INFO, "*** server 0 healthy");
servers_[0]->SetServingStatus("health_check_service_name", true);
EXPECT_TRUE(WaitForChannelReady(channel.get()));
for (int i = 0; i < 10; ++i) {
CheckRpcSendOk(stub, DEBUG_LOCATION);
}
EXPECT_EQ(10, servers_[0]->service_.request_count());
EXPECT_EQ(0, servers_[1]->service_.request_count());
EXPECT_EQ(0, servers_[2]->service_.request_count());
// Now set a second server to be healthy.
gpr_log(GPR_INFO, "*** server 2 healthy");
servers_[2]->SetServingStatus("health_check_service_name", true);
WaitForServer(stub, 2, DEBUG_LOCATION);
for (int i = 0; i < 10; ++i) {
CheckRpcSendOk(stub, DEBUG_LOCATION);
}
EXPECT_EQ(5, servers_[0]->service_.request_count());
EXPECT_EQ(0, servers_[1]->service_.request_count());
EXPECT_EQ(5, servers_[2]->service_.request_count());
// Now set the remaining server to be healthy.
gpr_log(GPR_INFO, "*** server 1 healthy");
servers_[1]->SetServingStatus("health_check_service_name", true);
WaitForServer(stub, 1, DEBUG_LOCATION);
for (int i = 0; i < 9; ++i) {
CheckRpcSendOk(stub, DEBUG_LOCATION);
}
EXPECT_EQ(3, servers_[0]->service_.request_count());
EXPECT_EQ(3, servers_[1]->service_.request_count());
EXPECT_EQ(3, servers_[2]->service_.request_count());
// Now set one server to be unhealthy again. Then wait until the
// unhealthiness has hit the client. We know that the client will see
// this when we send kNumServers requests and one of the remaining servers
// sees two of the requests.
gpr_log(GPR_INFO, "*** server 0 unhealthy");
servers_[0]->SetServingStatus("health_check_service_name", false);
do {
ResetCounters();
for (int i = 0; i < kNumServers; ++i) {
CheckRpcSendOk(stub, DEBUG_LOCATION);
}
} while (servers_[1]->service_.request_count() != 2 &&
servers_[2]->service_.request_count() != 2);
// Now set the remaining two servers to be unhealthy. Make sure the
// channel leaves READY state and that RPCs fail.
gpr_log(GPR_INFO, "*** all servers unhealthy");
servers_[1]->SetServingStatus("health_check_service_name", false);
servers_[2]->SetServingStatus("health_check_service_name", false);
EXPECT_TRUE(WaitForChannelNotReady(channel.get()));
CheckRpcSendFailure(stub);
// Clean up.
EnableDefaultHealthCheckService(false);
}
TEST_F(ClientLbEnd2endTest, RoundRobinWithHealthCheckingInhibitPerChannel) {
EnableDefaultHealthCheckService(true);
// Start server.
const int kNumServers = 1;
StartServers(kNumServers);
// Create a channel with health-checking enabled.
ChannelArguments args;
args.SetServiceConfigJSON(
"{\"healthCheckConfig\": "
"{\"serviceName\": \"health_check_service_name\"}}");
auto channel1 = BuildChannel("round_robin", args);
auto stub1 = BuildStub(channel1);
std::vector<int> ports = GetServersPorts();
SetNextResolution(ports);
// Create a channel with health checking enabled but inhibited.
args.SetInt(GRPC_ARG_INHIBIT_HEALTH_CHECKING, 1);
auto channel2 = BuildChannel("round_robin", args);
auto stub2 = BuildStub(channel2);
SetNextResolution(ports);
// First channel should not become READY, because health checks should be
// failing.
EXPECT_FALSE(WaitForChannelReady(channel1.get(), 1));
CheckRpcSendFailure(stub1);
// Second channel should be READY.
EXPECT_TRUE(WaitForChannelReady(channel2.get(), 1));
CheckRpcSendOk(stub2, DEBUG_LOCATION);
// Clean up.
EnableDefaultHealthCheckService(false);
}
} // namespace
} // namespace testing
} // namespace grpc

@ -63,6 +63,7 @@ CONFIG = [
'grpc.max_response_message_bytes',
# well known method names
'/grpc.lb.v1.LoadBalancer/BalanceLoad',
'/grpc.health.v1.Health/Watch',
# compression algorithm names
'deflate',
'gzip',

@ -75,6 +75,8 @@ _EXEMPT = frozenset((
'examples/python/multiplex/route_guide_pb2_grpc.py',
'examples/python/route_guide/route_guide_pb2.py',
'examples/python/route_guide/route_guide_pb2_grpc.py',
'src/core/ext/filters/client_channel/health/health.pb.h',
'src/core/ext/filters/client_channel/health/health.pb.c',
'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h',
'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c',
'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h',
@ -87,8 +89,6 @@ _EXEMPT = frozenset((
'src/core/tsi/alts/handshaker/handshaker.pb.c',
'src/core/tsi/alts/handshaker/transport_security_common.pb.h',
'src/core/tsi/alts/handshaker/transport_security_common.pb.c',
'src/cpp/server/health/health.pb.h',
'src/cpp/server/health/health.pb.c',
# An older file originally from outside gRPC.
'src/php/tests/bootstrap.php',

@ -156,6 +156,7 @@ argp.add_argument('--precommit', default=False, action='store_true')
args = argp.parse_args()
KNOWN_BAD = set([
'src/core/ext/filters/client_channel/health/health.pb.h',
'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h',
'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h',
'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h',

@ -71,7 +71,7 @@ fi
#
# checks for health.proto
#
readonly HEALTH_GRPC_OUTPUT_PATH='src/cpp/server/health'
readonly HEALTH_GRPC_OUTPUT_PATH='src/core/ext/filters/client_channel/health'
# nanopb-compile the proto to a temp location
./tools/codegen/core/gen_nano_proto.sh \
src/proto/grpc/health/v1/health.proto \
@ -79,7 +79,7 @@ readonly HEALTH_GRPC_OUTPUT_PATH='src/cpp/server/health'
"$HEALTH_GRPC_OUTPUT_PATH"
# compare outputs to checked compiled code
for NANOPB_OUTPUT_FILE in $NANOPB_HEALTH_TMP_OUTPUT/*.pb.*; do
if ! diff "$NANOPB_OUTPUT_FILE" "src/cpp/server/health/$(basename $NANOPB_OUTPUT_FILE)"; then
if ! diff "$NANOPB_OUTPUT_FILE" "${HEALTH_GRPC_OUTPUT_PATH}/$(basename $NANOPB_OUTPUT_FILE)"; then
echo "Outputs differ: $NANOPB_HEALTH_TMP_OUTPUT vs $HEALTH_GRPC_OUTPUT_PATH"
exit 2
fi

@ -1012,6 +1012,8 @@ include/grpcpp/support/string_ref.h \
include/grpcpp/support/stub_options.h \
include/grpcpp/support/sync_stream.h \
include/grpcpp/support/time.h \
src/core/ext/filters/client_channel/health/health.pb.c \
src/core/ext/filters/client_channel/health/health.pb.h \
src/core/ext/transport/inproc/inproc_transport.h \
src/core/lib/avl/avl.h \
src/core/lib/backoff/backoff.h \
@ -1208,8 +1210,6 @@ src/cpp/server/dynamic_thread_pool.cc \
src/cpp/server/dynamic_thread_pool.h \
src/cpp/server/health/default_health_check_service.cc \
src/cpp/server/health/default_health_check_service.h \
src/cpp/server/health/health.pb.c \
src/cpp/server/health/health.pb.h \
src/cpp/server/health/health_check_service.cc \
src/cpp/server/health/health_check_service_server_builder_option.cc \
src/cpp/server/insecure_server_credentials.cc \
@ -1228,8 +1228,11 @@ src/cpp/util/status.cc \
src/cpp/util/string_ref.cc \
src/cpp/util/time_cc.cc \
third_party/nanopb/pb.h \
third_party/nanopb/pb_common.c \
third_party/nanopb/pb_common.h \
third_party/nanopb/pb_decode.c \
third_party/nanopb/pb_decode.h \
third_party/nanopb/pb_encode.c \
third_party/nanopb/pb_encode.h
# This tag can be used to specify the character encoding of the source files

@ -885,6 +885,10 @@ src/core/ext/filters/client_channel/client_channel_factory.h \
src/core/ext/filters/client_channel/client_channel_plugin.cc \
src/core/ext/filters/client_channel/connector.cc \
src/core/ext/filters/client_channel/connector.h \
src/core/ext/filters/client_channel/health/health.pb.c \
src/core/ext/filters/client_channel/health/health.pb.h \
src/core/ext/filters/client_channel/health/health_check_client.cc \
src/core/ext/filters/client_channel/health/health_check_client.h \
src/core/ext/filters/client_channel/http_connect_handshaker.cc \
src/core/ext/filters/client_channel/http_connect_handshaker.h \
src/core/ext/filters/client_channel/http_proxy.cc \

@ -9984,7 +9984,8 @@
"deps": [
"gpr",
"grpc_base",
"grpc_deadline_filter"
"grpc_deadline_filter",
"health_proto"
],
"headers": [
"src/core/ext/filters/client_channel/backup_poller.h",
@ -9992,6 +9993,7 @@
"src/core/ext/filters/client_channel/client_channel_channelz.h",
"src/core/ext/filters/client_channel/client_channel_factory.h",
"src/core/ext/filters/client_channel/connector.h",
"src/core/ext/filters/client_channel/health/health_check_client.h",
"src/core/ext/filters/client_channel/http_connect_handshaker.h",
"src/core/ext/filters/client_channel/http_proxy.h",
"src/core/ext/filters/client_channel/lb_policy.h",
@ -10025,6 +10027,8 @@
"src/core/ext/filters/client_channel/client_channel_plugin.cc",
"src/core/ext/filters/client_channel/connector.cc",
"src/core/ext/filters/client_channel/connector.h",
"src/core/ext/filters/client_channel/health/health_check_client.cc",
"src/core/ext/filters/client_channel/health/health_check_client.h",
"src/core/ext/filters/client_channel/http_connect_handshaker.cc",
"src/core/ext/filters/client_channel/http_connect_handshaker.h",
"src/core/ext/filters/client_channel/http_proxy.cc",
@ -10995,6 +10999,23 @@
"third_party": false,
"type": "filegroup"
},
{
"deps": [
"nanopb"
],
"headers": [
"src/core/ext/filters/client_channel/health/health.pb.h"
],
"is_filegroup": true,
"language": "c",
"name": "health_proto",
"src": [
"src/core/ext/filters/client_channel/health/health.pb.c",
"src/core/ext/filters/client_channel/health/health.pb.h"
],
"third_party": false,
"type": "filegroup"
},
{
"deps": [
"nanopb_headers"
@ -11289,6 +11310,7 @@
"grpc++_codegen_base",
"grpc_base_headers",
"grpc_transport_inproc_headers",
"health_proto",
"nanopb_headers"
],
"headers": [
@ -11389,7 +11411,6 @@
"src/cpp/common/channel_filter.h",
"src/cpp/server/dynamic_thread_pool.h",
"src/cpp/server/health/default_health_check_service.h",
"src/cpp/server/health/health.pb.h",
"src/cpp/server/thread_pool_interface.h",
"src/cpp/thread_manager/thread_manager.h"
],
@ -11514,8 +11535,6 @@
"src/cpp/server/dynamic_thread_pool.h",
"src/cpp/server/health/default_health_check_service.cc",
"src/cpp/server/health/default_health_check_service.h",
"src/cpp/server/health/health.pb.c",
"src/cpp/server/health/health.pb.h",
"src/cpp/server/health/health_check_service.cc",
"src/cpp/server/health/health_check_service_server_builder_option.cc",
"src/cpp/server/server_builder.cc",

Loading…
Cancel
Save