Merge branch 'master' into darwin-zlib-implicit-declaration

pull/24979/head
Masaki Hara 4 years ago
commit 6d6c5ca009
  1. 4
      .bazelignore
  2. 2
      .github/ISSUE_TEMPLATE/bug_report.md
  3. 2
      .github/ISSUE_TEMPLATE/cleanup_request.md
  4. 2
      .github/ISSUE_TEMPLATE/feature_request.md
  5. 2
      .github/ISSUE_TEMPLATE/question.md
  6. 2
      .github/pull_request_template.md
  7. 61
      BUILD
  8. 10
      BUILD.gn
  9. 100
      CMakeLists.txt
  10. 54
      Makefile
  11. 14
      Rakefile
  12. 13
      bazel/grpc_deps.bzl
  13. 4
      bazel/grpc_extra_deps.bzl
  14. 4
      bazel/update_mirror.sh
  15. 42
      build_autogenerated.yaml
  16. 2
      build_config.rb
  17. 6
      build_handwritten.yaml
  18. 10
      config.m4
  19. 10
      config.w32
  20. 2
      doc/environment_variables.md
  21. 3
      doc/g_stands_for.md
  22. 8
      doc/grpc_xds_features.md
  23. 252
      examples/BUILD
  24. 35
      examples/cpp/compression/BUILD
  25. 66
      examples/cpp/helloworld/BUILD
  26. 38
      examples/cpp/keyvaluestore/BUILD
  27. 35
      examples/cpp/load_balancing/BUILD
  28. 35
      examples/cpp/metadata/BUILD
  29. 56
      examples/cpp/route_guide/BUILD
  30. 62
      examples/node/xds/greeter_client.js
  31. 10
      examples/node/xds/package.json
  32. 12
      examples/objective-c/BUILD
  33. 2
      examples/objective-c/helloworld/README.md
  34. 83
      examples/protos/BUILD
  35. 50
      examples/python/async_streaming/README.md
  36. 119
      examples/python/async_streaming/client.py
  37. 52
      examples/python/async_streaming/phone.proto
  38. 267
      examples/python/async_streaming/phone_pb2.py
  39. 65
      examples/python/async_streaming/phone_pb2_grpc.py
  40. 92
      examples/python/async_streaming/server.py
  41. 8
      examples/python/compression/BUILD.bazel
  42. 4
      examples/python/compression/client.py
  43. 4
      examples/python/compression/server.py
  44. 59
      examples/python/debug/BUILD.bazel
  45. 83
      examples/python/debug/asyncio_debug_server.py
  46. 46
      examples/python/debug/asyncio_get_stats.py
  47. 61
      examples/python/debug/asyncio_send_message.py
  48. 8
      examples/python/debug/debug_server.py
  49. 8
      examples/python/debug/get_stats.py
  50. 1
      examples/python/debug/helloworld.proto
  51. 5
      examples/python/debug/send_message.py
  52. 26
      examples/python/debug/test/_debug_example_test.py
  53. 8
      examples/python/errors/BUILD.bazel
  54. 4
      examples/python/errors/client.py
  55. 4
      examples/python/errors/server.py
  56. 2
      examples/python/errors/test/_error_handling_example_test.py
  57. 129
      examples/python/route_guide/asyncio_route_guide_client.py
  58. 134
      examples/python/route_guide/asyncio_route_guide_server.py
  59. 28
      examples/python/wait_for_ready/BUILD.bazel
  60. 109
      examples/python/wait_for_ready/asyncio_wait_for_ready_example.py
  61. 1
      examples/python/wait_for_ready/helloworld.proto
  62. 9
      examples/python/wait_for_ready/test/_wait_for_ready_example_test.py
  63. 5
      examples/python/wait_for_ready/wait_for_ready_example.py
  64. 28
      gRPC-C++.podspec
  65. 35
      gRPC-Core.podspec
  66. 2
      gRPC-ProtoRPC.podspec
  67. 2
      gRPC-RxLibrary.podspec
  68. 2
      gRPC.podspec
  69. 4
      grpc.def
  70. 19
      grpc.gemspec
  71. 19
      grpc.gyp
  72. 14
      include/grpc/grpc.h
  73. 35
      include/grpc/grpc_security.h
  74. 1
      include/grpcpp/impl/codegen/config_protobuf.h
  75. 6
      include/grpcpp/security/credentials.h
  76. 38
      include/grpcpp/security/tls_credentials_options.h
  77. 1
      include/grpcpp/server.h
  78. 6
      include/grpcpp/server_builder.h
  79. 43
      include/grpcpp/xds_server_builder.h
  80. 25
      package.xml
  81. 6
      src/core/ext/filters/client_channel/backend_metric.cc
  82. 3483
      src/core/ext/filters/client_channel/client_channel.cc
  83. 4
      src/core/ext/filters/client_channel/config_selector.h
  84. 186
      src/core/ext/filters/client_channel/dynamic_filters.cc
  85. 99
      src/core/ext/filters/client_channel/dynamic_filters.h
  86. 12
      src/core/ext/filters/client_channel/health/health_check_client.cc
  87. 4
      src/core/ext/filters/client_channel/health/health_check_client.h
  88. 5
      src/core/ext/filters/client_channel/lb_policy.h
  89. 25
      src/core/ext/filters/client_channel/lb_policy/xds/cds.cc
  90. 908
      src/core/ext/filters/client_channel/lb_policy/xds/eds.cc
  91. 8
      src/core/ext/filters/client_channel/lb_policy/xds/xds.h
  92. 24
      src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_args.h
  93. 7
      src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc
  94. 1262
      src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc
  95. 485
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc
  96. 33
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h
  97. 464
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc
  98. 5
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h
  99. 68
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc
  100. 24
      src/core/ext/filters/client_channel/resolver_result_parsing.cc
  101. Some files were not shown because too many files have changed in this diff Show More

@ -7,6 +7,10 @@ libs
objs
third_party/abseil-cpp
third_party/bloaty
third_party/boringssl-with-bazel
third_party/googleapis
third_party/googletest
third_party/protobuf
third_party/protoc-gen-validate
third_party/udpa
third_party/upb

@ -2,7 +2,7 @@
name: Report a bug
about: Create a report to help us improve
labels: kind/bug, priority/P2
assignees: nicolasnoble
assignees: donnadionne
---

@ -2,7 +2,7 @@
name: Request a cleanup
about: Suggest a cleanup in our repository
labels: kind/internal cleanup, priority/P2
assignees: nicolasnoble
assignees: donnadionne
---

@ -2,7 +2,7 @@
name: Request a feature
about: Suggest an idea for this project
labels: kind/enhancement, priority/P2
assignees: nicolasnoble
assignees: donnadionne
---

@ -2,7 +2,7 @@
name: Ask a question
about: Ask a question
labels: kind/question, priority/P3
assignees: nicolasnoble
assignees: donnadionne
---

@ -8,4 +8,4 @@ If you know who should review your pull request, please remove the mentioning be
-->
@nicolasnoble
@donnadionne

61
BUILD

@ -80,11 +80,11 @@ config_setting(
python_config_settings()
# This should be updated along with build_handwritten.yaml
g_stands_for = "gecko"
g_stands_for = "gummybear"
core_version = "14.0.0"
core_version = "15.0.0"
version = "1.35.0-dev"
version = "1.36.0-dev"
GPR_PUBLIC_HDRS = [
"include/grpc/support/alloc.h",
@ -323,10 +323,11 @@ grpc_cc_library(
"grpc_no_xds": [],
"//conditions:default": [
"grpc_lb_policy_cds",
"grpc_lb_policy_eds",
"grpc_lb_policy_xds_cluster_impl",
"grpc_lb_policy_xds_cluster_manager",
"grpc_lb_policy_xds_cluster_resolver",
"grpc_resolver_xds",
"grpc_xds_server_config_fetcher",
],
},
standalone = True,
@ -377,7 +378,8 @@ grpc_cc_library(
select_deps = {
"grpc_no_xds": [],
"//conditions:default": [
"grpc++_xds_credentials",
"grpc++_xds_client",
"grpc++_xds_server",
],
},
standalone = True,
@ -393,16 +395,31 @@ grpc_cc_library(
)
grpc_cc_library(
name = "grpc++_xds_credentials",
name = "grpc++_xds_client",
srcs = [
"src/cpp/client/xds_credentials.cc",
"src/cpp/server/xds_server_credentials.cc",
],
hdrs = [
"src/cpp/client/secure_credentials.h",
],
language = "c++",
deps = [
"grpc++_base",
],
)
grpc_cc_library(
name = "grpc++_xds_server",
srcs = [
"src/cpp/server/xds_server_credentials.cc",
],
hdrs = [
"src/cpp/server/secure_server_credentials.h",
],
language = "c++",
public_hdrs = [
"include/grpcpp/xds_server_builder.h",
],
deps = [
"grpc++_base",
],
@ -574,7 +591,6 @@ grpc_cc_library(
"src/core/lib/gprpp/global_config_generic.h",
"src/core/lib/gprpp/host_port.h",
"src/core/lib/gprpp/manual_constructor.h",
"src/core/lib/gprpp/map.h",
"src/core/lib/gprpp/memory.h",
"src/core/lib/gprpp/mpscq.h",
"src/core/lib/gprpp/stat.h",
@ -1079,6 +1095,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/config_selector.cc",
"src/core/ext/filters/client_channel/dynamic_filters.cc",
"src/core/ext/filters/client_channel/global_subchannel_pool.cc",
"src/core/ext/filters/client_channel/health/health_check_client.cc",
"src/core/ext/filters/client_channel/http_connect_handshaker.cc",
@ -1107,6 +1124,7 @@ grpc_cc_library(
"src/core/ext/filters/client_channel/client_channel_factory.h",
"src/core/ext/filters/client_channel/config_selector.h",
"src/core/ext/filters/client_channel/connector.h",
"src/core/ext/filters/client_channel/dynamic_filters.h",
"src/core/ext/filters/client_channel/global_subchannel_pool.h",
"src/core/ext/filters/client_channel/health/health_check_client.h",
"src/core/ext/filters/client_channel/http_connect_handshaker.h",
@ -1384,6 +1402,17 @@ grpc_cc_library(
],
)
grpc_cc_library(
name = "grpc_xds_server_config_fetcher",
srcs = [
"src/core/ext/xds/xds_server_config_fetcher.cc",
],
language = "c++",
deps = [
"grpc_xds_client",
],
)
grpc_cc_library(
name = "grpc_google_mesh_ca_certificate_provider_factory",
srcs = [
@ -1412,6 +1441,14 @@ grpc_cc_library(
],
)
grpc_cc_library(
name = "grpc_lb_xds_channel_args",
hdrs = [
"src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_args.h",
],
language = "c++",
)
grpc_cc_library(
name = "grpc_lb_xds_common",
hdrs = [
@ -1426,9 +1463,9 @@ grpc_cc_library(
)
grpc_cc_library(
name = "grpc_lb_policy_eds",
name = "grpc_lb_policy_xds_cluster_resolver",
srcs = [
"src/core/ext/filters/client_channel/lb_policy/xds/eds.cc",
"src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc",
],
external_deps = [
"absl/strings",
@ -1455,6 +1492,7 @@ grpc_cc_library(
deps = [
"grpc_base",
"grpc_client_channel",
"grpc_lb_xds_channel_args",
"grpc_lb_xds_common",
"grpc_xds_client",
],
@ -1709,12 +1747,10 @@ grpc_cc_library(
name = "grpc_resolver_dns_ares",
srcs = [
"src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc",
"src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc",
"src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc",
"src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc",
"src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc",
"src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc",
"src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc",
"src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc",
"src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc",
"src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc",
@ -1880,6 +1916,7 @@ grpc_cc_library(
deps = [
"alts_util",
"grpc_base",
"grpc_lb_xds_channel_args",
"grpc_transport_chttp2_alpn",
"tsi",
],

@ -159,7 +159,6 @@ config("grpc_config") {
"src/core/lib/gprpp/host_port.cc",
"src/core/lib/gprpp/host_port.h",
"src/core/lib/gprpp/manual_constructor.h",
"src/core/lib/gprpp/map.h",
"src/core/lib/gprpp/memory.h",
"src/core/lib/gprpp/mpscq.cc",
"src/core/lib/gprpp/mpscq.h",
@ -224,6 +223,8 @@ config("grpc_config") {
"src/core/ext/filters/client_channel/config_selector.cc",
"src/core/ext/filters/client_channel/config_selector.h",
"src/core/ext/filters/client_channel/connector.h",
"src/core/ext/filters/client_channel/dynamic_filters.cc",
"src/core/ext/filters/client_channel/dynamic_filters.h",
"src/core/ext/filters/client_channel/global_subchannel_pool.cc",
"src/core/ext/filters/client_channel/global_subchannel_pool.h",
"src/core/ext/filters/client_channel/health/health_check_client.cc",
@ -256,10 +257,11 @@ config("grpc_config") {
"src/core/ext/filters/client_channel/lb_policy/subchannel_list.h",
"src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc",
"src/core/ext/filters/client_channel/lb_policy/xds/cds.cc",
"src/core/ext/filters/client_channel/lb_policy/xds/eds.cc",
"src/core/ext/filters/client_channel/lb_policy/xds/xds.h",
"src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_args.h",
"src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc",
"src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc",
"src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc",
"src/core/ext/filters/client_channel/lb_policy_factory.h",
"src/core/ext/filters/client_channel/lb_policy_registry.cc",
"src/core/ext/filters/client_channel/lb_policy_registry.h",
@ -271,14 +273,12 @@ config("grpc_config") {
"src/core/ext/filters/client_channel/resolver.cc",
"src/core/ext/filters/client_channel/resolver.h",
"src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc",
"src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc",
"src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h",
"src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc",
"src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc",
"src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc",
"src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc",
"src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h",
"src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc",
"src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc",
"src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc",
"src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc",
@ -739,6 +739,7 @@ config("grpc_config") {
"src/core/ext/xds/xds_client.h",
"src/core/ext/xds/xds_client_stats.cc",
"src/core/ext/xds/xds_client_stats.h",
"src/core/ext/xds/xds_server_config_fetcher.cc",
"src/core/lib/avl/avl.cc",
"src/core/lib/avl/avl.h",
"src/core/lib/backoff/backoff.cc",
@ -1427,6 +1428,7 @@ config("grpc_config") {
"include/grpcpp/support/sync_stream.h",
"include/grpcpp/support/time.h",
"include/grpcpp/support/validate_service_config.h",
"include/grpcpp/xds_server_builder.h",
"src/cpp/client/channel_cc.cc",
"src/cpp/client/client_callback.cc",
"src/cpp/client/client_context.cc",

@ -25,12 +25,12 @@
cmake_minimum_required(VERSION 3.5.1)
set(PACKAGE_NAME "grpc")
set(PACKAGE_VERSION "1.35.0-dev")
set(gRPC_CORE_VERSION "14.0.0")
set(gRPC_CORE_SOVERSION "14")
set(gRPC_CPP_VERSION "1.35.0-dev")
set(PACKAGE_VERSION "1.36.0-dev")
set(gRPC_CORE_VERSION "15.0.0")
set(gRPC_CORE_SOVERSION "15")
set(gRPC_CPP_VERSION "1.36.0-dev")
set(gRPC_CPP_SOVERSION "1")
set(gRPC_CSHARP_VERSION "2.35.0-dev")
set(gRPC_CSHARP_VERSION "2.36.0-dev")
set(gRPC_CSHARP_SOVERSION "2")
set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
set(PACKAGE_TARNAME "${PACKAGE_NAME}-${PACKAGE_VERSION}")
@ -698,7 +698,6 @@ if(gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_c udp_server_test)
endif()
add_dependencies(buildtests_c uri_parser_test)
add_dependencies(buildtests_c useful_test)
add_dependencies(buildtests_c varint_test)
@ -937,6 +936,7 @@ if(gRPC_BUILD_TESTS)
add_dependencies(buildtests_cxx tls_security_connector_test)
add_dependencies(buildtests_cxx too_many_pings_test)
add_dependencies(buildtests_cxx unknown_frame_bad_client_test)
add_dependencies(buildtests_cxx uri_parser_test)
add_dependencies(buildtests_cxx window_overflow_bad_client_test)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx work_serializer_test)
@ -1453,6 +1453,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/config_selector.cc
src/core/ext/filters/client_channel/dynamic_filters.cc
src/core/ext/filters/client_channel/global_subchannel_pool.cc
src/core/ext/filters/client_channel/health/health_check_client.cc
src/core/ext/filters/client_channel/http_connect_handshaker.cc
@ -1471,20 +1472,18 @@ add_library(grpc
src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc
src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc
src/core/ext/filters/client_channel/lb_policy/xds/cds.cc
src/core/ext/filters/client_channel/lb_policy/xds/eds.cc
src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc
src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc
src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc
src/core/ext/filters/client_channel/lb_policy_registry.cc
src/core/ext/filters/client_channel/local_subchannel_pool.cc
src/core/ext/filters/client_channel/proxy_mapper_registry.cc
src/core/ext/filters/client_channel/resolver.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc
@ -1721,6 +1720,7 @@ add_library(grpc
src/core/ext/xds/xds_certificate_provider.cc
src/core/ext/xds/xds_client.cc
src/core/ext/xds/xds_client_stats.cc
src/core/ext/xds/xds_server_config_fetcher.cc
src/core/lib/avl/avl.cc
src/core/lib/backoff/backoff.cc
src/core/lib/channel/channel_args.cc
@ -2254,6 +2254,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/config_selector.cc
src/core/ext/filters/client_channel/dynamic_filters.cc
src/core/ext/filters/client_channel/global_subchannel_pool.cc
src/core/ext/filters/client_channel/health/health_check_client.cc
src/core/ext/filters/client_channel/http_connect_handshaker.cc
@ -2276,12 +2277,10 @@ add_library(grpc_unsecure
src/core/ext/filters/client_channel/proxy_mapper_registry.cc
src/core/ext/filters/client_channel/resolver.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc
@ -2953,6 +2952,7 @@ foreach(_hdr
include/grpcpp/support/sync_stream.h
include/grpcpp/support/time.h
include/grpcpp/support/validate_service_config.h
include/grpcpp/xds_server_builder.h
)
string(REPLACE "include/" "" _path ${_hdr})
get_filename_component(_path ${_path} PATH)
@ -3781,15 +3781,17 @@ endif()
endif()
add_library(upb
third_party/upb/upb/decode_fast.c
third_party/upb/upb/decode.c
third_party/upb/upb/def.c
third_party/upb/upb/encode.c
third_party/upb/upb/json_decode.c
third_party/upb/upb/json_encode.c
third_party/upb/upb/msg.c
third_party/upb/upb/port.c
third_party/upb/upb/table.c
third_party/upb/upb/upb.c
third_party/upb/upb/def.c
third_party/upb/upb/reflection.c
third_party/upb/upb/table.c
third_party/upb/upb/text_encode.c
third_party/upb/upb/upb.c
src/core/ext/upb-generated/google/protobuf/any.upb.c
src/core/ext/upb-generated/google/protobuf/descriptor.upb.c
src/core/ext/upb-generated/google/protobuf/duration.upb.c
@ -8020,36 +8022,6 @@ endif()
endif()
if(gRPC_BUILD_TESTS)
add_executable(uri_parser_test
test/core/uri/uri_parser_test.cc
)
target_include_directories(uri_parser_test
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/include
${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
${_gRPC_RE2_INCLUDE_DIR}
${_gRPC_SSL_INCLUDE_DIR}
${_gRPC_UPB_GENERATED_DIR}
${_gRPC_UPB_GRPC_GENERATED_DIR}
${_gRPC_UPB_INCLUDE_DIR}
${_gRPC_ZLIB_INCLUDE_DIR}
)
target_link_libraries(uri_parser_test
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util
grpc
gpr
address_sorting
upb
)
endif()
if(gRPC_BUILD_TESTS)
add_executable(useful_test
test/core/gpr/useful_test.cc
)
@ -15144,6 +15116,44 @@ target_link_libraries(unknown_frame_bad_client_test
)
endif()
if(gRPC_BUILD_TESTS)
add_executable(uri_parser_test
test/core/uri/uri_parser_test.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
)
target_include_directories(uri_parser_test
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/include
${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
${_gRPC_RE2_INCLUDE_DIR}
${_gRPC_SSL_INCLUDE_DIR}
${_gRPC_UPB_GENERATED_DIR}
${_gRPC_UPB_GRPC_GENERATED_DIR}
${_gRPC_UPB_INCLUDE_DIR}
${_gRPC_ZLIB_INCLUDE_DIR}
third_party/googletest/googletest/include
third_party/googletest/googletest
third_party/googletest/googlemock/include
third_party/googletest/googlemock
${_gRPC_PROTO_GENS_DIR}
)
target_link_libraries(uri_parser_test
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util
grpc
gpr
address_sorting
upb
)
endif()
if(gRPC_BUILD_TESTS)

@ -454,9 +454,9 @@ E = @echo
Q = @
endif
CORE_VERSION = 14.0.0
CPP_VERSION = 1.35.0-dev
CSHARP_VERSION = 2.35.0-dev
CORE_VERSION = 15.0.0
CPP_VERSION = 1.36.0-dev
CSHARP_VERSION = 2.36.0-dev
CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES))
CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS)
@ -492,7 +492,7 @@ SHARED_EXT_CORE = dll
SHARED_EXT_CPP = dll
SHARED_EXT_CSHARP = dll
SHARED_PREFIX =
SHARED_VERSION_CORE = -14
SHARED_VERSION_CORE = -15
SHARED_VERSION_CPP = -1
SHARED_VERSION_CSHARP = -2
else ifeq ($(SYSTEM),Darwin)
@ -891,8 +891,8 @@ $(LIBDIR)/$(CONFIG)/libaddress_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE):
ifeq ($(SYSTEM),Darwin)
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libaddress_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBADDRESS_SORTING_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
else
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libaddress_sorting.so.14 -o $(LIBDIR)/$(CONFIG)/libaddress_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBADDRESS_SORTING_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
$(Q) ln -sf $(SHARED_PREFIX)address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libaddress_sorting$(SHARED_VERSION_CORE).so.14
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libaddress_sorting.so.15 -o $(LIBDIR)/$(CONFIG)/libaddress_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBADDRESS_SORTING_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
$(Q) ln -sf $(SHARED_PREFIX)address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libaddress_sorting$(SHARED_VERSION_CORE).so.15
$(Q) ln -sf $(SHARED_PREFIX)address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libaddress_sorting$(SHARED_VERSION_CORE).so
endif
endif
@ -1019,8 +1019,8 @@ $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGPR_OB
ifeq ($(SYSTEM),Darwin)
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGPR_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
else
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgpr.so.14 -o $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGPR_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
$(Q) ln -sf $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).so.14
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgpr.so.15 -o $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGPR_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
$(Q) ln -sf $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).so.15
$(Q) ln -sf $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).so
endif
endif
@ -1042,6 +1042,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/config_selector.cc \
src/core/ext/filters/client_channel/dynamic_filters.cc \
src/core/ext/filters/client_channel/global_subchannel_pool.cc \
src/core/ext/filters/client_channel/health/health_check_client.cc \
src/core/ext/filters/client_channel/http_connect_handshaker.cc \
@ -1060,20 +1061,18 @@ LIBGRPC_SRC = \
src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc \
src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc \
src/core/ext/filters/client_channel/lb_policy/xds/cds.cc \
src/core/ext/filters/client_channel/lb_policy/xds/eds.cc \
src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc \
src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc \
src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc \
src/core/ext/filters/client_channel/lb_policy_registry.cc \
src/core/ext/filters/client_channel/local_subchannel_pool.cc \
src/core/ext/filters/client_channel/proxy_mapper_registry.cc \
src/core/ext/filters/client_channel/resolver.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \
@ -1310,6 +1309,7 @@ LIBGRPC_SRC = \
src/core/ext/xds/xds_certificate_provider.cc \
src/core/ext/xds/xds_client.cc \
src/core/ext/xds/xds_client_stats.cc \
src/core/ext/xds/xds_server_config_fetcher.cc \
src/core/lib/avl/avl.cc \
src/core/lib/backoff/backoff.cc \
src/core/lib/channel/channel_args.cc \
@ -1611,8 +1611,8 @@ $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_
ifeq ($(SYSTEM),Darwin)
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
else
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc.so.14 -o $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
$(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).so.14
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc.so.15 -o $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
$(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).so.15
$(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).so
endif
endif
@ -1669,8 +1669,8 @@ $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE):
ifeq ($(SYSTEM),Darwin)
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_CSHARP_EXT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
else
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_csharp_ext.so.14 -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_CSHARP_EXT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
$(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CORE).so.14
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_csharp_ext.so.15 -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_CSHARP_EXT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
$(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CORE).so.15
$(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CORE).so
endif
endif
@ -1696,6 +1696,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/config_selector.cc \
src/core/ext/filters/client_channel/dynamic_filters.cc \
src/core/ext/filters/client_channel/global_subchannel_pool.cc \
src/core/ext/filters/client_channel/health/health_check_client.cc \
src/core/ext/filters/client_channel/http_connect_handshaker.cc \
@ -1718,12 +1719,10 @@ LIBGRPC_UNSECURE_SRC = \
src/core/ext/filters/client_channel/proxy_mapper_registry.cc \
src/core/ext/filters/client_channel/resolver.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \
@ -2008,8 +2007,8 @@ $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $
ifeq ($(SYSTEM),Darwin)
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
else
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_unsecure.so.14 -o $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
$(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).so.14
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_unsecure.so.15 -o $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
$(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).so.15
$(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).so
endif
endif
@ -2367,15 +2366,17 @@ endif
# start of build recipe for library "upb" (generated by makelib(lib) template function)
LIBUPB_SRC = \
third_party/upb/upb/decode_fast.c \
third_party/upb/upb/decode.c \
third_party/upb/upb/def.c \
third_party/upb/upb/encode.c \
third_party/upb/upb/json_decode.c \
third_party/upb/upb/json_encode.c \
third_party/upb/upb/msg.c \
third_party/upb/upb/port.c \
third_party/upb/upb/table.c \
third_party/upb/upb/upb.c \
third_party/upb/upb/def.c \
third_party/upb/upb/reflection.c \
third_party/upb/upb/table.c \
third_party/upb/upb/text_encode.c \
third_party/upb/upb/upb.c \
src/core/ext/upb-generated/google/protobuf/any.upb.c \
src/core/ext/upb-generated/google/protobuf/descriptor.upb.c \
src/core/ext/upb-generated/google/protobuf/duration.upb.c \
@ -2419,8 +2420,8 @@ $(LIBDIR)/$(CONFIG)/libupb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBUPB_OB
ifeq ($(SYSTEM),Darwin)
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)upb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libupb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBUPB_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
else
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libupb.so.14 -o $(LIBDIR)/$(CONFIG)/libupb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBUPB_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
$(Q) ln -sf $(SHARED_PREFIX)upb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libupb$(SHARED_VERSION_CORE).so.14
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libupb.so.15 -o $(LIBDIR)/$(CONFIG)/libupb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBUPB_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
$(Q) ln -sf $(SHARED_PREFIX)upb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libupb$(SHARED_VERSION_CORE).so.15
$(Q) ln -sf $(SHARED_PREFIX)upb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libupb$(SHARED_VERSION_CORE).so
endif
endif
@ -2666,9 +2667,9 @@ ifneq ($(OPENSSL_DEP),)
# otherwise parallel compilation will fail if a source is compiled first.
src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc: $(OPENSSL_DEP)
src/core/ext/filters/client_channel/lb_policy/xds/cds.cc: $(OPENSSL_DEP)
src/core/ext/filters/client_channel/lb_policy/xds/eds.cc: $(OPENSSL_DEP)
src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc: $(OPENSSL_DEP)
src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc: $(OPENSSL_DEP)
src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc: $(OPENSSL_DEP)
src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc: $(OPENSSL_DEP)
src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc: $(OPENSSL_DEP)
src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc: $(OPENSSL_DEP)
@ -2822,6 +2823,7 @@ src/core/ext/xds/xds_bootstrap.cc: $(OPENSSL_DEP)
src/core/ext/xds/xds_certificate_provider.cc: $(OPENSSL_DEP)
src/core/ext/xds/xds_client.cc: $(OPENSSL_DEP)
src/core/ext/xds/xds_client_stats.cc: $(OPENSSL_DEP)
src/core/ext/xds/xds_server_config_fetcher.cc: $(OPENSSL_DEP)
src/core/lib/http/httpcli_security_connector.cc: $(OPENSSL_DEP)
src/core/lib/security/authorization/authorization_engine.cc: $(OPENSSL_DEP)
src/core/lib/security/authorization/evaluate_args.cc: $(OPENSSL_DEP)

@ -121,7 +121,7 @@ task 'gem:native' do
verbose = ENV['V'] || '0'
grpc_config = ENV['GRPC_CONFIG'] || 'opt'
ruby_cc_versions = '2.7.0:2.6.0:2.5.0:2.4.0:2.3.0'
ruby_cc_versions = ['3.0.0', '2.7.0', '2.6.0', '2.5.0', '2.4.0', '2.3.0'].join(':')
if RUBY_PLATFORM =~ /darwin/
FileUtils.touch 'grpc_c.32.ruby'
@ -139,20 +139,22 @@ task 'gem:native' do
gem update --system --no-document && \
bundle && \
rake native:#{plat} pkg/#{spec.full_name}-#{plat}.gem pkg/#{spec.full_name}.gem \
RUBY_CC_VERSION=#{ruby_cc_versions} V=#{verbose} GRPC_CONFIG=#{grpc_config}
RUBY_CC_VERSION=#{ruby_cc_versions} \
V=#{verbose} \
GRPC_CONFIG=#{grpc_config}
EOT
end
# Truncate grpc_c.*.ruby files because they're for Windows only.
File.truncate('grpc_c.32.ruby', 0)
File.truncate('grpc_c.64.ruby', 0)
['x86_64-linux', 'x86-linux'].each do |plat|
run_rake_compiler plat, <<-EOT
run_rake_compiler plat, <<-EOT
gem update --system --no-document && \
bundle && \
rake native:#{plat} pkg/#{spec.full_name}-#{plat}.gem pkg/#{spec.full_name}.gem \
RUBY_CC_VERSION=#{ruby_cc_versions} V=#{verbose} GRPC_CONFIG=#{grpc_config} &&
sudo chmod -R a+rw pkg &&
patchelf_gem.sh pkg/#{spec.full_name}-#{plat}.gem
RUBY_CC_VERSION=#{ruby_cc_versions} \
V=#{verbose} \
GRPC_CONFIG=#{grpc_config}
EOT
end
end

@ -21,6 +21,11 @@ def grpc_deps():
actual = "@upb//:textformat",
)
native.bind(
name = "upb_json_lib",
actual = "@upb//:json",
)
native.bind(
name = "absl",
actual = "@com_google_absl//absl",
@ -288,11 +293,11 @@ def grpc_deps():
if "upb" not in native.existing_rules():
http_archive(
name = "upb",
sha256 = "7992217989f3156f8109931c1fc6db3434b7414957cb82371552377beaeb9d6c",
strip_prefix = "upb-382d5afc60e05470c23e8de19b19fc5ad231e732",
sha256 = "c0b97bf91dfea7e8d7579c24e2ecdd02d10b00f3c5defc3dce23d95100d0e664",
strip_prefix = "upb-60607da72e89ba0c84c84054d2e562d8b6b61177",
urls = [
"https://storage.googleapis.com/grpc-bazel-mirror/github.com/protocolbuffers/upb/archive/382d5afc60e05470c23e8de19b19fc5ad231e732.tar.gz",
"https://github.com/protocolbuffers/upb/archive/382d5afc60e05470c23e8de19b19fc5ad231e732.tar.gz",
"https://storage.googleapis.com/grpc-bazel-mirror/github.com/protocolbuffers/upb/archive/60607da72e89ba0c84c84054d2e562d8b6b61177.tar.gz",
"https://github.com/protocolbuffers/upb/archive/60607da72e89ba0c84c84054d2e562d8b6b61177.tar.gz",
],
)

@ -7,7 +7,7 @@ load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_depe
load("@build_bazel_rules_apple//apple:repositories.bzl", "apple_rules_dependencies")
load("@build_bazel_apple_support//lib:repositories.bzl", "apple_support_dependencies")
def grpc_extra_deps():
def grpc_extra_deps(ignore_version_differences = False):
"""Loads the extra dependencies.
These are necessary for using the external repositories defined in
@ -35,6 +35,6 @@ def grpc_extra_deps():
go_rules_dependencies()
go_register_toolchains()
apple_rules_dependencies()
apple_rules_dependencies(ignore_version_differences = ignore_version_differences)
apple_support_dependencies()

@ -60,6 +60,10 @@ upload github.com/bazelbuild/bazel/releases/download/2.2.0/bazel-2.2.0-linux-x86
upload github.com/bazelbuild/bazel/releases/download/2.2.0/bazel-2.2.0-darwin-x86_64
upload github.com/bazelbuild/bazel/releases/download/2.2.0/bazel-2.2.0-windows-x86_64.exe
upload github.com/bazelbuild/bazel/releases/download/3.7.1/bazel-3.7.1-linux-x86_64
upload github.com/bazelbuild/bazel/releases/download/3.7.1/bazel-3.7.1-darwin-x86_64
upload github.com/bazelbuild/bazel/releases/download/3.7.1/bazel-3.7.1-windows-x86_64.exe
# Collect the github archives to mirror from grpc_deps.bzl
grep -o '"https://github.com/[^"]*"' bazel/grpc_deps.bzl | sed 's/^"https:\/\///' | sed 's/"$//' | while read -r line ; do
echo "Updating mirror for ${line}"

@ -303,7 +303,6 @@ libs:
- src/core/lib/gprpp/global_config_generic.h
- src/core/lib/gprpp/host_port.h
- src/core/lib/gprpp/manual_constructor.h
- src/core/lib/gprpp/map.h
- src/core/lib/gprpp/memory.h
- src/core/lib/gprpp/mpscq.h
- src/core/lib/gprpp/stat.h
@ -391,6 +390,7 @@ libs:
- src/core/ext/filters/client_channel/client_channel_factory.h
- src/core/ext/filters/client_channel/config_selector.h
- src/core/ext/filters/client_channel/connector.h
- src/core/ext/filters/client_channel/dynamic_filters.h
- src/core/ext/filters/client_channel/global_subchannel_pool.h
- src/core/ext/filters/client_channel/health/health_check_client.h
- src/core/ext/filters/client_channel/http_connect_handshaker.h
@ -406,6 +406,7 @@ libs:
- src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h
- src/core/ext/filters/client_channel/lb_policy/subchannel_list.h
- src/core/ext/filters/client_channel/lb_policy/xds/xds.h
- src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_args.h
- src/core/ext/filters/client_channel/lb_policy_factory.h
- src/core/ext/filters/client_channel/lb_policy_registry.h
- src/core/ext/filters/client_channel/local_subchannel_pool.h
@ -873,6 +874,7 @@ libs:
- 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/config_selector.cc
- src/core/ext/filters/client_channel/dynamic_filters.cc
- src/core/ext/filters/client_channel/global_subchannel_pool.cc
- src/core/ext/filters/client_channel/health/health_check_client.cc
- src/core/ext/filters/client_channel/http_connect_handshaker.cc
@ -891,20 +893,18 @@ libs:
- src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc
- src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc
- src/core/ext/filters/client_channel/lb_policy/xds/cds.cc
- src/core/ext/filters/client_channel/lb_policy/xds/eds.cc
- src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc
- src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc
- src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc
- src/core/ext/filters/client_channel/lb_policy_registry.cc
- src/core/ext/filters/client_channel/local_subchannel_pool.cc
- src/core/ext/filters/client_channel/proxy_mapper_registry.cc
- src/core/ext/filters/client_channel/resolver.cc
- src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
- src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc
- src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc
- src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc
- src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc
- src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc
- src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc
- src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc
- src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc
- src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc
@ -1141,6 +1141,7 @@ libs:
- src/core/ext/xds/xds_certificate_provider.cc
- src/core/ext/xds/xds_client.cc
- src/core/ext/xds/xds_client_stats.cc
- src/core/ext/xds/xds_server_config_fetcher.cc
- src/core/lib/avl/avl.cc
- src/core/lib/backoff/backoff.cc
- src/core/lib/channel/channel_args.cc
@ -1560,6 +1561,7 @@ libs:
- src/core/ext/filters/client_channel/client_channel_factory.h
- src/core/ext/filters/client_channel/config_selector.h
- src/core/ext/filters/client_channel/connector.h
- src/core/ext/filters/client_channel/dynamic_filters.h
- src/core/ext/filters/client_channel/global_subchannel_pool.h
- src/core/ext/filters/client_channel/health/health_check_client.h
- src/core/ext/filters/client_channel/http_connect_handshaker.h
@ -1803,6 +1805,7 @@ libs:
- 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/config_selector.cc
- src/core/ext/filters/client_channel/dynamic_filters.cc
- src/core/ext/filters/client_channel/global_subchannel_pool.cc
- src/core/ext/filters/client_channel/health/health_check_client.cc
- src/core/ext/filters/client_channel/http_connect_handshaker.cc
@ -1825,12 +1828,10 @@ libs:
- src/core/ext/filters/client_channel/proxy_mapper_registry.cc
- src/core/ext/filters/client_channel/resolver.cc
- src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
- src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc
- src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc
- src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc
- src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc
- src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc
- src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc
- src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc
- src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc
- src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc
@ -2298,6 +2299,7 @@ libs:
- include/grpcpp/support/sync_stream.h
- include/grpcpp/support/time.h
- include/grpcpp/support/validate_service_config.h
- include/grpcpp/xds_server_builder.h
headers:
- src/cpp/client/create_channel_internal.h
- src/cpp/client/secure_credentials.h
@ -3259,7 +3261,6 @@ targets:
uses_polling: false
- name: concurrent_connectivity_test
build: test
run: false
language: c
headers: []
src:
@ -4625,18 +4626,6 @@ targets:
- linux
- posix
- mac
- name: uri_parser_test
build: test
language: c
headers: []
src:
- test/core/uri/uri_parser_test.cc
deps:
- grpc_test_util
- grpc
- gpr
- address_sorting
- upb
- name: useful_test
build: test
language: c
@ -5421,7 +5410,6 @@ targets:
- name: cancel_ares_query_test
gtest: true
build: test
run: false
language: c++
headers:
- test/core/end2end/cq_verifier.h
@ -7523,7 +7511,6 @@ targets:
- name: stranded_event_test
gtest: true
build: test
run: false
language: c++
headers:
- test/core/end2end/cq_verifier.h
@ -7776,6 +7763,19 @@ targets:
corpus_dirs:
- test/core/uri/uri_corpus
maxlen: 128
- name: uri_parser_test
gtest: true
build: test
language: c++
headers: []
src:
- test/core/uri/uri_parser_test.cc
deps:
- grpc_test_util
- grpc
- gpr
- address_sorting
- upb
- name: window_overflow_bad_client_test
gtest: true
build: test

@ -13,5 +13,5 @@
# limitations under the License.
module GrpcBuildConfig
CORE_WINDOWS_DLL = '/tmp/libs/opt/grpc-14.dll'
CORE_WINDOWS_DLL = '/tmp/libs/opt/grpc-15.dll'
end

@ -12,11 +12,11 @@ settings:
'#08': Use "-preN" suffixes to identify pre-release versions
'#09': Per-language overrides are possible with (eg) ruby_version tag here
'#10': See the expand_version.py for all the quirks here
core_version: 14.0.0
core_version: 15.0.0
csharp_major_version: 2
g_stands_for: gecko
g_stands_for: gummybear
protobuf_version: 3.13.0
version: 1.35.0-dev
version: 1.36.0-dev
targets:
- name: check_epollexclusive
build: tool

@ -48,6 +48,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/config_selector.cc \
src/core/ext/filters/client_channel/dynamic_filters.cc \
src/core/ext/filters/client_channel/global_subchannel_pool.cc \
src/core/ext/filters/client_channel/health/health_check_client.cc \
src/core/ext/filters/client_channel/http_connect_handshaker.cc \
@ -66,20 +67,18 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc \
src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc \
src/core/ext/filters/client_channel/lb_policy/xds/cds.cc \
src/core/ext/filters/client_channel/lb_policy/xds/eds.cc \
src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc \
src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc \
src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc \
src/core/ext/filters/client_channel/lb_policy_registry.cc \
src/core/ext/filters/client_channel/local_subchannel_pool.cc \
src/core/ext/filters/client_channel/proxy_mapper_registry.cc \
src/core/ext/filters/client_channel/resolver.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \
@ -317,6 +316,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/xds/xds_certificate_provider.cc \
src/core/ext/xds/xds_client.cc \
src/core/ext/xds/xds_client_stats.cc \
src/core/ext/xds/xds_server_config_fetcher.cc \
src/core/lib/avl/avl.cc \
src/core/lib/backoff/backoff.cc \
src/core/lib/channel/channel_args.cc \
@ -987,10 +987,12 @@ if test "$PHP_GRPC" != "no"; then
third_party/re2/util/rune.cc \
third_party/re2/util/strutil.cc \
third_party/upb/upb/decode.c \
third_party/upb/upb/decode_fast.c \
third_party/upb/upb/def.c \
third_party/upb/upb/encode.c \
third_party/upb/upb/json_decode.c \
third_party/upb/upb/json_encode.c \
third_party/upb/upb/msg.c \
third_party/upb/upb/port.c \
third_party/upb/upb/reflection.c \
third_party/upb/upb/table.c \
third_party/upb/upb/text_encode.c \

@ -15,6 +15,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\\config_selector.cc " +
"src\\core\\ext\\filters\\client_channel\\dynamic_filters.cc " +
"src\\core\\ext\\filters\\client_channel\\global_subchannel_pool.cc " +
"src\\core\\ext\\filters\\client_channel\\health\\health_check_client.cc " +
"src\\core\\ext\\filters\\client_channel\\http_connect_handshaker.cc " +
@ -33,20 +34,18 @@ if (PHP_GRPC != "no") {
"src\\core\\ext\\filters\\client_channel\\lb_policy\\round_robin\\round_robin.cc " +
"src\\core\\ext\\filters\\client_channel\\lb_policy\\weighted_target\\weighted_target.cc " +
"src\\core\\ext\\filters\\client_channel\\lb_policy\\xds\\cds.cc " +
"src\\core\\ext\\filters\\client_channel\\lb_policy\\xds\\eds.cc " +
"src\\core\\ext\\filters\\client_channel\\lb_policy\\xds\\xds_cluster_impl.cc " +
"src\\core\\ext\\filters\\client_channel\\lb_policy\\xds\\xds_cluster_manager.cc " +
"src\\core\\ext\\filters\\client_channel\\lb_policy\\xds\\xds_cluster_resolver.cc " +
"src\\core\\ext\\filters\\client_channel\\lb_policy_registry.cc " +
"src\\core\\ext\\filters\\client_channel\\local_subchannel_pool.cc " +
"src\\core\\ext\\filters\\client_channel\\proxy_mapper_registry.cc " +
"src\\core\\ext\\filters\\client_channel\\resolver.cc " +
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\dns_resolver_ares.cc " +
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_ev_driver.cc " +
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_ev_driver_libuv.cc " +
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_ev_driver_posix.cc " +
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_ev_driver_windows.cc " +
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper.cc " +
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_fallback.cc " +
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_libuv.cc " +
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_posix.cc " +
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_windows.cc " +
@ -284,6 +283,7 @@ if (PHP_GRPC != "no") {
"src\\core\\ext\\xds\\xds_certificate_provider.cc " +
"src\\core\\ext\\xds\\xds_client.cc " +
"src\\core\\ext\\xds\\xds_client_stats.cc " +
"src\\core\\ext\\xds\\xds_server_config_fetcher.cc " +
"src\\core\\lib\\avl\\avl.cc " +
"src\\core\\lib\\backoff\\backoff.cc " +
"src\\core\\lib\\channel\\channel_args.cc " +
@ -954,10 +954,12 @@ if (PHP_GRPC != "no") {
"third_party\\re2\\util\\rune.cc " +
"third_party\\re2\\util\\strutil.cc " +
"third_party\\upb\\upb\\decode.c " +
"third_party\\upb\\upb\\decode_fast.c " +
"third_party\\upb\\upb\\def.c " +
"third_party\\upb\\upb\\encode.c " +
"third_party\\upb\\upb\\json_decode.c " +
"third_party\\upb\\upb\\json_encode.c " +
"third_party\\upb\\upb\\msg.c " +
"third_party\\upb\\upb\\port.c " +
"third_party\\upb\\upb\\reflection.c " +
"third_party\\upb\\upb\\table.c " +
"third_party\\upb\\upb\\text_encode.c " +

@ -57,7 +57,6 @@ some configuration as environment variables that can be set.
- compression - traces compression operations
- connectivity_state - traces connectivity state changes to channels
- cronet - traces state in the cronet transport engine
- eds_lb - traces eds LB policy
- executor - traces grpc's internal thread pool ('the executor')
- glb - traces the grpclb load balancer
- handshaker - traces handshaking state
@ -91,6 +90,7 @@ some configuration as environment variables that can be set.
- xds_client - traces xds client
- xds_cluster_manager_lb - traces cluster manager LB policy
- xds_cluster_impl_lb - traces cluster impl LB policy
- xds_cluster_resolver_lb - traces xds cluster resolver LB policy
- xds_resolver - traces xds resolver
The following tracers will only run in binaries built in DEBUG mode. This is

@ -34,4 +34,5 @@
- 1.32 'g' stands for ['giggle'](https://github.com/grpc/grpc/tree/v1.32.x)
- 1.33 'g' stands for ['geeky'](https://github.com/grpc/grpc/tree/v1.33.x)
- 1.34 'g' stands for ['gauntlet'](https://github.com/grpc/grpc/tree/v1.34.x)
- 1.35 'g' stands for ['gecko'](https://github.com/grpc/grpc/tree/master)
- 1.35 'g' stands for ['gecko'](https://github.com/grpc/grpc/tree/v1.35.x)
- 1.36 'g' stands for ['gummybear'](https://github.com/grpc/grpc/tree/master)

@ -34,8 +34,12 @@ The optional `load_balancing_weight` is always ignored.
Initially, only `google_default` channel creds will be supported
to authenticate with the xDS server.
Features | gRFCs | [C++, Python,<br> Ruby, PHP, C#](https://github.com/grpc/grpc/releases) | [Java](https://github.com/grpc/grpc-java/releases) | [Go](https://github.com/grpc/grpc-go/releases) | [Node](https://github.com/grpc/grpc-node/releases)
The gRPC language implementations not listed in the table below do not support
xDS features.
Features | gRFCs | [C++, Python,<br> Ruby, PHP](https://github.com/grpc/grpc/releases) | [Java](https://github.com/grpc/grpc-java/releases) | [Go](https://github.com/grpc/grpc-go/releases) | [Node](https://github.com/grpc/grpc-node/releases)
---------|--------|--------------|------|------|------
**xDS Infrastructure in gRPC client channel:**<ul><li>LDS->RDS->CDS->EDS flow</li><li>ADS stream</li></ul> | [A27](https://github.com/grpc/proposal/blob/master/A27-xds-global-load-balancing.md) | v1.30.0 | v1.30.0 | v1.30.0 | v1.2.0 |
**Load Balancing:**<ul><li>[Virtual host](https://www.envoyproxy.io/docs/envoy/latest/api-v2/api/v2/route/route_components.proto#route-virtualhost) domains matching</li><li>Only default path ("" or "/") matching</li><li>Priority-based weighted round-robin locality picking</li><li>Round-robin endpoint picking within locality</li><li>[Cluster](https://www.envoyproxy.io/docs/envoy/latest/api-v2/api/v2/route/route_components.proto#envoy-api-msg-route-routeaction) route action</li><li>Client-side Load reporting via [LRS](https://github.com/envoyproxy/data-plane-api/blob/master/envoy/service/load_stats/v2/lrs.proto)</li></ul> | [A27](https://github.com/grpc/proposal/blob/master/A27-xds-global-load-balancing.md) | v1.30.0 | v1.30.0 | v1.30.0 | v1.2.0 |
Request matching based on:<ul><li>[Path](https://www.envoyproxy.io/docs/envoy/latest/api-v2/api/v2/route/route_components.proto#route-routematch) (prefix, full path and safe regex)</li><li>[Headers](https://www.envoyproxy.io/docs/envoy/latest/api-v2/api/v2/route/route_components.proto#route-headermatcher)</li></ul>Request routing to multiple clusters based on [weights](https://www.envoyproxy.io/docs/envoy/latest/api-v2/api/v2/route/route_components.proto#route-weightedcluster) | [A28](https://github.com/grpc/proposal/blob/master/A28-xds-traffic-splitting-and-routing.md) | v1.31.0 | v1.31.0 | v1.31.0 | |
Request matching based on:<ul><li>[Path](https://www.envoyproxy.io/docs/envoy/latest/api-v2/api/v2/route/route_components.proto#route-routematch) (prefix, full path and safe regex)</li><ul><li>[case_sensitive](https://www.envoyproxy.io/docs/envoy/latest/api-v2/api/v2/route/route_components.proto#route-routematch) must be true else config is NACKed</li></ul><li>[Headers](https://www.envoyproxy.io/docs/envoy/latest/api-v2/api/v2/route/route_components.proto#route-headermatcher)</li></ul>Request routing to multiple clusters based on [weights](https://www.envoyproxy.io/docs/envoy/latest/api-v2/api/v2/route/route_components.proto#route-weightedcluster) | [A28](https://github.com/grpc/proposal/blob/master/A28-xds-traffic-splitting-and-routing.md) | v1.31.0 | v1.31.0 | v1.31.0 | |
Case insensitive prefix/full path matching:<ul><li>[case_sensitive](https://www.envoyproxy.io/docs/envoy/latest/api-v2/api/v2/route/route_components.proto#route-routematch) can be true or false</li></ul> | | v1.34.0 | v1.34.0 | v1.34.0 | |

@ -1,252 +0,0 @@
# Copyright 2017 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.
licenses(["notice"]) # 3-clause BSD
package(default_visibility = ["//visibility:public"])
load("@grpc_python_dependencies//:requirements.bzl", "requirement")
load("@rules_proto//proto:defs.bzl", "proto_library")
load("//bazel:cc_grpc_library.bzl", "cc_grpc_library")
load("//bazel:grpc_build_system.bzl", "grpc_proto_library")
load("//bazel:python_rules.bzl", "py_grpc_library", "py_proto_library")
grpc_proto_library(
name = "auth_sample",
srcs = ["protos/auth_sample.proto"],
)
grpc_proto_library(
name = "hellostreamingworld",
srcs = ["protos/hellostreamingworld.proto"],
)
# The following three rules demonstrate the usage of the cc_grpc_library rule in
# in a mode compatible with the native proto_library and cc_proto_library rules.
proto_library(
name = "helloworld_proto",
srcs = ["protos/helloworld.proto"],
)
cc_proto_library(
name = "helloworld_cc_proto",
deps = [":helloworld_proto"],
)
cc_grpc_library(
name = "helloworld_cc_grpc",
srcs = [":helloworld_proto"],
grpc_only = True,
deps = [":helloworld_cc_proto"],
)
grpc_proto_library(
name = "route_guide",
srcs = ["protos/route_guide.proto"],
)
proto_library(
name = "keyvaluestore_proto",
srcs = ["protos/keyvaluestore.proto"],
)
grpc_proto_library(
name = "keyvaluestore",
srcs = ["protos/keyvaluestore.proto"],
)
proto_library(
name = "protos/helloworld_proto",
srcs = ["protos/helloworld.proto"],
)
py_proto_library(
name = "helloworld_py_pb2",
deps = [":protos/helloworld_proto"],
)
py_grpc_library(
name = "helloworld_py_pb2_grpc",
srcs = [":protos/helloworld_proto"],
deps = [":helloworld_py_pb2"],
)
cc_binary(
name = "greeter_client",
srcs = ["cpp/helloworld/greeter_client.cc"],
defines = ["BAZEL_BUILD"],
deps = [
":helloworld_cc_grpc",
"//:grpc++",
],
)
cc_binary(
name = "greeter_async_client",
srcs = ["cpp/helloworld/greeter_async_client.cc"],
defines = ["BAZEL_BUILD"],
deps = [
":helloworld_cc_grpc",
"//:grpc++",
],
)
cc_binary(
name = "greeter_async_client2",
srcs = ["cpp/helloworld/greeter_async_client2.cc"],
defines = ["BAZEL_BUILD"],
deps = [
":helloworld_cc_grpc",
"//:grpc++",
],
)
cc_binary(
name = "greeter_server",
srcs = ["cpp/helloworld/greeter_server.cc"],
defines = ["BAZEL_BUILD"],
deps = [
":helloworld_cc_grpc",
"//:grpc++",
"//:grpc++_reflection",
],
)
cc_binary(
name = "greeter_async_server",
srcs = ["cpp/helloworld/greeter_async_server.cc"],
defines = ["BAZEL_BUILD"],
deps = [
":helloworld_cc_grpc",
"//:grpc++",
],
)
cc_binary(
name = "metadata_client",
srcs = ["cpp/metadata/greeter_client.cc"],
defines = ["BAZEL_BUILD"],
deps = [
":helloworld_cc_grpc",
"//:grpc++",
],
)
cc_binary(
name = "metadata_server",
srcs = ["cpp/metadata/greeter_server.cc"],
defines = ["BAZEL_BUILD"],
deps = [
":helloworld_cc_grpc",
"//:grpc++",
],
)
cc_binary(
name = "lb_client",
srcs = ["cpp/load_balancing/greeter_client.cc"],
defines = ["BAZEL_BUILD"],
deps = [
":helloworld_cc_grpc",
"//:grpc++",
],
)
cc_binary(
name = "lb_server",
srcs = ["cpp/load_balancing/greeter_server.cc"],
defines = ["BAZEL_BUILD"],
deps = [
":helloworld_cc_grpc",
"//:grpc++",
],
)
cc_binary(
name = "compression_client",
srcs = ["cpp/compression/greeter_client.cc"],
defines = ["BAZEL_BUILD"],
deps = [
":helloworld_cc_grpc",
"//:grpc++",
],
)
cc_binary(
name = "compression_server",
srcs = ["cpp/compression/greeter_server.cc"],
defines = ["BAZEL_BUILD"],
deps = [
":helloworld_cc_grpc",
"//:grpc++",
],
)
cc_binary(
name = "keyvaluestore_client",
srcs = [
"cpp/keyvaluestore/caching_interceptor.h",
"cpp/keyvaluestore/client.cc",
],
defines = ["BAZEL_BUILD"],
deps = [
":keyvaluestore",
"//:grpc++",
],
)
cc_binary(
name = "keyvaluestore_server",
srcs = ["cpp/keyvaluestore/server.cc"],
defines = ["BAZEL_BUILD"],
deps = [
":keyvaluestore",
"//:grpc++",
],
)
cc_binary(
name = "route_guide_client",
srcs = [
"cpp/route_guide/helper.cc",
"cpp/route_guide/helper.h",
"cpp/route_guide/route_guide_client.cc",
],
data = ["cpp/route_guide/route_guide_db.json"],
defines = ["BAZEL_BUILD"],
deps = [
":route_guide",
"//:grpc++",
],
)
cc_binary(
name = "route_guide_server",
srcs = [
"cpp/route_guide/helper.cc",
"cpp/route_guide/helper.h",
"cpp/route_guide/route_guide_server.cc",
],
data = ["cpp/route_guide/route_guide_db.json"],
defines = ["BAZEL_BUILD"],
deps = [
":route_guide",
"//:grpc++",
],
)
proto_library(
name = "route_guide_proto",
srcs = ["protos/route_guide.proto"],
)

@ -0,0 +1,35 @@
# Copyright 2020 the 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.
licenses(["notice"]) # 3-clause BSD
cc_binary(
name = "compression_client",
srcs = ["greeter_client.cc"],
defines = ["BAZEL_BUILD"],
deps = [
"//:grpc++",
"//examples/protos:helloworld_cc_grpc",
],
)
cc_binary(
name = "compression_server",
srcs = ["greeter_server.cc"],
defines = ["BAZEL_BUILD"],
deps = [
"//:grpc++",
"//examples/protos:helloworld_cc_grpc",
],
)

@ -0,0 +1,66 @@
# Copyright 2020 the 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.
licenses(["notice"]) # 3-clause BSD
cc_binary(
name = "greeter_client",
srcs = ["greeter_client.cc"],
defines = ["BAZEL_BUILD"],
deps = [
"//:grpc++",
"//examples/protos:helloworld_cc_grpc",
],
)
cc_binary(
name = "greeter_async_client",
srcs = ["greeter_async_client.cc"],
defines = ["BAZEL_BUILD"],
deps = [
"//:grpc++",
"//examples/protos:helloworld_cc_grpc",
],
)
cc_binary(
name = "greeter_async_client2",
srcs = ["greeter_async_client2.cc"],
defines = ["BAZEL_BUILD"],
deps = [
"//:grpc++",
"//examples/protos:helloworld_cc_grpc",
],
)
cc_binary(
name = "greeter_server",
srcs = ["greeter_server.cc"],
defines = ["BAZEL_BUILD"],
deps = [
"//:grpc++",
"//:grpc++_reflection",
"//examples/protos:helloworld_cc_grpc",
],
)
cc_binary(
name = "greeter_async_server",
srcs = ["greeter_async_server.cc"],
defines = ["BAZEL_BUILD"],
deps = [
"//:grpc++",
"//examples/protos:helloworld_cc_grpc",
],
)

@ -0,0 +1,38 @@
# Copyright 2020 the 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.
licenses(["notice"]) # 3-clause BSD
cc_binary(
name = "keyvaluestore_client",
srcs = [
"caching_interceptor.h",
"client.cc",
],
defines = ["BAZEL_BUILD"],
deps = [
"//:grpc++",
"//examples/protos:keyvaluestore",
],
)
cc_binary(
name = "keyvaluestore_server",
srcs = ["server.cc"],
defines = ["BAZEL_BUILD"],
deps = [
"//:grpc++",
"//examples/protos:keyvaluestore",
],
)

@ -0,0 +1,35 @@
# Copyright 2020 the 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.
licenses(["notice"]) # 3-clause BSD
cc_binary(
name = "lb_server",
srcs = ["greeter_server.cc"],
defines = ["BAZEL_BUILD"],
deps = [
"//:grpc++",
"//examples/protos:helloworld_cc_grpc",
],
)
cc_binary(
name = "lb_client",
srcs = ["greeter_client.cc"],
defines = ["BAZEL_BUILD"],
deps = [
"//:grpc++",
"//examples/protos:helloworld_cc_grpc",
],
)

@ -0,0 +1,35 @@
# Copyright 2020 the 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.
licenses(["notice"]) # 3-clause BSD
cc_binary(
name = "metadata_client",
srcs = ["greeter_client.cc"],
defines = ["BAZEL_BUILD"],
deps = [
"//:grpc++",
"//examples/protos:helloworld_cc_grpc",
],
)
cc_binary(
name = "metadata_server",
srcs = ["greeter_server.cc"],
defines = ["BAZEL_BUILD"],
deps = [
"//:grpc++",
"//examples/protos:helloworld_cc_grpc",
],
)

@ -0,0 +1,56 @@
# Copyright 2020 the 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.
licenses(["notice"]) # 3-clause BSD
cc_library(
name = "route_guide_helper",
srcs = [
"helper.cc",
"helper.h",
],
defines = ["BAZEL_BUILD"],
deps = [
"//:grpc++",
"//examples/protos:route_guide",
],
)
cc_binary(
name = "route_guide_client",
srcs = [
"route_guide_client.cc",
],
data = ["route_guide_db.json"],
defines = ["BAZEL_BUILD"],
deps = [
":route_guide_helper",
"//:grpc++",
"//examples/protos:route_guide",
],
)
cc_binary(
name = "route_guide_server",
srcs = [
"route_guide_server.cc",
],
data = ["route_guide_db.json"],
defines = ["BAZEL_BUILD"],
deps = [
":route_guide_helper",
"//:grpc++",
"//examples/protos:route_guide",
],
)

@ -0,0 +1,62 @@
/*
*
* Copyright 2015 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.
*
*/
var PROTO_PATH = __dirname + '/../../protos/helloworld.proto';
var parseArgs = require('minimist');
var grpc = require('@grpc/grpc-js');
var grpc_xds = require('@grpc/grpc-js-xds');
grpc_xds.register();
var protoLoader = require('@grpc/proto-loader');
var packageDefinition = protoLoader.loadSync(
PROTO_PATH,
{keepCase: true,
longs: String,
enums: String,
defaults: true,
oneofs: true
});
var hello_proto = grpc.loadPackageDefinition(packageDefinition).helloworld;
function main() {
var argv = parseArgs(process.argv.slice(2), {
string: 'target'
});
var target;
if (argv.target) {
target = argv.target;
} else {
target = 'localhost:50051';
}
var client = new hello_proto.Greeter(target,
grpc.credentials.createInsecure());
var user;
if (argv._.length > 0) {
user = argv._[0];
} else {
user = 'world';
}
client.sayHello({name: user}, function(err, response) {
if (err) throw err;
console.log('Greeting:', response.message);
client.close();
});
}
main();

@ -0,0 +1,10 @@
{
"name": "grpc-examples-xds",
"version": "0.1.0",
"dependencies": {
"@grpc/proto-loader": "^0.5.0",
"@grpc/grpc-js": "^1.2.0",
"@grpc/grpc-js-xds": "^1.2.0",
"minimist": "^1.2.0"
}
}

@ -22,17 +22,17 @@ load("@build_bazel_rules_apple//apple:macos.bzl", "macos_application")
objc_grpc_library(
name = "HelloWorld_grpc_proto",
srcs = ["//examples:protos/helloworld.proto"],
srcs = ["//examples/protos:helloworld.proto"],
tags = ["manual"],
deps = ["//examples:helloworld_proto"],
deps = ["//examples/protos:helloworld_proto"],
)
# This one works with import "external/com_github_grpc_grpc/examples/protos/Keyvaluestore.pbrpc.h"
objc_grpc_library(
name = "Keyvaluestore_grpc_proto_external",
srcs = ["//external/com_github_grpc_grpc/examples:protos/keyvaluestore.proto"],
srcs = ["//external/com_github_grpc_grpc/examples/protos:keyvaluestore.proto"],
tags = ["manual"],
deps = ["@com_github_grpc_grpc//examples:keyvaluestore_proto"],
deps = ["@com_github_grpc_grpc//examples/protos:keyvaluestore_proto"],
)
objc_library(
@ -86,9 +86,9 @@ macos_application(
objc_grpc_library(
name = "RouteGuide",
srcs = ["//examples:protos/route_guide.proto"],
srcs = ["//examples/protos:route_guide.proto"],
tags = ["manual"],
deps = ["//examples:route_guide_proto"],
deps = ["//examples/protos:route_guide_proto"],
)
objc_library(

@ -84,7 +84,7 @@ $ bazel build :HelloWorld
#### Try it!
To run the Hello World sample properly, we need a local server. Let's compile and run the corresponding C++ server:
```shell
$ bazel run //examples:greeter_server
$ bazel run //examples/cpp/helloworld:greeter_server
```
To run the sample, you need to know the available simulator runtimes in your machine. You could either list the available runtimes yourself by running:

@ -0,0 +1,83 @@
# Copyright 2020 the 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.
licenses(["notice"]) # 3-clause BSD
package(default_visibility = ["//visibility:public"])
load("@grpc_python_dependencies//:requirements.bzl", "requirement")
load("@rules_proto//proto:defs.bzl", "proto_library")
load("//bazel:cc_grpc_library.bzl", "cc_grpc_library")
load("//bazel:grpc_build_system.bzl", "grpc_proto_library")
load("//bazel:python_rules.bzl", "py_grpc_library", "py_proto_library")
grpc_proto_library(
name = "auth_sample",
srcs = ["auth_sample.proto"],
)
grpc_proto_library(
name = "hellostreamingworld",
srcs = ["hellostreamingworld.proto"],
)
# The following three rules demonstrate the usage of the cc_grpc_library rule in
# in a mode compatible with the native proto_library and cc_proto_library rules.
proto_library(
name = "helloworld_proto",
srcs = ["helloworld.proto"],
)
cc_proto_library(
name = "helloworld_cc_proto",
deps = [":helloworld_proto"],
)
cc_grpc_library(
name = "helloworld_cc_grpc",
srcs = [":helloworld_proto"],
grpc_only = True,
deps = [":helloworld_cc_proto"],
)
grpc_proto_library(
name = "route_guide",
srcs = ["route_guide.proto"],
)
proto_library(
name = "keyvaluestore_proto",
srcs = ["keyvaluestore.proto"],
)
grpc_proto_library(
name = "keyvaluestore",
srcs = ["keyvaluestore.proto"],
)
py_proto_library(
name = "helloworld_py_pb2",
deps = [":helloworld_proto"],
)
py_grpc_library(
name = "helloworld_py_pb2_grpc",
srcs = [":helloworld_proto"],
deps = [":helloworld_py_pb2"],
)
proto_library(
name = "route_guide_proto",
srcs = [":route_guide.proto"],
)

@ -0,0 +1,50 @@
# gRPC Python Non-Blocking Streaming RPC Client Example
The goal of this example is to demonstrate how to handle streaming responses
without blocking the current thread. Effectively, this can be achieved by
converting the gRPC Python streaming API into callback-based.
In this example, the RPC service `Phone` simulates the life cycle of virtual
phone calls. It requires one thread to handle the phone-call session state
changes, and another thread to process the audio stream. In this case, the
normal blocking style API could not fulfill the need easily. Hence, we should
asynchronously execute the streaming RPC.
## Steps to run this example
Start the server in one session
```
python3 server.py
```
Start the client in another session
```
python3 client.py
```
## Example Output
```
$ python3 server.py
INFO:root:Server serving at [::]:50051
INFO:root:Received a phone call request for number [1415926535]
INFO:root:Created a call session [{
"sessionId": "0",
"media": "https://link.to.audio.resources"
}]
INFO:root:Call finished [1415926535]
INFO:root:Call session cleaned [{
"sessionId": "0",
"media": "https://link.to.audio.resources"
}]
```
```
$ python3 client.py
INFO:root:Waiting for peer to connect [1415926535]...
INFO:root:Call toward [1415926535] enters [NEW] state
INFO:root:Call toward [1415926535] enters [ACTIVE] state
INFO:root:Consuming audio resource [https://link.to.audio.resources]
INFO:root:Call toward [1415926535] enters [ENDED] state
INFO:root:Audio session finished [https://link.to.audio.resources]
INFO:root:Call finished!
```

@ -0,0 +1,119 @@
# Copyright 2020 The 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.
import logging
import threading
from typing import Iterator
from concurrent.futures import ThreadPoolExecutor
import grpc
import phone_pb2
import phone_pb2_grpc
class CallMaker:
def __init__(self, executor: ThreadPoolExecutor, channel: grpc.Channel,
phone_number: str) -> None:
self._executor = executor
self._channel = channel
self._stub = phone_pb2_grpc.PhoneStub(self._channel)
self._phone_number = phone_number
self._session_id = None
self._audio_session_link = None
self._call_state = None
self._peer_responded = threading.Event()
self._call_finished = threading.Event()
self._consumer_future = None
def _response_watcher(
self,
response_iterator: Iterator[phone_pb2.StreamCallResponse]) -> None:
try:
for response in response_iterator:
# NOTE: All fields in Proto3 are optional. This is the recommended way
# to check if a field is present or not, or to exam which one-of field is
# fulfilled by this message.
if response.HasField("call_info"):
self._on_call_info(response.call_info)
elif response.HasField("call_state"):
self._on_call_state(response.call_state.state)
else:
raise RuntimeError(
"Received StreamCallResponse without call_info and call_state"
)
except Exception as e:
self._peer_responded.set()
raise
def _on_call_info(self, call_info: phone_pb2.CallInfo) -> None:
self._session_id = call_info.session_id
self._audio_session_link = call_info.media
def _on_call_state(self, call_state: phone_pb2.CallState.State) -> None:
logging.info("Call toward [%s] enters [%s] state", self._phone_number,
phone_pb2.CallState.State.Name(call_state))
self._call_state = call_state
if call_state is phone_pb2.CallState.State.ACTIVE:
self._peer_responded.set()
if call_state is phone_pb2.CallState.State.ENDED:
self._peer_responded.set()
self._call_finished.set()
def call(self) -> None:
request = phone_pb2.StreamCallRequest()
request.phone_number = self._phone_number
response_iterator = self._stub.StreamCall(iter((request,)))
# Instead of consuming the response on current thread, spawn a consumption thread.
self._consumer_future = self._executor.submit(self._response_watcher,
response_iterator)
def wait_peer(self) -> None:
logging.info("Waiting for peer to connect [%s]...", self._phone_number)
self._peer_responded.wait(timeout=None)
if self._consumer_future.done():
# If the future raises, forwards the exception here
self._consumer_future.result()
return self._call_state is phone_pb2.CallState.State.ACTIVE
def audio_session(self) -> None:
assert self._audio_session_link is not None
logging.info("Consuming audio resource [%s]", self._audio_session_link)
self._call_finished.wait(timeout=None)
logging.info("Audio session finished [%s]", self._audio_session_link)
def process_call(executor: ThreadPoolExecutor, channel: grpc.Channel,
phone_number: str) -> None:
call_maker = CallMaker(executor, channel, phone_number)
call_maker.call()
if call_maker.wait_peer():
call_maker.audio_session()
logging.info("Call finished!")
else:
logging.info("Call failed: peer didn't answer")
def run():
executor = ThreadPoolExecutor()
with grpc.insecure_channel("localhost:50051") as channel:
future = executor.submit(process_call, executor, channel,
"555-0100-XXXX")
future.result()
if __name__ == '__main__':
logging.basicConfig(level=logging.INFO)
run()

@ -0,0 +1,52 @@
// Copyright 2020 The 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.
syntax = "proto3";
package grpc.testing;
message CallInfo {
string session_id = 1;
string media = 2;
}
message CallState {
enum State {
// The default state.
UNDEFINED = 0;
// The call is newly created.
NEW = 1;
// The call is connected.
ACTIVE = 6;
// The call is finished.
ENDED = 7;
}
State state = 2;
}
message StreamCallRequest {
string phone_number = 1;
}
message StreamCallResponse {
oneof stream_call_response {
CallInfo call_info = 1;
CallState call_state = 2;
}
}
service Phone {
// Makes a phone call and communicate states via a stream.
rpc StreamCall(stream StreamCallRequest) returns (stream StreamCallResponse);
}

@ -0,0 +1,267 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: phone.proto
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor.FileDescriptor(
name='phone.proto',
package='grpc.testing',
syntax='proto3',
serialized_options=None,
serialized_pb=b'\n\x0bphone.proto\x12\x0cgrpc.testing\"-\n\x08\x43\x61llInfo\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\r\n\x05media\x18\x02 \x01(\t\"q\n\tCallState\x12,\n\x05state\x18\x02 \x01(\x0e\x32\x1d.grpc.testing.CallState.State\"6\n\x05State\x12\r\n\tUNDEFINED\x10\x00\x12\x07\n\x03NEW\x10\x01\x12\n\n\x06\x41\x43TIVE\x10\x06\x12\t\n\x05\x45NDED\x10\x07\")\n\x11StreamCallRequest\x12\x14\n\x0cphone_number\x18\x01 \x01(\t\"\x88\x01\n\x12StreamCallResponse\x12+\n\tcall_info\x18\x01 \x01(\x0b\x32\x16.grpc.testing.CallInfoH\x00\x12-\n\ncall_state\x18\x02 \x01(\x0b\x32\x17.grpc.testing.CallStateH\x00\x42\x16\n\x14stream_call_response2\\\n\x05Phone\x12S\n\nStreamCall\x12\x1f.grpc.testing.StreamCallRequest\x1a .grpc.testing.StreamCallResponse(\x01\x30\x01\x62\x06proto3'
)
_CALLSTATE_STATE = _descriptor.EnumDescriptor(
name='State',
full_name='grpc.testing.CallState.State',
filename=None,
file=DESCRIPTOR,
values=[
_descriptor.EnumValueDescriptor(
name='UNDEFINED', index=0, number=0,
serialized_options=None,
type=None),
_descriptor.EnumValueDescriptor(
name='NEW', index=1, number=1,
serialized_options=None,
type=None),
_descriptor.EnumValueDescriptor(
name='ACTIVE', index=2, number=6,
serialized_options=None,
type=None),
_descriptor.EnumValueDescriptor(
name='ENDED', index=3, number=7,
serialized_options=None,
type=None),
],
containing_type=None,
serialized_options=None,
serialized_start=135,
serialized_end=189,
)
_sym_db.RegisterEnumDescriptor(_CALLSTATE_STATE)
_CALLINFO = _descriptor.Descriptor(
name='CallInfo',
full_name='grpc.testing.CallInfo',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='session_id', full_name='grpc.testing.CallInfo.session_id', index=0,
number=1, type=9, cpp_type=9, label=1,
has_default_value=False, default_value=b"".decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='media', full_name='grpc.testing.CallInfo.media', index=1,
number=2, type=9, cpp_type=9, label=1,
has_default_value=False, default_value=b"".decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto3',
extension_ranges=[],
oneofs=[
],
serialized_start=29,
serialized_end=74,
)
_CALLSTATE = _descriptor.Descriptor(
name='CallState',
full_name='grpc.testing.CallState',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='state', full_name='grpc.testing.CallState.state', index=0,
number=2, type=14, cpp_type=8, label=1,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
_CALLSTATE_STATE,
],
serialized_options=None,
is_extendable=False,
syntax='proto3',
extension_ranges=[],
oneofs=[
],
serialized_start=76,
serialized_end=189,
)
_STREAMCALLREQUEST = _descriptor.Descriptor(
name='StreamCallRequest',
full_name='grpc.testing.StreamCallRequest',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='phone_number', full_name='grpc.testing.StreamCallRequest.phone_number', index=0,
number=1, type=9, cpp_type=9, label=1,
has_default_value=False, default_value=b"".decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto3',
extension_ranges=[],
oneofs=[
],
serialized_start=191,
serialized_end=232,
)
_STREAMCALLRESPONSE = _descriptor.Descriptor(
name='StreamCallResponse',
full_name='grpc.testing.StreamCallResponse',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='call_info', full_name='grpc.testing.StreamCallResponse.call_info', index=0,
number=1, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='call_state', full_name='grpc.testing.StreamCallResponse.call_state', index=1,
number=2, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto3',
extension_ranges=[],
oneofs=[
_descriptor.OneofDescriptor(
name='stream_call_response', full_name='grpc.testing.StreamCallResponse.stream_call_response',
index=0, containing_type=None, fields=[]),
],
serialized_start=235,
serialized_end=371,
)
_CALLSTATE.fields_by_name['state'].enum_type = _CALLSTATE_STATE
_CALLSTATE_STATE.containing_type = _CALLSTATE
_STREAMCALLRESPONSE.fields_by_name['call_info'].message_type = _CALLINFO
_STREAMCALLRESPONSE.fields_by_name['call_state'].message_type = _CALLSTATE
_STREAMCALLRESPONSE.oneofs_by_name['stream_call_response'].fields.append(
_STREAMCALLRESPONSE.fields_by_name['call_info'])
_STREAMCALLRESPONSE.fields_by_name['call_info'].containing_oneof = _STREAMCALLRESPONSE.oneofs_by_name['stream_call_response']
_STREAMCALLRESPONSE.oneofs_by_name['stream_call_response'].fields.append(
_STREAMCALLRESPONSE.fields_by_name['call_state'])
_STREAMCALLRESPONSE.fields_by_name['call_state'].containing_oneof = _STREAMCALLRESPONSE.oneofs_by_name['stream_call_response']
DESCRIPTOR.message_types_by_name['CallInfo'] = _CALLINFO
DESCRIPTOR.message_types_by_name['CallState'] = _CALLSTATE
DESCRIPTOR.message_types_by_name['StreamCallRequest'] = _STREAMCALLREQUEST
DESCRIPTOR.message_types_by_name['StreamCallResponse'] = _STREAMCALLRESPONSE
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
CallInfo = _reflection.GeneratedProtocolMessageType('CallInfo', (_message.Message,), {
'DESCRIPTOR' : _CALLINFO,
'__module__' : 'phone_pb2'
# @@protoc_insertion_point(class_scope:grpc.testing.CallInfo)
})
_sym_db.RegisterMessage(CallInfo)
CallState = _reflection.GeneratedProtocolMessageType('CallState', (_message.Message,), {
'DESCRIPTOR' : _CALLSTATE,
'__module__' : 'phone_pb2'
# @@protoc_insertion_point(class_scope:grpc.testing.CallState)
})
_sym_db.RegisterMessage(CallState)
StreamCallRequest = _reflection.GeneratedProtocolMessageType('StreamCallRequest', (_message.Message,), {
'DESCRIPTOR' : _STREAMCALLREQUEST,
'__module__' : 'phone_pb2'
# @@protoc_insertion_point(class_scope:grpc.testing.StreamCallRequest)
})
_sym_db.RegisterMessage(StreamCallRequest)
StreamCallResponse = _reflection.GeneratedProtocolMessageType('StreamCallResponse', (_message.Message,), {
'DESCRIPTOR' : _STREAMCALLRESPONSE,
'__module__' : 'phone_pb2'
# @@protoc_insertion_point(class_scope:grpc.testing.StreamCallResponse)
})
_sym_db.RegisterMessage(StreamCallResponse)
_PHONE = _descriptor.ServiceDescriptor(
name='Phone',
full_name='grpc.testing.Phone',
file=DESCRIPTOR,
index=0,
serialized_options=None,
serialized_start=373,
serialized_end=465,
methods=[
_descriptor.MethodDescriptor(
name='StreamCall',
full_name='grpc.testing.Phone.StreamCall',
index=0,
containing_service=None,
input_type=_STREAMCALLREQUEST,
output_type=_STREAMCALLRESPONSE,
serialized_options=None,
),
])
_sym_db.RegisterServiceDescriptor(_PHONE)
DESCRIPTOR.services_by_name['Phone'] = _PHONE
# @@protoc_insertion_point(module_scope)

@ -0,0 +1,65 @@
# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
import grpc
import phone_pb2 as phone__pb2
class PhoneStub(object):
"""Missing associated documentation comment in .proto file"""
def __init__(self, channel):
"""Constructor.
Args:
channel: A grpc.Channel.
"""
self.StreamCall = channel.stream_stream(
'/grpc.testing.Phone/StreamCall',
request_serializer=phone__pb2.StreamCallRequest.SerializeToString,
response_deserializer=phone__pb2.StreamCallResponse.FromString,
)
class PhoneServicer(object):
"""Missing associated documentation comment in .proto file"""
def StreamCall(self, request_iterator, context):
"""Makes a phone call and communicate states via a stream.
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def add_PhoneServicer_to_server(servicer, server):
rpc_method_handlers = {
'StreamCall': grpc.stream_stream_rpc_method_handler(
servicer.StreamCall,
request_deserializer=phone__pb2.StreamCallRequest.FromString,
response_serializer=phone__pb2.StreamCallResponse.SerializeToString,
),
}
generic_handler = grpc.method_handlers_generic_handler(
'grpc.testing.Phone', rpc_method_handlers)
server.add_generic_rpc_handlers((generic_handler,))
# This class is part of an EXPERIMENTAL API.
class Phone(object):
"""Missing associated documentation comment in .proto file"""
@staticmethod
def StreamCall(request_iterator,
target,
options=(),
channel_credentials=None,
call_credentials=None,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.stream_stream(request_iterator, target, '/grpc.testing.Phone/StreamCall',
phone__pb2.StreamCallRequest.SerializeToString,
phone__pb2.StreamCallResponse.FromString,
options, channel_credentials,
call_credentials, compression, wait_for_ready, timeout, metadata)

@ -0,0 +1,92 @@
# Copyright 2020 The 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.
import logging
import time
from concurrent.futures import ThreadPoolExecutor
from typing import Iterable
import threading
import grpc
from google.protobuf.json_format import MessageToJson
import phone_pb2
import phone_pb2_grpc
def create_state_response(call_state: phone_pb2.CallState.State
) -> phone_pb2.StreamCallResponse:
response = phone_pb2.StreamCallResponse()
response.call_state.state = call_state
return response
class Phone(phone_pb2_grpc.PhoneServicer):
def __init__(self):
self._id_counter = 0
self._lock = threading.RLock()
def _create_call_session(self) -> phone_pb2.CallInfo:
call_info = phone_pb2.CallInfo()
with self._lock:
call_info.session_id = str(self._id_counter)
self._id_counter += 1
call_info.media = "https://link.to.audio.resources"
logging.info("Created a call session [%s]", MessageToJson(call_info))
return call_info
def _clean_call_session(self, call_info: phone_pb2.CallInfo) -> None:
logging.info("Call session cleaned [%s]", MessageToJson(call_info))
def StreamCall(self,
request_iterator: Iterable[phone_pb2.StreamCallRequest],
context: grpc.ServicerContext
) -> Iterable[phone_pb2.StreamCallResponse]:
try:
request = next(request_iterator)
logging.info("Received a phone call request for number [%s]",
request.phone_number)
except StopIteration:
raise RuntimeError("Failed to receive call request")
# Simulate the acceptance of call request
time.sleep(1)
yield create_state_response(phone_pb2.CallState.NEW)
# Simulate the start of the call session
time.sleep(1)
call_info = self._create_call_session()
context.add_callback(lambda: self._clean_call_session(call_info))
response = phone_pb2.StreamCallResponse()
response.call_info.session_id = call_info.session_id
response.call_info.media = call_info.media
yield response
yield create_state_response(phone_pb2.CallState.ACTIVE)
# Simulate the end of the call
time.sleep(2)
yield create_state_response(phone_pb2.CallState.ENDED)
logging.info("Call finished [%s]", request.phone_number)
def serve(address: str) -> None:
server = grpc.server(ThreadPoolExecutor())
phone_pb2_grpc.add_PhoneServicer_to_server(Phone(), server)
server.add_insecure_port(address)
server.start()
logging.info("Server serving at %s", address)
server.wait_for_termination()
if __name__ == "__main__":
logging.basicConfig(level=logging.INFO)
serve("[::]:50051")

@ -18,8 +18,8 @@ py_binary(
python_version = "PY3",
srcs_version = "PY2AND3",
deps = [
"//examples:helloworld_py_pb2",
"//examples:helloworld_py_pb2_grpc",
"//examples/protos:helloworld_py_pb2",
"//examples/protos:helloworld_py_pb2_grpc",
"//src/python/grpcio/grpc:grpcio",
],
)
@ -30,8 +30,8 @@ py_binary(
python_version = "PY3",
srcs_version = "PY2AND3",
deps = [
"//examples:helloworld_py_pb2",
"//examples:helloworld_py_pb2_grpc",
"//examples/protos:helloworld_py_pb2",
"//examples/protos:helloworld_py_pb2_grpc",
"//src/python/grpcio/grpc:grpcio",
],
)

@ -21,8 +21,8 @@ import argparse
import logging
import grpc
from examples import helloworld_pb2
from examples import helloworld_pb2_grpc
from examples.protos import helloworld_pb2
from examples.protos import helloworld_pb2_grpc
_DESCRIPTION = 'A client capable of compression.'
_COMPRESSION_OPTIONS = {

@ -23,8 +23,8 @@ import logging
import threading
import grpc
from examples import helloworld_pb2
from examples import helloworld_pb2_grpc
from examples.protos import helloworld_pb2
from examples.protos import helloworld_pb2_grpc
_DESCRIPTION = 'A server capable of compression.'
_COMPRESSION_OPTIONS = {

@ -14,33 +14,35 @@
load("@grpc_python_dependencies//:requirements.bzl", "requirement")
package(default_testonly = 1)
py_binary(
name = "debug_server",
testonly = 1,
srcs = ["debug_server.py"],
data = ["helloworld.proto"],
imports = ["."],
python_version = "PY3",
deps = [
"//examples:helloworld_py_pb2",
"//examples:helloworld_py_pb2_grpc",
"//src/python/grpcio/grpc:grpcio",
"//src/python/grpcio_channelz/grpc_channelz/v1:grpc_channelz",
"//tools/distrib/python/grpcio_tools:grpc_tools",
],
)
py_binary(
name = "send_message",
testonly = 1,
srcs = ["send_message.py"],
data = ["helloworld.proto"],
imports = ["."],
python_version = "PY3",
deps = [
"//examples:helloworld_py_pb2",
"//examples:helloworld_py_pb2_grpc",
"//src/python/grpcio/grpc:grpcio",
"//tools/distrib/python/grpcio_tools:grpc_tools",
],
)
py_binary(
name = "get_stats",
testonly = 1,
srcs = ["get_stats.py"],
python_version = "PY3",
deps = [
@ -49,17 +51,52 @@ py_binary(
],
)
py_binary(
name = "asyncio_debug_server",
srcs = ["asyncio_debug_server.py"],
data = ["helloworld.proto"],
imports = ["."],
python_version = "PY3",
deps = [
"//src/python/grpcio/grpc:grpcio",
"//src/python/grpcio_channelz/grpc_channelz/v1:grpc_channelz",
"//tools/distrib/python/grpcio_tools:grpc_tools",
],
)
py_binary(
name = "asyncio_send_message",
srcs = ["asyncio_send_message.py"],
data = ["helloworld.proto"],
imports = ["."],
python_version = "PY3",
deps = [
"//src/python/grpcio/grpc:grpcio",
"//tools/distrib/python/grpcio_tools:grpc_tools",
],
)
py_binary(
name = "asyncio_get_stats",
srcs = ["asyncio_get_stats.py"],
python_version = "PY3",
deps = [
"//src/python/grpcio/grpc:grpcio",
"//src/python/grpcio_channelz/grpc_channelz/v1:grpc_channelz",
],
)
py_test(
name = "_debug_example_test",
srcs = ["test/_debug_example_test.py"],
imports = ["."],
python_version = "PY3",
deps = [
":asyncio_debug_server",
":asyncio_get_stats",
":asyncio_send_message",
":debug_server",
":get_stats",
":send_message",
"//examples:helloworld_py_pb2",
"//examples:helloworld_py_pb2_grpc",
"//src/python/grpcio/grpc:grpcio",
"//src/python/grpcio_channelz/grpc_channelz/v1:grpc_channelz",
],
)

@ -0,0 +1,83 @@
# Copyright 2020 The 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.
"""The Python AsyncIO example of utilizing Channelz feature."""
import asyncio
import argparse
import logging
import random
import grpc
helloworld_pb2, helloworld_pb2_grpc = grpc.protos_and_services(
"helloworld.proto")
# TODO: Suppress until the macOS segfault fix rolled out
from grpc_channelz.v1 import channelz # pylint: disable=wrong-import-position
_LOGGER = logging.getLogger(__name__)
_LOGGER.setLevel(logging.INFO)
_RANDOM_FAILURE_RATE = 0.3
class FaultInjectGreeter(helloworld_pb2_grpc.GreeterServicer):
def __init__(self, failure_rate):
self._failure_rate = failure_rate
async def SayHello(self, request: helloworld_pb2.HelloRequest,
context: grpc.aio.ServicerContext
) -> helloworld_pb2.HelloReply:
if random.random() < self._failure_rate:
context.abort(grpc.StatusCode.UNAVAILABLE,
'Randomly injected failure.')
return helloworld_pb2.HelloReply(message=f'Hello, {request.name}!')
def create_server(addr: str, failure_rate: float) -> grpc.aio.Server:
server = grpc.aio.server()
helloworld_pb2_grpc.add_GreeterServicer_to_server(
FaultInjectGreeter(failure_rate), server)
# Add Channelz Servicer to the gRPC server
channelz.add_channelz_servicer(server)
server.add_insecure_port(addr)
return server
async def main() -> None:
parser = argparse.ArgumentParser()
parser.add_argument('--addr',
nargs=1,
type=str,
default='[::]:50051',
help='the address to listen on')
parser.add_argument(
'--failure_rate',
nargs=1,
type=float,
default=0.3,
help='a float indicates the percentage of failed message injections')
args = parser.parse_args()
server = create_server(addr=args.addr, failure_rate=args.failure_rate)
await server.start()
await server.wait_for_termination()
if __name__ == '__main__':
logging.basicConfig(level=logging.INFO)
asyncio.get_event_loop().run_until_complete(main())

@ -0,0 +1,46 @@
# Copyright 2020 The 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.
"""Poll statistics from the server."""
import asyncio
import logging
import argparse
import grpc
from grpc_channelz.v1 import channelz_pb2
from grpc_channelz.v1 import channelz_pb2_grpc
async def run(addr: str) -> None:
async with grpc.aio.insecure_channel(addr) as channel:
channelz_stub = channelz_pb2_grpc.ChannelzStub(channel)
response = await channelz_stub.GetServers(
channelz_pb2.GetServersRequest(start_server_id=0))
print('Info for all servers: %s' % response)
async def main() -> None:
parser = argparse.ArgumentParser()
parser.add_argument('--addr',
nargs=1,
type=str,
default='[::]:50051',
help='the address to request')
args = parser.parse_args()
run(addr=args.addr)
if __name__ == '__main__':
logging.basicConfig()
asyncio.get_event_loop().run_until_complete(main())

@ -0,0 +1,61 @@
# Copyright 2020 The 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.
"""Send multiple greeting messages to the backend."""
import asyncio
import logging
import argparse
import grpc
helloworld_pb2, helloworld_pb2_grpc = grpc.protos_and_services(
"helloworld.proto")
async def process(stub: helloworld_pb2_grpc.GreeterStub,
request: helloworld_pb2.HelloRequest) -> None:
try:
response = await stub.SayHello(request)
except grpc.aio.AioRpcError as rpc_error:
print(f'Received error: {rpc_error}')
else:
print(f'Received message: {response}')
async def run(addr: str, n: int) -> None:
async with grpc.aio.insecure_channel(addr) as channel:
stub = helloworld_pb2_grpc.GreeterStub(channel)
request = helloworld_pb2.HelloRequest(name='you')
for _ in range(n):
await process(stub, request)
async def main() -> None:
parser = argparse.ArgumentParser()
parser.add_argument('--addr',
nargs=1,
type=str,
default='[::]:50051',
help='the address to request')
parser.add_argument('-n',
nargs=1,
type=int,
default=10,
help='an integer for number of messages to sent')
args = parser.parse_args()
await run(addr=args.addr, n=args.n)
if __name__ == '__main__':
logging.basicConfig(level=logging.INFO)
asyncio.get_event_loop().run_until_complete(main())

@ -23,10 +23,12 @@ from concurrent import futures
import random
import grpc
from grpc_channelz.v1 import channelz
from examples import helloworld_pb2
from examples import helloworld_pb2_grpc
helloworld_pb2, helloworld_pb2_grpc = grpc.protos_and_services(
"helloworld.proto")
# TODO: Suppress until the macOS segfault fix rolled out
from grpc_channelz.v1 import channelz # pylint: disable=wrong-import-position
_LOGGER = logging.getLogger(__name__)
_LOGGER.setLevel(logging.INFO)

@ -28,9 +28,11 @@ from grpc_channelz.v1 import channelz_pb2_grpc
def run(addr):
with grpc.insecure_channel(addr) as channel:
channelz_stub = channelz_pb2_grpc.ChannelzStub(channel)
response = channelz_stub.GetServers(
channelz_pb2.GetServersRequest(start_server_id=0))
print('Info for all servers: %s' % response)
# This RPC pulls server-level metrics, like sent/received messages,
# succeeded/failed RPCs. For more info see:
# https://github.com/grpc/grpc/blob/master/src/proto/grpc/channelz/channelz.proto
response = channelz_stub.GetServers(channelz_pb2.GetServersRequest())
print(f'Info for all servers: {response}')
def main():

@ -0,0 +1 @@
../../protos/helloworld.proto

@ -20,8 +20,9 @@ from __future__ import print_function
import logging
import argparse
import grpc
from examples import helloworld_pb2
from examples import helloworld_pb2_grpc
helloworld_pb2, helloworld_pb2_grpc = grpc.protos_and_services(
"helloworld.proto")
def process(stub, request):

@ -13,16 +13,16 @@
# limitations under the License.
"""Test for gRPC Python debug example."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import asyncio
import logging
import unittest
from examples.python.debug import debug_server
from examples.python.debug import asyncio_debug_server
from examples.python.debug import send_message
from examples.python.debug import asyncio_send_message
from examples.python.debug import get_stats
from examples.python.debug import asyncio_get_stats
_LOGGER = logging.getLogger(__name__)
_LOGGER.setLevel(logging.INFO)
@ -47,7 +47,23 @@ class DebugExampleTest(unittest.TestCase):
server.stop(None)
# No unhandled exception raised, test passed!
def test_asyncio_channelz_example(self):
async def body():
server = asyncio_debug_server.create_server(
addr='[::]:0', failure_rate=_FAILURE_RATE)
port = server.add_insecure_port('[::]:0')
await server.start()
address = _ADDR_TEMPLATE % port
await asyncio_send_message.run(addr=address, n=_NUMBER_OF_MESSAGES)
await asyncio_get_stats.run(addr=address)
await server.stop(None)
# No unhandled exception raised, test passed!
asyncio.get_event_loop().run_until_complete(body())
if __name__ == '__main__':
logging.basicConfig()
logging.basicConfig(level=logging.DEBUG)
unittest.main(verbosity=2)

@ -19,8 +19,8 @@ py_library(
testonly = 1,
srcs = ["client.py"],
deps = [
"//examples:helloworld_py_pb2",
"//examples:helloworld_py_pb2_grpc",
"//examples/protos:helloworld_py_pb2",
"//examples/protos:helloworld_py_pb2_grpc",
"//src/python/grpcio/grpc:grpcio",
"//src/python/grpcio_status/grpc_status",
requirement("googleapis-common-protos"),
@ -34,8 +34,8 @@ py_library(
deps = [
"//src/python/grpcio/grpc:grpcio",
"//src/python/grpcio_status/grpc_status:grpc_status",
"//examples:helloworld_py_pb2",
"//examples:helloworld_py_pb2_grpc",
"//examples/protos:helloworld_py_pb2",
"//examples/protos:helloworld_py_pb2_grpc",
] + select({
"//conditions:default": [requirement("futures")],
"//:python3": [],

@ -20,8 +20,8 @@ import grpc
from grpc_status import rpc_status
from google.rpc import error_details_pb2
from examples import helloworld_pb2
from examples import helloworld_pb2_grpc
from examples.protos import helloworld_pb2
from examples.protos import helloworld_pb2_grpc
_LOGGER = logging.getLogger(__name__)

@ -23,8 +23,8 @@ from grpc_status import rpc_status
from google.protobuf import any_pb2
from google.rpc import code_pb2, status_pb2, error_details_pb2
from examples import helloworld_pb2
from examples import helloworld_pb2_grpc
from examples.protos import helloworld_pb2
from examples.protos import helloworld_pb2_grpc
def create_greet_limit_exceed_error_status(name):

@ -26,7 +26,7 @@ import logging
import grpc
from examples import helloworld_pb2_grpc
from examples.protos import helloworld_pb2_grpc
from examples.python.errors import client as error_handling_client
from examples.python.errors import server as error_handling_server

@ -0,0 +1,129 @@
# Copyright 2020 The 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.
"""The Python AsyncIO implementation of the gRPC route guide client."""
import asyncio
import random
import logging
from typing import List, Iterable
import grpc
import route_guide_pb2
import route_guide_pb2_grpc
import route_guide_resources
def make_route_note(message: str, latitude: int,
longitude: int) -> route_guide_pb2.RouteNote:
return route_guide_pb2.RouteNote(
message=message,
location=route_guide_pb2.Point(latitude=latitude, longitude=longitude))
# Performs an unary call
async def guide_get_one_feature(stub: route_guide_pb2_grpc.RouteGuideStub,
point: route_guide_pb2.Point) -> None:
feature = await stub.GetFeature(point)
if not feature.location:
print("Server returned incomplete feature")
return
if feature.name:
print(f"Feature called {feature.name} at {feature.location}")
else:
print(f"Found no feature at {feature.location}")
async def guide_get_feature(stub: route_guide_pb2_grpc.RouteGuideStub) -> None:
await guide_get_one_feature(
stub, route_guide_pb2.Point(latitude=409146138, longitude=-746188906))
await guide_get_one_feature(stub,
route_guide_pb2.Point(latitude=0, longitude=0))
# Performs a server-streaming call
async def guide_list_features(stub: route_guide_pb2_grpc.RouteGuideStub
) -> None:
rectangle = route_guide_pb2.Rectangle(
lo=route_guide_pb2.Point(latitude=400000000, longitude=-750000000),
hi=route_guide_pb2.Point(latitude=420000000, longitude=-730000000))
print("Looking for features between 40, -75 and 42, -73")
features = stub.ListFeatures(rectangle)
async for feature in features:
print(f"Feature called {feature.name} at {feature.location}")
def generate_route(feature_list: List[route_guide_pb2.Feature]
) -> Iterable[route_guide_pb2.Point]:
for _ in range(0, 10):
random_feature = random.choice(feature_list)
print(f"Visiting point {random_feature.location}")
yield random_feature.location
# Performs a client-streaming call
async def guide_record_route(stub: route_guide_pb2_grpc.RouteGuideStub) -> None:
feature_list = route_guide_resources.read_route_guide_database()
route_iterator = generate_route(feature_list)
# gRPC AsyncIO client-streaming RPC API accepts both synchronous iterables
# and async iterables.
route_summary = await stub.RecordRoute(route_iterator)
print(f"Finished trip with {route_summary.point_count} points")
print(f"Passed {route_summary.feature_count} features")
print(f"Travelled {route_summary.distance} meters")
print(f"It took {route_summary.elapsed_time} seconds")
def generate_messages() -> Iterable[route_guide_pb2.RouteNote]:
messages = [
make_route_note("First message", 0, 0),
make_route_note("Second message", 0, 1),
make_route_note("Third message", 1, 0),
make_route_note("Fourth message", 0, 0),
make_route_note("Fifth message", 1, 0),
]
for msg in messages:
print(f"Sending {msg.message} at {msg.location}")
yield msg
# Performs a bidi-streaming call
async def guide_route_chat(stub: route_guide_pb2_grpc.RouteGuideStub) -> None:
# gRPC AsyncIO bidi-streaming RPC API accepts both synchronous iterables
# and async iterables.
call = stub.RouteChat(generate_messages())
async for response in call:
print(f"Received message {response.message} at {response.location}")
async def main() -> None:
async with grpc.aio.insecure_channel('localhost:50051') as channel:
stub = route_guide_pb2_grpc.RouteGuideStub(channel)
print("-------------- GetFeature --------------")
await guide_get_feature(stub)
print("-------------- ListFeatures --------------")
await guide_list_features(stub)
print("-------------- RecordRoute --------------")
await guide_record_route(stub)
print("-------------- RouteChat --------------")
await guide_route_chat(stub)
if __name__ == '__main__':
logging.basicConfig(level=logging.INFO)
asyncio.get_event_loop().run_until_complete(main())

@ -0,0 +1,134 @@
# Copyright 2020 The 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.
"""The Python AsyncIO implementation of the gRPC route guide server."""
import asyncio
import time
import math
import logging
from typing import AsyncIterable, Iterable
import grpc
import route_guide_pb2
import route_guide_pb2_grpc
import route_guide_resources
def get_feature(feature_db: Iterable[route_guide_pb2.Feature],
point: route_guide_pb2.Point) -> route_guide_pb2.Feature:
"""Returns Feature at given location or None."""
for feature in feature_db:
if feature.location == point:
return feature
return None
def get_distance(start: route_guide_pb2.Point,
end: route_guide_pb2.Point) -> float:
"""Distance between two points."""
coord_factor = 10000000.0
lat_1 = start.latitude / coord_factor
lat_2 = end.latitude / coord_factor
lon_1 = start.longitude / coord_factor
lon_2 = end.longitude / coord_factor
lat_rad_1 = math.radians(lat_1)
lat_rad_2 = math.radians(lat_2)
delta_lat_rad = math.radians(lat_2 - lat_1)
delta_lon_rad = math.radians(lon_2 - lon_1)
# Formula is based on http://mathforum.org/library/drmath/view/51879.html
a = (pow(math.sin(delta_lat_rad / 2), 2) +
(math.cos(lat_rad_1) * math.cos(lat_rad_2) *
pow(math.sin(delta_lon_rad / 2), 2)))
c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
R = 6371000
# metres
return R * c
class RouteGuideServicer(route_guide_pb2_grpc.RouteGuideServicer):
"""Provides methods that implement functionality of route guide server."""
def __init__(self) -> None:
self.db = route_guide_resources.read_route_guide_database()
def GetFeature(self, request: route_guide_pb2.Point,
unused_context) -> route_guide_pb2.Feature:
feature = get_feature(self.db, request)
if feature is None:
return route_guide_pb2.Feature(name="", location=request)
else:
return feature
async def ListFeatures(self, request: route_guide_pb2.Rectangle,
unused_context
) -> AsyncIterable[route_guide_pb2.Feature]:
left = min(request.lo.longitude, request.hi.longitude)
right = max(request.lo.longitude, request.hi.longitude)
top = max(request.lo.latitude, request.hi.latitude)
bottom = min(request.lo.latitude, request.hi.latitude)
for feature in self.db:
if (feature.location.longitude >= left and
feature.location.longitude <= right and
feature.location.latitude >= bottom and
feature.location.latitude <= top):
yield feature
async def RecordRoute(
self, request_iterator: AsyncIterable[route_guide_pb2.Point],
unused_context) -> route_guide_pb2.RouteSummary:
point_count = 0
feature_count = 0
distance = 0.0
prev_point = None
start_time = time.time()
async for point in request_iterator:
point_count += 1
if get_feature(self.db, point):
feature_count += 1
if prev_point:
distance += get_distance(prev_point, point)
prev_point = point
elapsed_time = time.time() - start_time
return route_guide_pb2.RouteSummary(point_count=point_count,
feature_count=feature_count,
distance=int(distance),
elapsed_time=int(elapsed_time))
async def RouteChat(
self, request_iterator: AsyncIterable[route_guide_pb2.RouteNote],
unused_context) -> AsyncIterable[route_guide_pb2.RouteNote]:
prev_notes = []
async for new_note in request_iterator:
for prev_note in prev_notes:
if prev_note.location == new_note.location:
yield prev_note
prev_notes.append(new_note)
async def serve() -> None:
server = grpc.aio.server()
route_guide_pb2_grpc.add_RouteGuideServicer_to_server(
RouteGuideServicer(), server)
server.add_insecure_port('[::]:50051')
await server.start()
await server.wait_for_termination()
if __name__ == '__main__':
logging.basicConfig(level=logging.INFO)
asyncio.get_event_loop().run_until_complete(serve())

@ -14,14 +14,29 @@
load("@grpc_python_dependencies//:requirements.bzl", "requirement")
py_library(
package(default_testonly = 1)
py_binary(
name = "wait_for_ready_example",
testonly = 1,
srcs = ["wait_for_ready_example.py"],
data = ["helloworld.proto"],
imports = ["."],
python_version = "PY3",
deps = [
"//src/python/grpcio/grpc:grpcio",
"//tools/distrib/python/grpcio_tools:grpc_tools",
],
)
py_binary(
name = "asyncio_wait_for_ready_example",
srcs = ["asyncio_wait_for_ready_example.py"],
data = ["helloworld.proto"],
imports = ["."],
python_version = "PY3",
deps = [
"//examples:helloworld_py_pb2",
"//examples:helloworld_py_pb2_grpc",
"//src/python/grpcio/grpc:grpcio",
"//tools/distrib/python/grpcio_tools:grpc_tools",
],
)
@ -30,5 +45,8 @@ py_test(
size = "small",
srcs = ["test/_wait_for_ready_example_test.py"],
python_version = "PY3",
deps = [":wait_for_ready_example"],
deps = [
":asyncio_wait_for_ready_example",
":wait_for_ready_example",
],
)

@ -0,0 +1,109 @@
# Copyright 2020 The 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.
"""The Python example of utilizing wait-for-ready flag."""
import asyncio
import logging
from contextlib import contextmanager
import socket
from typing import Iterable
import grpc
helloworld_pb2, helloworld_pb2_grpc = grpc.protos_and_services(
"helloworld.proto")
_LOGGER = logging.getLogger(__name__)
_LOGGER.setLevel(logging.INFO)
@contextmanager
def get_free_loopback_tcp_port() -> Iterable[str]:
if socket.has_ipv6:
tcp_socket = socket.socket(socket.AF_INET6)
else:
tcp_socket = socket.socket(socket.AF_INET)
tcp_socket.bind(('', 0))
address_tuple = tcp_socket.getsockname()
yield f"localhost:{address_tuple[1]}"
tcp_socket.close()
class Greeter(helloworld_pb2_grpc.GreeterServicer):
async def SayHello(self, request: helloworld_pb2.HelloRequest,
unused_context) -> helloworld_pb2.HelloReply:
return helloworld_pb2.HelloReply(message=f'Hello, {request.name}!')
def create_server(server_address: str):
server = grpc.aio.server()
helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
bound_port = server.add_insecure_port(server_address)
assert bound_port == int(server_address.split(':')[-1])
return server
async def process(stub: helloworld_pb2_grpc.GreeterStub,
wait_for_ready: bool = None) -> None:
try:
response = await stub.SayHello(helloworld_pb2.HelloRequest(name='you'),
wait_for_ready=wait_for_ready)
message = response.message
except grpc.aio.AioRpcError as rpc_error:
assert rpc_error.code() == grpc.StatusCode.UNAVAILABLE
assert not wait_for_ready
message = rpc_error
else:
assert wait_for_ready
_LOGGER.info("Wait-for-ready %s, client received: %s",
"enabled" if wait_for_ready else "disabled", message)
async def main() -> None:
# Pick a random free port
with get_free_loopback_tcp_port() as server_address:
# Create gRPC channel
channel = grpc.aio.insecure_channel(server_address)
stub = helloworld_pb2_grpc.GreeterStub(channel)
# Fire an RPC without wait_for_ready
fail_fast_task = asyncio.get_event_loop().create_task(
process(stub, wait_for_ready=False))
# Fire an RPC with wait_for_ready
wait_for_ready_task = asyncio.get_event_loop().create_task(
process(stub, wait_for_ready=True))
# Wait for the channel entering TRANSIENT FAILURE state.
state = channel.get_state()
while state != grpc.ChannelConnectivity.TRANSIENT_FAILURE:
await channel.wait_for_state_change(state)
state = channel.get_state()
# Start the server to handle the RPC
server = create_server(server_address)
await server.start()
# Expected to fail with StatusCode.UNAVAILABLE.
await fail_fast_task
# Expected to success.
await wait_for_ready_task
await server.stop(None)
await channel.close()
if __name__ == '__main__':
logging.basicConfig(level=logging.INFO)
asyncio.get_event_loop().run_until_complete(main())

@ -0,0 +1 @@
../../protos/helloworld.proto

@ -13,10 +13,12 @@
# limitations under the License.
"""Tests of the wait-for-ready example."""
import asyncio
import unittest
import logging
from examples.python.wait_for_ready import wait_for_ready_example
from examples.python.wait_for_ready import asyncio_wait_for_ready_example
class WaitForReadyExampleTest(unittest.TestCase):
@ -25,7 +27,12 @@ class WaitForReadyExampleTest(unittest.TestCase):
wait_for_ready_example.main()
# No unhandled exception raised, no deadlock, test passed!
def test_asyncio_wait_for_ready_example(self):
asyncio.get_event_loop().run_until_complete(
asyncio_wait_for_ready_example.main())
# No unhandled exception raised, no deadlock, test passed!
if __name__ == '__main__':
logging.basicConfig()
logging.basicConfig(level=logging.DEBUG)
unittest.main(verbosity=2)

@ -13,7 +13,6 @@
# limitations under the License.
"""The Python example of utilizing wait-for-ready flag."""
from __future__ import print_function
import logging
from concurrent import futures
from contextlib import contextmanager
@ -22,8 +21,8 @@ import threading
import grpc
from examples import helloworld_pb2
from examples import helloworld_pb2_grpc
helloworld_pb2, helloworld_pb2_grpc = grpc.protos_and_services(
"helloworld.proto")
_LOGGER = logging.getLogger(__name__)
_LOGGER.setLevel(logging.INFO)

@ -22,7 +22,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-C++'
# TODO (mxyan): use version that match gRPC version when pod is stabilized
version = '1.35.0-dev'
version = '1.36.0-dev'
s.version = version
s.summary = 'gRPC C++ library'
s.homepage = 'https://grpc.io'
@ -177,7 +177,8 @@ Pod::Spec.new do |s|
'include/grpcpp/support/stub_options.h',
'include/grpcpp/support/sync_stream.h',
'include/grpcpp/support/time.h',
'include/grpcpp/support/validate_service_config.h'
'include/grpcpp/support/validate_service_config.h',
'include/grpcpp/xds_server_builder.h'
end
s.subspec 'Implementation' do |ss|
@ -206,6 +207,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/client_channel_factory.h',
'src/core/ext/filters/client_channel/config_selector.h',
'src/core/ext/filters/client_channel/connector.h',
'src/core/ext/filters/client_channel/dynamic_filters.h',
'src/core/ext/filters/client_channel/global_subchannel_pool.h',
'src/core/ext/filters/client_channel/health/health_check_client.h',
'src/core/ext/filters/client_channel/http_connect_handshaker.h',
@ -221,6 +223,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h',
'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h',
'src/core/ext/filters/client_channel/lb_policy/xds/xds.h',
'src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_args.h',
'src/core/ext/filters/client_channel/lb_policy_factory.h',
'src/core/ext/filters/client_channel/lb_policy_registry.h',
'src/core/ext/filters/client_channel/local_subchannel_pool.h',
@ -505,7 +508,6 @@ Pod::Spec.new do |s|
'src/core/lib/gprpp/global_config_generic.h',
'src/core/lib/gprpp/host_port.h',
'src/core/lib/gprpp/manual_constructor.h',
'src/core/lib/gprpp/map.h',
'src/core/lib/gprpp/memory.h',
'src/core/lib/gprpp/mpscq.h',
'src/core/lib/gprpp/orphanable.h',
@ -797,10 +799,15 @@ Pod::Spec.new do |s|
'third_party/re2/util/test.h',
'third_party/re2/util/utf.h',
'third_party/re2/util/util.h',
'third_party/upb/third_party/wyhash/wyhash.h',
'third_party/upb/upb/decode.h',
'third_party/upb/upb/decode.int.h',
'third_party/upb/upb/decode_fast.h',
'third_party/upb/upb/def.h',
'third_party/upb/upb/def.hpp',
'third_party/upb/upb/encode.h',
'third_party/upb/upb/json_decode.h',
'third_party/upb/upb/json_encode.h',
'third_party/upb/upb/msg.h',
'third_party/upb/upb/port_def.inc',
'third_party/upb/upb/port_undef.inc',
@ -808,7 +815,8 @@ Pod::Spec.new do |s|
'third_party/upb/upb/table.int.h',
'third_party/upb/upb/text_encode.h',
'third_party/upb/upb/upb.h',
'third_party/upb/upb/upb.hpp'
'third_party/upb/upb/upb.hpp',
'third_party/upb/upb/upb.int.h'
ss.private_header_files = 'src/core/ext/filters/client_channel/backend_metric.h',
'src/core/ext/filters/client_channel/backup_poller.h',
@ -817,6 +825,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/client_channel_factory.h',
'src/core/ext/filters/client_channel/config_selector.h',
'src/core/ext/filters/client_channel/connector.h',
'src/core/ext/filters/client_channel/dynamic_filters.h',
'src/core/ext/filters/client_channel/global_subchannel_pool.h',
'src/core/ext/filters/client_channel/health/health_check_client.h',
'src/core/ext/filters/client_channel/http_connect_handshaker.h',
@ -832,6 +841,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h',
'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h',
'src/core/ext/filters/client_channel/lb_policy/xds/xds.h',
'src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_args.h',
'src/core/ext/filters/client_channel/lb_policy_factory.h',
'src/core/ext/filters/client_channel/lb_policy_registry.h',
'src/core/ext/filters/client_channel/local_subchannel_pool.h',
@ -1116,7 +1126,6 @@ Pod::Spec.new do |s|
'src/core/lib/gprpp/global_config_generic.h',
'src/core/lib/gprpp/host_port.h',
'src/core/lib/gprpp/manual_constructor.h',
'src/core/lib/gprpp/map.h',
'src/core/lib/gprpp/memory.h',
'src/core/lib/gprpp/mpscq.h',
'src/core/lib/gprpp/orphanable.h',
@ -1358,10 +1367,15 @@ Pod::Spec.new do |s|
'third_party/re2/util/test.h',
'third_party/re2/util/utf.h',
'third_party/re2/util/util.h',
'third_party/upb/third_party/wyhash/wyhash.h',
'third_party/upb/upb/decode.h',
'third_party/upb/upb/decode.int.h',
'third_party/upb/upb/decode_fast.h',
'third_party/upb/upb/def.h',
'third_party/upb/upb/def.hpp',
'third_party/upb/upb/encode.h',
'third_party/upb/upb/json_decode.h',
'third_party/upb/upb/json_encode.h',
'third_party/upb/upb/msg.h',
'third_party/upb/upb/port_def.inc',
'third_party/upb/upb/port_undef.inc',
@ -1369,7 +1383,8 @@ Pod::Spec.new do |s|
'third_party/upb/upb/table.int.h',
'third_party/upb/upb/text_encode.h',
'third_party/upb/upb/upb.h',
'third_party/upb/upb/upb.hpp'
'third_party/upb/upb/upb.hpp',
'third_party/upb/upb/upb.int.h'
end
s.subspec 'Protobuf' do |ss|
@ -1402,6 +1417,7 @@ Pod::Spec.new do |s|
s.prepare_command = <<-END_OF_COMMAND
sed -E -i '' 's;#include <openssl/(.*)>;#if COCOAPODS==1\\\n #include <openssl_grpc/\\1>\\\n#else\\\n #include <openssl/\\1>\\\n#endif;g' $(find src/core -type f \\( -path '*.h' -or -path '*.cc' \\) -print | xargs grep -H -c '#include <openssl_grpc/' | grep 0$ | cut -d':' -f1)
find third_party/upb/ -type f \\( -name '*.h' -or -name '*.hpp' -or -name '*.c' -or -name '*.cc' \\) -print0 | xargs -0 -L1 sed -E -i'.grpc_back' 's;#include "third_party/(.*)";#if COCOAPODS==1\\\n #include "third_party/upb/third_party/\\1"\\\n#else\\\n #include "third_party/\\1"\\\n#endif;g'
find src/core/ src/cpp/ third_party/upb/ -type f \\( -name '*.h' -or -name '*.hpp' -or -name '*.c' -or -name '*.cc' \\) -print0 | xargs -0 -L1 sed -E -i'.grpc_back' 's;#include "upb/(.*)";#if COCOAPODS==1\\\n #include "third_party/upb/upb/\\1"\\\n#else\\\n #include "upb/\\1"\\\n#endif;g'
find src/core/ src/cpp/ third_party/upb/ -type f -name '*.grpc_back' -print0 | xargs -0 rm
find src/core/ src/cpp/ third_party/upb/ -type f \\( -name '*.h' -or -name '*.c' -or -name '*.cc' \\) -print0 | xargs -0 -L1 sed -E -i'.grpc_back' 's;#include "(.*).upb.h";#if COCOAPODS==1\\\n #include "src/core/ext/upb-generated/\\1.upb.h"\\\n#else\\\n #include "\\1.upb.h"\\\n#endif;g'

@ -21,7 +21,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-Core'
version = '1.35.0-dev'
version = '1.36.0-dev'
s.version = version
s.summary = 'Core cross-platform gRPC library, written in C'
s.homepage = 'https://grpc.io'
@ -205,6 +205,8 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/config_selector.cc',
'src/core/ext/filters/client_channel/config_selector.h',
'src/core/ext/filters/client_channel/connector.h',
'src/core/ext/filters/client_channel/dynamic_filters.cc',
'src/core/ext/filters/client_channel/dynamic_filters.h',
'src/core/ext/filters/client_channel/global_subchannel_pool.cc',
'src/core/ext/filters/client_channel/global_subchannel_pool.h',
'src/core/ext/filters/client_channel/health/health_check_client.cc',
@ -237,10 +239,11 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h',
'src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc',
'src/core/ext/filters/client_channel/lb_policy/xds/cds.cc',
'src/core/ext/filters/client_channel/lb_policy/xds/eds.cc',
'src/core/ext/filters/client_channel/lb_policy/xds/xds.h',
'src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_args.h',
'src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc',
'src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc',
'src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc',
'src/core/ext/filters/client_channel/lb_policy_factory.h',
'src/core/ext/filters/client_channel/lb_policy_registry.cc',
'src/core/ext/filters/client_channel/lb_policy_registry.h',
@ -252,14 +255,12 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/resolver.cc',
'src/core/ext/filters/client_channel/resolver.h',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc',
@ -722,6 +723,7 @@ Pod::Spec.new do |s|
'src/core/ext/xds/xds_client.h',
'src/core/ext/xds/xds_client_stats.cc',
'src/core/ext/xds/xds_client_stats.h',
'src/core/ext/xds/xds_server_config_fetcher.cc',
'src/core/lib/avl/avl.cc',
'src/core/lib/avl/avl.h',
'src/core/lib/backoff/backoff.cc',
@ -832,7 +834,6 @@ Pod::Spec.new do |s|
'src/core/lib/gprpp/host_port.cc',
'src/core/lib/gprpp/host_port.h',
'src/core/lib/gprpp/manual_constructor.h',
'src/core/lib/gprpp/map.h',
'src/core/lib/gprpp/memory.h',
'src/core/lib/gprpp/mpscq.cc',
'src/core/lib/gprpp/mpscq.h',
@ -1319,16 +1320,23 @@ Pod::Spec.new do |s|
'third_party/re2/util/test.h',
'third_party/re2/util/utf.h',
'third_party/re2/util/util.h',
'third_party/upb/third_party/wyhash/wyhash.h',
'third_party/upb/upb/decode.c',
'third_party/upb/upb/decode.h',
'third_party/upb/upb/decode.int.h',
'third_party/upb/upb/decode_fast.c',
'third_party/upb/upb/decode_fast.h',
'third_party/upb/upb/def.c',
'third_party/upb/upb/def.h',
'third_party/upb/upb/def.hpp',
'third_party/upb/upb/encode.c',
'third_party/upb/upb/encode.h',
'third_party/upb/upb/json_decode.c',
'third_party/upb/upb/json_decode.h',
'third_party/upb/upb/json_encode.c',
'third_party/upb/upb/json_encode.h',
'third_party/upb/upb/msg.c',
'third_party/upb/upb/msg.h',
'third_party/upb/upb/port.c',
'third_party/upb/upb/port_def.inc',
'third_party/upb/upb/port_undef.inc',
'third_party/upb/upb/reflection.c',
@ -1339,7 +1347,8 @@ Pod::Spec.new do |s|
'third_party/upb/upb/text_encode.h',
'third_party/upb/upb/upb.c',
'third_party/upb/upb/upb.h',
'third_party/upb/upb/upb.hpp'
'third_party/upb/upb/upb.hpp',
'third_party/upb/upb/upb.int.h'
ss.private_header_files = 'src/core/ext/filters/client_channel/backend_metric.h',
'src/core/ext/filters/client_channel/backup_poller.h',
'src/core/ext/filters/client_channel/client_channel.h',
@ -1347,6 +1356,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/client_channel_factory.h',
'src/core/ext/filters/client_channel/config_selector.h',
'src/core/ext/filters/client_channel/connector.h',
'src/core/ext/filters/client_channel/dynamic_filters.h',
'src/core/ext/filters/client_channel/global_subchannel_pool.h',
'src/core/ext/filters/client_channel/health/health_check_client.h',
'src/core/ext/filters/client_channel/http_connect_handshaker.h',
@ -1362,6 +1372,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h',
'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h',
'src/core/ext/filters/client_channel/lb_policy/xds/xds.h',
'src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_args.h',
'src/core/ext/filters/client_channel/lb_policy_factory.h',
'src/core/ext/filters/client_channel/lb_policy_registry.h',
'src/core/ext/filters/client_channel/local_subchannel_pool.h',
@ -1646,7 +1657,6 @@ Pod::Spec.new do |s|
'src/core/lib/gprpp/global_config_generic.h',
'src/core/lib/gprpp/host_port.h',
'src/core/lib/gprpp/manual_constructor.h',
'src/core/lib/gprpp/map.h',
'src/core/lib/gprpp/memory.h',
'src/core/lib/gprpp/mpscq.h',
'src/core/lib/gprpp/orphanable.h',
@ -1877,10 +1887,15 @@ Pod::Spec.new do |s|
'third_party/re2/util/test.h',
'third_party/re2/util/utf.h',
'third_party/re2/util/util.h',
'third_party/upb/third_party/wyhash/wyhash.h',
'third_party/upb/upb/decode.h',
'third_party/upb/upb/decode.int.h',
'third_party/upb/upb/decode_fast.h',
'third_party/upb/upb/def.h',
'third_party/upb/upb/def.hpp',
'third_party/upb/upb/encode.h',
'third_party/upb/upb/json_decode.h',
'third_party/upb/upb/json_encode.h',
'third_party/upb/upb/msg.h',
'third_party/upb/upb/port_def.inc',
'third_party/upb/upb/port_undef.inc',
@ -1888,7 +1903,8 @@ Pod::Spec.new do |s|
'third_party/upb/upb/table.int.h',
'third_party/upb/upb/text_encode.h',
'third_party/upb/upb/upb.h',
'third_party/upb/upb/upb.hpp'
'third_party/upb/upb/upb.hpp',
'third_party/upb/upb/upb.int.h'
end
# CFStream is now default. Leaving this subspec only for compatibility purpose.
@ -2071,6 +2087,7 @@ Pod::Spec.new do |s|
# TODO (mxyan): Instead of this hack, add include path "third_party" to C core's include path?
s.prepare_command = <<-END_OF_COMMAND
sed -E -i '' 's;#include <openssl/(.*)>;#if COCOAPODS==1\\\n #include <openssl_grpc/\\1>\\\n#else\\\n #include <openssl/\\1>\\\n#endif;g' $(find src/core -type f \\( -path '*.h' -or -path '*.cc' \\) -print | xargs grep -H -c '#include <openssl_grpc/' | grep 0$ | cut -d':' -f1)
find third_party/upb/ -type f \\( -name '*.h' -or -name '*.hpp' -or -name '*.c' -or -name '*.cc' \\) -print0 | xargs -0 -L1 sed -E -i'.grpc_back' 's;#include "third_party/(.*)";#if COCOAPODS==1\\\n #include "third_party/upb/third_party/\\1"\\\n#else\\\n #include "third_party/\\1"\\\n#endif;g'
find src/core/ src/cpp/ third_party/upb/ -type f \\( -name '*.h' -or -name '*.hpp' -or -name '*.c' -or -name '*.cc' \\) -print0 | xargs -0 -L1 sed -E -i'.grpc_back' 's;#include "upb/(.*)";#if COCOAPODS==1\\\n #include "third_party/upb/upb/\\1"\\\n#else\\\n #include "upb/\\1"\\\n#endif;g'
find src/core/ src/cpp/ third_party/upb/ -type f -name '*.grpc_back' -print0 | xargs -0 rm
find src/core/ src/cpp/ third_party/upb/ -type f \\( -name '*.h' -or -name '*.c' -or -name '*.cc' \\) -print0 | xargs -0 -L1 sed -E -i'.grpc_back' 's;#include "(.*).upb.h";#if COCOAPODS==1\\\n #include "src/core/ext/upb-generated/\\1.upb.h"\\\n#else\\\n #include "\\1.upb.h"\\\n#endif;g'

@ -21,7 +21,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-ProtoRPC'
version = '1.35.0-dev'
version = '1.36.0-dev'
s.version = version
s.summary = 'RPC library for Protocol Buffers, based on gRPC'
s.homepage = 'https://grpc.io'

@ -21,7 +21,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-RxLibrary'
version = '1.35.0-dev'
version = '1.36.0-dev'
s.version = version
s.summary = 'Reactive Extensions library for iOS/OSX.'
s.homepage = 'https://grpc.io'

@ -20,7 +20,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC'
version = '1.35.0-dev'
version = '1.36.0-dev'
s.version = version
s.summary = 'gRPC client library for iOS/OSX'
s.homepage = 'https://grpc.io'

@ -57,6 +57,9 @@ EXPORTS
grpc_server_request_registered_call
grpc_server_create
grpc_server_register_completion_queue
grpc_server_config_fetcher_xds_create
grpc_server_config_fetcher_destroy
grpc_server_set_config_fetcher
grpc_server_add_insecure_http2_port
grpc_server_start
grpc_server_shutdown_and_notify
@ -107,6 +110,7 @@ EXPORTS
grpc_google_compute_engine_credentials_create
grpc_max_auth_token_lifetime
grpc_service_account_jwt_access_credentials_create
grpc_external_account_credentials_create
grpc_google_refresh_token_credentials_create
grpc_access_token_credentials_create
grpc_google_iam_credentials_create

@ -120,6 +120,8 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/filters/client_channel/config_selector.cc )
s.files += %w( src/core/ext/filters/client_channel/config_selector.h )
s.files += %w( src/core/ext/filters/client_channel/connector.h )
s.files += %w( src/core/ext/filters/client_channel/dynamic_filters.cc )
s.files += %w( src/core/ext/filters/client_channel/dynamic_filters.h )
s.files += %w( src/core/ext/filters/client_channel/global_subchannel_pool.cc )
s.files += %w( src/core/ext/filters/client_channel/global_subchannel_pool.h )
s.files += %w( src/core/ext/filters/client_channel/health/health_check_client.cc )
@ -152,10 +154,11 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/filters/client_channel/lb_policy/subchannel_list.h )
s.files += %w( src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc )
s.files += %w( src/core/ext/filters/client_channel/lb_policy/xds/cds.cc )
s.files += %w( src/core/ext/filters/client_channel/lb_policy/xds/eds.cc )
s.files += %w( src/core/ext/filters/client_channel/lb_policy/xds/xds.h )
s.files += %w( src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_args.h )
s.files += %w( src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc )
s.files += %w( src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc )
s.files += %w( src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc )
s.files += %w( src/core/ext/filters/client_channel/lb_policy_factory.h )
s.files += %w( src/core/ext/filters/client_channel/lb_policy_registry.cc )
s.files += %w( src/core/ext/filters/client_channel/lb_policy_registry.h )
@ -167,14 +170,12 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/filters/client_channel/resolver.cc )
s.files += %w( src/core/ext/filters/client_channel/resolver.h )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc )
@ -637,6 +638,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/xds/xds_client.h )
s.files += %w( src/core/ext/xds/xds_client_stats.cc )
s.files += %w( src/core/ext/xds/xds_client_stats.h )
s.files += %w( src/core/ext/xds/xds_server_config_fetcher.cc )
s.files += %w( src/core/lib/avl/avl.cc )
s.files += %w( src/core/lib/avl/avl.h )
s.files += %w( src/core/lib/backoff/backoff.cc )
@ -747,7 +749,6 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/gprpp/host_port.cc )
s.files += %w( src/core/lib/gprpp/host_port.h )
s.files += %w( src/core/lib/gprpp/manual_constructor.h )
s.files += %w( src/core/lib/gprpp/map.h )
s.files += %w( src/core/lib/gprpp/memory.h )
s.files += %w( src/core/lib/gprpp/mpscq.cc )
s.files += %w( src/core/lib/gprpp/mpscq.h )
@ -2023,16 +2024,23 @@ Gem::Specification.new do |s|
s.files += %w( third_party/re2/util/test.h )
s.files += %w( third_party/re2/util/utf.h )
s.files += %w( third_party/re2/util/util.h )
s.files += %w( third_party/upb/third_party/wyhash/wyhash.h )
s.files += %w( third_party/upb/upb/decode.c )
s.files += %w( third_party/upb/upb/decode.h )
s.files += %w( third_party/upb/upb/decode.int.h )
s.files += %w( third_party/upb/upb/decode_fast.c )
s.files += %w( third_party/upb/upb/decode_fast.h )
s.files += %w( third_party/upb/upb/def.c )
s.files += %w( third_party/upb/upb/def.h )
s.files += %w( third_party/upb/upb/def.hpp )
s.files += %w( third_party/upb/upb/encode.c )
s.files += %w( third_party/upb/upb/encode.h )
s.files += %w( third_party/upb/upb/json_decode.c )
s.files += %w( third_party/upb/upb/json_decode.h )
s.files += %w( third_party/upb/upb/json_encode.c )
s.files += %w( third_party/upb/upb/json_encode.h )
s.files += %w( third_party/upb/upb/msg.c )
s.files += %w( third_party/upb/upb/msg.h )
s.files += %w( third_party/upb/upb/port.c )
s.files += %w( third_party/upb/upb/port_def.inc )
s.files += %w( third_party/upb/upb/port_undef.inc )
s.files += %w( third_party/upb/upb/reflection.c )
@ -2044,6 +2052,7 @@ Gem::Specification.new do |s|
s.files += %w( third_party/upb/upb/upb.c )
s.files += %w( third_party/upb/upb/upb.h )
s.files += %w( third_party/upb/upb/upb.hpp )
s.files += %w( third_party/upb/upb/upb.int.h )
s.files += %w( third_party/zlib/adler32.c )
s.files += %w( third_party/zlib/compress.c )
s.files += %w( third_party/zlib/crc32.c )

@ -461,6 +461,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/config_selector.cc',
'src/core/ext/filters/client_channel/dynamic_filters.cc',
'src/core/ext/filters/client_channel/global_subchannel_pool.cc',
'src/core/ext/filters/client_channel/health/health_check_client.cc',
'src/core/ext/filters/client_channel/http_connect_handshaker.cc',
@ -479,20 +480,18 @@
'src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc',
'src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc',
'src/core/ext/filters/client_channel/lb_policy/xds/cds.cc',
'src/core/ext/filters/client_channel/lb_policy/xds/eds.cc',
'src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc',
'src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc',
'src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc',
'src/core/ext/filters/client_channel/lb_policy_registry.cc',
'src/core/ext/filters/client_channel/local_subchannel_pool.cc',
'src/core/ext/filters/client_channel/proxy_mapper_registry.cc',
'src/core/ext/filters/client_channel/resolver.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc',
@ -729,6 +728,7 @@
'src/core/ext/xds/xds_certificate_provider.cc',
'src/core/ext/xds/xds_client.cc',
'src/core/ext/xds/xds_client_stats.cc',
'src/core/ext/xds/xds_server_config_fetcher.cc',
'src/core/lib/avl/avl.cc',
'src/core/lib/backoff/backoff.cc',
'src/core/lib/channel/channel_args.cc',
@ -1091,6 +1091,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/config_selector.cc',
'src/core/ext/filters/client_channel/dynamic_filters.cc',
'src/core/ext/filters/client_channel/global_subchannel_pool.cc',
'src/core/ext/filters/client_channel/health/health_check_client.cc',
'src/core/ext/filters/client_channel/http_connect_handshaker.cc',
@ -1113,12 +1114,10 @@
'src/core/ext/filters/client_channel/proxy_mapper_registry.cc',
'src/core/ext/filters/client_channel/resolver.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc',
@ -1974,15 +1973,17 @@
'dependencies': [
],
'sources': [
'third_party/upb/upb/decode_fast.c',
'third_party/upb/upb/decode.c',
'third_party/upb/upb/def.c',
'third_party/upb/upb/encode.c',
'third_party/upb/upb/json_decode.c',
'third_party/upb/upb/json_encode.c',
'third_party/upb/upb/msg.c',
'third_party/upb/upb/port.c',
'third_party/upb/upb/table.c',
'third_party/upb/upb/upb.c',
'third_party/upb/upb/def.c',
'third_party/upb/upb/reflection.c',
'third_party/upb/upb/table.c',
'third_party/upb/upb/text_encode.c',
'third_party/upb/upb/upb.c',
'src/core/ext/upb-generated/google/protobuf/any.upb.c',
'src/core/ext/upb-generated/google/protobuf/descriptor.upb.c',
'src/core/ext/upb-generated/google/protobuf/duration.upb.c',

@ -411,6 +411,20 @@ GRPCAPI void grpc_server_register_completion_queue(grpc_server* server,
grpc_completion_queue* cq,
void* reserved);
typedef struct grpc_server_config_fetcher grpc_server_config_fetcher;
/** EXPERIMENTAL. Creates an xDS config fetcher. */
GRPCAPI grpc_server_config_fetcher* grpc_server_config_fetcher_xds_create();
/** EXPERIMENTAL. Destroys a config fetcher. */
GRPCAPI void grpc_server_config_fetcher_destroy(
grpc_server_config_fetcher* config_fetcher);
/** EXPERIMENTAL. Sets the server's config fetcher. Takes ownership.
Must be called before adding ports */
GRPCAPI void grpc_server_set_config_fetcher(
grpc_server* server, grpc_server_config_fetcher* config_fetcher);
/** Add a HTTP2 over plaintext over tcp listener.
Returns bound port number on success, 0 on failure.
REQUIRES: server not started */

@ -330,6 +330,14 @@ grpc_service_account_jwt_access_credentials_create(const char* json_key,
gpr_timespec token_lifetime,
void* reserved);
/** Builds External Account credentials.
- json_string is the JSON string containing the credentials options.
- scopes_string contains the scopes to be binded with the credentials.
This API is used for experimental purposes for now and may change in the
future. */
GRPCAPI grpc_call_credentials* grpc_external_account_credentials_create(
const char* json_string, const char* scopes_string);
/** Creates an Oauth2 Refresh Token credentials object for connecting to Google.
May return NULL if the input is invalid.
WARNING: Do NOT use this credentials to connect to a non-google service as
@ -848,8 +856,8 @@ GRPCAPI grpc_tls_credentials_options* grpc_tls_credentials_options_create(void);
/**
* Sets the options of whether to request and verify client certs. This should
* be called only on the server side. It returns 1 on success and 0 on failure.
* It is used for experimental purpose for now and subject to change.
* be called only on the server side. It is used for experimental purpose for
* now and subject to change.
*/
GRPCAPI void grpc_tls_credentials_options_set_cert_request_type(
grpc_tls_credentials_options* options,
@ -860,8 +868,7 @@ GRPCAPI void grpc_tls_credentials_options_set_cert_request_type(
* hostname check, etc. This should be called only on the client side. If
* |server_verification_option| is not GRPC_TLS_SERVER_VERIFICATION, use of a
* custom authorization check (grpc_tls_server_authorization_check_config) is
* mandatory. It returns 1 on success and 0 on failure. It is used for
* experimental purpose for now and subject to change.
* mandatory. It is used for experimental purpose for now and subject to change.
*/
GRPCAPI void grpc_tls_credentials_options_set_server_verification_option(
grpc_tls_credentials_options* options,
@ -870,7 +877,6 @@ GRPCAPI void grpc_tls_credentials_options_set_server_verification_option(
/**
* Sets the credential provider in the options.
* The |options| will implicitly take a new ref to the |provider|.
* It returns 1 on success and 0 on failure.
* It is used for experimental purpose for now and subject to change.
*/
GRPCAPI void grpc_tls_credentials_options_set_certificate_provider(
@ -879,8 +885,14 @@ GRPCAPI void grpc_tls_credentials_options_set_certificate_provider(
/**
* If set, gRPC stack will keep watching the root certificates with
* name |root_cert_name|. It returns 1 on success and 0 on failure. It is used
* for experimental purpose for now and subject to change.
* name |root_cert_name|.
* If this is not set on the client side, we will use the root certificates
* stored in the default system location, since client side must provide root
* certificates in TLS.
* If this is not set on the server side, we will not watch any root certificate
* updates, and assume no root certificates needed for the server(single-side
* TLS). Default root certs on the server side is not supported.
* It is used for experimental purpose for now and subject to change.
*/
GRPCAPI void grpc_tls_credentials_options_watch_root_certs(
grpc_tls_credentials_options* options);
@ -895,8 +907,9 @@ GRPCAPI void grpc_tls_credentials_options_set_root_cert_name(
/**
* If set, gRPC stack will keep watching the identity key-cert pairs
* with name |identity_cert_name|. It returns 1 on success and 0 on failure. It
* is used for experimental purpose for now and subject to change.
* with name |identity_cert_name|.
* This is required on the server side, and optional on the client side.
* It is used for experimental purpose for now and subject to change.
*/
GRPCAPI void grpc_tls_credentials_options_watch_identity_key_cert_pairs(
grpc_tls_credentials_options* options);
@ -912,8 +925,8 @@ GRPCAPI void grpc_tls_credentials_options_set_identity_cert_name(
/**
* Sets the configuration for a custom authorization check performed at the end
* of the handshake. The |options| will implicitly take a new ref to the
* |config|. It returns 1 on success and 0 on failure. It is used for
* experimental purpose for now and subject to change.
* |config|.
* It is used for experimental purpose for now and subject to change.
*/
GRPCAPI void grpc_tls_credentials_options_set_server_authorization_check_config(
grpc_tls_credentials_options* options,

@ -65,6 +65,7 @@
#ifndef GRPC_CUSTOM_JSONUTIL
#include <google/protobuf/util/json_util.h>
#include <google/protobuf/util/type_resolver_util.h>
#define GRPC_CUSTOM_JSONUTIL ::google::protobuf::util
#define GRPC_CUSTOM_UTIL_STATUS ::google::protobuf::util::Status
#endif

@ -307,6 +307,12 @@ grpc::Status StsCredentialsOptionsFromEnv(StsCredentialsOptions* options);
std::shared_ptr<CallCredentials> StsCredentials(
const StsCredentialsOptions& options);
/// Builds External Account credentials.
/// json_string is the JSON string containing the credentials options.
/// scopes contains the scopes to be binded with the credentials.
std::shared_ptr<CallCredentials> ExternalAccountCredentials(
const grpc::string& json_string, const std::vector<grpc::string>& scopes);
std::shared_ptr<CallCredentials> MetadataCredentialsFromPlugin(
std::unique_ptr<MetadataCredentialsPlugin> plugin,
grpc_security_level min_security_level);

@ -155,13 +155,21 @@ class TlsCredentialsOptions {
//
// @param certificate_provider the provider which fetches TLS credentials that
// will be used in the TLS handshake
explicit TlsCredentialsOptions(
std::shared_ptr<CertificateProviderInterface> certificate_provider);
TlsCredentialsOptions();
// ---- Setters for member fields ----
// Sets the certificate provider used to store root certs and identity certs.
void set_certificate_provider(
std::shared_ptr<CertificateProviderInterface> certificate_provider);
// Watches the updates of root certificates with name |root_cert_name|.
// If used in TLS credentials, it should always be set unless the root
// certificates are not needed(e.g. in the one-side TLS scenario, the server
// is not required to verify the client).
// If used in TLS credentials, setting this field is optional for both the
// client side and the server side.
// If this is not set on the client side, we will use the root certificates
// stored in the default system location, since client side must provide root
// certificates in TLS(no matter single-side TLS or mutual TLS).
// If this is not set on the server side, we will not watch any root
// certificate updates, and assume no root certificates needed for the server
// (in the one-side TLS scenario, the server is not required to provide root
// certs). We don't support default root certs on server side.
void watch_root_certs();
// Sets the name of root certificates being watched, if |watch_root_certs| is
// called. If not set, an empty string will be used as the name.
@ -169,9 +177,9 @@ class TlsCredentialsOptions {
// @param root_cert_name the name of root certs being set.
void set_root_cert_name(const std::string& root_cert_name);
// Watches the updates of identity key-cert pairs with name
// |identity_cert_name|. If used in TLS credentials, it should always be set
// unless the identity certificates are not needed(e.g. in the one-side TLS
// scenario, the client is not required to provide certs).
// |identity_cert_name|. If used in TLS credentials, it is required to be set
// on the server side, and optional for the client side(in the one-side
// TLS scenario, the client is not required to provide identity certs).
void watch_identity_key_cert_pairs();
// Sets the name of identity key-cert pairs being watched, if
// |watch_identity_key_cert_pairs| is called. If not set, an empty string will
@ -192,13 +200,13 @@ class TlsCredentialsOptions {
};
// Contains configurable options on the client side.
// Client side doesn't need to always use certificate provider. When the
// certificate provider is not set, we will use the root certificates stored
// in the system default locations, and assume client won't provide any
// identity certificates(single side TLS).
// It is used for experimental purposes for now and it is subject to change.
class TlsChannelCredentialsOptions final : public TlsCredentialsOptions {
public:
explicit TlsChannelCredentialsOptions(
std::shared_ptr<CertificateProviderInterface> certificate_provider)
: TlsCredentialsOptions(std::move(certificate_provider)) {}
// Sets the option to verify the server.
// The default is GRPC_TLS_SERVER_VERIFICATION.
void set_server_verification_option(
@ -215,9 +223,13 @@ class TlsChannelCredentialsOptions final : public TlsCredentialsOptions {
// It is used for experimental purposes for now and it is subject to change.
class TlsServerCredentialsOptions final : public TlsCredentialsOptions {
public:
// Server side is required to use a provider, because server always needs to
// use identity certs.
explicit TlsServerCredentialsOptions(
std::shared_ptr<CertificateProviderInterface> certificate_provider)
: TlsCredentialsOptions(std::move(certificate_provider)) {}
: TlsCredentialsOptions() {
set_certificate_provider(certificate_provider);
}
// Sets option to request the certificates from the client.
// The default is GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE.

@ -179,6 +179,7 @@ class Server : public ServerInterface, private GrpcLibraryCodegen {
int min_pollers, int max_pollers, int sync_cq_timeout_msec,
std::vector<std::shared_ptr<internal::ExternalConnectionAcceptorImpl>>
acceptors,
grpc_server_config_fetcher* server_config_fetcher = nullptr,
grpc_resource_quota* server_rq = nullptr,
std::vector<
std::unique_ptr<experimental::ServerInterceptorFactoryInterface>>

@ -347,6 +347,11 @@ class ServerBuilder {
return option_refs;
}
/// Experimental API, subject to change.
void set_fetcher(grpc_server_config_fetcher* server_config_fetcher) {
server_config_fetcher_ = server_config_fetcher;
}
private:
friend class ::grpc::testing::ServerBuilderPluginTest;
@ -405,6 +410,7 @@ class ServerBuilder {
interceptor_creators_;
std::vector<std::shared_ptr<grpc::internal::ExternalConnectionAcceptorImpl>>
acceptors_;
grpc_server_config_fetcher* server_config_fetcher_ = nullptr;
};
} // namespace grpc

@ -0,0 +1,43 @@
//
//
// Copyright 2020 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 GRPCPP_XDS_SERVER_BUILDER_H
#define GRPCPP_XDS_SERVER_BUILDER_H
#include <grpc/impl/codegen/port_platform.h>
#include <grpcpp/server_builder.h>
namespace grpc {
namespace experimental {
class XdsServerBuilder : public ::grpc::ServerBuilder {
public:
std::unique_ptr<Server> BuildAndStart() override {
grpc_server_config_fetcher* fetcher =
grpc_server_config_fetcher_xds_create();
if (fetcher == nullptr) return nullptr;
set_fetcher(fetcher);
return ServerBuilder::BuildAndStart();
}
};
} // namespace experimental
} // namespace grpc
#endif /* GRPCPP_XDS_SERVER_BUILDER_H */

@ -13,8 +13,8 @@
<date>2019-09-24</date>
<time>16:06:07</time>
<version>
<release>1.35.0dev</release>
<api>1.35.0dev</api>
<release>1.36.0dev</release>
<api>1.36.0dev</api>
</version>
<stability>
<release>beta</release>
@ -22,7 +22,7 @@
</stability>
<license>Apache 2.0</license>
<notes>
- gRPC Core 1.35.0 update
- gRPC Core 1.36.0 update
</notes>
<contents>
<dir baseinstalldir="/" name="/">
@ -100,6 +100,8 @@
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/config_selector.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/config_selector.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/dynamic_filters.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/dynamic_filters.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/global_subchannel_pool.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/global_subchannel_pool.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/health/health_check_client.cc" role="src" />
@ -132,10 +134,11 @@
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/subchannel_list.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/xds/cds.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/xds/eds.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/xds/xds.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_args.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy_factory.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy_registry.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy_registry.h" role="src" />
@ -147,14 +150,12 @@
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc" role="src" />
@ -617,6 +618,7 @@
<file baseinstalldir="/" name="src/core/ext/xds/xds_client.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/xds/xds_client_stats.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/xds/xds_client_stats.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/xds/xds_server_config_fetcher.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/avl/avl.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/avl/avl.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/backoff/backoff.cc" role="src" />
@ -727,7 +729,6 @@
<file baseinstalldir="/" name="src/core/lib/gprpp/host_port.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/host_port.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/manual_constructor.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/map.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/memory.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/mpscq.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/mpscq.h" role="src" />
@ -1948,16 +1949,23 @@
<file baseinstalldir="/" name="third_party/re2/util/test.h" role="src" />
<file baseinstalldir="/" name="third_party/re2/util/utf.h" role="src" />
<file baseinstalldir="/" name="third_party/re2/util/util.h" role="src" />
<file baseinstalldir="/" name="third_party/upb/third_party/wyhash/wyhash.h" role="src" />
<file baseinstalldir="/" name="third_party/upb/upb/decode.c" role="src" />
<file baseinstalldir="/" name="third_party/upb/upb/decode.h" role="src" />
<file baseinstalldir="/" name="third_party/upb/upb/decode.int.h" role="src" />
<file baseinstalldir="/" name="third_party/upb/upb/decode_fast.c" role="src" />
<file baseinstalldir="/" name="third_party/upb/upb/decode_fast.h" role="src" />
<file baseinstalldir="/" name="third_party/upb/upb/def.c" role="src" />
<file baseinstalldir="/" name="third_party/upb/upb/def.h" role="src" />
<file baseinstalldir="/" name="third_party/upb/upb/def.hpp" role="src" />
<file baseinstalldir="/" name="third_party/upb/upb/encode.c" role="src" />
<file baseinstalldir="/" name="third_party/upb/upb/encode.h" role="src" />
<file baseinstalldir="/" name="third_party/upb/upb/json_decode.c" role="src" />
<file baseinstalldir="/" name="third_party/upb/upb/json_decode.h" role="src" />
<file baseinstalldir="/" name="third_party/upb/upb/json_encode.c" role="src" />
<file baseinstalldir="/" name="third_party/upb/upb/json_encode.h" role="src" />
<file baseinstalldir="/" name="third_party/upb/upb/msg.c" role="src" />
<file baseinstalldir="/" name="third_party/upb/upb/msg.h" role="src" />
<file baseinstalldir="/" name="third_party/upb/upb/port.c" role="src" />
<file baseinstalldir="/" name="third_party/upb/upb/port_def.inc" role="src" />
<file baseinstalldir="/" name="third_party/upb/upb/port_undef.inc" role="src" />
<file baseinstalldir="/" name="third_party/upb/upb/reflection.c" role="src" />
@ -1969,6 +1977,7 @@
<file baseinstalldir="/" name="third_party/upb/upb/upb.c" role="src" />
<file baseinstalldir="/" name="third_party/upb/upb/upb.h" role="src" />
<file baseinstalldir="/" name="third_party/upb/upb/upb.hpp" role="src" />
<file baseinstalldir="/" name="third_party/upb/upb/upb.int.h" role="src" />
<file baseinstalldir="/" name="third_party/zlib/adler32.c" role="src" />
<file baseinstalldir="/" name="third_party/zlib/compress.c" role="src" />
<file baseinstalldir="/" name="third_party/zlib/crc32.c" role="src" />

@ -23,20 +23,18 @@
#include "udpa/data/orca/v1/orca_load_report.upb.h"
#include "upb/upb.hpp"
#include "src/core/lib/gprpp/map.h"
namespace grpc_core {
namespace {
template <typename EntryType>
std::map<absl::string_view, double, StringLess> ParseMap(
std::map<absl::string_view, double> ParseMap(
udpa_data_orca_v1_OrcaLoadReport* msg,
const EntryType* (*entry_func)(const udpa_data_orca_v1_OrcaLoadReport*,
size_t*),
upb_strview (*key_func)(const EntryType*),
double (*value_func)(const EntryType*), Arena* arena) {
std::map<absl::string_view, double, StringLess> result;
std::map<absl::string_view, double> result;
size_t i = UPB_MAP_BEGIN;
while (true) {
const auto* entry = entry_func(msg, &i);

File diff suppressed because it is too large Load Diff

@ -21,6 +21,7 @@
#include <functional>
#include <map>
#include <vector>
#include "absl/strings/string_view.h"
@ -28,6 +29,7 @@
#include "src/core/ext/filters/client_channel/service_config.h"
#include "src/core/ext/filters/client_channel/service_config_parser.h"
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/gprpp/arena.h"
#include "src/core/lib/gprpp/ref_counted.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
@ -80,6 +82,8 @@ class ConfigSelector : public RefCounted<ConfigSelector> {
return cs1->Equals(cs2);
}
virtual std::vector<const grpc_channel_filter*> GetFilters() { return {}; }
virtual CallConfig GetCallConfig(GetCallConfigArgs args) = 0;
grpc_arg MakeChannelArg() const;

@ -0,0 +1,186 @@
//
// Copyright 2020 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 "src/core/ext/filters/client_channel/dynamic_filters.h"
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/surface/lame_client.h"
// Conversion between call and call stack.
#define CALL_TO_CALL_STACK(call) \
(grpc_call_stack*)((char*)(call) + GPR_ROUND_UP_TO_ALIGNMENT_SIZE( \
sizeof(DynamicFilters::Call)))
#define CALL_STACK_TO_CALL(callstack) \
(DynamicFilters::Call*)(((char*)(call_stack)) - \
GPR_ROUND_UP_TO_ALIGNMENT_SIZE( \
sizeof(DynamicFilters::Call)))
namespace grpc_core {
//
// DynamicFilters::Call
//
DynamicFilters::Call::Call(Args args, grpc_error** error)
: channel_stack_(std::move(args.channel_stack)) {
grpc_call_stack* call_stack = CALL_TO_CALL_STACK(this);
const grpc_call_element_args call_args = {
call_stack, /* call_stack */
nullptr, /* server_transport_data */
args.context, /* context */
args.path, /* path */
args.start_time, /* start_time */
args.deadline, /* deadline */
args.arena, /* arena */
args.call_combiner /* call_combiner */
};
*error = grpc_call_stack_init(channel_stack_->channel_stack_, 1, Destroy,
this, &call_args);
if (GPR_UNLIKELY(*error != GRPC_ERROR_NONE)) {
const char* error_string = grpc_error_string(*error);
gpr_log(GPR_ERROR, "error: %s", error_string);
return;
}
grpc_call_stack_set_pollset_or_pollset_set(call_stack, args.pollent);
}
void DynamicFilters::Call::StartTransportStreamOpBatch(
grpc_transport_stream_op_batch* batch) {
grpc_call_stack* call_stack = CALL_TO_CALL_STACK(this);
grpc_call_element* top_elem = grpc_call_stack_element(call_stack, 0);
GRPC_CALL_LOG_OP(GPR_INFO, top_elem, batch);
top_elem->filter->start_transport_stream_op_batch(top_elem, batch);
}
void DynamicFilters::Call::SetAfterCallStackDestroy(grpc_closure* closure) {
GPR_ASSERT(after_call_stack_destroy_ == nullptr);
GPR_ASSERT(closure != nullptr);
after_call_stack_destroy_ = closure;
}
RefCountedPtr<DynamicFilters::Call> DynamicFilters::Call::Ref() {
IncrementRefCount();
return RefCountedPtr<DynamicFilters::Call>(this);
}
RefCountedPtr<DynamicFilters::Call> DynamicFilters::Call::Ref(
const grpc_core::DebugLocation& location, const char* reason) {
IncrementRefCount(location, reason);
return RefCountedPtr<DynamicFilters::Call>(this);
}
void DynamicFilters::Call::Unref() {
GRPC_CALL_STACK_UNREF(CALL_TO_CALL_STACK(this), "");
}
void DynamicFilters::Call::Unref(const DebugLocation& /*location*/,
const char* reason) {
GRPC_CALL_STACK_UNREF(CALL_TO_CALL_STACK(this), reason);
}
void DynamicFilters::Call::Destroy(void* arg, grpc_error* /*error*/) {
DynamicFilters::Call* self = static_cast<DynamicFilters::Call*>(arg);
// Keep some members before destroying the subchannel call.
grpc_closure* after_call_stack_destroy = self->after_call_stack_destroy_;
RefCountedPtr<DynamicFilters> channel_stack = std::move(self->channel_stack_);
// Destroy the subchannel call.
self->~Call();
// Destroy the call stack. This should be after destroying the call, because
// call->after_call_stack_destroy(), if not null, will free the call arena.
grpc_call_stack_destroy(CALL_TO_CALL_STACK(self), nullptr,
after_call_stack_destroy);
// Automatically reset channel_stack. This should be after destroying the call
// stack, because destroying call stack needs access to the channel stack.
}
void DynamicFilters::Call::IncrementRefCount() {
GRPC_CALL_STACK_REF(CALL_TO_CALL_STACK(this), "");
}
void DynamicFilters::Call::IncrementRefCount(
const grpc_core::DebugLocation& /*location*/, const char* reason) {
GRPC_CALL_STACK_REF(CALL_TO_CALL_STACK(this), reason);
}
//
// DynamicFilters
//
namespace {
void DestroyChannelStack(void* arg, grpc_error* /*error*/) {
grpc_channel_stack* channel_stack = static_cast<grpc_channel_stack*>(arg);
grpc_channel_stack_destroy(channel_stack);
gpr_free(channel_stack);
}
std::pair<grpc_channel_stack*, grpc_error*> CreateChannelStack(
const grpc_channel_args* args,
std::vector<const grpc_channel_filter*> filters) {
// Allocate memory for channel stack.
const size_t channel_stack_size =
grpc_channel_stack_size(filters.data(), filters.size());
grpc_channel_stack* channel_stack =
reinterpret_cast<grpc_channel_stack*>(gpr_zalloc(channel_stack_size));
// Initialize stack.
grpc_error* error = grpc_channel_stack_init(
/*initial_refs=*/1, DestroyChannelStack, channel_stack, filters.data(),
filters.size(), args, /*optional_transport=*/nullptr, "DynamicFilters",
channel_stack);
if (error != GRPC_ERROR_NONE) {
gpr_log(GPR_ERROR, "error initializing client internal stack: %s",
grpc_error_string(error));
grpc_channel_stack_destroy(channel_stack);
gpr_free(channel_stack);
return {nullptr, error};
}
return {channel_stack, GRPC_ERROR_NONE};
}
} // namespace
RefCountedPtr<DynamicFilters> DynamicFilters::Create(
const grpc_channel_args* args,
std::vector<const grpc_channel_filter*> filters) {
// Attempt to create channel stack from requested filters.
auto p = CreateChannelStack(args, std::move(filters));
if (p.second != GRPC_ERROR_NONE) {
// Initial pass failed. Create with lame filter.
grpc_error* error = p.second;
p = CreateChannelStack(args, {&grpc_lame_filter});
GPR_ASSERT(p.second == GRPC_ERROR_NONE);
grpc_channel_element* elem = grpc_channel_stack_element(p.first, 0);
SetLameFilterError(elem, error);
}
return MakeRefCounted<DynamicFilters>(p.first);
}
DynamicFilters::~DynamicFilters() {
GRPC_CHANNEL_STACK_UNREF(channel_stack_, "~DynamicFilters");
}
RefCountedPtr<DynamicFilters::Call> DynamicFilters::CreateCall(
DynamicFilters::Call::Args args, grpc_error** error) {
size_t allocation_size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(Call)) +
channel_stack_->call_stack_size;
Call* call = static_cast<Call*>(args.arena->Alloc(allocation_size));
new (call) Call(std::move(args), error);
return call;
}
} // namespace grpc_core

@ -0,0 +1,99 @@
//
// Copyright 2020 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_DYNAMIC_FILTERS_H
#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_DYNAMIC_FILTERS_H
#include <grpc/support/port_platform.h>
#include <vector>
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/gpr/time_precise.h"
#include "src/core/lib/gprpp/arena.h"
#include "src/core/lib/gprpp/ref_counted.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/iomgr/polling_entity.h"
namespace grpc_core {
class DynamicFilters : public RefCounted<DynamicFilters> {
public:
// Implements the interface of RefCounted<>.
class Call {
public:
struct Args {
RefCountedPtr<DynamicFilters> channel_stack;
grpc_polling_entity* pollent;
grpc_slice path;
gpr_cycle_counter start_time;
grpc_millis deadline;
Arena* arena;
grpc_call_context_element* context;
CallCombiner* call_combiner;
};
Call(Args args, grpc_error** error);
// Continues processing a transport stream op batch.
void StartTransportStreamOpBatch(grpc_transport_stream_op_batch* batch);
// Sets the 'then_schedule_closure' argument for call stack destruction.
// Must be called once per call.
void SetAfterCallStackDestroy(grpc_closure* closure);
// Interface of RefCounted<>.
RefCountedPtr<Call> Ref() GRPC_MUST_USE_RESULT;
RefCountedPtr<Call> Ref(const DebugLocation& location,
const char* reason) GRPC_MUST_USE_RESULT;
// When refcount drops to 0, destroys itself and the associated call stack,
// but does NOT free the memory because it's in the call arena.
void Unref();
void Unref(const DebugLocation& location, const char* reason);
private:
// Allow RefCountedPtr<> to access IncrementRefCount().
template <typename T>
friend class RefCountedPtr;
// Interface of RefCounted<>.
void IncrementRefCount();
void IncrementRefCount(const DebugLocation& location, const char* reason);
static void Destroy(void* arg, grpc_error* error);
RefCountedPtr<DynamicFilters> channel_stack_;
grpc_closure* after_call_stack_destroy_ = nullptr;
};
static RefCountedPtr<DynamicFilters> Create(
const grpc_channel_args* args,
std::vector<const grpc_channel_filter*> filters);
explicit DynamicFilters(grpc_channel_stack* channel_stack)
: channel_stack_(channel_stack) {}
~DynamicFilters() override;
RefCountedPtr<Call> CreateCall(Call::Args args, grpc_error** error);
private:
grpc_channel_stack* channel_stack_;
};
} // namespace grpc_core
#endif // GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_DYNAMIC_FILTERS_H

@ -46,7 +46,7 @@ TraceFlag grpc_health_check_client_trace(false, "health_check_client");
//
HealthCheckClient::HealthCheckClient(
const char* service_name,
std::string service_name,
RefCountedPtr<ConnectedSubchannel> connected_subchannel,
grpc_pollset_set* interested_parties,
RefCountedPtr<channelz::SubchannelNode> channelz_node,
@ -55,7 +55,7 @@ HealthCheckClient::HealthCheckClient(
GRPC_TRACE_FLAG_ENABLED(grpc_health_check_client_trace)
? "HealthCheckClient"
: nullptr),
service_name_(service_name),
service_name_(std::move(service_name)),
connected_subchannel_(std::move(connected_subchannel)),
interested_parties_(interested_parties),
channelz_node_(std::move(channelz_node)),
@ -180,13 +180,14 @@ void HealthCheckClient::OnRetryTimer(void* arg, grpc_error* error) {
namespace {
void EncodeRequest(const char* service_name,
void EncodeRequest(const std::string& service_name,
ManualConstructor<SliceBufferByteStream>* send_message) {
upb::Arena arena;
grpc_health_v1_HealthCheckRequest* request_struct =
grpc_health_v1_HealthCheckRequest_new(arena.ptr());
grpc_health_v1_HealthCheckRequest_set_service(
request_struct, upb_strview_makez(service_name));
request_struct,
upb_strview_make(service_name.data(), service_name.size()));
size_t buf_length;
char* buf = grpc_health_v1_HealthCheckRequest_serialize(
request_struct, arena.ptr(), &buf_length);
@ -252,7 +253,7 @@ HealthCheckClient::CallState::CallState(
: health_check_client_(std::move(health_check_client)),
pollent_(grpc_polling_entity_create_from_pollset_set(interested_parties)),
arena_(Arena::Create(health_check_client_->connected_subchannel_
->GetInitialCallSizeEstimate(0))),
->GetInitialCallSizeEstimate())),
payload_(context_) {}
HealthCheckClient::CallState::~CallState() {
@ -291,7 +292,6 @@ void HealthCheckClient::CallState::StartCall() {
arena_,
context_,
&call_combiner_,
0, // parent_data_size
};
grpc_error* error = GRPC_ERROR_NONE;
call_ = SubchannelCall::Create(std::move(args), &error).release();

@ -44,7 +44,7 @@ namespace grpc_core {
class HealthCheckClient : public InternallyRefCounted<HealthCheckClient> {
public:
HealthCheckClient(const char* service_name,
HealthCheckClient(std::string service_name,
RefCountedPtr<ConnectedSubchannel> connected_subchannel,
grpc_pollset_set* interested_parties,
RefCountedPtr<channelz::SubchannelNode> channelz_node,
@ -150,7 +150,7 @@ class HealthCheckClient : public InternallyRefCounted<HealthCheckClient> {
void SetHealthStatusLocked(grpc_connectivity_state state,
const char* reason); // Requires holding mu_.
const char* service_name_; // Do not own.
std::string service_name_;
RefCountedPtr<ConnectedSubchannel> connected_subchannel_;
grpc_pollset_set* interested_parties_; // Do not own.
RefCountedPtr<channelz::SubchannelNode> channelz_node_;

@ -30,7 +30,6 @@
#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/ext/filters/client_channel/service_config.h"
#include "src/core/ext/filters/client_channel/subchannel_interface.h"
#include "src/core/lib/gprpp/map.h"
#include "src/core/lib/gprpp/orphanable.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/iomgr/polling_entity.h"
@ -95,11 +94,11 @@ class LoadBalancingPolicy : public InternallyRefCounted<LoadBalancingPolicy> {
/// Application-specific requests cost metrics. Metric names are
/// determined by the application. Each value is an absolute cost
/// (e.g. 3487 bytes of storage) associated with the request.
std::map<absl::string_view, double, StringLess> request_cost;
std::map<absl::string_view, double> request_cost;
/// Application-specific resource utilization metrics. Metric names
/// are determined by the application. Each value is expressed as a
/// fraction of total resources available.
std::map<absl::string_view, double, StringLess> utilization;
std::map<absl::string_view, double> utilization;
};
/// Interface for accessing per-call state.

@ -330,9 +330,23 @@ void CdsLb::OnClusterChanged(XdsApi::CdsUpdate cluster_data) {
return OnError(error);
}
// Construct config for child policy.
Json::Object child_config = {
Json::Object discovery_mechanism = {
{"clusterName", config_->cluster()},
{"max_concurrent_requests", cluster_data.max_concurrent_requests},
{"type", "EDS"},
};
if (!cluster_data.eds_service_name.empty()) {
discovery_mechanism["edsServiceName"] = cluster_data.eds_service_name;
}
if (cluster_data.lrs_load_reporting_server_name.has_value()) {
discovery_mechanism["lrsLoadReportingServerName"] =
cluster_data.lrs_load_reporting_server_name.value();
}
Json::Object child_config = {
{"discoveryMechanisms",
Json::Array{
discovery_mechanism,
}},
{"localityPickingPolicy",
Json::Array{
Json::Object{
@ -349,16 +363,9 @@ void CdsLb::OnClusterChanged(XdsApi::CdsUpdate cluster_data) {
},
}},
};
if (!cluster_data.eds_service_name.empty()) {
child_config["edsServiceName"] = cluster_data.eds_service_name;
}
if (cluster_data.lrs_load_reporting_server_name.has_value()) {
child_config["lrsLoadReportingServerName"] =
cluster_data.lrs_load_reporting_server_name.value();
}
Json json = Json::Array{
Json::Object{
{"eds_experimental", std::move(child_config)},
{"xds_cluster_resolver_experimental", std::move(child_config)},
},
};
if (GRPC_TRACE_FLAG_ENABLED(grpc_cds_lb_trace)) {

@ -1,908 +0,0 @@
//
// 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 <inttypes.h>
#include <limits.h>
#include "absl/strings/str_cat.h"
#include "absl/types/optional.h"
#include <grpc/grpc.h>
#include "src/core/ext/filters/client_channel/client_channel.h"
#include "src/core/ext/filters/client_channel/lb_policy.h"
#include "src/core/ext/filters/client_channel/lb_policy/address_filtering.h"
#include "src/core/ext/filters/client_channel/lb_policy/child_policy_handler.h"
#include "src/core/ext/filters/client_channel/lb_policy/xds/xds.h"
#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/ext/xds/xds_channel_args.h"
#include "src/core/ext/xds/xds_client.h"
#include "src/core/ext/xds/xds_client_stats.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/orphanable.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/iomgr/work_serializer.h"
#include "src/core/lib/transport/error_utils.h"
#include "src/core/lib/uri/uri_parser.h"
#define GRPC_EDS_DEFAULT_FALLBACK_TIMEOUT 10000
namespace grpc_core {
TraceFlag grpc_lb_eds_trace(false, "eds_lb");
const char* kXdsLocalityNameAttributeKey = "xds_locality_name";
namespace {
constexpr char kEds[] = "eds_experimental";
// Config for EDS LB policy.
class EdsLbConfig : public LoadBalancingPolicy::Config {
public:
EdsLbConfig(std::string cluster_name, std::string eds_service_name,
absl::optional<std::string> lrs_load_reporting_server_name,
Json locality_picking_policy, Json endpoint_picking_policy,
uint32_t max_concurrent_requests)
: cluster_name_(std::move(cluster_name)),
eds_service_name_(std::move(eds_service_name)),
lrs_load_reporting_server_name_(
std::move(lrs_load_reporting_server_name)),
locality_picking_policy_(std::move(locality_picking_policy)),
endpoint_picking_policy_(std::move(endpoint_picking_policy)),
max_concurrent_requests_(max_concurrent_requests) {}
const char* name() const override { return kEds; }
const std::string& cluster_name() const { return cluster_name_; }
const std::string& eds_service_name() const { return eds_service_name_; }
const absl::optional<std::string>& lrs_load_reporting_server_name() const {
return lrs_load_reporting_server_name_;
};
const Json& locality_picking_policy() const {
return locality_picking_policy_;
}
const Json& endpoint_picking_policy() const {
return endpoint_picking_policy_;
}
const uint32_t max_concurrent_requests() const {
return max_concurrent_requests_;
}
private:
std::string cluster_name_;
std::string eds_service_name_;
absl::optional<std::string> lrs_load_reporting_server_name_;
Json locality_picking_policy_;
Json endpoint_picking_policy_;
uint32_t max_concurrent_requests_;
};
// EDS LB policy.
class EdsLb : public LoadBalancingPolicy {
public:
EdsLb(RefCountedPtr<XdsClient> xds_client, Args args);
const char* name() const override { return kEds; }
void UpdateLocked(UpdateArgs args) override;
void ResetBackoffLocked() override;
private:
class EndpointWatcher : public XdsClient::EndpointWatcherInterface {
public:
explicit EndpointWatcher(RefCountedPtr<EdsLb> parent)
: parent_(std::move(parent)) {}
void OnEndpointChanged(XdsApi::EdsUpdate update) override {
new Notifier(parent_, std::move(update));
}
void OnError(grpc_error* error) override { new Notifier(parent_, error); }
void OnResourceDoesNotExist() override { new Notifier(parent_); }
private:
class Notifier {
public:
Notifier(RefCountedPtr<EdsLb> parent, XdsApi::EdsUpdate update);
Notifier(RefCountedPtr<EdsLb> parent, grpc_error* error);
explicit Notifier(RefCountedPtr<EdsLb> parent);
private:
enum Type { kUpdate, kError, kDoesNotExist };
static void RunInExecCtx(void* arg, grpc_error* error);
void RunInWorkSerializer(grpc_error* error);
RefCountedPtr<EdsLb> parent_;
grpc_closure closure_;
XdsApi::EdsUpdate update_;
Type type_;
};
RefCountedPtr<EdsLb> parent_;
};
class Helper : public ChannelControlHelper {
public:
explicit Helper(RefCountedPtr<EdsLb> eds_policy)
: eds_policy_(std::move(eds_policy)) {}
~Helper() override { eds_policy_.reset(DEBUG_LOCATION, "Helper"); }
RefCountedPtr<SubchannelInterface> CreateSubchannel(
ServerAddress address, const grpc_channel_args& args) override;
void UpdateState(grpc_connectivity_state state, const absl::Status& status,
std::unique_ptr<SubchannelPicker> picker) override;
// This is a no-op, because we get the addresses from the xds
// client, which is a watch-based API.
void RequestReresolution() override {}
void AddTraceEvent(TraceSeverity severity,
absl::string_view message) override;
private:
RefCountedPtr<EdsLb> eds_policy_;
};
~EdsLb() override;
void ShutdownLocked() override;
void OnEndpointChanged(XdsApi::EdsUpdate update);
void OnError(grpc_error* error);
void OnResourceDoesNotExist();
void MaybeDestroyChildPolicyLocked();
void UpdatePriorityList(XdsApi::EdsUpdate::PriorityList priority_list);
void UpdateChildPolicyLocked();
OrphanablePtr<LoadBalancingPolicy> CreateChildPolicyLocked(
const grpc_channel_args* args);
ServerAddressList CreateChildPolicyAddressesLocked();
RefCountedPtr<Config> CreateChildPolicyConfigLocked();
grpc_channel_args* CreateChildPolicyArgsLocked(
const grpc_channel_args* args_in);
// Caller must ensure that config_ is set before calling.
const absl::string_view GetEdsResourceName() const {
if (!is_xds_uri_) return server_name_;
if (!config_->eds_service_name().empty()) {
return config_->eds_service_name();
}
return config_->cluster_name();
}
// Returns a pair containing the cluster and eds_service_name to use
// for LRS load reporting.
// Caller must ensure that config_ is set before calling.
std::pair<absl::string_view, absl::string_view> GetLrsClusterKey() const {
if (!is_xds_uri_) return {server_name_, nullptr};
return {config_->cluster_name(), config_->eds_service_name()};
}
// Server name from target URI.
std::string server_name_;
bool is_xds_uri_;
// Current channel args and config from the resolver.
const grpc_channel_args* args_ = nullptr;
RefCountedPtr<EdsLbConfig> config_;
// Internal state.
bool shutting_down_ = false;
// The xds client and endpoint watcher.
RefCountedPtr<XdsClient> xds_client_;
// A pointer to the endpoint watcher, to be used when cancelling the watch.
// Note that this is not owned, so this pointer must never be derefernced.
EndpointWatcher* endpoint_watcher_ = nullptr;
// The latest data from the endpoint watcher.
XdsApi::EdsUpdate::PriorityList priority_list_;
// State used to retain child policy names for priority policy.
std::vector<size_t /*child_number*/> priority_child_numbers_;
RefCountedPtr<XdsApi::EdsUpdate::DropConfig> drop_config_;
OrphanablePtr<LoadBalancingPolicy> child_policy_;
};
//
// EdsLb::Helper
//
RefCountedPtr<SubchannelInterface> EdsLb::Helper::CreateSubchannel(
ServerAddress address, const grpc_channel_args& args) {
if (eds_policy_->shutting_down_) return nullptr;
return eds_policy_->channel_control_helper()->CreateSubchannel(
std::move(address), args);
}
void EdsLb::Helper::UpdateState(grpc_connectivity_state state,
const absl::Status& status,
std::unique_ptr<SubchannelPicker> picker) {
if (eds_policy_->shutting_down_ || eds_policy_->child_policy_ == nullptr) {
return;
}
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_eds_trace)) {
gpr_log(GPR_INFO, "[edslb %p] child policy updated state=%s (%s) picker=%p",
eds_policy_.get(), ConnectivityStateName(state),
status.ToString().c_str(), picker.get());
}
eds_policy_->channel_control_helper()->UpdateState(state, status,
std::move(picker));
}
void EdsLb::Helper::AddTraceEvent(TraceSeverity severity,
absl::string_view message) {
if (eds_policy_->shutting_down_) return;
eds_policy_->channel_control_helper()->AddTraceEvent(severity, message);
}
//
// EdsLb::EndpointWatcher::Notifier
//
EdsLb::EndpointWatcher::Notifier::Notifier(RefCountedPtr<EdsLb> parent,
XdsApi::EdsUpdate update)
: parent_(std::move(parent)), update_(std::move(update)), type_(kUpdate) {
GRPC_CLOSURE_INIT(&closure_, &RunInExecCtx, this, nullptr);
ExecCtx::Run(DEBUG_LOCATION, &closure_, GRPC_ERROR_NONE);
}
EdsLb::EndpointWatcher::Notifier::Notifier(RefCountedPtr<EdsLb> parent,
grpc_error* error)
: parent_(std::move(parent)), type_(kError) {
GRPC_CLOSURE_INIT(&closure_, &RunInExecCtx, this, nullptr);
ExecCtx::Run(DEBUG_LOCATION, &closure_, error);
}
EdsLb::EndpointWatcher::Notifier::Notifier(RefCountedPtr<EdsLb> parent)
: parent_(std::move(parent)), type_(kDoesNotExist) {
GRPC_CLOSURE_INIT(&closure_, &RunInExecCtx, this, nullptr);
ExecCtx::Run(DEBUG_LOCATION, &closure_, GRPC_ERROR_NONE);
}
void EdsLb::EndpointWatcher::Notifier::RunInExecCtx(void* arg,
grpc_error* error) {
Notifier* self = static_cast<Notifier*>(arg);
GRPC_ERROR_REF(error);
self->parent_->work_serializer()->Run(
[self, error]() { self->RunInWorkSerializer(error); }, DEBUG_LOCATION);
}
void EdsLb::EndpointWatcher::Notifier::RunInWorkSerializer(grpc_error* error) {
switch (type_) {
case kUpdate:
parent_->OnEndpointChanged(std::move(update_));
break;
case kError:
parent_->OnError(error);
break;
case kDoesNotExist:
parent_->OnResourceDoesNotExist();
break;
};
delete this;
}
//
// EdsLb public methods
//
EdsLb::EdsLb(RefCountedPtr<XdsClient> xds_client, Args args)
: LoadBalancingPolicy(std::move(args)), xds_client_(std::move(xds_client)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_eds_trace)) {
gpr_log(GPR_INFO, "[edslb %p] created -- using xds client %p", this,
xds_client_.get());
}
// Record server name.
const char* server_uri =
grpc_channel_args_find_string(args.args, GRPC_ARG_SERVER_URI);
GPR_ASSERT(server_uri != nullptr);
absl::StatusOr<URI> uri = URI::Parse(server_uri);
GPR_ASSERT(uri.ok() && !uri->path().empty());
server_name_ = std::string(absl::StripPrefix(uri->path(), "/"));
is_xds_uri_ = uri->scheme() == "xds";
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_eds_trace)) {
gpr_log(GPR_INFO, "[edslb %p] server name from channel (is_xds_uri=%d): %s",
this, is_xds_uri_, server_name_.c_str());
}
// EDS-only flow.
if (!is_xds_uri_) {
// Setup channelz linkage.
channelz::ChannelNode* parent_channelz_node =
grpc_channel_args_find_pointer<channelz::ChannelNode>(
args.args, GRPC_ARG_CHANNELZ_CHANNEL_NODE);
if (parent_channelz_node != nullptr) {
xds_client_->AddChannelzLinkage(parent_channelz_node);
}
// Couple polling.
grpc_pollset_set_add_pollset_set(xds_client_->interested_parties(),
interested_parties());
}
}
EdsLb::~EdsLb() {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_eds_trace)) {
gpr_log(GPR_INFO, "[edslb %p] destroying eds LB policy", this);
}
}
void EdsLb::ShutdownLocked() {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_eds_trace)) {
gpr_log(GPR_INFO, "[edslb %p] shutting down", this);
}
shutting_down_ = true;
MaybeDestroyChildPolicyLocked();
// Cancel watcher.
if (endpoint_watcher_ != nullptr) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_eds_trace)) {
gpr_log(GPR_INFO, "[edslb %p] cancelling xds watch for %s", this,
std::string(GetEdsResourceName()).c_str());
}
xds_client_->CancelEndpointDataWatch(GetEdsResourceName(),
endpoint_watcher_);
}
if (!is_xds_uri_) {
// Remove channelz linkage.
channelz::ChannelNode* parent_channelz_node =
grpc_channel_args_find_pointer<channelz::ChannelNode>(
args_, GRPC_ARG_CHANNELZ_CHANNEL_NODE);
if (parent_channelz_node != nullptr) {
xds_client_->RemoveChannelzLinkage(parent_channelz_node);
}
// Decouple polling.
grpc_pollset_set_del_pollset_set(xds_client_->interested_parties(),
interested_parties());
}
xds_client_.reset(DEBUG_LOCATION, "EdsLb");
// Destroy channel args.
grpc_channel_args_destroy(args_);
args_ = nullptr;
}
void EdsLb::MaybeDestroyChildPolicyLocked() {
if (child_policy_ != nullptr) {
grpc_pollset_set_del_pollset_set(child_policy_->interested_parties(),
interested_parties());
child_policy_.reset();
}
}
void EdsLb::UpdateLocked(UpdateArgs args) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_eds_trace)) {
gpr_log(GPR_INFO, "[edslb %p] Received update", this);
}
const bool is_initial_update = args_ == nullptr;
// Update config.
auto old_config = std::move(config_);
config_ = std::move(args.config);
// Update args.
grpc_channel_args_destroy(args_);
args_ = args.args;
args.args = nullptr;
// Update child policy if needed.
if (child_policy_ != nullptr) UpdateChildPolicyLocked();
// Create endpoint watcher if needed.
if (is_initial_update) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_eds_trace)) {
gpr_log(GPR_INFO, "[edslb %p] starting xds watch for %s", this,
std::string(GetEdsResourceName()).c_str());
}
auto watcher = absl::make_unique<EndpointWatcher>(
Ref(DEBUG_LOCATION, "EndpointWatcher"));
endpoint_watcher_ = watcher.get();
xds_client_->WatchEndpointData(GetEdsResourceName(), std::move(watcher));
}
}
void EdsLb::ResetBackoffLocked() {
// When the XdsClient is instantiated in the resolver instead of in this
// LB policy, this is done via the resolver, so we don't need to do it here.
if (!is_xds_uri_ && xds_client_ != nullptr) xds_client_->ResetBackoff();
if (child_policy_ != nullptr) {
child_policy_->ResetBackoffLocked();
}
}
void EdsLb::OnEndpointChanged(XdsApi::EdsUpdate update) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_eds_trace)) {
gpr_log(GPR_INFO, "[edslb %p] Received EDS update from xds client", this);
}
// Update the drop config.
drop_config_ = std::move(update.drop_config);
// If priority list is empty, add a single priority, just so that we
// have a child in which to create the xds_cluster_impl policy.
if (update.priorities.empty()) update.priorities.emplace_back();
// Update child policy.
UpdatePriorityList(std::move(update.priorities));
}
void EdsLb::OnError(grpc_error* error) {
gpr_log(GPR_ERROR, "[edslb %p] xds watcher reported error: %s", this,
grpc_error_string(error));
// Go into TRANSIENT_FAILURE if we have not yet created the child
// policy (i.e., we have not yet received data from xds). Otherwise,
// we keep running with the data we had previously.
if (child_policy_ == nullptr) {
channel_control_helper()->UpdateState(
GRPC_CHANNEL_TRANSIENT_FAILURE, grpc_error_to_absl_status(error),
absl::make_unique<TransientFailurePicker>(error));
} else {
GRPC_ERROR_UNREF(error);
}
}
void EdsLb::OnResourceDoesNotExist() {
gpr_log(
GPR_ERROR,
"[edslb %p] EDS resource does not exist -- reporting TRANSIENT_FAILURE",
this);
grpc_error* error = grpc_error_set_int(
GRPC_ERROR_CREATE_FROM_STATIC_STRING("EDS resource does not exist"),
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
channel_control_helper()->UpdateState(
GRPC_CHANNEL_TRANSIENT_FAILURE, grpc_error_to_absl_status(error),
absl::make_unique<TransientFailurePicker>(error));
MaybeDestroyChildPolicyLocked();
}
//
// child policy-related methods
//
void EdsLb::UpdatePriorityList(XdsApi::EdsUpdate::PriorityList priority_list) {
// Build some maps from locality to child number and the reverse from
// the old data in priority_list_ and priority_child_numbers_.
std::map<XdsLocalityName*, size_t /*child_number*/, XdsLocalityName::Less>
locality_child_map;
std::map<size_t, std::set<XdsLocalityName*>> child_locality_map;
for (size_t priority = 0; priority < priority_list_.size(); ++priority) {
size_t child_number = priority_child_numbers_[priority];
const auto& localities = priority_list_[priority].localities;
for (const auto& p : localities) {
XdsLocalityName* locality_name = p.first;
locality_child_map[locality_name] = child_number;
child_locality_map[child_number].insert(locality_name);
}
}
// Construct new list of children.
std::vector<size_t> priority_child_numbers;
for (size_t priority = 0; priority < priority_list.size(); ++priority) {
const auto& localities = priority_list[priority].localities;
absl::optional<size_t> child_number;
// If one of the localities in this priority already existed, reuse its
// child number.
for (const auto& p : localities) {
XdsLocalityName* locality_name = p.first;
if (!child_number.has_value()) {
auto it = locality_child_map.find(locality_name);
if (it != locality_child_map.end()) {
child_number = it->second;
locality_child_map.erase(it);
// Remove localities that *used* to be in this child number, so
// that we don't incorrectly reuse this child number for a
// subsequent priority.
for (XdsLocalityName* old_locality :
child_locality_map[*child_number]) {
locality_child_map.erase(old_locality);
}
}
} else {
// Remove all localities that are now in this child number, so
// that we don't accidentally reuse this child number for a
// subsequent priority.
locality_child_map.erase(locality_name);
}
}
// If we didn't find an existing child number, assign a new one.
if (!child_number.has_value()) {
for (child_number = 0;
child_locality_map.find(*child_number) != child_locality_map.end();
++(*child_number)) {
}
// Add entry so we know that the child number is in use.
// (Don't need to add the list of localities, since we won't use them.)
child_locality_map[*child_number];
}
priority_child_numbers.push_back(*child_number);
}
// Save update.
priority_list_ = std::move(priority_list);
priority_child_numbers_ = std::move(priority_child_numbers);
// Update child policy.
UpdateChildPolicyLocked();
}
ServerAddressList EdsLb::CreateChildPolicyAddressesLocked() {
ServerAddressList addresses;
for (size_t priority = 0; priority < priority_list_.size(); ++priority) {
const auto& localities = priority_list_[priority].localities;
std::string priority_child_name =
absl::StrCat("child", priority_child_numbers_[priority]);
for (const auto& p : localities) {
const auto& locality_name = p.first;
const auto& locality = p.second;
std::vector<std::string> hierarchical_path = {
priority_child_name, locality_name->AsHumanReadableString()};
for (const auto& endpoint : locality.endpoints) {
addresses.emplace_back(
endpoint
.WithAttribute(kHierarchicalPathAttributeKey,
MakeHierarchicalPathAttribute(hierarchical_path))
.WithAttribute(kXdsLocalityNameAttributeKey,
absl::make_unique<XdsLocalityAttribute>(
locality_name->Ref())));
}
}
}
return addresses;
}
RefCountedPtr<LoadBalancingPolicy::Config>
EdsLb::CreateChildPolicyConfigLocked() {
const auto lrs_key = GetLrsClusterKey();
Json::Object priority_children;
Json::Array priority_priorities;
for (size_t priority = 0; priority < priority_list_.size(); ++priority) {
const auto& localities = priority_list_[priority].localities;
Json::Object weighted_targets;
for (const auto& p : localities) {
XdsLocalityName* locality_name = p.first;
const auto& locality = p.second;
// Construct JSON object containing locality name.
Json::Object locality_name_json;
if (!locality_name->region().empty()) {
locality_name_json["region"] = locality_name->region();
}
if (!locality_name->zone().empty()) {
locality_name_json["zone"] = locality_name->zone();
}
if (!locality_name->sub_zone().empty()) {
locality_name_json["subzone"] = locality_name->sub_zone();
}
// Add weighted target entry.
weighted_targets[locality_name->AsHumanReadableString()] = Json::Object{
{"weight", locality.lb_weight},
{"childPolicy", config_->endpoint_picking_policy()},
};
}
// Construct locality-picking policy.
// Start with field from our config and add the "targets" field.
Json locality_picking_config = config_->locality_picking_policy();
Json::Object& config =
*(*locality_picking_config.mutable_array())[0].mutable_object();
auto it = config.begin();
GPR_ASSERT(it != config.end());
(*it->second.mutable_object())["targets"] = std::move(weighted_targets);
// Wrap it in the drop policy.
Json::Array drop_categories;
for (const auto& category : drop_config_->drop_category_list()) {
drop_categories.push_back(Json::Object{
{"category", category.name},
{"requests_per_million", category.parts_per_million},
});
}
Json::Object xds_cluster_impl_config = {
{"clusterName", std::string(lrs_key.first)},
{"childPolicy", std::move(locality_picking_config)},
{"dropCategories", std::move(drop_categories)},
{"maxConcurrentRequests", config_->max_concurrent_requests()},
};
if (!lrs_key.second.empty()) {
xds_cluster_impl_config["edsServiceName"] = std::string(lrs_key.second);
}
if (config_->lrs_load_reporting_server_name().has_value()) {
xds_cluster_impl_config["lrsLoadReportingServerName"] =
config_->lrs_load_reporting_server_name().value();
}
Json locality_picking_policy = Json::Array{Json::Object{
{"xds_cluster_impl_experimental", std::move(xds_cluster_impl_config)},
}};
// Add priority entry.
const size_t child_number = priority_child_numbers_[priority];
std::string child_name = absl::StrCat("child", child_number);
priority_priorities.emplace_back(child_name);
priority_children[child_name] = Json::Object{
{"config", std::move(locality_picking_policy)},
{"ignore_reresolution_requests", true},
};
}
Json json = Json::Array{Json::Object{
{"priority_experimental",
Json::Object{
{"children", std::move(priority_children)},
{"priorities", std::move(priority_priorities)},
}},
}};
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_eds_trace)) {
std::string json_str = json.Dump(/*indent=*/1);
gpr_log(GPR_INFO, "[edslb %p] generated config for child policy: %s", this,
json_str.c_str());
}
grpc_error* error = GRPC_ERROR_NONE;
RefCountedPtr<LoadBalancingPolicy::Config> config =
LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(json, &error);
if (error != GRPC_ERROR_NONE) {
// This should never happen, but if it does, we basically have no
// way to fix it, so we put the channel in TRANSIENT_FAILURE.
gpr_log(GPR_ERROR,
"[edslb %p] error parsing generated child policy config -- "
"will put channel in TRANSIENT_FAILURE: %s",
this, grpc_error_string(error));
error = grpc_error_set_int(
grpc_error_add_child(
GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"eds LB policy: error parsing generated child policy config"),
error),
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_INTERNAL);
channel_control_helper()->UpdateState(
GRPC_CHANNEL_TRANSIENT_FAILURE, grpc_error_to_absl_status(error),
absl::make_unique<TransientFailurePicker>(error));
return nullptr;
}
return config;
}
void EdsLb::UpdateChildPolicyLocked() {
if (shutting_down_) return;
UpdateArgs update_args;
update_args.config = CreateChildPolicyConfigLocked();
if (update_args.config == nullptr) return;
update_args.addresses = CreateChildPolicyAddressesLocked();
update_args.args = CreateChildPolicyArgsLocked(args_);
if (child_policy_ == nullptr) {
child_policy_ = CreateChildPolicyLocked(update_args.args);
}
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_eds_trace)) {
gpr_log(GPR_INFO, "[edslb %p] Updating child policy %p", this,
child_policy_.get());
}
child_policy_->UpdateLocked(std::move(update_args));
}
grpc_channel_args* EdsLb::CreateChildPolicyArgsLocked(
const grpc_channel_args* args) {
grpc_arg args_to_add[] = {
// A channel arg indicating if the target is a backend inferred from an
// xds load balancer.
// TODO(roth): This isn't needed with the new fallback design.
// Remove as part of implementing the new fallback functionality.
grpc_channel_arg_integer_create(
const_cast<char*>(GRPC_ARG_ADDRESS_IS_BACKEND_FROM_XDS_LOAD_BALANCER),
1),
// Inhibit client-side health checking, since the balancer does
// this for us.
grpc_channel_arg_integer_create(
const_cast<char*>(GRPC_ARG_INHIBIT_HEALTH_CHECKING), 1),
};
return grpc_channel_args_copy_and_add(args, args_to_add,
GPR_ARRAY_SIZE(args_to_add));
}
OrphanablePtr<LoadBalancingPolicy> EdsLb::CreateChildPolicyLocked(
const grpc_channel_args* args) {
LoadBalancingPolicy::Args lb_policy_args;
lb_policy_args.work_serializer = work_serializer();
lb_policy_args.args = args;
lb_policy_args.channel_control_helper =
absl::make_unique<Helper>(Ref(DEBUG_LOCATION, "Helper"));
OrphanablePtr<LoadBalancingPolicy> lb_policy =
LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy(
"priority_experimental", std::move(lb_policy_args));
if (GPR_UNLIKELY(lb_policy == nullptr)) {
gpr_log(GPR_ERROR, "[edslb %p] failure creating child policy", this);
return nullptr;
}
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_eds_trace)) {
gpr_log(GPR_INFO, "[edslb %p]: Created new child policy %p", this,
lb_policy.get());
}
// Add our interested_parties pollset_set to that of the newly created
// child policy. This will make the child policy progress upon activity on
// this policy, which in turn is tied to the application's call.
grpc_pollset_set_add_pollset_set(lb_policy->interested_parties(),
interested_parties());
return lb_policy;
}
//
// factory
//
class EdsLbFactory : public LoadBalancingPolicyFactory {
public:
OrphanablePtr<LoadBalancingPolicy> CreateLoadBalancingPolicy(
LoadBalancingPolicy::Args args) const override {
grpc_error* error = GRPC_ERROR_NONE;
RefCountedPtr<XdsClient> xds_client = XdsClient::GetOrCreate(&error);
if (error != GRPC_ERROR_NONE) {
gpr_log(GPR_ERROR,
"cannot get XdsClient to instantiate eds LB policy: %s",
grpc_error_string(error));
GRPC_ERROR_UNREF(error);
return nullptr;
}
return MakeOrphanable<EdsChildHandler>(std::move(xds_client),
std::move(args));
}
const char* name() const override { return kEds; }
RefCountedPtr<LoadBalancingPolicy::Config> ParseLoadBalancingConfig(
const Json& json, grpc_error** error) const override {
GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE);
if (json.type() == Json::Type::JSON_NULL) {
// eds was mentioned as a policy in the deprecated loadBalancingPolicy
// field or in the client API.
*error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:loadBalancingPolicy error:eds policy requires configuration. "
"Please use loadBalancingConfig field of service config instead.");
return nullptr;
}
std::vector<grpc_error*> error_list;
// EDS service name.
std::string eds_service_name;
auto it = json.object_value().find("edsServiceName");
if (it != json.object_value().end()) {
if (it->second.type() != Json::Type::STRING) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:edsServiceName error:type should be string"));
} else {
eds_service_name = it->second.string_value();
}
}
// Cluster name.
std::string cluster_name;
it = json.object_value().find("clusterName");
if (it == json.object_value().end()) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:clusterName error:required field missing"));
} else if (it->second.type() != Json::Type::STRING) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:clusterName error:type should be string"));
} else {
cluster_name = it->second.string_value();
}
// LRS load reporting server name.
absl::optional<std::string> lrs_load_reporting_server_name;
it = json.object_value().find("lrsLoadReportingServerName");
if (it != json.object_value().end()) {
if (it->second.type() != Json::Type::STRING) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:lrsLoadReportingServerName error:type should be string"));
} else {
lrs_load_reporting_server_name.emplace(it->second.string_value());
}
}
// Locality-picking policy.
Json locality_picking_policy;
it = json.object_value().find("localityPickingPolicy");
if (it == json.object_value().end()) {
locality_picking_policy = Json::Array{
Json::Object{
{"weighted_target_experimental",
Json::Object{
{"targets", Json::Object()},
}},
},
};
} else {
locality_picking_policy = it->second;
}
grpc_error* parse_error = GRPC_ERROR_NONE;
if (LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(
locality_picking_policy, &parse_error) == nullptr) {
GPR_DEBUG_ASSERT(parse_error != GRPC_ERROR_NONE);
error_list.push_back(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
"localityPickingPolicy", &parse_error, 1));
GRPC_ERROR_UNREF(parse_error);
}
// Endpoint-picking policy. Called "childPolicy" for xds policy.
Json endpoint_picking_policy;
it = json.object_value().find("endpointPickingPolicy");
if (it == json.object_value().end()) {
endpoint_picking_policy = Json::Array{
Json::Object{
{"round_robin", Json::Object()},
},
};
} else {
endpoint_picking_policy = it->second;
}
parse_error = GRPC_ERROR_NONE;
if (LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(
endpoint_picking_policy, &parse_error) == nullptr) {
GPR_DEBUG_ASSERT(parse_error != GRPC_ERROR_NONE);
error_list.push_back(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
"endpointPickingPolicy", &parse_error, 1));
GRPC_ERROR_UNREF(parse_error);
}
// Max concurrent requests.
uint32_t max_concurrent_requests = 1024;
it = json.object_value().find("max_concurrent_requests");
if (it != json.object_value().end()) {
if (it->second.type() != Json::Type::NUMBER) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:max_concurrent_requests error:must be of type number"));
} else {
max_concurrent_requests =
gpr_parse_nonnegative_int(it->second.string_value().c_str());
}
}
// Construct config.
if (error_list.empty()) {
return MakeRefCounted<EdsLbConfig>(
std::move(cluster_name), std::move(eds_service_name),
std::move(lrs_load_reporting_server_name),
std::move(locality_picking_policy),
std::move(endpoint_picking_policy), max_concurrent_requests);
} else {
*error = GRPC_ERROR_CREATE_FROM_VECTOR(
"eds_experimental LB policy config", &error_list);
return nullptr;
}
}
private:
class EdsChildHandler : public ChildPolicyHandler {
public:
EdsChildHandler(RefCountedPtr<XdsClient> xds_client, Args args)
: ChildPolicyHandler(std::move(args), &grpc_lb_eds_trace),
xds_client_(std::move(xds_client)) {}
bool ConfigChangeRequiresNewPolicyInstance(
LoadBalancingPolicy::Config* old_config,
LoadBalancingPolicy::Config* new_config) const override {
GPR_ASSERT(old_config->name() == kEds);
GPR_ASSERT(new_config->name() == kEds);
EdsLbConfig* old_eds_config = static_cast<EdsLbConfig*>(old_config);
EdsLbConfig* new_eds_config = static_cast<EdsLbConfig*>(new_config);
return old_eds_config->cluster_name() != new_eds_config->cluster_name() ||
old_eds_config->eds_service_name() !=
new_eds_config->eds_service_name() ||
old_eds_config->lrs_load_reporting_server_name() !=
new_eds_config->lrs_load_reporting_server_name();
}
OrphanablePtr<LoadBalancingPolicy> CreateLoadBalancingPolicy(
const char* name, LoadBalancingPolicy::Args args) const override {
return MakeOrphanable<EdsLb>(xds_client_, std::move(args));
}
private:
RefCountedPtr<XdsClient> xds_client_;
};
};
} // namespace
} // namespace grpc_core
//
// Plugin registration
//
void grpc_lb_policy_eds_init() {
grpc_core::LoadBalancingPolicyRegistry::Builder::
RegisterLoadBalancingPolicyFactory(
absl::make_unique<grpc_core::EdsLbFactory>());
}
void grpc_lb_policy_eds_shutdown() {}

@ -23,14 +23,6 @@
#include "src/core/ext/xds/xds_client_stats.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
/** Channel arg indicating if a target corresponding to the address is a backend
* received from a balancer. The type of this arg is an integer and the value is
* treated as a bool. */
// TODO(roth): Depending on how we ultimately decide to handle fallback,
// this may no longer be needed.
#define GRPC_ARG_ADDRESS_IS_BACKEND_FROM_XDS_LOAD_BALANCER \
"grpc.address_is_backend_from_xds_load_balancer"
namespace grpc_core {
// Defined in the EDS policy.

@ -0,0 +1,24 @@
//
// Copyright 2020 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_LB_POLICY_XDS_XDS_CHANNEL_ARGS_H
#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_XDS_XDS_CHANNEL_ARGS_H
// Channel arg indicating the xDS cluster name.
// Set by xds_cluster_impl LB policy and used by GoogleDefaultCredentials.
#define GRPC_ARG_XDS_CLUSTER_NAME "grpc.internal.xds_cluster_name"
#endif // GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_XDS_XDS_CHANNEL_ARGS_H

@ -23,6 +23,7 @@
#include "src/core/ext/filters/client_channel/lb_policy.h"
#include "src/core/ext/filters/client_channel/lb_policy/child_policy_handler.h"
#include "src/core/ext/filters/client_channel/lb_policy/xds/xds.h"
#include "src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_args.h"
#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
#include "src/core/ext/xds/xds_client.h"
@ -454,7 +455,6 @@ void XdsClusterImplLb::UpdateLocked(UpdateArgs args) {
}
// Update child policy.
UpdateChildPolicyLocked(std::move(args.addresses), args.args);
args.args = nullptr;
}
void XdsClusterImplLb::MaybeUpdatePickerLocked() {
@ -522,7 +522,10 @@ void XdsClusterImplLb::UpdateChildPolicyLocked(ServerAddressList addresses,
UpdateArgs update_args;
update_args.addresses = std::move(addresses);
update_args.config = config_->child_policy();
update_args.args = args;
grpc_arg cluster_arg = grpc_channel_arg_string_create(
const_cast<char*>(GRPC_ARG_XDS_CLUSTER_NAME),
const_cast<char*>(config_->cluster_name().c_str()));
update_args.args = grpc_channel_args_copy_and_add(args, &cluster_arg, 1);
// Update the policy.
if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_cluster_impl_lb_trace)) {
gpr_log(GPR_INFO,

@ -1,485 +0,0 @@
/*
*
* Copyright 2016 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 "src/core/lib/iomgr/port.h"
#if GRPC_ARES == 1
#include <ares.h>
#include <string.h>
#include "absl/strings/str_cat.h"
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <grpc/support/time.h>
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/iomgr/iomgr_internal.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
#include "src/core/lib/iomgr/timer.h"
typedef struct fd_node {
/** the owner of this fd node */
grpc_ares_ev_driver* ev_driver;
/** a closure wrapping on_readable_locked, which should be
invoked when the grpc_fd in this node becomes readable. */
grpc_closure read_closure;
/** a closure wrapping on_writable_locked, which should be
invoked when the grpc_fd in this node becomes writable. */
grpc_closure write_closure;
/** next fd node in the list */
struct fd_node* next;
/** wrapped fd that's polled by grpc's poller for the current platform */
grpc_core::GrpcPolledFd* grpc_polled_fd;
/** if the readable closure has been registered */
bool readable_registered;
/** if the writable closure has been registered */
bool writable_registered;
/** if the fd has been shutdown yet from grpc iomgr perspective */
bool already_shutdown;
} fd_node;
struct grpc_ares_ev_driver {
/** the ares_channel owned by this event driver */
ares_channel channel;
/** pollset set for driving the IO events of the channel */
grpc_pollset_set* pollset_set;
/** refcount of the event driver */
gpr_refcount refs;
/** work_serializer to synchronize c-ares and I/O callbacks on */
std::shared_ptr<grpc_core::WorkSerializer> work_serializer;
/** a list of grpc_fd that this event driver is currently using. */
fd_node* fds;
/** is this event driver currently working? */
bool working;
/** is this event driver being shut down */
bool shutting_down;
/** request object that's using this ev driver */
grpc_ares_request* request;
/** Owned by the ev_driver. Creates new GrpcPolledFd's */
std::unique_ptr<grpc_core::GrpcPolledFdFactory> polled_fd_factory;
/** query timeout in milliseconds */
int query_timeout_ms;
/** alarm to cancel active queries */
grpc_timer query_timeout;
/** cancels queries on a timeout */
grpc_closure on_timeout_locked;
/** alarm to poll ares_process on in case fd events don't happen */
grpc_timer ares_backup_poll_alarm;
/** polls ares_process on a periodic timer */
grpc_closure on_ares_backup_poll_alarm_locked;
};
static void grpc_ares_notify_on_event_locked(grpc_ares_ev_driver* ev_driver);
static grpc_ares_ev_driver* grpc_ares_ev_driver_ref(
grpc_ares_ev_driver* ev_driver) {
GRPC_CARES_TRACE_LOG("request:%p Ref ev_driver %p", ev_driver->request,
ev_driver);
gpr_ref(&ev_driver->refs);
return ev_driver;
}
static void grpc_ares_ev_driver_unref(grpc_ares_ev_driver* ev_driver) {
GRPC_CARES_TRACE_LOG("request:%p Unref ev_driver %p", ev_driver->request,
ev_driver);
if (gpr_unref(&ev_driver->refs)) {
GRPC_CARES_TRACE_LOG("request:%p destroy ev_driver %p", ev_driver->request,
ev_driver);
GPR_ASSERT(ev_driver->fds == nullptr);
ares_destroy(ev_driver->channel);
grpc_ares_complete_request_locked(ev_driver->request);
delete ev_driver;
}
}
static void fd_node_destroy_locked(fd_node* fdn) {
GRPC_CARES_TRACE_LOG("request:%p delete fd: %s", fdn->ev_driver->request,
fdn->grpc_polled_fd->GetName());
GPR_ASSERT(!fdn->readable_registered);
GPR_ASSERT(!fdn->writable_registered);
GPR_ASSERT(fdn->already_shutdown);
delete fdn->grpc_polled_fd;
gpr_free(fdn);
}
static void fd_node_shutdown_locked(fd_node* fdn, const char* reason) {
if (!fdn->already_shutdown) {
fdn->already_shutdown = true;
fdn->grpc_polled_fd->ShutdownLocked(
GRPC_ERROR_CREATE_FROM_STATIC_STRING(reason));
}
}
static void on_timeout(void* arg, grpc_error* error);
static void on_timeout_locked(grpc_ares_ev_driver* driver, grpc_error* error);
static void on_ares_backup_poll_alarm(void* arg, grpc_error* error);
static void on_ares_backup_poll_alarm_locked(grpc_ares_ev_driver* driver,
grpc_error* error);
static void noop_inject_channel_config(ares_channel /*channel*/) {}
void (*grpc_ares_test_only_inject_config)(ares_channel channel) =
noop_inject_channel_config;
grpc_error* grpc_ares_ev_driver_create_locked(
grpc_ares_ev_driver** ev_driver, grpc_pollset_set* pollset_set,
int query_timeout_ms,
std::shared_ptr<grpc_core::WorkSerializer> work_serializer,
grpc_ares_request* request) {
*ev_driver = new grpc_ares_ev_driver();
ares_options opts;
memset(&opts, 0, sizeof(opts));
opts.flags |= ARES_FLAG_STAYOPEN;
int status = ares_init_options(&(*ev_driver)->channel, &opts, ARES_OPT_FLAGS);
grpc_ares_test_only_inject_config((*ev_driver)->channel);
GRPC_CARES_TRACE_LOG("request:%p grpc_ares_ev_driver_create_locked", request);
if (status != ARES_SUCCESS) {
grpc_error* err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(
absl::StrCat("Failed to init ares channel. C-ares error: ",
ares_strerror(status))
.c_str());
gpr_free(*ev_driver);
return err;
}
(*ev_driver)->work_serializer = std::move(work_serializer);
gpr_ref_init(&(*ev_driver)->refs, 1);
(*ev_driver)->pollset_set = pollset_set;
(*ev_driver)->fds = nullptr;
(*ev_driver)->working = false;
(*ev_driver)->shutting_down = false;
(*ev_driver)->request = request;
(*ev_driver)->polled_fd_factory =
grpc_core::NewGrpcPolledFdFactory((*ev_driver)->work_serializer);
(*ev_driver)
->polled_fd_factory->ConfigureAresChannelLocked((*ev_driver)->channel);
(*ev_driver)->query_timeout_ms = query_timeout_ms;
return GRPC_ERROR_NONE;
}
void grpc_ares_ev_driver_on_queries_complete_locked(
grpc_ares_ev_driver* ev_driver) {
// We mark the event driver as being shut down. If the event driver
// is working, grpc_ares_notify_on_event_locked will shut down the
// fds; if it's not working, there are no fds to shut down.
ev_driver->shutting_down = true;
grpc_timer_cancel(&ev_driver->query_timeout);
grpc_timer_cancel(&ev_driver->ares_backup_poll_alarm);
grpc_ares_ev_driver_unref(ev_driver);
}
void grpc_ares_ev_driver_shutdown_locked(grpc_ares_ev_driver* ev_driver) {
ev_driver->shutting_down = true;
fd_node* fn = ev_driver->fds;
while (fn != nullptr) {
fd_node_shutdown_locked(fn, "grpc_ares_ev_driver_shutdown");
fn = fn->next;
}
}
// Search fd in the fd_node list head. This is an O(n) search, the max possible
// value of n is ARES_GETSOCK_MAXNUM (16). n is typically 1 - 2 in our tests.
static fd_node* pop_fd_node_locked(fd_node** head, ares_socket_t as) {
fd_node dummy_head;
dummy_head.next = *head;
fd_node* node = &dummy_head;
while (node->next != nullptr) {
if (node->next->grpc_polled_fd->GetWrappedAresSocketLocked() == as) {
fd_node* ret = node->next;
node->next = node->next->next;
*head = dummy_head.next;
return ret;
}
node = node->next;
}
return nullptr;
}
static grpc_millis calculate_next_ares_backup_poll_alarm_ms(
grpc_ares_ev_driver* driver) {
// An alternative here could be to use ares_timeout to try to be more
// accurate, but that would require using "struct timeval"'s, which just makes
// things a bit more complicated. So just poll every second, as suggested
// by the c-ares code comments.
grpc_millis ms_until_next_ares_backup_poll_alarm = 1000;
GRPC_CARES_TRACE_LOG(
"request:%p ev_driver=%p. next ares process poll time in "
"%" PRId64 " ms",
driver->request, driver, ms_until_next_ares_backup_poll_alarm);
return ms_until_next_ares_backup_poll_alarm +
grpc_core::ExecCtx::Get()->Now();
}
static void on_timeout(void* arg, grpc_error* error) {
grpc_ares_ev_driver* driver = static_cast<grpc_ares_ev_driver*>(arg);
GRPC_ERROR_REF(error); // ref owned by lambda
driver->work_serializer->Run(
[driver, error]() { on_timeout_locked(driver, error); }, DEBUG_LOCATION);
}
static void on_timeout_locked(grpc_ares_ev_driver* driver, grpc_error* error) {
GRPC_CARES_TRACE_LOG(
"request:%p ev_driver=%p on_timeout_locked. driver->shutting_down=%d. "
"err=%s",
driver->request, driver, driver->shutting_down, grpc_error_string(error));
if (!driver->shutting_down && error == GRPC_ERROR_NONE) {
grpc_ares_ev_driver_shutdown_locked(driver);
}
grpc_ares_ev_driver_unref(driver);
GRPC_ERROR_UNREF(error);
}
static void on_ares_backup_poll_alarm(void* arg, grpc_error* error) {
grpc_ares_ev_driver* driver = static_cast<grpc_ares_ev_driver*>(arg);
GRPC_ERROR_REF(error);
driver->work_serializer->Run(
[driver, error]() { on_ares_backup_poll_alarm_locked(driver, error); },
DEBUG_LOCATION);
}
/* In case of non-responsive DNS servers, dropped packets, etc., c-ares has
* intelligent timeout and retry logic, which we can take advantage of by
* polling ares_process_fd on time intervals. Overall, the c-ares library is
* meant to be called into and given a chance to proceed name resolution:
* a) when fd events happen
* b) when some time has passed without fd events having happened
* For the latter, we use this backup poller. Also see
* https://github.com/grpc/grpc/pull/17688 description for more details. */
static void on_ares_backup_poll_alarm_locked(grpc_ares_ev_driver* driver,
grpc_error* error) {
GRPC_CARES_TRACE_LOG(
"request:%p ev_driver=%p on_ares_backup_poll_alarm_locked. "
"driver->shutting_down=%d. "
"err=%s",
driver->request, driver, driver->shutting_down, grpc_error_string(error));
if (!driver->shutting_down && error == GRPC_ERROR_NONE) {
fd_node* fdn = driver->fds;
while (fdn != nullptr) {
if (!fdn->already_shutdown) {
GRPC_CARES_TRACE_LOG(
"request:%p ev_driver=%p on_ares_backup_poll_alarm_locked; "
"ares_process_fd. fd=%s",
driver->request, driver, fdn->grpc_polled_fd->GetName());
ares_socket_t as = fdn->grpc_polled_fd->GetWrappedAresSocketLocked();
ares_process_fd(driver->channel, as, as);
}
fdn = fdn->next;
}
if (!driver->shutting_down) {
grpc_millis next_ares_backup_poll_alarm =
calculate_next_ares_backup_poll_alarm_ms(driver);
grpc_ares_ev_driver_ref(driver);
GRPC_CLOSURE_INIT(&driver->on_ares_backup_poll_alarm_locked,
on_ares_backup_poll_alarm, driver,
grpc_schedule_on_exec_ctx);
grpc_timer_init(&driver->ares_backup_poll_alarm,
next_ares_backup_poll_alarm,
&driver->on_ares_backup_poll_alarm_locked);
}
grpc_ares_notify_on_event_locked(driver);
}
grpc_ares_ev_driver_unref(driver);
GRPC_ERROR_UNREF(error);
}
static void on_readable_locked(fd_node* fdn, grpc_error* error) {
GPR_ASSERT(fdn->readable_registered);
grpc_ares_ev_driver* ev_driver = fdn->ev_driver;
const ares_socket_t as = fdn->grpc_polled_fd->GetWrappedAresSocketLocked();
fdn->readable_registered = false;
GRPC_CARES_TRACE_LOG("request:%p readable on %s", fdn->ev_driver->request,
fdn->grpc_polled_fd->GetName());
if (error == GRPC_ERROR_NONE) {
do {
ares_process_fd(ev_driver->channel, as, ARES_SOCKET_BAD);
} while (fdn->grpc_polled_fd->IsFdStillReadableLocked());
} else {
// If error is not GRPC_ERROR_NONE, it means the fd has been shutdown or
// timed out. The pending lookups made on this ev_driver will be cancelled
// by the following ares_cancel() and the on_done callbacks will be invoked
// with a status of ARES_ECANCELLED. The remaining file descriptors in this
// ev_driver will be cleaned up in the follwing
// grpc_ares_notify_on_event_locked().
ares_cancel(ev_driver->channel);
}
grpc_ares_notify_on_event_locked(ev_driver);
grpc_ares_ev_driver_unref(ev_driver);
GRPC_ERROR_UNREF(error);
}
static void on_readable(void* arg, grpc_error* error) {
fd_node* fdn = static_cast<fd_node*>(arg);
GRPC_ERROR_REF(error); /* ref owned by lambda */
fdn->ev_driver->work_serializer->Run(
[fdn, error]() { on_readable_locked(fdn, error); }, DEBUG_LOCATION);
}
static void on_writable_locked(fd_node* fdn, grpc_error* error) {
GPR_ASSERT(fdn->writable_registered);
grpc_ares_ev_driver* ev_driver = fdn->ev_driver;
const ares_socket_t as = fdn->grpc_polled_fd->GetWrappedAresSocketLocked();
fdn->writable_registered = false;
GRPC_CARES_TRACE_LOG("request:%p writable on %s", ev_driver->request,
fdn->grpc_polled_fd->GetName());
if (error == GRPC_ERROR_NONE) {
ares_process_fd(ev_driver->channel, ARES_SOCKET_BAD, as);
} else {
// If error is not GRPC_ERROR_NONE, it means the fd has been shutdown or
// timed out. The pending lookups made on this ev_driver will be cancelled
// by the following ares_cancel() and the on_done callbacks will be invoked
// with a status of ARES_ECANCELLED. The remaining file descriptors in this
// ev_driver will be cleaned up in the follwing
// grpc_ares_notify_on_event_locked().
ares_cancel(ev_driver->channel);
}
grpc_ares_notify_on_event_locked(ev_driver);
grpc_ares_ev_driver_unref(ev_driver);
GRPC_ERROR_UNREF(error);
}
static void on_writable(void* arg, grpc_error* error) {
fd_node* fdn = static_cast<fd_node*>(arg);
GRPC_ERROR_REF(error); /* ref owned by lambda */
fdn->ev_driver->work_serializer->Run(
[fdn, error]() { on_writable_locked(fdn, error); }, DEBUG_LOCATION);
}
ares_channel* grpc_ares_ev_driver_get_channel_locked(
grpc_ares_ev_driver* ev_driver) {
return &ev_driver->channel;
}
// Get the file descriptors used by the ev_driver's ares channel, register
// driver_closure with these filedescriptors.
static void grpc_ares_notify_on_event_locked(grpc_ares_ev_driver* ev_driver) {
fd_node* new_list = nullptr;
if (!ev_driver->shutting_down) {
ares_socket_t socks[ARES_GETSOCK_MAXNUM];
int socks_bitmask =
ares_getsock(ev_driver->channel, socks, ARES_GETSOCK_MAXNUM);
for (size_t i = 0; i < ARES_GETSOCK_MAXNUM; i++) {
if (ARES_GETSOCK_READABLE(socks_bitmask, i) ||
ARES_GETSOCK_WRITABLE(socks_bitmask, i)) {
fd_node* fdn = pop_fd_node_locked(&ev_driver->fds, socks[i]);
// Create a new fd_node if sock[i] is not in the fd_node list.
if (fdn == nullptr) {
fdn = static_cast<fd_node*>(gpr_malloc(sizeof(fd_node)));
fdn->grpc_polled_fd =
ev_driver->polled_fd_factory->NewGrpcPolledFdLocked(
socks[i], ev_driver->pollset_set, ev_driver->work_serializer);
GRPC_CARES_TRACE_LOG("request:%p new fd: %s", ev_driver->request,
fdn->grpc_polled_fd->GetName());
fdn->ev_driver = ev_driver;
fdn->readable_registered = false;
fdn->writable_registered = false;
fdn->already_shutdown = false;
}
fdn->next = new_list;
new_list = fdn;
// Register read_closure if the socket is readable and read_closure has
// not been registered with this socket.
if (ARES_GETSOCK_READABLE(socks_bitmask, i) &&
!fdn->readable_registered) {
grpc_ares_ev_driver_ref(ev_driver);
GRPC_CARES_TRACE_LOG("request:%p notify read on: %s",
ev_driver->request,
fdn->grpc_polled_fd->GetName());
GRPC_CLOSURE_INIT(&fdn->read_closure, on_readable, fdn,
grpc_schedule_on_exec_ctx);
fdn->grpc_polled_fd->RegisterForOnReadableLocked(&fdn->read_closure);
fdn->readable_registered = true;
}
// Register write_closure if the socket is writable and write_closure
// has not been registered with this socket.
if (ARES_GETSOCK_WRITABLE(socks_bitmask, i) &&
!fdn->writable_registered) {
GRPC_CARES_TRACE_LOG("request:%p notify write on: %s",
ev_driver->request,
fdn->grpc_polled_fd->GetName());
grpc_ares_ev_driver_ref(ev_driver);
GRPC_CLOSURE_INIT(&fdn->write_closure, on_writable, fdn,
grpc_schedule_on_exec_ctx);
fdn->grpc_polled_fd->RegisterForOnWriteableLocked(
&fdn->write_closure);
fdn->writable_registered = true;
}
}
}
}
// Any remaining fds in ev_driver->fds were not returned by ares_getsock() and
// are therefore no longer in use, so they can be shut down and removed from
// the list.
while (ev_driver->fds != nullptr) {
fd_node* cur = ev_driver->fds;
ev_driver->fds = ev_driver->fds->next;
fd_node_shutdown_locked(cur, "c-ares fd shutdown");
if (!cur->readable_registered && !cur->writable_registered) {
fd_node_destroy_locked(cur);
} else {
cur->next = new_list;
new_list = cur;
}
}
ev_driver->fds = new_list;
// If the ev driver has no working fd, all the tasks are done.
if (new_list == nullptr) {
ev_driver->working = false;
GRPC_CARES_TRACE_LOG("request:%p ev driver stop working",
ev_driver->request);
}
}
void grpc_ares_ev_driver_start_locked(grpc_ares_ev_driver* ev_driver) {
if (!ev_driver->working) {
ev_driver->working = true;
grpc_ares_notify_on_event_locked(ev_driver);
// Initialize overall DNS resolution timeout alarm
grpc_millis timeout =
ev_driver->query_timeout_ms == 0
? GRPC_MILLIS_INF_FUTURE
: ev_driver->query_timeout_ms + grpc_core::ExecCtx::Get()->Now();
GRPC_CARES_TRACE_LOG(
"request:%p ev_driver=%p grpc_ares_ev_driver_start_locked. timeout in "
"%" PRId64 " ms",
ev_driver->request, ev_driver, timeout);
grpc_ares_ev_driver_ref(ev_driver);
GRPC_CLOSURE_INIT(&ev_driver->on_timeout_locked, on_timeout, ev_driver,
grpc_schedule_on_exec_ctx);
grpc_timer_init(&ev_driver->query_timeout, timeout,
&ev_driver->on_timeout_locked);
// Initialize the backup poll alarm
grpc_millis next_ares_backup_poll_alarm =
calculate_next_ares_backup_poll_alarm_ms(ev_driver);
grpc_ares_ev_driver_ref(ev_driver);
GRPC_CLOSURE_INIT(&ev_driver->on_ares_backup_poll_alarm_locked,
on_ares_backup_poll_alarm, ev_driver,
grpc_schedule_on_exec_ctx);
grpc_timer_init(&ev_driver->ares_backup_poll_alarm,
next_ares_backup_poll_alarm,
&ev_driver->on_ares_backup_poll_alarm_locked);
}
}
#endif /* GRPC_ARES == 1 */

@ -22,39 +22,8 @@
#include <grpc/support/port_platform.h>
#include <ares.h>
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
#include "src/core/lib/iomgr/pollset_set.h"
typedef struct grpc_ares_ev_driver grpc_ares_ev_driver;
/* Start \a ev_driver. It will keep working until all IO on its ares_channel is
done, or grpc_ares_ev_driver_destroy() is called. It may notify the callbacks
bound to its ares_channel when necessary. */
void grpc_ares_ev_driver_start_locked(grpc_ares_ev_driver* ev_driver);
/* Returns the ares_channel owned by \a ev_driver. To bind a c-ares query to
\a ev_driver, use the ares_channel owned by \a ev_driver as the arg of the
query. */
ares_channel* grpc_ares_ev_driver_get_channel_locked(
grpc_ares_ev_driver* ev_driver);
/* Creates a new grpc_ares_ev_driver. Returns GRPC_ERROR_NONE if \a ev_driver is
created successfully. */
grpc_error* grpc_ares_ev_driver_create_locked(
grpc_ares_ev_driver** ev_driver, grpc_pollset_set* pollset_set,
int query_timeout_ms,
std::shared_ptr<grpc_core::WorkSerializer> work_serializer,
grpc_ares_request* request);
/* Called back when all DNS lookups have completed. */
void grpc_ares_ev_driver_on_queries_complete_locked(
grpc_ares_ev_driver* ev_driver);
/* Shutdown all the grpc_fds used by \a ev_driver */
void grpc_ares_ev_driver_shutdown_locked(grpc_ares_ev_driver* ev_driver);
/* Exposed in this header for C-core tests only */
extern void (*grpc_ares_test_only_inject_config)(ares_channel channel);
#include "src/core/lib/iomgr/work_serializer.h"
namespace grpc_core {

@ -46,6 +46,7 @@
#include "src/core/lib/iomgr/nameser.h"
#include "src/core/lib/iomgr/parse_address.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
#include "src/core/lib/iomgr/timer.h"
#include "src/core/lib/transport/authority_override.h"
using grpc_core::ServerAddress;
@ -56,6 +57,8 @@ grpc_core::TraceFlag grpc_trace_cares_address_sorting(false,
grpc_core::TraceFlag grpc_trace_cares_resolver(false, "cares_resolver");
typedef struct grpc_ares_ev_driver grpc_ares_ev_driver;
struct grpc_ares_request {
/** indicates the DNS server to use, if specified */
struct ares_addr_port_node dns_server_addr;
@ -77,6 +80,60 @@ struct grpc_ares_request {
grpc_error* error;
};
typedef struct fd_node {
/** the owner of this fd node */
grpc_ares_ev_driver* ev_driver;
/** a closure wrapping on_readable_locked, which should be
invoked when the grpc_fd in this node becomes readable. */
grpc_closure read_closure;
/** a closure wrapping on_writable_locked, which should be
invoked when the grpc_fd in this node becomes writable. */
grpc_closure write_closure;
/** next fd node in the list */
struct fd_node* next;
/** wrapped fd that's polled by grpc's poller for the current platform */
grpc_core::GrpcPolledFd* grpc_polled_fd;
/** if the readable closure has been registered */
bool readable_registered;
/** if the writable closure has been registered */
bool writable_registered;
/** if the fd has been shutdown yet from grpc iomgr perspective */
bool already_shutdown;
} fd_node;
struct grpc_ares_ev_driver {
/** the ares_channel owned by this event driver */
ares_channel channel;
/** pollset set for driving the IO events of the channel */
grpc_pollset_set* pollset_set;
/** refcount of the event driver */
gpr_refcount refs;
/** work_serializer to synchronize c-ares and I/O callbacks on */
std::shared_ptr<grpc_core::WorkSerializer> work_serializer;
/** a list of grpc_fd that this event driver is currently using. */
fd_node* fds;
/** is this event driver currently working? */
bool working;
/** is this event driver being shut down */
bool shutting_down;
/** request object that's using this ev driver */
grpc_ares_request* request;
/** Owned by the ev_driver. Creates new GrpcPolledFd's */
std::unique_ptr<grpc_core::GrpcPolledFdFactory> polled_fd_factory;
/** query timeout in milliseconds */
int query_timeout_ms;
/** alarm to cancel active queries */
grpc_timer query_timeout;
/** cancels queries on a timeout */
grpc_closure on_timeout_locked;
/** alarm to poll ares_process on in case fd events don't happen */
grpc_timer ares_backup_poll_alarm;
/** polls ares_process on a periodic timer */
grpc_closure on_ares_backup_poll_alarm_locked;
};
// TODO(apolcyn): make grpc_ares_hostbyname_request a sub-class
// of GrpcAresQuery.
typedef struct grpc_ares_hostbyname_request {
@ -121,6 +178,390 @@ class GrpcAresQuery {
const std::string name_;
};
static grpc_ares_ev_driver* grpc_ares_ev_driver_ref(
grpc_ares_ev_driver* ev_driver) {
GRPC_CARES_TRACE_LOG("request:%p Ref ev_driver %p", ev_driver->request,
ev_driver);
gpr_ref(&ev_driver->refs);
return ev_driver;
}
static void grpc_ares_ev_driver_unref(grpc_ares_ev_driver* ev_driver) {
GRPC_CARES_TRACE_LOG("request:%p Unref ev_driver %p", ev_driver->request,
ev_driver);
if (gpr_unref(&ev_driver->refs)) {
GRPC_CARES_TRACE_LOG("request:%p destroy ev_driver %p", ev_driver->request,
ev_driver);
GPR_ASSERT(ev_driver->fds == nullptr);
ares_destroy(ev_driver->channel);
grpc_ares_complete_request_locked(ev_driver->request);
delete ev_driver;
}
}
static void fd_node_destroy_locked(fd_node* fdn) {
GRPC_CARES_TRACE_LOG("request:%p delete fd: %s", fdn->ev_driver->request,
fdn->grpc_polled_fd->GetName());
GPR_ASSERT(!fdn->readable_registered);
GPR_ASSERT(!fdn->writable_registered);
GPR_ASSERT(fdn->already_shutdown);
delete fdn->grpc_polled_fd;
gpr_free(fdn);
}
static void fd_node_shutdown_locked(fd_node* fdn, const char* reason) {
if (!fdn->already_shutdown) {
fdn->already_shutdown = true;
fdn->grpc_polled_fd->ShutdownLocked(
GRPC_ERROR_CREATE_FROM_STATIC_STRING(reason));
}
}
void grpc_ares_ev_driver_on_queries_complete_locked(
grpc_ares_ev_driver* ev_driver) {
// We mark the event driver as being shut down. If the event driver
// is working, grpc_ares_notify_on_event_locked will shut down the
// fds; if it's not working, there are no fds to shut down.
ev_driver->shutting_down = true;
grpc_timer_cancel(&ev_driver->query_timeout);
grpc_timer_cancel(&ev_driver->ares_backup_poll_alarm);
grpc_ares_ev_driver_unref(ev_driver);
}
void grpc_ares_ev_driver_shutdown_locked(grpc_ares_ev_driver* ev_driver) {
ev_driver->shutting_down = true;
fd_node* fn = ev_driver->fds;
while (fn != nullptr) {
fd_node_shutdown_locked(fn, "grpc_ares_ev_driver_shutdown");
fn = fn->next;
}
}
// Search fd in the fd_node list head. This is an O(n) search, the max possible
// value of n is ARES_GETSOCK_MAXNUM (16). n is typically 1 - 2 in our tests.
static fd_node* pop_fd_node_locked(fd_node** head, ares_socket_t as) {
fd_node dummy_head;
dummy_head.next = *head;
fd_node* node = &dummy_head;
while (node->next != nullptr) {
if (node->next->grpc_polled_fd->GetWrappedAresSocketLocked() == as) {
fd_node* ret = node->next;
node->next = node->next->next;
*head = dummy_head.next;
return ret;
}
node = node->next;
}
return nullptr;
}
static grpc_millis calculate_next_ares_backup_poll_alarm_ms(
grpc_ares_ev_driver* driver) {
// An alternative here could be to use ares_timeout to try to be more
// accurate, but that would require using "struct timeval"'s, which just makes
// things a bit more complicated. So just poll every second, as suggested
// by the c-ares code comments.
grpc_millis ms_until_next_ares_backup_poll_alarm = 1000;
GRPC_CARES_TRACE_LOG(
"request:%p ev_driver=%p. next ares process poll time in "
"%" PRId64 " ms",
driver->request, driver, ms_until_next_ares_backup_poll_alarm);
return ms_until_next_ares_backup_poll_alarm +
grpc_core::ExecCtx::Get()->Now();
}
static void on_timeout_locked(grpc_ares_ev_driver* driver, grpc_error* error) {
GRPC_CARES_TRACE_LOG(
"request:%p ev_driver=%p on_timeout_locked. driver->shutting_down=%d. "
"err=%s",
driver->request, driver, driver->shutting_down, grpc_error_string(error));
if (!driver->shutting_down && error == GRPC_ERROR_NONE) {
grpc_ares_ev_driver_shutdown_locked(driver);
}
grpc_ares_ev_driver_unref(driver);
GRPC_ERROR_UNREF(error);
}
static void on_timeout(void* arg, grpc_error* error) {
grpc_ares_ev_driver* driver = static_cast<grpc_ares_ev_driver*>(arg);
GRPC_ERROR_REF(error); // ref owned by lambda
driver->work_serializer->Run(
[driver, error]() { on_timeout_locked(driver, error); }, DEBUG_LOCATION);
}
static void grpc_ares_notify_on_event_locked(grpc_ares_ev_driver* ev_driver);
static void on_ares_backup_poll_alarm_locked(grpc_ares_ev_driver* driver,
grpc_error* error);
static void on_ares_backup_poll_alarm(void* arg, grpc_error* error) {
grpc_ares_ev_driver* driver = static_cast<grpc_ares_ev_driver*>(arg);
GRPC_ERROR_REF(error);
driver->work_serializer->Run(
[driver, error]() { on_ares_backup_poll_alarm_locked(driver, error); },
DEBUG_LOCATION);
}
/* In case of non-responsive DNS servers, dropped packets, etc., c-ares has
* intelligent timeout and retry logic, which we can take advantage of by
* polling ares_process_fd on time intervals. Overall, the c-ares library is
* meant to be called into and given a chance to proceed name resolution:
* a) when fd events happen
* b) when some time has passed without fd events having happened
* For the latter, we use this backup poller. Also see
* https://github.com/grpc/grpc/pull/17688 description for more details. */
static void on_ares_backup_poll_alarm_locked(grpc_ares_ev_driver* driver,
grpc_error* error) {
GRPC_CARES_TRACE_LOG(
"request:%p ev_driver=%p on_ares_backup_poll_alarm_locked. "
"driver->shutting_down=%d. "
"err=%s",
driver->request, driver, driver->shutting_down, grpc_error_string(error));
if (!driver->shutting_down && error == GRPC_ERROR_NONE) {
fd_node* fdn = driver->fds;
while (fdn != nullptr) {
if (!fdn->already_shutdown) {
GRPC_CARES_TRACE_LOG(
"request:%p ev_driver=%p on_ares_backup_poll_alarm_locked; "
"ares_process_fd. fd=%s",
driver->request, driver, fdn->grpc_polled_fd->GetName());
ares_socket_t as = fdn->grpc_polled_fd->GetWrappedAresSocketLocked();
ares_process_fd(driver->channel, as, as);
}
fdn = fdn->next;
}
if (!driver->shutting_down) {
grpc_millis next_ares_backup_poll_alarm =
calculate_next_ares_backup_poll_alarm_ms(driver);
grpc_ares_ev_driver_ref(driver);
GRPC_CLOSURE_INIT(&driver->on_ares_backup_poll_alarm_locked,
on_ares_backup_poll_alarm, driver,
grpc_schedule_on_exec_ctx);
grpc_timer_init(&driver->ares_backup_poll_alarm,
next_ares_backup_poll_alarm,
&driver->on_ares_backup_poll_alarm_locked);
}
grpc_ares_notify_on_event_locked(driver);
}
grpc_ares_ev_driver_unref(driver);
GRPC_ERROR_UNREF(error);
}
static void on_readable_locked(fd_node* fdn, grpc_error* error) {
GPR_ASSERT(fdn->readable_registered);
grpc_ares_ev_driver* ev_driver = fdn->ev_driver;
const ares_socket_t as = fdn->grpc_polled_fd->GetWrappedAresSocketLocked();
fdn->readable_registered = false;
GRPC_CARES_TRACE_LOG("request:%p readable on %s", fdn->ev_driver->request,
fdn->grpc_polled_fd->GetName());
if (error == GRPC_ERROR_NONE) {
do {
ares_process_fd(ev_driver->channel, as, ARES_SOCKET_BAD);
} while (fdn->grpc_polled_fd->IsFdStillReadableLocked());
} else {
// If error is not GRPC_ERROR_NONE, it means the fd has been shutdown or
// timed out. The pending lookups made on this ev_driver will be cancelled
// by the following ares_cancel() and the on_done callbacks will be invoked
// with a status of ARES_ECANCELLED. The remaining file descriptors in this
// ev_driver will be cleaned up in the follwing
// grpc_ares_notify_on_event_locked().
ares_cancel(ev_driver->channel);
}
grpc_ares_notify_on_event_locked(ev_driver);
grpc_ares_ev_driver_unref(ev_driver);
GRPC_ERROR_UNREF(error);
}
static void on_readable(void* arg, grpc_error* error) {
fd_node* fdn = static_cast<fd_node*>(arg);
GRPC_ERROR_REF(error); /* ref owned by lambda */
fdn->ev_driver->work_serializer->Run(
[fdn, error]() { on_readable_locked(fdn, error); }, DEBUG_LOCATION);
}
static void on_writable_locked(fd_node* fdn, grpc_error* error) {
GPR_ASSERT(fdn->writable_registered);
grpc_ares_ev_driver* ev_driver = fdn->ev_driver;
const ares_socket_t as = fdn->grpc_polled_fd->GetWrappedAresSocketLocked();
fdn->writable_registered = false;
GRPC_CARES_TRACE_LOG("request:%p writable on %s", ev_driver->request,
fdn->grpc_polled_fd->GetName());
if (error == GRPC_ERROR_NONE) {
ares_process_fd(ev_driver->channel, ARES_SOCKET_BAD, as);
} else {
// If error is not GRPC_ERROR_NONE, it means the fd has been shutdown or
// timed out. The pending lookups made on this ev_driver will be cancelled
// by the following ares_cancel() and the on_done callbacks will be invoked
// with a status of ARES_ECANCELLED. The remaining file descriptors in this
// ev_driver will be cleaned up in the follwing
// grpc_ares_notify_on_event_locked().
ares_cancel(ev_driver->channel);
}
grpc_ares_notify_on_event_locked(ev_driver);
grpc_ares_ev_driver_unref(ev_driver);
GRPC_ERROR_UNREF(error);
}
static void on_writable(void* arg, grpc_error* error) {
fd_node* fdn = static_cast<fd_node*>(arg);
GRPC_ERROR_REF(error); /* ref owned by lambda */
fdn->ev_driver->work_serializer->Run(
[fdn, error]() { on_writable_locked(fdn, error); }, DEBUG_LOCATION);
}
// Get the file descriptors used by the ev_driver's ares channel, register
// driver_closure with these filedescriptors.
static void grpc_ares_notify_on_event_locked(grpc_ares_ev_driver* ev_driver) {
fd_node* new_list = nullptr;
if (!ev_driver->shutting_down) {
ares_socket_t socks[ARES_GETSOCK_MAXNUM];
int socks_bitmask =
ares_getsock(ev_driver->channel, socks, ARES_GETSOCK_MAXNUM);
for (size_t i = 0; i < ARES_GETSOCK_MAXNUM; i++) {
if (ARES_GETSOCK_READABLE(socks_bitmask, i) ||
ARES_GETSOCK_WRITABLE(socks_bitmask, i)) {
fd_node* fdn = pop_fd_node_locked(&ev_driver->fds, socks[i]);
// Create a new fd_node if sock[i] is not in the fd_node list.
if (fdn == nullptr) {
fdn = static_cast<fd_node*>(gpr_malloc(sizeof(fd_node)));
fdn->grpc_polled_fd =
ev_driver->polled_fd_factory->NewGrpcPolledFdLocked(
socks[i], ev_driver->pollset_set, ev_driver->work_serializer);
GRPC_CARES_TRACE_LOG("request:%p new fd: %s", ev_driver->request,
fdn->grpc_polled_fd->GetName());
fdn->ev_driver = ev_driver;
fdn->readable_registered = false;
fdn->writable_registered = false;
fdn->already_shutdown = false;
}
fdn->next = new_list;
new_list = fdn;
// Register read_closure if the socket is readable and read_closure has
// not been registered with this socket.
if (ARES_GETSOCK_READABLE(socks_bitmask, i) &&
!fdn->readable_registered) {
grpc_ares_ev_driver_ref(ev_driver);
GRPC_CARES_TRACE_LOG("request:%p notify read on: %s",
ev_driver->request,
fdn->grpc_polled_fd->GetName());
GRPC_CLOSURE_INIT(&fdn->read_closure, on_readable, fdn,
grpc_schedule_on_exec_ctx);
fdn->grpc_polled_fd->RegisterForOnReadableLocked(&fdn->read_closure);
fdn->readable_registered = true;
}
// Register write_closure if the socket is writable and write_closure
// has not been registered with this socket.
if (ARES_GETSOCK_WRITABLE(socks_bitmask, i) &&
!fdn->writable_registered) {
GRPC_CARES_TRACE_LOG("request:%p notify write on: %s",
ev_driver->request,
fdn->grpc_polled_fd->GetName());
grpc_ares_ev_driver_ref(ev_driver);
GRPC_CLOSURE_INIT(&fdn->write_closure, on_writable, fdn,
grpc_schedule_on_exec_ctx);
GRPC_CLOSURE_INIT(&fdn->write_closure, on_writable, fdn,
grpc_schedule_on_exec_ctx);
fdn->grpc_polled_fd->RegisterForOnWriteableLocked(
&fdn->write_closure);
fdn->writable_registered = true;
}
}
}
}
// Any remaining fds in ev_driver->fds were not returned by ares_getsock() and
// are therefore no longer in use, so they can be shut down and removed from
// the list.
while (ev_driver->fds != nullptr) {
fd_node* cur = ev_driver->fds;
ev_driver->fds = ev_driver->fds->next;
fd_node_shutdown_locked(cur, "c-ares fd shutdown");
if (!cur->readable_registered && !cur->writable_registered) {
fd_node_destroy_locked(cur);
} else {
cur->next = new_list;
new_list = cur;
}
}
ev_driver->fds = new_list;
// If the ev driver has no working fd, all the tasks are done.
if (new_list == nullptr) {
ev_driver->working = false;
GRPC_CARES_TRACE_LOG("request:%p ev driver stop working",
ev_driver->request);
}
}
void grpc_ares_ev_driver_start_locked(grpc_ares_ev_driver* ev_driver) {
if (!ev_driver->working) {
ev_driver->working = true;
grpc_ares_notify_on_event_locked(ev_driver);
// Initialize overall DNS resolution timeout alarm
grpc_millis timeout =
ev_driver->query_timeout_ms == 0
? GRPC_MILLIS_INF_FUTURE
: ev_driver->query_timeout_ms + grpc_core::ExecCtx::Get()->Now();
GRPC_CARES_TRACE_LOG(
"request:%p ev_driver=%p grpc_ares_ev_driver_start_locked. timeout in "
"%" PRId64 " ms",
ev_driver->request, ev_driver, timeout);
grpc_ares_ev_driver_ref(ev_driver);
GRPC_CLOSURE_INIT(&ev_driver->on_timeout_locked, on_timeout, ev_driver,
grpc_schedule_on_exec_ctx);
grpc_timer_init(&ev_driver->query_timeout, timeout,
&ev_driver->on_timeout_locked);
// Initialize the backup poll alarm
grpc_millis next_ares_backup_poll_alarm =
calculate_next_ares_backup_poll_alarm_ms(ev_driver);
grpc_ares_ev_driver_ref(ev_driver);
GRPC_CLOSURE_INIT(&ev_driver->on_ares_backup_poll_alarm_locked,
on_ares_backup_poll_alarm, ev_driver,
grpc_schedule_on_exec_ctx);
grpc_timer_init(&ev_driver->ares_backup_poll_alarm,
next_ares_backup_poll_alarm,
&ev_driver->on_ares_backup_poll_alarm_locked);
}
}
static void noop_inject_channel_config(ares_channel /*channel*/) {}
void (*grpc_ares_test_only_inject_config)(ares_channel channel) =
noop_inject_channel_config;
grpc_error* grpc_ares_ev_driver_create_locked(
grpc_ares_ev_driver** ev_driver, grpc_pollset_set* pollset_set,
int query_timeout_ms,
std::shared_ptr<grpc_core::WorkSerializer> work_serializer,
grpc_ares_request* request) {
*ev_driver = new grpc_ares_ev_driver();
ares_options opts;
memset(&opts, 0, sizeof(opts));
opts.flags |= ARES_FLAG_STAYOPEN;
int status = ares_init_options(&(*ev_driver)->channel, &opts, ARES_OPT_FLAGS);
grpc_ares_test_only_inject_config((*ev_driver)->channel);
GRPC_CARES_TRACE_LOG("request:%p grpc_ares_ev_driver_create_locked", request);
if (status != ARES_SUCCESS) {
grpc_error* err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(
absl::StrCat("Failed to init ares channel. C-ares error: ",
ares_strerror(status))
.c_str());
gpr_free(*ev_driver);
return err;
}
(*ev_driver)->work_serializer = std::move(work_serializer);
gpr_ref_init(&(*ev_driver)->refs, 1);
(*ev_driver)->pollset_set = pollset_set;
(*ev_driver)->fds = nullptr;
(*ev_driver)->working = false;
(*ev_driver)->shutting_down = false;
(*ev_driver)->request = request;
(*ev_driver)->polled_fd_factory =
grpc_core::NewGrpcPolledFdFactory((*ev_driver)->work_serializer);
(*ev_driver)
->polled_fd_factory->ConfigureAresChannelLocked((*ev_driver)->channel);
(*ev_driver)->query_timeout_ms = query_timeout_ms;
return GRPC_ERROR_NONE;
}
static void log_address_sorting_list(const grpc_ares_request* r,
const ServerAddressList& addresses,
const char* input_output_str) {
@ -303,20 +744,18 @@ static void on_srv_query_done_locked(void* arg, int status, int /*timeouts*/,
GRPC_CARES_TRACE_LOG("request:%p ares_parse_srv_reply: %d", r,
parse_status);
if (parse_status == ARES_SUCCESS) {
ares_channel* channel =
grpc_ares_ev_driver_get_channel_locked(r->ev_driver);
for (struct ares_srv_reply* srv_it = reply; srv_it != nullptr;
srv_it = srv_it->next) {
if (grpc_ares_query_ipv6()) {
grpc_ares_hostbyname_request* hr = create_hostbyname_request_locked(
r, srv_it->host, htons(srv_it->port), true /* is_balancer */,
"AAAA");
ares_gethostbyname(*channel, hr->host, AF_INET6,
ares_gethostbyname(r->ev_driver->channel, hr->host, AF_INET6,
on_hostbyname_done_locked, hr);
}
grpc_ares_hostbyname_request* hr = create_hostbyname_request_locked(
r, srv_it->host, htons(srv_it->port), true /* is_balancer */, "A");
ares_gethostbyname(*channel, hr->host, AF_INET,
ares_gethostbyname(r->ev_driver->channel, hr->host, AF_INET,
on_hostbyname_done_locked, hr);
grpc_ares_ev_driver_start_locked(r->ev_driver);
}
@ -400,7 +839,6 @@ void grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked(
std::shared_ptr<grpc_core::WorkSerializer> work_serializer) {
grpc_error* error = GRPC_ERROR_NONE;
grpc_ares_hostbyname_request* hr = nullptr;
ares_channel* channel = nullptr;
/* parse name, splitting it into host and port parts */
std::string host;
std::string port;
@ -423,7 +861,6 @@ void grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked(
query_timeout_ms,
std::move(work_serializer), r);
if (error != GRPC_ERROR_NONE) goto error_cleanup;
channel = grpc_ares_ev_driver_get_channel_locked(r->ev_driver);
// If dns_server is specified, use it.
if (dns_server != nullptr && dns_server[0] != '\0') {
GRPC_CARES_TRACE_LOG("request:%p Using DNS server %s", r, dns_server);
@ -450,7 +887,8 @@ void grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked(
GRPC_ERROR_STR_TARGET_ADDRESS, grpc_slice_from_copied_string(name));
goto error_cleanup;
}
int status = ares_set_servers_ports(*channel, &r->dns_server_addr);
int status =
ares_set_servers_ports(r->ev_driver->channel, &r->dns_server_addr);
if (status != ARES_SUCCESS) {
error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(
absl::StrCat("C-ares status is not ARES_SUCCESS: ",
@ -464,25 +902,25 @@ void grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked(
hr = create_hostbyname_request_locked(r, host.c_str(),
grpc_strhtons(port.c_str()),
/*is_balancer=*/false, "AAAA");
ares_gethostbyname(*channel, hr->host, AF_INET6, on_hostbyname_done_locked,
hr);
ares_gethostbyname(r->ev_driver->channel, hr->host, AF_INET6,
on_hostbyname_done_locked, hr);
}
hr = create_hostbyname_request_locked(r, host.c_str(),
grpc_strhtons(port.c_str()),
/*is_balancer=*/false, "A");
ares_gethostbyname(*channel, hr->host, AF_INET, on_hostbyname_done_locked,
hr);
ares_gethostbyname(r->ev_driver->channel, hr->host, AF_INET,
on_hostbyname_done_locked, hr);
if (r->balancer_addresses_out != nullptr) {
/* Query the SRV record */
std::string service_name = absl::StrCat("_grpclb._tcp.", host);
GrpcAresQuery* srv_query = new GrpcAresQuery(r, service_name);
ares_query(*channel, service_name.c_str(), ns_c_in, ns_t_srv,
ares_query(r->ev_driver->channel, service_name.c_str(), ns_c_in, ns_t_srv,
on_srv_query_done_locked, srv_query);
}
if (r->service_config_json_out != nullptr) {
std::string config_name = absl::StrCat("_grpc_config.", host);
GrpcAresQuery* txt_query = new GrpcAresQuery(r, config_name);
ares_search(*channel, config_name.c_str(), ns_c_in, ns_t_txt,
ares_search(r->ev_driver->channel, config_name.c_str(), ns_c_in, ns_t_txt,
on_txt_done_locked, txt_query);
}
grpc_ares_ev_driver_start_locked(r->ev_driver);

@ -21,6 +21,8 @@
#include <grpc/support/port_platform.h>
#include <ares.h>
#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/lib/iomgr/iomgr.h"
#include "src/core/lib/iomgr/polling_entity.h"
@ -93,5 +95,8 @@ bool grpc_ares_query_ipv6();
void grpc_cares_wrapper_address_sorting_sort(
const grpc_ares_request* request, grpc_core::ServerAddressList* addresses);
/* Exposed in this header for C-core tests only */
extern void (*grpc_ares_test_only_inject_config)(ares_channel channel);
#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_WRAPPER_H \
*/

@ -1,68 +0,0 @@
/*
*
* Copyright 2016-2017 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>
#if GRPC_ARES != 1
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
struct grpc_ares_request {
char val;
};
static grpc_ares_request* grpc_dns_lookup_ares_locked_impl(
const char* dns_server, const char* name, const char* default_port,
grpc_pollset_set* interested_parties, grpc_closure* on_done,
std::unique_ptr<grpc_core::ServerAddressList>* addrs,
std::unique_ptr<grpc_core::ServerAddressList>* balancer_addrs,
char** service_config_json, int query_timeout_ms,
std::shared_ptr<grpc_core::WorkSerializer> work_serializer) {
return NULL;
}
grpc_ares_request* (*grpc_dns_lookup_ares_locked)(
const char* dns_server, const char* name, const char* default_port,
grpc_pollset_set* interested_parties, grpc_closure* on_done,
std::unique_ptr<grpc_core::ServerAddressList>* addrs,
std::unique_ptr<grpc_core::ServerAddressList>* balancer_addrs,
char** service_config_json, int query_timeout_ms,
std::shared_ptr<grpc_core::WorkSerializer> work_serializer) =
grpc_dns_lookup_ares_locked_impl;
static void grpc_cancel_ares_request_locked_impl(grpc_ares_request* r) {}
void (*grpc_cancel_ares_request_locked)(grpc_ares_request* r) =
grpc_cancel_ares_request_locked_impl;
grpc_error* grpc_ares_init(void) { return GRPC_ERROR_NONE; }
void grpc_ares_cleanup(void) {}
static void grpc_resolve_address_ares_impl(const char* name,
const char* default_port,
grpc_pollset_set* interested_parties,
grpc_closure* on_done,
grpc_resolved_addresses** addrs) {}
void (*grpc_resolve_address_ares)(
const char* name, const char* default_port,
grpc_pollset_set* interested_parties, grpc_closure* on_done,
grpc_resolved_addresses** addrs) = grpc_resolve_address_ares_impl;
#endif /* GRPC_ARES != 1 */

@ -248,27 +248,25 @@ grpc_error* ParseRetryThrottling(
return GRPC_ERROR_CREATE_FROM_VECTOR("retryPolicy", &error_list);
}
const char* ParseHealthCheckConfig(const Json& field, grpc_error** error) {
absl::optional<std::string> ParseHealthCheckConfig(const Json& field,
grpc_error** error) {
GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE);
const char* service_name = nullptr;
if (field.type() != Json::Type::OBJECT) {
*error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:healthCheckConfig error:should be of type object");
return nullptr;
return absl::nullopt;
}
std::vector<grpc_error*> error_list;
absl::optional<std::string> service_name;
auto it = field.object_value().find("serviceName");
if (it != field.object_value().end()) {
if (it->second.type() != Json::Type::STRING) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:serviceName error:should be of type string"));
} else {
service_name = it->second.string_value().c_str();
service_name = it->second.string_value();
}
}
if (!error_list.empty()) {
return nullptr;
}
*error =
GRPC_ERROR_CREATE_FROM_VECTOR("field:healthCheckConfig", &error_list);
return service_name;
@ -281,12 +279,8 @@ ClientChannelServiceConfigParser::ParseGlobalParams(
const grpc_channel_args* /*args*/, const Json& json, grpc_error** error) {
GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE);
std::vector<grpc_error*> error_list;
RefCountedPtr<LoadBalancingPolicy::Config> parsed_lb_config;
std::string lb_policy_name;
absl::optional<ClientChannelGlobalParsedConfig::RetryThrottling>
retry_throttling;
const char* health_check_service_name = nullptr;
// Parse LB config.
RefCountedPtr<LoadBalancingPolicy::Config> parsed_lb_config;
auto it = json.object_value().find("loadBalancingConfig");
if (it != json.object_value().end()) {
grpc_error* parse_error = GRPC_ERROR_NONE;
@ -300,6 +294,7 @@ ClientChannelServiceConfigParser::ParseGlobalParams(
}
}
// Parse deprecated LB policy.
std::string lb_policy_name;
it = json.object_value().find("loadBalancingPolicy");
if (it != json.object_value().end()) {
if (it->second.type() != Json::Type::STRING) {
@ -325,6 +320,8 @@ ClientChannelServiceConfigParser::ParseGlobalParams(
}
}
// Parse retry throttling.
absl::optional<ClientChannelGlobalParsedConfig::RetryThrottling>
retry_throttling;
it = json.object_value().find("retryThrottling");
if (it != json.object_value().end()) {
ClientChannelGlobalParsedConfig::RetryThrottling data;
@ -336,6 +333,7 @@ ClientChannelServiceConfigParser::ParseGlobalParams(
}
}
// Parse health check config.
absl::optional<std::string> health_check_service_name;
it = json.object_value().find("healthCheckConfig");
if (it != json.object_value().end()) {
grpc_error* parsing_error = GRPC_ERROR_NONE;
@ -350,7 +348,7 @@ ClientChannelServiceConfigParser::ParseGlobalParams(
if (*error == GRPC_ERROR_NONE) {
return absl::make_unique<ClientChannelGlobalParsedConfig>(
std::move(parsed_lb_config), std::move(lb_policy_name),
retry_throttling, health_check_service_name);
retry_throttling, std::move(health_check_service_name));
}
return nullptr;
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save