Merge branch 'master' into grpc_namespace_channelz_service_plugin

pull/18375/head
Karthik Ravi Shankar 6 years ago
commit 2ed030b3e8
  1. 5
      BUILD
  2. 5
      BUILD.gn
  3. 12
      CMakeLists.txt
  4. 13
      Makefile
  5. 4
      bazel/grpc_deps.bzl
  6. 4
      build.yaml
  7. 2
      config.m4
  8. 2
      config.w32
  9. 5
      doc/environment_variables.md
  10. 3
      gRPC-C++.podspec
  11. 7
      gRPC-Core.podspec
  12. 6
      grpc.gemspec
  13. 8
      grpc.gyp
  14. 5
      include/grpcpp/generic/generic_stub.h
  15. 20
      include/grpcpp/impl/codegen/async_generic_service.h
  16. 118
      include/grpcpp/impl/codegen/client_callback.h
  17. 2
      include/grpcpp/impl/codegen/rpc_service_method.h
  18. 174
      include/grpcpp/impl/codegen/server_callback.h
  19. 4
      include/grpcpp/server_builder.h
  20. 4
      package.xml
  21. 2
      src/c-ares/gen_build_yaml.py
  22. 2
      src/core/README.md
  23. 6
      src/core/ext/filters/client_channel/client_channel.cc
  24. 43
      src/core/ext/filters/client_channel/lb_policy.cc
  25. 32
      src/core/ext/filters/client_channel/lb_policy.h
  26. 116
      src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc
  27. 2
      src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc
  28. 4
      src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h
  29. 8
      src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc
  30. 30
      src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
  31. 24
      src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc
  32. 1
      src/core/ext/filters/client_channel/lb_policy/subchannel_list.h
  33. 72
      src/core/ext/filters/client_channel/lb_policy/xds/xds.cc
  34. 51
      src/core/ext/filters/client_channel/resolver.cc
  35. 31
      src/core/ext/filters/client_channel/resolver.h
  36. 25
      src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
  37. 12
      src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc
  38. 83
      src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc
  39. 17
      src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h
  40. 26
      src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc
  41. 1
      src/core/ext/filters/client_channel/resolver_registry.h
  42. 115
      src/core/ext/filters/client_channel/resolver_result_parsing.cc
  43. 10
      src/core/ext/filters/client_channel/resolver_result_parsing.h
  44. 49
      src/core/ext/filters/client_channel/resolving_lb_policy.cc
  45. 14
      src/core/ext/filters/client_channel/resolving_lb_policy.h
  46. 48
      src/core/ext/filters/client_channel/server_address.cc
  47. 10
      src/core/ext/filters/client_channel/server_address.h
  48. 13
      src/core/ext/filters/client_channel/service_config.cc
  49. 16
      src/core/ext/filters/client_channel/service_config.h
  50. 2
      src/core/ext/filters/client_channel/subchannel.cc
  51. 2
      src/core/ext/filters/message_size/message_size_filter.cc
  52. 4
      src/core/ext/transport/chttp2/transport/chttp2_transport.cc
  53. 2
      src/core/lib/channel/channel_args.cc
  54. 5
      src/core/lib/security/credentials/jwt/jwt_verifier.cc
  55. 7
      src/core/lib/transport/transport.h
  56. 2
      src/csharp/Grpc.Core.Api/AuthContext.cs
  57. 7
      src/csharp/Grpc.Core/Version.csproj.include
  58. 10
      src/csharp/Grpc.Tools.Tests/ProtoCompileBasicTest.cs
  59. 81
      src/csharp/Grpc.Tools.Tests/ProtoCompileCommandLineGeneratorTest.cs
  60. 129
      src/csharp/Grpc.Tools/ProtoCompile.cs
  61. 1
      src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.targets
  62. 3
      src/csharp/doc/docfx.json
  63. 2
      src/objective-c/!ProtoCompiler-gRPCPlugin.podspec
  64. 3
      src/objective-c/!ProtoCompiler.podspec
  65. 2
      src/objective-c/BoringSSL-GRPC.podspec
  66. 11
      src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi
  67. 2
      src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi
  68. 12
      src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
  69. 2
      src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pxd.pxi
  70. 2
      src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi
  71. 3
      src/python/grpcio/grpc_core_dependencies.py
  72. 4
      src/python/grpcio_tests/commands.py
  73. 2
      templates/gRPC-Core.podspec.template
  74. 2
      templates/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec.template
  75. 2
      templates/src/objective-c/BoringSSL-GRPC.podspec.template
  76. 16
      test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc
  77. 15
      test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc
  78. 73
      test/core/client_channel/resolvers/fake_resolver_test.cc
  79. 4
      test/core/client_channel/resolvers/sockaddr_resolver_test.cc
  80. 1
      test/core/end2end/connection_refused_test.cc
  81. 1
      test/core/end2end/tests/cancel_after_accept.cc
  82. 1
      test/core/end2end/tests/cancel_after_round_trip.cc
  83. 1
      test/core/end2end/tests/max_message_length.cc
  84. 5
      test/core/util/test_lb_policies.cc
  85. 8
      test/cpp/client/client_channel_stress_test.cc
  86. 5
      test/cpp/end2end/client_callback_end2end_test.cc
  87. 21
      test/cpp/end2end/client_lb_end2end_test.cc
  88. 24
      test/cpp/end2end/grpclb_end2end_test.cc
  89. 46
      test/cpp/end2end/xds_end2end_test.cc
  90. 2
      test/cpp/naming/cancel_ares_query_test.cc
  91. 37
      test/cpp/naming/resolver_component_test.cc
  92. 2
      test/distrib/cpp/run_distrib_test_cmake.sh
  93. 2
      third_party/cares/cares
  94. 2
      third_party/cares/cares.BUILD
  95. 3
      third_party/cares/config_android/ares_config.h
  96. 3
      third_party/cares/config_darwin/ares_config.h
  97. 3
      third_party/cares/config_freebsd/ares_config.h
  98. 3
      third_party/cares/config_linux/ares_config.h
  99. 3
      third_party/cares/config_openbsd/ares_config.h
  100. 3
      third_party/cares/config_windows/ares_config.h
  101. Some files were not shown because too many files have changed in this diff Show More

@ -839,7 +839,6 @@ grpc_cc_library(
"src/core/lib/transport/metadata.cc",
"src/core/lib/transport/metadata_batch.cc",
"src/core/lib/transport/pid_controller.cc",
"src/core/lib/transport/service_config.cc",
"src/core/lib/transport/static_metadata.cc",
"src/core/lib/transport/status_conversion.cc",
"src/core/lib/transport/status_metadata.cc",
@ -974,7 +973,6 @@ grpc_cc_library(
"src/core/lib/transport/metadata.h",
"src/core/lib/transport/metadata_batch.h",
"src/core/lib/transport/pid_controller.h",
"src/core/lib/transport/service_config.h",
"src/core/lib/transport/static_metadata.h",
"src/core/lib/transport/status_conversion.h",
"src/core/lib/transport/status_metadata.h",
@ -1085,6 +1083,7 @@ grpc_cc_library(
"src/core/ext/filters/client_channel/resolving_lb_policy.cc",
"src/core/ext/filters/client_channel/retry_throttle.cc",
"src/core/ext/filters/client_channel/server_address.cc",
"src/core/ext/filters/client_channel/service_config.cc",
"src/core/ext/filters/client_channel/subchannel.cc",
"src/core/ext/filters/client_channel/subchannel_pool_interface.cc",
],
@ -1112,6 +1111,7 @@ grpc_cc_library(
"src/core/ext/filters/client_channel/resolving_lb_policy.h",
"src/core/ext/filters/client_channel/retry_throttle.h",
"src/core/ext/filters/client_channel/server_address.h",
"src/core/ext/filters/client_channel/service_config.h",
"src/core/ext/filters/client_channel/subchannel.h",
"src/core/ext/filters/client_channel/subchannel_pool_interface.h",
],
@ -1182,6 +1182,7 @@ grpc_cc_library(
language = "c++",
deps = [
"grpc_base",
"grpc_client_channel",
],
)

@ -329,6 +329,8 @@ config("grpc_config") {
"src/core/ext/filters/client_channel/retry_throttle.h",
"src/core/ext/filters/client_channel/server_address.cc",
"src/core/ext/filters/client_channel/server_address.h",
"src/core/ext/filters/client_channel/service_config.cc",
"src/core/ext/filters/client_channel/service_config.h",
"src/core/ext/filters/client_channel/subchannel.cc",
"src/core/ext/filters/client_channel/subchannel.h",
"src/core/ext/filters/client_channel/subchannel_pool_interface.cc",
@ -762,8 +764,6 @@ config("grpc_config") {
"src/core/lib/transport/metadata_batch.h",
"src/core/lib/transport/pid_controller.cc",
"src/core/lib/transport/pid_controller.h",
"src/core/lib/transport/service_config.cc",
"src/core/lib/transport/service_config.h",
"src/core/lib/transport/static_metadata.cc",
"src/core/lib/transport/static_metadata.h",
"src/core/lib/transport/status_conversion.cc",
@ -1251,7 +1251,6 @@ config("grpc_config") {
"src/core/lib/transport/metadata.h",
"src/core/lib/transport/metadata_batch.h",
"src/core/lib/transport/pid_controller.h",
"src/core/lib/transport/service_config.h",
"src/core/lib/transport/static_metadata.h",
"src/core/lib/transport/status_conversion.h",
"src/core/lib/transport/status_metadata.h",

@ -1109,7 +1109,6 @@ add_library(grpc
src/core/lib/transport/metadata.cc
src/core/lib/transport/metadata_batch.cc
src/core/lib/transport/pid_controller.cc
src/core/lib/transport/service_config.cc
src/core/lib/transport/static_metadata.cc
src/core/lib/transport/status_conversion.cc
src/core/lib/transport/status_metadata.cc
@ -1245,6 +1244,7 @@ add_library(grpc
src/core/ext/filters/client_channel/resolving_lb_policy.cc
src/core/ext/filters/client_channel/retry_throttle.cc
src/core/ext/filters/client_channel/server_address.cc
src/core/ext/filters/client_channel/service_config.cc
src/core/ext/filters/client_channel/subchannel.cc
src/core/ext/filters/client_channel/subchannel_pool_interface.cc
src/core/ext/filters/deadline/deadline_filter.cc
@ -1535,7 +1535,6 @@ add_library(grpc_cronet
src/core/lib/transport/metadata.cc
src/core/lib/transport/metadata_batch.cc
src/core/lib/transport/pid_controller.cc
src/core/lib/transport/service_config.cc
src/core/lib/transport/static_metadata.cc
src/core/lib/transport/status_conversion.cc
src/core/lib/transport/status_metadata.cc
@ -1599,6 +1598,7 @@ add_library(grpc_cronet
src/core/ext/filters/client_channel/resolving_lb_policy.cc
src/core/ext/filters/client_channel/retry_throttle.cc
src/core/ext/filters/client_channel/server_address.cc
src/core/ext/filters/client_channel/service_config.cc
src/core/ext/filters/client_channel/subchannel.cc
src/core/ext/filters/client_channel/subchannel_pool_interface.cc
src/core/ext/filters/deadline/deadline_filter.cc
@ -1946,7 +1946,6 @@ add_library(grpc_test_util
src/core/lib/transport/metadata.cc
src/core/lib/transport/metadata_batch.cc
src/core/lib/transport/pid_controller.cc
src/core/lib/transport/service_config.cc
src/core/lib/transport/static_metadata.cc
src/core/lib/transport/status_conversion.cc
src/core/lib/transport/status_metadata.cc
@ -1978,6 +1977,7 @@ add_library(grpc_test_util
src/core/ext/filters/client_channel/resolving_lb_policy.cc
src/core/ext/filters/client_channel/retry_throttle.cc
src/core/ext/filters/client_channel/server_address.cc
src/core/ext/filters/client_channel/service_config.cc
src/core/ext/filters/client_channel/subchannel.cc
src/core/ext/filters/client_channel/subchannel_pool_interface.cc
src/core/ext/filters/deadline/deadline_filter.cc
@ -2270,7 +2270,6 @@ add_library(grpc_test_util_unsecure
src/core/lib/transport/metadata.cc
src/core/lib/transport/metadata_batch.cc
src/core/lib/transport/pid_controller.cc
src/core/lib/transport/service_config.cc
src/core/lib/transport/static_metadata.cc
src/core/lib/transport/status_conversion.cc
src/core/lib/transport/status_metadata.cc
@ -2302,6 +2301,7 @@ add_library(grpc_test_util_unsecure
src/core/ext/filters/client_channel/resolving_lb_policy.cc
src/core/ext/filters/client_channel/retry_throttle.cc
src/core/ext/filters/client_channel/server_address.cc
src/core/ext/filters/client_channel/service_config.cc
src/core/ext/filters/client_channel/subchannel.cc
src/core/ext/filters/client_channel/subchannel_pool_interface.cc
src/core/ext/filters/deadline/deadline_filter.cc
@ -2570,7 +2570,6 @@ add_library(grpc_unsecure
src/core/lib/transport/metadata.cc
src/core/lib/transport/metadata_batch.cc
src/core/lib/transport/pid_controller.cc
src/core/lib/transport/service_config.cc
src/core/lib/transport/static_metadata.cc
src/core/lib/transport/status_conversion.cc
src/core/lib/transport/status_metadata.cc
@ -2637,6 +2636,7 @@ add_library(grpc_unsecure
src/core/ext/filters/client_channel/resolving_lb_policy.cc
src/core/ext/filters/client_channel/retry_throttle.cc
src/core/ext/filters/client_channel/server_address.cc
src/core/ext/filters/client_channel/service_config.cc
src/core/ext/filters/client_channel/subchannel.cc
src/core/ext/filters/client_channel/subchannel_pool_interface.cc
src/core/ext/filters/deadline/deadline_filter.cc
@ -3457,7 +3457,6 @@ add_library(grpc++_cronet
src/core/lib/transport/metadata.cc
src/core/lib/transport/metadata_batch.cc
src/core/lib/transport/pid_controller.cc
src/core/lib/transport/service_config.cc
src/core/lib/transport/static_metadata.cc
src/core/lib/transport/status_conversion.cc
src/core/lib/transport/status_metadata.cc
@ -3494,6 +3493,7 @@ add_library(grpc++_cronet
src/core/ext/filters/client_channel/resolving_lb_policy.cc
src/core/ext/filters/client_channel/retry_throttle.cc
src/core/ext/filters/client_channel/server_address.cc
src/core/ext/filters/client_channel/service_config.cc
src/core/ext/filters/client_channel/subchannel.cc
src/core/ext/filters/client_channel/subchannel_pool_interface.cc
src/core/ext/filters/deadline/deadline_filter.cc

@ -3556,7 +3556,6 @@ LIBGRPC_SRC = \
src/core/lib/transport/metadata.cc \
src/core/lib/transport/metadata_batch.cc \
src/core/lib/transport/pid_controller.cc \
src/core/lib/transport/service_config.cc \
src/core/lib/transport/static_metadata.cc \
src/core/lib/transport/status_conversion.cc \
src/core/lib/transport/status_metadata.cc \
@ -3692,6 +3691,7 @@ LIBGRPC_SRC = \
src/core/ext/filters/client_channel/resolving_lb_policy.cc \
src/core/ext/filters/client_channel/retry_throttle.cc \
src/core/ext/filters/client_channel/server_address.cc \
src/core/ext/filters/client_channel/service_config.cc \
src/core/ext/filters/client_channel/subchannel.cc \
src/core/ext/filters/client_channel/subchannel_pool_interface.cc \
src/core/ext/filters/deadline/deadline_filter.cc \
@ -3976,7 +3976,6 @@ LIBGRPC_CRONET_SRC = \
src/core/lib/transport/metadata.cc \
src/core/lib/transport/metadata_batch.cc \
src/core/lib/transport/pid_controller.cc \
src/core/lib/transport/service_config.cc \
src/core/lib/transport/static_metadata.cc \
src/core/lib/transport/status_conversion.cc \
src/core/lib/transport/status_metadata.cc \
@ -4040,6 +4039,7 @@ LIBGRPC_CRONET_SRC = \
src/core/ext/filters/client_channel/resolving_lb_policy.cc \
src/core/ext/filters/client_channel/retry_throttle.cc \
src/core/ext/filters/client_channel/server_address.cc \
src/core/ext/filters/client_channel/service_config.cc \
src/core/ext/filters/client_channel/subchannel.cc \
src/core/ext/filters/client_channel/subchannel_pool_interface.cc \
src/core/ext/filters/deadline/deadline_filter.cc \
@ -4380,7 +4380,6 @@ LIBGRPC_TEST_UTIL_SRC = \
src/core/lib/transport/metadata.cc \
src/core/lib/transport/metadata_batch.cc \
src/core/lib/transport/pid_controller.cc \
src/core/lib/transport/service_config.cc \
src/core/lib/transport/static_metadata.cc \
src/core/lib/transport/status_conversion.cc \
src/core/lib/transport/status_metadata.cc \
@ -4412,6 +4411,7 @@ LIBGRPC_TEST_UTIL_SRC = \
src/core/ext/filters/client_channel/resolving_lb_policy.cc \
src/core/ext/filters/client_channel/retry_throttle.cc \
src/core/ext/filters/client_channel/server_address.cc \
src/core/ext/filters/client_channel/service_config.cc \
src/core/ext/filters/client_channel/subchannel.cc \
src/core/ext/filters/client_channel/subchannel_pool_interface.cc \
src/core/ext/filters/deadline/deadline_filter.cc \
@ -4691,7 +4691,6 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \
src/core/lib/transport/metadata.cc \
src/core/lib/transport/metadata_batch.cc \
src/core/lib/transport/pid_controller.cc \
src/core/lib/transport/service_config.cc \
src/core/lib/transport/static_metadata.cc \
src/core/lib/transport/status_conversion.cc \
src/core/lib/transport/status_metadata.cc \
@ -4723,6 +4722,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \
src/core/ext/filters/client_channel/resolving_lb_policy.cc \
src/core/ext/filters/client_channel/retry_throttle.cc \
src/core/ext/filters/client_channel/server_address.cc \
src/core/ext/filters/client_channel/service_config.cc \
src/core/ext/filters/client_channel/subchannel.cc \
src/core/ext/filters/client_channel/subchannel_pool_interface.cc \
src/core/ext/filters/deadline/deadline_filter.cc \
@ -4965,7 +4965,6 @@ LIBGRPC_UNSECURE_SRC = \
src/core/lib/transport/metadata.cc \
src/core/lib/transport/metadata_batch.cc \
src/core/lib/transport/pid_controller.cc \
src/core/lib/transport/service_config.cc \
src/core/lib/transport/static_metadata.cc \
src/core/lib/transport/status_conversion.cc \
src/core/lib/transport/status_metadata.cc \
@ -5032,6 +5031,7 @@ LIBGRPC_UNSECURE_SRC = \
src/core/ext/filters/client_channel/resolving_lb_policy.cc \
src/core/ext/filters/client_channel/retry_throttle.cc \
src/core/ext/filters/client_channel/server_address.cc \
src/core/ext/filters/client_channel/service_config.cc \
src/core/ext/filters/client_channel/subchannel.cc \
src/core/ext/filters/client_channel/subchannel_pool_interface.cc \
src/core/ext/filters/deadline/deadline_filter.cc \
@ -5828,7 +5828,6 @@ LIBGRPC++_CRONET_SRC = \
src/core/lib/transport/metadata.cc \
src/core/lib/transport/metadata_batch.cc \
src/core/lib/transport/pid_controller.cc \
src/core/lib/transport/service_config.cc \
src/core/lib/transport/static_metadata.cc \
src/core/lib/transport/status_conversion.cc \
src/core/lib/transport/status_metadata.cc \
@ -5865,6 +5864,7 @@ LIBGRPC++_CRONET_SRC = \
src/core/ext/filters/client_channel/resolving_lb_policy.cc \
src/core/ext/filters/client_channel/retry_throttle.cc \
src/core/ext/filters/client_channel/server_address.cc \
src/core/ext/filters/client_channel/service_config.cc \
src/core/ext/filters/client_channel/subchannel.cc \
src/core/ext/filters/client_channel/subchannel_pool_interface.cc \
src/core/ext/filters/deadline/deadline_filter.cc \
@ -8228,6 +8228,7 @@ LIBARES_SRC = \
third_party/cares/cares/ares_strcasecmp.c \
third_party/cares/cares/ares_strdup.c \
third_party/cares/cares/ares_strerror.c \
third_party/cares/cares/ares_strsplit.c \
third_party/cares/cares/ares_timeout.c \
third_party/cares/cares/ares_version.c \
third_party/cares/cares/ares_writev.c \

@ -162,8 +162,8 @@ def grpc_deps():
http_archive(
name = "com_github_cares_cares",
build_file = "@com_github_grpc_grpc//third_party:cares/cares.BUILD",
strip_prefix = "c-ares-3be1924221e1326df520f8498d704a5c4c8d0cce",
url = "https://github.com/c-ares/c-ares/archive/3be1924221e1326df520f8498d704a5c4c8d0cce.tar.gz",
strip_prefix = "c-ares-e982924acee7f7313b4baa4ee5ec000c5e373c30",
url = "https://github.com/c-ares/c-ares/archive/e982924acee7f7313b4baa4ee5ec000c5e373c30.tar.gz",
)
if "com_google_absl" not in native.existing_rules():

@ -372,7 +372,6 @@ filegroups:
- src/core/lib/transport/metadata.cc
- src/core/lib/transport/metadata_batch.cc
- src/core/lib/transport/pid_controller.cc
- src/core/lib/transport/service_config.cc
- src/core/lib/transport/static_metadata.cc
- src/core/lib/transport/status_conversion.cc
- src/core/lib/transport/status_metadata.cc
@ -530,7 +529,6 @@ filegroups:
- src/core/lib/transport/metadata.h
- src/core/lib/transport/metadata_batch.h
- src/core/lib/transport/pid_controller.h
- src/core/lib/transport/service_config.h
- src/core/lib/transport/static_metadata.h
- src/core/lib/transport/status_conversion.h
- src/core/lib/transport/status_metadata.h
@ -590,6 +588,7 @@ filegroups:
- src/core/ext/filters/client_channel/resolving_lb_policy.h
- src/core/ext/filters/client_channel/retry_throttle.h
- src/core/ext/filters/client_channel/server_address.h
- src/core/ext/filters/client_channel/service_config.h
- src/core/ext/filters/client_channel/subchannel.h
- src/core/ext/filters/client_channel/subchannel_pool_interface.h
src:
@ -616,6 +615,7 @@ filegroups:
- src/core/ext/filters/client_channel/resolving_lb_policy.cc
- src/core/ext/filters/client_channel/retry_throttle.cc
- src/core/ext/filters/client_channel/server_address.cc
- src/core/ext/filters/client_channel/service_config.cc
- src/core/ext/filters/client_channel/subchannel.cc
- src/core/ext/filters/client_channel/subchannel_pool_interface.cc
plugin: grpc_client_channel

@ -226,7 +226,6 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/transport/metadata.cc \
src/core/lib/transport/metadata_batch.cc \
src/core/lib/transport/pid_controller.cc \
src/core/lib/transport/service_config.cc \
src/core/lib/transport/static_metadata.cc \
src/core/lib/transport/status_conversion.cc \
src/core/lib/transport/status_metadata.cc \
@ -362,6 +361,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/filters/client_channel/resolving_lb_policy.cc \
src/core/ext/filters/client_channel/retry_throttle.cc \
src/core/ext/filters/client_channel/server_address.cc \
src/core/ext/filters/client_channel/service_config.cc \
src/core/ext/filters/client_channel/subchannel.cc \
src/core/ext/filters/client_channel/subchannel_pool_interface.cc \
src/core/ext/filters/deadline/deadline_filter.cc \

@ -201,7 +201,6 @@ if (PHP_GRPC != "no") {
"src\\core\\lib\\transport\\metadata.cc " +
"src\\core\\lib\\transport\\metadata_batch.cc " +
"src\\core\\lib\\transport\\pid_controller.cc " +
"src\\core\\lib\\transport\\service_config.cc " +
"src\\core\\lib\\transport\\static_metadata.cc " +
"src\\core\\lib\\transport\\status_conversion.cc " +
"src\\core\\lib\\transport\\status_metadata.cc " +
@ -337,6 +336,7 @@ if (PHP_GRPC != "no") {
"src\\core\\ext\\filters\\client_channel\\resolving_lb_policy.cc " +
"src\\core\\ext\\filters\\client_channel\\retry_throttle.cc " +
"src\\core\\ext\\filters\\client_channel\\server_address.cc " +
"src\\core\\ext\\filters\\client_channel\\service_config.cc " +
"src\\core\\ext\\filters\\client_channel\\subchannel.cc " +
"src\\core\\ext\\filters\\client_channel\\subchannel_pool_interface.cc " +
"src\\core\\ext\\filters\\deadline\\deadline_filter.cc " +

@ -124,9 +124,10 @@ some configuration as environment variables that can be set.
Declares which DNS resolver to use. The default is ares if gRPC is built with
c-ares support. Otherwise, the value of this environment variable is ignored.
Available DNS resolver include:
- native (default)- a DNS resolver based around getaddrinfo(), creates a new thread to
- ares (default on most platforms except iOS, Android or Node)- a DNS
resolver based around the c-ares library
- native - a DNS resolver based around getaddrinfo(), creates a new thread to
perform name resolution
- ares - a DNS resolver based around the c-ares library
* GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS
Default: 5000

@ -367,6 +367,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/resolving_lb_policy.h',
'src/core/ext/filters/client_channel/retry_throttle.h',
'src/core/ext/filters/client_channel/server_address.h',
'src/core/ext/filters/client_channel/service_config.h',
'src/core/ext/filters/client_channel/subchannel.h',
'src/core/ext/filters/client_channel/subchannel_pool_interface.h',
'src/core/ext/filters/deadline/deadline_filter.h',
@ -509,7 +510,6 @@ Pod::Spec.new do |s|
'src/core/lib/transport/metadata.h',
'src/core/lib/transport/metadata_batch.h',
'src/core/lib/transport/pid_controller.h',
'src/core/lib/transport/service_config.h',
'src/core/lib/transport/static_metadata.h',
'src/core/lib/transport/status_conversion.h',
'src/core/lib/transport/status_metadata.h',
@ -700,7 +700,6 @@ Pod::Spec.new do |s|
'src/core/lib/transport/metadata.h',
'src/core/lib/transport/metadata_batch.h',
'src/core/lib/transport/pid_controller.h',
'src/core/lib/transport/service_config.h',
'src/core/lib/transport/static_metadata.h',
'src/core/lib/transport/status_conversion.h',
'src/core/lib/transport/status_metadata.h',

@ -361,6 +361,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/resolving_lb_policy.h',
'src/core/ext/filters/client_channel/retry_throttle.h',
'src/core/ext/filters/client_channel/server_address.h',
'src/core/ext/filters/client_channel/service_config.h',
'src/core/ext/filters/client_channel/subchannel.h',
'src/core/ext/filters/client_channel/subchannel_pool_interface.h',
'src/core/ext/filters/deadline/deadline_filter.h',
@ -503,7 +504,6 @@ Pod::Spec.new do |s|
'src/core/lib/transport/metadata.h',
'src/core/lib/transport/metadata_batch.h',
'src/core/lib/transport/pid_controller.h',
'src/core/lib/transport/service_config.h',
'src/core/lib/transport/static_metadata.h',
'src/core/lib/transport/status_conversion.h',
'src/core/lib/transport/status_metadata.h',
@ -674,7 +674,6 @@ Pod::Spec.new do |s|
'src/core/lib/transport/metadata.cc',
'src/core/lib/transport/metadata_batch.cc',
'src/core/lib/transport/pid_controller.cc',
'src/core/lib/transport/service_config.cc',
'src/core/lib/transport/static_metadata.cc',
'src/core/lib/transport/status_conversion.cc',
'src/core/lib/transport/status_metadata.cc',
@ -807,6 +806,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/resolving_lb_policy.cc',
'src/core/ext/filters/client_channel/retry_throttle.cc',
'src/core/ext/filters/client_channel/server_address.cc',
'src/core/ext/filters/client_channel/service_config.cc',
'src/core/ext/filters/client_channel/subchannel.cc',
'src/core/ext/filters/client_channel/subchannel_pool_interface.cc',
'src/core/ext/filters/deadline/deadline_filter.cc',
@ -991,6 +991,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/resolving_lb_policy.h',
'src/core/ext/filters/client_channel/retry_throttle.h',
'src/core/ext/filters/client_channel/server_address.h',
'src/core/ext/filters/client_channel/service_config.h',
'src/core/ext/filters/client_channel/subchannel.h',
'src/core/ext/filters/client_channel/subchannel_pool_interface.h',
'src/core/ext/filters/deadline/deadline_filter.h',
@ -1133,7 +1134,6 @@ Pod::Spec.new do |s|
'src/core/lib/transport/metadata.h',
'src/core/lib/transport/metadata_batch.h',
'src/core/lib/transport/pid_controller.h',
'src/core/lib/transport/service_config.h',
'src/core/lib/transport/static_metadata.h',
'src/core/lib/transport/status_conversion.h',
'src/core/lib/transport/status_metadata.h',
@ -1235,7 +1235,6 @@ Pod::Spec.new do |s|
'test/core/util/port_isolated_runtime_environment.cc',
'test/core/util/port_server_client.cc',
'test/core/util/slice_splitter.cc',
'test/core/util/subprocess_posix.cc',
'test/core/util/subprocess_windows.cc',
'test/core/util/test_config.cc',
'test/core/util/test_lb_policies.cc',

@ -295,6 +295,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/filters/client_channel/resolving_lb_policy.h )
s.files += %w( src/core/ext/filters/client_channel/retry_throttle.h )
s.files += %w( src/core/ext/filters/client_channel/server_address.h )
s.files += %w( src/core/ext/filters/client_channel/service_config.h )
s.files += %w( src/core/ext/filters/client_channel/subchannel.h )
s.files += %w( src/core/ext/filters/client_channel/subchannel_pool_interface.h )
s.files += %w( src/core/ext/filters/deadline/deadline_filter.h )
@ -437,7 +438,6 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/transport/metadata.h )
s.files += %w( src/core/lib/transport/metadata_batch.h )
s.files += %w( src/core/lib/transport/pid_controller.h )
s.files += %w( src/core/lib/transport/service_config.h )
s.files += %w( src/core/lib/transport/static_metadata.h )
s.files += %w( src/core/lib/transport/status_conversion.h )
s.files += %w( src/core/lib/transport/status_metadata.h )
@ -608,7 +608,6 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/transport/metadata.cc )
s.files += %w( src/core/lib/transport/metadata_batch.cc )
s.files += %w( src/core/lib/transport/pid_controller.cc )
s.files += %w( src/core/lib/transport/service_config.cc )
s.files += %w( src/core/lib/transport/static_metadata.cc )
s.files += %w( src/core/lib/transport/status_conversion.cc )
s.files += %w( src/core/lib/transport/status_metadata.cc )
@ -744,6 +743,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/filters/client_channel/resolving_lb_policy.cc )
s.files += %w( src/core/ext/filters/client_channel/retry_throttle.cc )
s.files += %w( src/core/ext/filters/client_channel/server_address.cc )
s.files += %w( src/core/ext/filters/client_channel/service_config.cc )
s.files += %w( src/core/ext/filters/client_channel/subchannel.cc )
s.files += %w( src/core/ext/filters/client_channel/subchannel_pool_interface.cc )
s.files += %w( src/core/ext/filters/deadline/deadline_filter.cc )
@ -1266,6 +1266,7 @@ Gem::Specification.new do |s|
s.files += %w( third_party/cares/cares/ares_setup.h )
s.files += %w( third_party/cares/cares/ares_strcasecmp.h )
s.files += %w( third_party/cares/cares/ares_strdup.h )
s.files += %w( third_party/cares/cares/ares_strsplit.h )
s.files += %w( third_party/cares/cares/ares_version.h )
s.files += %w( third_party/cares/cares/bitncmp.h )
s.files += %w( third_party/cares/cares/config-win32.h )
@ -1317,6 +1318,7 @@ Gem::Specification.new do |s|
s.files += %w( third_party/cares/cares/ares_strcasecmp.c )
s.files += %w( third_party/cares/cares/ares_strdup.c )
s.files += %w( third_party/cares/cares/ares_strerror.c )
s.files += %w( third_party/cares/cares/ares_strsplit.c )
s.files += %w( third_party/cares/cares/ares_timeout.c )
s.files += %w( third_party/cares/cares/ares_version.c )
s.files += %w( third_party/cares/cares/ares_writev.c )

@ -408,7 +408,6 @@
'src/core/lib/transport/metadata.cc',
'src/core/lib/transport/metadata_batch.cc',
'src/core/lib/transport/pid_controller.cc',
'src/core/lib/transport/service_config.cc',
'src/core/lib/transport/static_metadata.cc',
'src/core/lib/transport/status_conversion.cc',
'src/core/lib/transport/status_metadata.cc',
@ -544,6 +543,7 @@
'src/core/ext/filters/client_channel/resolving_lb_policy.cc',
'src/core/ext/filters/client_channel/retry_throttle.cc',
'src/core/ext/filters/client_channel/server_address.cc',
'src/core/ext/filters/client_channel/service_config.cc',
'src/core/ext/filters/client_channel/subchannel.cc',
'src/core/ext/filters/client_channel/subchannel_pool_interface.cc',
'src/core/ext/filters/deadline/deadline_filter.cc',
@ -775,7 +775,6 @@
'src/core/lib/transport/metadata.cc',
'src/core/lib/transport/metadata_batch.cc',
'src/core/lib/transport/pid_controller.cc',
'src/core/lib/transport/service_config.cc',
'src/core/lib/transport/static_metadata.cc',
'src/core/lib/transport/status_conversion.cc',
'src/core/lib/transport/status_metadata.cc',
@ -807,6 +806,7 @@
'src/core/ext/filters/client_channel/resolving_lb_policy.cc',
'src/core/ext/filters/client_channel/retry_throttle.cc',
'src/core/ext/filters/client_channel/server_address.cc',
'src/core/ext/filters/client_channel/service_config.cc',
'src/core/ext/filters/client_channel/subchannel.cc',
'src/core/ext/filters/client_channel/subchannel_pool_interface.cc',
'src/core/ext/filters/deadline/deadline_filter.cc',
@ -1019,7 +1019,6 @@
'src/core/lib/transport/metadata.cc',
'src/core/lib/transport/metadata_batch.cc',
'src/core/lib/transport/pid_controller.cc',
'src/core/lib/transport/service_config.cc',
'src/core/lib/transport/static_metadata.cc',
'src/core/lib/transport/status_conversion.cc',
'src/core/lib/transport/status_metadata.cc',
@ -1051,6 +1050,7 @@
'src/core/ext/filters/client_channel/resolving_lb_policy.cc',
'src/core/ext/filters/client_channel/retry_throttle.cc',
'src/core/ext/filters/client_channel/server_address.cc',
'src/core/ext/filters/client_channel/service_config.cc',
'src/core/ext/filters/client_channel/subchannel.cc',
'src/core/ext/filters/client_channel/subchannel_pool_interface.cc',
'src/core/ext/filters/deadline/deadline_filter.cc',
@ -1239,7 +1239,6 @@
'src/core/lib/transport/metadata.cc',
'src/core/lib/transport/metadata_batch.cc',
'src/core/lib/transport/pid_controller.cc',
'src/core/lib/transport/service_config.cc',
'src/core/lib/transport/static_metadata.cc',
'src/core/lib/transport/status_conversion.cc',
'src/core/lib/transport/status_metadata.cc',
@ -1306,6 +1305,7 @@
'src/core/ext/filters/client_channel/resolving_lb_policy.cc',
'src/core/ext/filters/client_channel/retry_throttle.cc',
'src/core/ext/filters/client_channel/server_address.cc',
'src/core/ext/filters/client_channel/service_config.cc',
'src/core/ext/filters/client_channel/subchannel.cc',
'src/core/ext/filters/client_channel/subchannel_pool_interface.cc',
'src/core/ext/filters/deadline/deadline_filter.cc',

@ -73,10 +73,15 @@ class GenericStub final {
public:
explicit experimental_type(GenericStub* stub) : stub_(stub) {}
/// Setup and start a unary call to a named method \a method using
/// \a context and specifying the \a request and \a response buffers.
void UnaryCall(ClientContext* context, const grpc::string& method,
const ByteBuffer* request, ByteBuffer* response,
std::function<void(Status)> on_completion);
/// Setup a call to a named method \a method using \a context and tied to
/// \a reactor . Like any other bidi streaming RPC, it will not be activated
/// until StartCall is invoked on its reactor.
void PrepareBidiStreamingCall(
ClientContext* context, const grpc::string& method,
experimental::ClientBidiReactor<ByteBuffer, ByteBuffer>* reactor);

@ -85,13 +85,23 @@ class AsyncGenericService final {
namespace experimental {
/// \a ServerGenericBidiReactor is the reactor class for bidi streaming RPCs
/// invoked on a CallbackGenericService. The API difference relative to
/// ServerBidiReactor is that the argument to OnStarted is a
/// GenericServerContext rather than a ServerContext. All other reaction and
/// operation initiation APIs are the same as ServerBidiReactor.
class ServerGenericBidiReactor
: public ServerBidiReactor<ByteBuffer, ByteBuffer> {
public:
/// Similar to ServerBidiReactor::OnStarted except for argument type.
///
/// \param[in] context The context object associated with this RPC.
virtual void OnStarted(GenericServerContext* context) {}
private:
void OnStarted(ServerContext* ctx) final {
OnStarted(static_cast<GenericServerContext*>(ctx));
}
virtual void OnStarted(GenericServerContext* ctx) {}
};
} // namespace experimental
@ -108,10 +118,18 @@ class UnimplementedGenericBidiReactor
} // namespace internal
namespace experimental {
/// \a CallbackGenericService is the base class for generic services implemented
/// using the callback API and registered through the ServerBuilder using
/// RegisterCallbackGenericService.
class CallbackGenericService {
public:
CallbackGenericService() {}
virtual ~CallbackGenericService() {}
/// The "method handler" for the generic API. This function should be
/// overridden to return a ServerGenericBidiReactor that implements the
/// application-level interface for this RPC.
virtual ServerGenericBidiReactor* CreateReactor() {
return new internal::UnimplementedGenericBidiReactor;
}

@ -157,28 +157,69 @@ class ClientCallbackWriter {
}
};
// The user must implement this reactor interface with reactions to each event
// type that gets called by the library. An empty reaction is provided by
// default
// The following classes are the reactor interfaces that are to be implemented
// by the user. They are passed in to the library as an argument to a call on a
// stub (either a codegen-ed call or a generic call). The streaming RPC is
// activated by calling StartCall, possibly after initiating StartRead,
// StartWrite, or AddHold operations on the streaming object. Note that none of
// the classes are pure; all reactions have a default empty reaction so that the
// user class only needs to override those classes that it cares about.
/// \a ClientBidiReactor is the interface for a bidirectional streaming RPC.
template <class Request, class Response>
class ClientBidiReactor {
public:
virtual ~ClientBidiReactor() {}
virtual void OnDone(const Status& s) {}
virtual void OnReadInitialMetadataDone(bool ok) {}
virtual void OnReadDone(bool ok) {}
virtual void OnWriteDone(bool ok) {}
virtual void OnWritesDoneDone(bool ok) {}
/// Activate the RPC and initiate any reads or writes that have been Start'ed
/// before this call. All streaming RPCs issued by the client MUST have
/// StartCall invoked on them (even if they are canceled) as this call is the
/// activation of their lifecycle.
void StartCall() { stream_->StartCall(); }
/// Initiate a read operation (or post it for later initiation if StartCall
/// has not yet been invoked).
///
/// \param[out] resp Where to eventually store the read message. Valid when
/// the library calls OnReadDone
void StartRead(Response* resp) { stream_->Read(resp); }
/// Initiate a write operation (or post it for later initiation if StartCall
/// has not yet been invoked).
///
/// \param[in] req The message to be written. The library takes temporary
/// ownership until OnWriteDone, at which point the application
/// regains ownership of msg.
void StartWrite(const Request* req) { StartWrite(req, WriteOptions()); }
/// Initiate/post a write operation with specified options.
///
/// \param[in] req The message to be written. The library takes temporary
/// ownership until OnWriteDone, at which point the application
/// regains ownership of msg.
/// \param[in] options The WriteOptions to use for writing this message
void StartWrite(const Request* req, WriteOptions options) {
stream_->Write(req, std::move(options));
}
/// Initiate/post a write operation with specified options and an indication
/// that this is the last write (like StartWrite and StartWritesDone, merged).
/// Note that calling this means that no more calls to StartWrite,
/// StartWriteLast, or StartWritesDone are allowed.
///
/// \param[in] req The message to be written. The library takes temporary
/// ownership until OnWriteDone, at which point the application
/// regains ownership of msg.
/// \param[in] options The WriteOptions to use for writing this message
void StartWriteLast(const Request* req, WriteOptions options) {
StartWrite(req, std::move(options.set_last_message()));
}
/// Indicate that the RPC will have no more write operations. This can only be
/// issued once for a given RPC. This is not required or allowed if
/// StartWriteLast is used since that already has the same implication.
/// Note that calling this means that no more calls to StartWrite,
/// StartWriteLast, or StartWritesDone are allowed.
void StartWritesDone() { stream_->WritesDone(); }
/// Holds are needed if (and only if) this stream has operations that take
@ -196,14 +237,51 @@ class ClientBidiReactor {
/// AddHold or AddMultipleHolds before StartCall. If there is going to be,
/// for example, a read-flow and a write-flow taking place outside the
/// reactions, then call AddMultipleHolds(2) before StartCall. When the
/// application knows that it won't issue any more Read operations (such as
/// application knows that it won't issue any more read operations (such as
/// when a read comes back as not ok), it should issue a RemoveHold(). It
/// should also call RemoveHold() again after it does StartWriteLast or
/// StartWritesDone that indicates that there will be no more Write ops.
/// StartWritesDone that indicates that there will be no more write ops.
/// The number of RemoveHold calls must match the total number of AddHold
/// calls plus the number of holds added by AddMultipleHolds.
void AddHold() { AddMultipleHolds(1); }
void AddMultipleHolds(int holds) { stream_->AddHold(holds); }
void RemoveHold() { stream_->RemoveHold(); }
/// Notifies the application that all operations associated with this RPC
/// have completed and provides the RPC status outcome.
///
/// \param[in] s The status outcome of this RPC
virtual void OnDone(const Status& s) {}
/// Notifies the application that a read of initial metadata from the
/// server is done. If the application chooses not to implement this method,
/// it can assume that the initial metadata has been read before the first
/// call of OnReadDone or OnDone.
///
/// \param[in] ok Was the initial metadata read successfully? If false, no
/// further read-side operation will succeed.
virtual void OnReadInitialMetadataDone(bool ok) {}
/// Notifies the application that a StartRead operation completed.
///
/// \param[in] ok Was it successful? If false, no further read-side operation
/// will succeed.
virtual void OnReadDone(bool ok) {}
/// Notifies the application that a StartWrite operation completed.
///
/// \param[in] ok Was it successful? If false, no further write-side operation
/// will succeed.
virtual void OnWriteDone(bool ok) {}
/// Notifies the application that a StartWritesDone operation completed. Note
/// that this is only used on explicit StartWritesDone operations and not for
/// those that are implicitly invoked as part of a StartWriteLast.
///
/// \param[in] ok Was it successful? If false, the application will later see
/// the failure reflected as a bad status in OnDone.
virtual void OnWritesDoneDone(bool ok) {}
private:
friend class ClientCallbackReaderWriter<Request, Response>;
void BindStream(ClientCallbackReaderWriter<Request, Response>* stream) {
@ -212,13 +290,12 @@ class ClientBidiReactor {
ClientCallbackReaderWriter<Request, Response>* stream_;
};
/// \a ClientReadReactor is the interface for a server-streaming RPC.
/// All public methods behave as in ClientBidiReactor.
template <class Response>
class ClientReadReactor {
public:
virtual ~ClientReadReactor() {}
virtual void OnDone(const Status& s) {}
virtual void OnReadInitialMetadataDone(bool ok) {}
virtual void OnReadDone(bool ok) {}
void StartCall() { reader_->StartCall(); }
void StartRead(Response* resp) { reader_->Read(resp); }
@ -227,20 +304,22 @@ class ClientReadReactor {
void AddMultipleHolds(int holds) { reader_->AddHold(holds); }
void RemoveHold() { reader_->RemoveHold(); }
virtual void OnDone(const Status& s) {}
virtual void OnReadInitialMetadataDone(bool ok) {}
virtual void OnReadDone(bool ok) {}
private:
friend class ClientCallbackReader<Response>;
void BindReader(ClientCallbackReader<Response>* reader) { reader_ = reader; }
ClientCallbackReader<Response>* reader_;
};
/// \a ClientWriteReactor is the interface for a client-streaming RPC.
/// All public methods behave as in ClientBidiReactor.
template <class Request>
class ClientWriteReactor {
public:
virtual ~ClientWriteReactor() {}
virtual void OnDone(const Status& s) {}
virtual void OnReadInitialMetadataDone(bool ok) {}
virtual void OnWriteDone(bool ok) {}
virtual void OnWritesDoneDone(bool ok) {}
void StartCall() { writer_->StartCall(); }
void StartWrite(const Request* req) { StartWrite(req, WriteOptions()); }
@ -256,6 +335,11 @@ class ClientWriteReactor {
void AddMultipleHolds(int holds) { writer_->AddHold(holds); }
void RemoveHold() { writer_->RemoveHold(); }
virtual void OnDone(const Status& s) {}
virtual void OnReadInitialMetadataDone(bool ok) {}
virtual void OnWriteDone(bool ok) {}
virtual void OnWritesDoneDone(bool ok) {}
private:
friend class ClientCallbackWriter<Request>;
void BindWriter(ClientCallbackWriter<Request>* writer) { writer_ = writer; }

@ -46,7 +46,7 @@ class MethodHandler {
/// \param context : the ServerContext structure for this server call
/// \param req : the request payload, if appropriate for this RPC
/// \param req_status : the request status after any interceptors have run
/// \param rpc_requester : used only by the callback API. It is a function
/// \param requester : used only by the callback API. It is a function
/// called by the RPC Controller to request another RPC (and also
/// to set up the state required to make that request possible)
HandlerParameter(Call* c, ServerContext* context, void* req,

@ -40,8 +40,8 @@ namespace internal {
class ServerReactor {
public:
virtual ~ServerReactor() = default;
virtual void OnDone() {}
virtual void OnCancel() {}
virtual void OnDone() = 0;
virtual void OnCancel() = 0;
};
} // namespace internal
@ -167,33 +167,120 @@ class ServerCallbackReaderWriter {
}
};
// The following classes are reactors that are to be implemented
// by the user, returned as the result of the method handler for
// a callback method, and activated by the call to OnStarted
// The following classes are the reactor interfaces that are to be implemented
// by the user, returned as the result of the method handler for a callback
// method, and activated by the call to OnStarted. Note that none of the classes
// are pure; all reactions have a default empty reaction so that the user class
// only needs to override those classes that it cares about.
/// \a ServerBidiReactor is the interface for a bidirectional streaming RPC.
template <class Request, class Response>
class ServerBidiReactor : public internal::ServerReactor {
public:
~ServerBidiReactor() = default;
virtual void OnStarted(ServerContext*) {}
virtual void OnSendInitialMetadataDone(bool ok) {}
virtual void OnReadDone(bool ok) {}
virtual void OnWriteDone(bool ok) {}
/// Send any initial metadata stored in the RPC context. If not invoked,
/// any initial metadata will be passed along with the first Write or the
/// Finish (if there are no writes).
void StartSendInitialMetadata() { stream_->SendInitialMetadata(); }
void StartRead(Request* msg) { stream_->Read(msg); }
void StartWrite(const Response* msg) { StartWrite(msg, WriteOptions()); }
void StartWrite(const Response* msg, WriteOptions options) {
stream_->Write(msg, std::move(options));
/// Initiate a read operation.
///
/// \param[out] req Where to eventually store the read message. Valid when
/// the library calls OnReadDone
void StartRead(Request* req) { stream_->Read(req); }
/// Initiate a write operation.
///
/// \param[in] resp The message to be written. The library takes temporary
/// ownership until OnWriteDone, at which point the
/// application regains ownership of resp.
void StartWrite(const Response* resp) { StartWrite(resp, WriteOptions()); }
/// Initiate a write operation with specified options.
///
/// \param[in] resp The message to be written. The library takes temporary
/// ownership until OnWriteDone, at which point the
/// application regains ownership of resp.
/// \param[in] options The WriteOptions to use for writing this message
void StartWrite(const Response* resp, WriteOptions options) {
stream_->Write(resp, std::move(options));
}
void StartWriteAndFinish(const Response* msg, WriteOptions options,
/// Initiate a write operation with specified options and final RPC Status,
/// which also causes any trailing metadata for this RPC to be sent out.
/// StartWriteAndFinish is like merging StartWriteLast and Finish into a
/// single step. A key difference, though, is that this operation doesn't have
/// an OnWriteDone reaction - it is considered complete only when OnDone is
/// available. An RPC can either have StartWriteAndFinish or Finish, but not
/// both.
///
/// \param[in] resp The message to be written. The library takes temporary
/// ownership until Onone, at which point the application
/// regains ownership of resp.
/// \param[in] options The WriteOptions to use for writing this message
/// \param[in] s The status outcome of this RPC
void StartWriteAndFinish(const Response* resp, WriteOptions options,
Status s) {
stream_->WriteAndFinish(msg, std::move(options), std::move(s));
stream_->WriteAndFinish(resp, std::move(options), std::move(s));
}
void StartWriteLast(const Response* msg, WriteOptions options) {
StartWrite(msg, std::move(options.set_last_message()));
/// Inform system of a planned write operation with specified options, but
/// allow the library to schedule the actual write coalesced with the writing
/// of trailing metadata (which takes place on a Finish call).
///
/// \param[in] resp The message to be written. The library takes temporary
/// ownership until OnWriteDone, at which point the
/// application regains ownership of resp.
/// \param[in] options The WriteOptions to use for writing this message
void StartWriteLast(const Response* resp, WriteOptions options) {
StartWrite(resp, std::move(options.set_last_message()));
}
/// Indicate that the stream is to be finished and the trailing metadata and
/// RPC status are to be sent. Every RPC MUST be finished using either Finish
/// or StartWriteAndFinish (but not both), even if the RPC is already
/// cancelled.
///
/// \param[in] s The status outcome of this RPC
void Finish(Status s) { stream_->Finish(std::move(s)); }
/// Notify the application that a streaming RPC has started
///
/// \param[in] context The context object now associated with this RPC
virtual void OnStarted(ServerContext* context) {}
/// Notifies the application that an explicit StartSendInitialMetadata
/// operation completed. Not used when the sending of initial metadata
/// piggybacks onto the first write.
///
/// \param[in] ok Was it successful? If false, no further write-side operation
/// will succeed.
virtual void OnSendInitialMetadataDone(bool ok) {}
/// Notifies the application that a StartRead operation completed.
///
/// \param[in] ok Was it successful? If false, no further read-side operation
/// will succeed.
virtual void OnReadDone(bool ok) {}
/// Notifies the application that a StartWrite (or StartWriteLast) operation
/// completed.
///
/// \param[in] ok Was it successful? If false, no further write-side operation
/// will succeed.
virtual void OnWriteDone(bool ok) {}
/// Notifies the application that all operations associated with this RPC
/// have completed. This is an override (from the internal base class) but not
/// final, so derived classes should override it if they want to take action.
void OnDone() override {}
/// Notifies the application that this RPC has been cancelled. This is an
/// override (from the internal base class) but not final, so derived classes
/// should override it if they want to take action.
void OnCancel() override {}
private:
friend class ServerCallbackReaderWriter<Request, Response>;
void BindStream(ServerCallbackReaderWriter<Request, Response>* stream) {
@ -203,18 +290,31 @@ class ServerBidiReactor : public internal::ServerReactor {
ServerCallbackReaderWriter<Request, Response>* stream_;
};
/// \a ServerReadReactor is the interface for a client-streaming RPC.
template <class Request, class Response>
class ServerReadReactor : public internal::ServerReactor {
public:
~ServerReadReactor() = default;
virtual void OnStarted(ServerContext*, Response* resp) {}
virtual void OnSendInitialMetadataDone(bool ok) {}
virtual void OnReadDone(bool ok) {}
/// The following operation initiations are exactly like ServerBidiReactor.
void StartSendInitialMetadata() { reader_->SendInitialMetadata(); }
void StartRead(Request* msg) { reader_->Read(msg); }
void StartRead(Request* req) { reader_->Read(req); }
void Finish(Status s) { reader_->Finish(std::move(s)); }
/// Similar to ServerBidiReactor::OnStarted, except that this also provides
/// the response object that the stream fills in before calling Finish.
/// (It must be filled in if status is OK, but it may be filled in otherwise.)
///
/// \param[in] context The context object now associated with this RPC
/// \param[in] resp The response object to be used by this RPC
virtual void OnStarted(ServerContext* context, Response* resp) {}
/// The following notifications are exactly like ServerBidiReactor.
virtual void OnSendInitialMetadataDone(bool ok) {}
virtual void OnReadDone(bool ok) {}
void OnDone() override {}
void OnCancel() override {}
private:
friend class ServerCallbackReader<Request>;
void BindReader(ServerCallbackReader<Request>* reader) { reader_ = reader; }
@ -222,28 +322,40 @@ class ServerReadReactor : public internal::ServerReactor {
ServerCallbackReader<Request>* reader_;
};
/// \a ServerReadReactor is the interface for a server-streaming RPC.
template <class Request, class Response>
class ServerWriteReactor : public internal::ServerReactor {
public:
~ServerWriteReactor() = default;
virtual void OnStarted(ServerContext*, const Request* req) {}
virtual void OnSendInitialMetadataDone(bool ok) {}
virtual void OnWriteDone(bool ok) {}
/// The following operation initiations are exactly like ServerBidiReactor.
void StartSendInitialMetadata() { writer_->SendInitialMetadata(); }
void StartWrite(const Response* msg) { StartWrite(msg, WriteOptions()); }
void StartWrite(const Response* msg, WriteOptions options) {
writer_->Write(msg, std::move(options));
void StartWrite(const Response* resp) { StartWrite(resp, WriteOptions()); }
void StartWrite(const Response* resp, WriteOptions options) {
writer_->Write(resp, std::move(options));
}
void StartWriteAndFinish(const Response* msg, WriteOptions options,
void StartWriteAndFinish(const Response* resp, WriteOptions options,
Status s) {
writer_->WriteAndFinish(msg, std::move(options), std::move(s));
writer_->WriteAndFinish(resp, std::move(options), std::move(s));
}
void StartWriteLast(const Response* msg, WriteOptions options) {
StartWrite(msg, std::move(options.set_last_message()));
void StartWriteLast(const Response* resp, WriteOptions options) {
StartWrite(resp, std::move(options.set_last_message()));
}
void Finish(Status s) { writer_->Finish(std::move(s)); }
/// Similar to ServerBidiReactor::OnStarted, except that this also provides
/// the request object sent by the client.
///
/// \param[in] context The context object now associated with this RPC
/// \param[in] req The request object sent by the client
virtual void OnStarted(ServerContext* context, const Request* req) {}
/// The following notifications are exactly like ServerBidiReactor.
virtual void OnSendInitialMetadataDone(bool ok) {}
virtual void OnWriteDone(bool ok) {}
void OnDone() override {}
void OnCancel() override {}
private:
friend class ServerCallbackWriter<Response>;
void BindWriter(ServerCallbackWriter<Response>* writer) { writer_ = writer; }

@ -231,6 +231,10 @@ class ServerBuilder {
builder_->interceptor_creators_ = std::move(interceptor_creators);
}
/// Register a generic service that uses the callback API.
/// Matches requests with any :authority
/// This is mostly useful for writing generic gRPC Proxies where the exact
/// serialization format is unknown
ServerBuilder& RegisterCallbackGenericService(
experimental::CallbackGenericService* service);

@ -300,6 +300,7 @@
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolving_lb_policy.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/retry_throttle.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/server_address.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/service_config.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/subchannel.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/subchannel_pool_interface.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/deadline/deadline_filter.h" role="src" />
@ -442,7 +443,6 @@
<file baseinstalldir="/" name="src/core/lib/transport/metadata.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/metadata_batch.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/pid_controller.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/service_config.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/static_metadata.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/status_conversion.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/status_metadata.h" role="src" />
@ -613,7 +613,6 @@
<file baseinstalldir="/" name="src/core/lib/transport/metadata.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/metadata_batch.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/pid_controller.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/service_config.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/static_metadata.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/status_conversion.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/status_metadata.cc" role="src" />
@ -749,6 +748,7 @@
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolving_lb_policy.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/retry_throttle.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/server_address.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/service_config.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/subchannel.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/subchannel_pool_interface.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/deadline/deadline_filter.cc" role="src" />

@ -97,6 +97,7 @@ try:
"third_party/cares/cares/ares_strcasecmp.c",
"third_party/cares/cares/ares_strdup.c",
"third_party/cares/cares/ares_strerror.c",
"third_party/cares/cares/ares_strsplit.c",
"third_party/cares/cares/ares_timeout.c",
"third_party/cares/cares/ares_version.c",
"third_party/cares/cares/ares_writev.c",
@ -123,6 +124,7 @@ try:
"third_party/cares/cares/ares_setup.h",
"third_party/cares/cares/ares_strcasecmp.h",
"third_party/cares/cares/ares_strdup.h",
"third_party/cares/cares/ares_strsplit.h",
"third_party/cares/cares/ares_version.h",
"third_party/cares/cares/bitncmp.h",
"third_party/cares/cares/config-win32.h",

@ -1,4 +1,4 @@
# Overview
This directory contains source code for C library (a.k.a the *gRPC C core*) that provides all gRPC's core functionality through a low level API. Libraries in other languages in this repository (C++, Ruby,
This directory contains source code for C library (a.k.a the *gRPC C core*) that provides all gRPC's core functionality through a low level API. Libraries in other languages in this repository (C++, C#, Ruby,
Python, PHP, NodeJS, Objective-C) are layered on top of this library.

@ -41,6 +41,7 @@
#include "src/core/ext/filters/client_channel/resolver_result_parsing.h"
#include "src/core/ext/filters/client_channel/resolving_lb_policy.h"
#include "src/core/ext/filters/client_channel/retry_throttle.h"
#include "src/core/ext/filters/client_channel/service_config.h"
#include "src/core/ext/filters/client_channel/subchannel.h"
#include "src/core/ext/filters/deadline/deadline_filter.h"
#include "src/core/lib/backoff/backoff.h"
@ -61,7 +62,6 @@
#include "src/core/lib/transport/error_utils.h"
#include "src/core/lib/transport/metadata.h"
#include "src/core/lib/transport/metadata_batch.h"
#include "src/core/lib/transport/service_config.h"
#include "src/core/lib/transport/static_metadata.h"
#include "src/core/lib/transport/status_metadata.h"
@ -252,11 +252,11 @@ class ClientChannelControlHelper
// Synchronous callback from chand->resolving_lb_policy to process a resolver
// result update.
static bool process_resolver_result_locked(
void* arg, const grpc_channel_args& args, const char** lb_policy_name,
void* arg, grpc_core::Resolver::Result* result, const char** lb_policy_name,
grpc_core::RefCountedPtr<LoadBalancingPolicy::Config>* lb_policy_config) {
channel_data* chand = static_cast<channel_data*>(arg);
chand->have_service_config = true;
ProcessedResolverResult resolver_result(args, chand->enable_retries);
ProcessedResolverResult resolver_result(result, chand->enable_retries);
grpc_core::UniquePtr<char> service_config_json =
resolver_result.service_config_json();
if (grpc_client_channel_routing_trace.enabled()) {

@ -23,11 +23,10 @@
#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
#include "src/core/lib/iomgr/combiner.h"
grpc_core::DebugOnlyTraceFlag grpc_trace_lb_policy_refcount(
false, "lb_policy_refcount");
namespace grpc_core {
DebugOnlyTraceFlag grpc_trace_lb_policy_refcount(false, "lb_policy_refcount");
//
// LoadBalancingPolicy
//
@ -89,6 +88,44 @@ grpc_json* LoadBalancingPolicy::ParseLoadBalancingConfig(
return nullptr;
}
//
// LoadBalancingPolicy::UpdateArgs
//
LoadBalancingPolicy::UpdateArgs::UpdateArgs(const UpdateArgs& other) {
addresses = other.addresses;
config = other.config;
args = grpc_channel_args_copy(other.args);
}
LoadBalancingPolicy::UpdateArgs::UpdateArgs(UpdateArgs&& other) {
addresses = std::move(other.addresses);
config = std::move(other.config);
// TODO(roth): Use std::move() once channel args is converted to C++.
args = other.args;
other.args = nullptr;
}
LoadBalancingPolicy::UpdateArgs& LoadBalancingPolicy::UpdateArgs::operator=(
const UpdateArgs& other) {
addresses = other.addresses;
config = other.config;
grpc_channel_args_destroy(args);
args = grpc_channel_args_copy(other.args);
return *this;
}
LoadBalancingPolicy::UpdateArgs& LoadBalancingPolicy::UpdateArgs::operator=(
UpdateArgs&& other) {
addresses = std::move(other.addresses);
config = std::move(other.config);
// TODO(roth): Use std::move() once channel args is converted to C++.
grpc_channel_args_destroy(args);
args = other.args;
other.args = nullptr;
return *this;
}
//
// LoadBalancingPolicy::QueuePicker
//

@ -22,6 +22,8 @@
#include <grpc/support/port_platform.h>
#include "src/core/ext/filters/client_channel/client_channel_channelz.h"
#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.h"
#include "src/core/lib/gprpp/abstract.h"
#include "src/core/lib/gprpp/orphanable.h"
@ -29,7 +31,6 @@
#include "src/core/lib/iomgr/combiner.h"
#include "src/core/lib/iomgr/polling_entity.h"
#include "src/core/lib/transport/connectivity_state.h"
#include "src/core/lib/transport/service_config.h"
extern grpc_core::DebugOnlyTraceFlag grpc_trace_lb_policy_refcount;
@ -212,6 +213,23 @@ class LoadBalancingPolicy : public InternallyRefCounted<LoadBalancingPolicy> {
RefCountedPtr<ServiceConfig> service_config_;
};
/// Data passed to the UpdateLocked() method when new addresses and
/// config are available.
struct UpdateArgs {
ServerAddressList addresses;
RefCountedPtr<Config> config;
const grpc_channel_args* args = nullptr;
// TODO(roth): Remove everything below once channel args is
// converted to a copyable and movable C++ object.
UpdateArgs() = default;
~UpdateArgs() { grpc_channel_args_destroy(args); }
UpdateArgs(const UpdateArgs& other);
UpdateArgs(UpdateArgs&& other);
UpdateArgs& operator=(const UpdateArgs& other);
UpdateArgs& operator=(UpdateArgs&& other);
};
/// Args used to instantiate an LB policy.
struct Args {
/// The combiner under which all LB policy calls will be run.
@ -239,14 +257,10 @@ class LoadBalancingPolicy : public InternallyRefCounted<LoadBalancingPolicy> {
/// Returns the name of the LB policy.
virtual const char* name() const GRPC_ABSTRACT;
/// Updates the policy with a new set of \a args and a new \a lb_config from
/// the resolver. Will be invoked immediately after LB policy is constructed,
/// and then again whenever the resolver returns a new result.
/// Note that the LB policy gets the set of addresses from the
/// GRPC_ARG_SERVER_ADDRESS_LIST channel arg.
virtual void UpdateLocked(const grpc_channel_args& args,
RefCountedPtr<Config>) // NOLINT
GRPC_ABSTRACT;
/// Updates the policy with new data from the resolver. Will be invoked
/// immediately after LB policy is constructed, and then again whenever
/// the resolver returns a new result.
virtual void UpdateLocked(UpdateArgs) GRPC_ABSTRACT; // NOLINT
/// Tries to enter a READY connectivity state.
/// This is a no-op by default, since most LB policies never go into

@ -125,8 +125,7 @@ class GrpcLb : public LoadBalancingPolicy {
const char* name() const override { return kGrpclb; }
void UpdateLocked(const grpc_channel_args& args,
RefCountedPtr<Config> lb_config) override;
void UpdateLocked(UpdateArgs args) override;
void ResetBackoffLocked() override;
void FillChildRefsForChannelz(
channelz::ChildRefsList* child_subchannels,
@ -295,7 +294,8 @@ class GrpcLb : public LoadBalancingPolicy {
void ShutdownLocked() override;
// Helper functions used in UpdateLocked().
void ProcessChannelArgsLocked(const grpc_channel_args& args);
void ProcessAddressesAndChannelArgsLocked(const ServerAddressList& addresses,
const grpc_channel_args& args);
void ParseLbConfig(Config* grpclb_config);
static void OnBalancerChannelConnectivityChangedLocked(void* arg,
grpc_error* error);
@ -311,7 +311,8 @@ class GrpcLb : public LoadBalancingPolicy {
static void OnBalancerCallRetryTimerLocked(void* arg, grpc_error* error);
// Methods for dealing with the child policy.
grpc_channel_args* CreateChildPolicyArgsLocked();
grpc_channel_args* CreateChildPolicyArgsLocked(
bool is_backend_from_grpclb_load_balancer);
OrphanablePtr<LoadBalancingPolicy> CreateChildPolicyLocked(
const char* name, const grpc_channel_args* args);
void CreateOrUpdateChildPolicyLocked();
@ -1204,7 +1205,6 @@ grpc_channel_args* BuildBalancerChannelArgs(
const ServerAddressList& addresses,
FakeResolverResponseGenerator* response_generator,
const grpc_channel_args* args) {
ServerAddressList balancer_addresses = ExtractBalancerAddresses(addresses);
// Channel args to remove.
static const char* args_to_remove[] = {
// LB policy name, since we want to use the default (pick_first) in
@ -1217,15 +1217,6 @@ grpc_channel_args* BuildBalancerChannelArgs(
// the LB channel than for the parent channel. The client channel
// factory will re-add this arg with the right value.
GRPC_ARG_SERVER_URI,
// The resolved addresses, which will be generated by the name resolver
// used in the LB channel. Note that the LB channel will use the fake
// resolver, so this won't actually generate a query to DNS (or some
// other name service). However, the addresses returned by the fake
// resolver will have is_balancer=false, whereas our own addresses have
// is_balancer=true. We need the LB channel to return addresses with
// is_balancer=false so that it does not wind up recursively using the
// grpclb LB policy.
GRPC_ARG_SERVER_ADDRESS_LIST,
// The fake resolver response generator, because we are replacing it
// with the one from the grpclb policy, used to propagate updates to
// the LB channel.
@ -1241,10 +1232,6 @@ grpc_channel_args* BuildBalancerChannelArgs(
};
// Channel args to add.
const grpc_arg args_to_add[] = {
// New address list.
// Note that we pass these in both when creating the LB channel
// and via the fake resolver. The latter is what actually gets used.
CreateServerAddressListChannelArg(&balancer_addresses),
// The fake resolver response generator, which we use to inject
// address updates into the LB channel.
grpc_core::FakeResolverResponseGenerator::MakeChannelArg(
@ -1262,7 +1249,7 @@ grpc_channel_args* BuildBalancerChannelArgs(
args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), args_to_add,
GPR_ARRAY_SIZE(args_to_add));
// Make any necessary modifications for security.
return grpc_lb_policy_grpclb_modify_lb_channel_args(new_args);
return grpc_lb_policy_grpclb_modify_lb_channel_args(addresses, new_args);
}
//
@ -1388,11 +1375,10 @@ void GrpcLb::FillChildRefsForChannelz(
}
}
void GrpcLb::UpdateLocked(const grpc_channel_args& args,
RefCountedPtr<Config> lb_config) {
void GrpcLb::UpdateLocked(UpdateArgs args) {
const bool is_initial_update = lb_channel_ == nullptr;
ParseLbConfig(lb_config.get());
ProcessChannelArgsLocked(args);
ParseLbConfig(args.config.get());
ProcessAddressesAndChannelArgsLocked(args.addresses, *args.args);
// Update the existing child policy.
if (child_policy_ != nullptr) CreateOrUpdateChildPolicyLocked();
// If this is the initial update, start the fallback-at-startup checks
@ -1442,18 +1428,10 @@ ServerAddressList ExtractBackendAddresses(const ServerAddressList& addresses) {
return backend_addresses;
}
void GrpcLb::ProcessChannelArgsLocked(const grpc_channel_args& args) {
const ServerAddressList* addresses = FindServerAddressListChannelArg(&args);
if (addresses == nullptr) {
// Ignore this update.
gpr_log(
GPR_ERROR,
"[grpclb %p] No valid LB addresses channel arg in update, ignoring.",
this);
return;
}
void GrpcLb::ProcessAddressesAndChannelArgsLocked(
const ServerAddressList& addresses, const grpc_channel_args& args) {
// Update fallback address list.
fallback_backend_addresses_ = ExtractBackendAddresses(*addresses);
fallback_backend_addresses_ = ExtractBackendAddresses(addresses);
// Make sure that GRPC_ARG_LB_POLICY_NAME is set in channel args,
// since we use this to trigger the client_load_reporting filter.
static const char* args_to_remove[] = {GRPC_ARG_LB_POLICY_NAME};
@ -1463,8 +1441,9 @@ void GrpcLb::ProcessChannelArgsLocked(const grpc_channel_args& args) {
args_ = grpc_channel_args_copy_and_add_and_remove(
&args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), &new_arg, 1);
// Construct args for balancer channel.
grpc_channel_args* lb_channel_args =
BuildBalancerChannelArgs(*addresses, response_generator_.get(), &args);
ServerAddressList balancer_addresses = ExtractBalancerAddresses(addresses);
grpc_channel_args* lb_channel_args = BuildBalancerChannelArgs(
balancer_addresses, response_generator_.get(), &args);
// Create balancer channel if needed.
if (lb_channel_ == nullptr) {
char* uri_str;
@ -1481,8 +1460,10 @@ void GrpcLb::ProcessChannelArgsLocked(const grpc_channel_args& args) {
}
// Propagate updates to the LB channel (pick_first) through the fake
// resolver.
response_generator_->SetResponse(lb_channel_args);
grpc_channel_args_destroy(lb_channel_args);
Resolver::Result result;
result.addresses = std::move(balancer_addresses);
result.args = lb_channel_args;
response_generator_->SetResponse(std::move(result));
}
void GrpcLb::ParseLbConfig(Config* grpclb_config) {
@ -1649,25 +1630,9 @@ void GrpcLb::OnFallbackTimerLocked(void* arg, grpc_error* error) {
// code for interacting with the child policy
//
grpc_channel_args* GrpcLb::CreateChildPolicyArgsLocked() {
ServerAddressList tmp_addresses;
ServerAddressList* addresses = &tmp_addresses;
bool is_backend_from_grpclb_load_balancer = false;
if (fallback_mode_) {
// Note: If fallback backend address list is empty, the child policy
// will go into state TRANSIENT_FAILURE.
addresses = &fallback_backend_addresses_;
} else {
tmp_addresses = serverlist_->GetServerAddressList(
lb_calld_ == nullptr ? nullptr : lb_calld_->client_stats());
is_backend_from_grpclb_load_balancer = true;
}
GPR_ASSERT(addresses != nullptr);
// Replace the server address list in the channel args that we pass down to
// the subchannel.
static const char* keys_to_remove[] = {GRPC_ARG_SERVER_ADDRESS_LIST};
grpc_arg args_to_add[3] = {
CreateServerAddressListChannelArg(addresses),
grpc_channel_args* GrpcLb::CreateChildPolicyArgsLocked(
bool is_backend_from_grpclb_load_balancer) {
grpc_arg args_to_add[2] = {
// A channel arg indicating if the target is a backend inferred from a
// grpclb load balancer.
grpc_channel_arg_integer_create(
@ -1675,15 +1640,12 @@ grpc_channel_args* GrpcLb::CreateChildPolicyArgsLocked() {
GRPC_ARG_ADDRESS_IS_BACKEND_FROM_GRPCLB_LOAD_BALANCER),
is_backend_from_grpclb_load_balancer),
};
size_t num_args_to_add = 2;
size_t num_args_to_add = 1;
if (is_backend_from_grpclb_load_balancer) {
args_to_add[2] = grpc_channel_arg_integer_create(
args_to_add[num_args_to_add++] = grpc_channel_arg_integer_create(
const_cast<char*>(GRPC_ARG_INHIBIT_HEALTH_CHECKING), 1);
++num_args_to_add;
}
return grpc_channel_args_copy_and_add_and_remove(
args_, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), args_to_add,
num_args_to_add);
return grpc_channel_args_copy_and_add(args_, args_to_add, num_args_to_add);
}
OrphanablePtr<LoadBalancingPolicy> GrpcLb::CreateChildPolicyLocked(
@ -1717,8 +1679,25 @@ OrphanablePtr<LoadBalancingPolicy> GrpcLb::CreateChildPolicyLocked(
void GrpcLb::CreateOrUpdateChildPolicyLocked() {
if (shutting_down_) return;
grpc_channel_args* args = CreateChildPolicyArgsLocked();
GPR_ASSERT(args != nullptr);
// Construct update args.
UpdateArgs update_args;
bool is_backend_from_grpclb_load_balancer = false;
if (fallback_mode_) {
// If CreateOrUpdateChildPolicyLocked() is invoked when we haven't
// received any serverlist from the balancer, we use the fallback backends
// returned by the resolver. Note that the fallback backend list may be
// empty, in which case the new round_robin policy will keep the requested
// picks pending.
update_args.addresses = fallback_backend_addresses_;
} else {
update_args.addresses = serverlist_->GetServerAddressList(
lb_calld_ == nullptr ? nullptr : lb_calld_->client_stats());
is_backend_from_grpclb_load_balancer = true;
}
update_args.args =
CreateChildPolicyArgsLocked(is_backend_from_grpclb_load_balancer);
GPR_ASSERT(update_args.args != nullptr);
update_args.config = child_policy_config_;
// If the child policy name changes, we need to create a new child
// policy. When this happens, we leave child_policy_ as-is and store
// the new child policy in pending_child_policy_. Once the new child
@ -1789,7 +1768,8 @@ void GrpcLb::CreateOrUpdateChildPolicyLocked() {
gpr_log(GPR_INFO, "[grpclb %p] Creating new %schild policy %s", this,
child_policy_ == nullptr ? "" : "pending ", child_policy_name);
}
auto new_policy = CreateChildPolicyLocked(child_policy_name, args);
auto new_policy =
CreateChildPolicyLocked(child_policy_name, update_args.args);
// Swap the policy into place.
auto& lb_policy =
child_policy_ == nullptr ? child_policy_ : pending_child_policy_;
@ -1813,9 +1793,7 @@ void GrpcLb::CreateOrUpdateChildPolicyLocked() {
policy_to_update == pending_child_policy_.get() ? "pending " : "",
policy_to_update);
}
policy_to_update->UpdateLocked(*args, child_policy_config_);
// Clean up.
grpc_channel_args_destroy(args);
policy_to_update->UpdateLocked(std::move(update_args));
}
//

@ -21,6 +21,6 @@
#include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h"
grpc_channel_args* grpc_lb_policy_grpclb_modify_lb_channel_args(
grpc_channel_args* args) {
const grpc_core::ServerAddressList& addresses, grpc_channel_args* args) {
return args;
}

@ -23,6 +23,8 @@
#include <grpc/impl/codegen/grpc_types.h>
#include "src/core/ext/filters/client_channel/server_address.h"
/// Makes any necessary modifications to \a args for use in the grpclb
/// balancer channel.
///
@ -30,7 +32,7 @@
///
/// Caller takes ownership of the returned args.
grpc_channel_args* grpc_lb_policy_grpclb_modify_lb_channel_args(
grpc_channel_args* args);
const grpc_core::ServerAddressList& addresses, grpc_channel_args* args);
#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_GRPCLB_GRPCLB_CHANNEL_H \
*/

@ -68,18 +68,14 @@ RefCountedPtr<TargetAuthorityTable> CreateTargetAuthorityTable(
} // namespace grpc_core
grpc_channel_args* grpc_lb_policy_grpclb_modify_lb_channel_args(
grpc_channel_args* args) {
const grpc_core::ServerAddressList& addresses, grpc_channel_args* args) {
const char* args_to_remove[1];
size_t num_args_to_remove = 0;
grpc_arg args_to_add[2];
size_t num_args_to_add = 0;
// Add arg for targets info table.
grpc_core::ServerAddressList* addresses =
grpc_core::FindServerAddressListChannelArg(args);
GPR_ASSERT(addresses != nullptr);
grpc_core::RefCountedPtr<grpc_core::TargetAuthorityTable>
target_authority_table =
grpc_core::CreateTargetAuthorityTable(*addresses);
target_authority_table = grpc_core::CreateTargetAuthorityTable(addresses);
args_to_add[num_args_to_add++] =
grpc_core::CreateTargetAuthorityTableChannelArg(
target_authority_table.get());

@ -50,8 +50,7 @@ class PickFirst : public LoadBalancingPolicy {
const char* name() const override { return kPickFirst; }
void UpdateLocked(const grpc_channel_args& args,
RefCountedPtr<Config> lb_config) override;
void UpdateLocked(UpdateArgs args) override;
void ExitIdleLocked() override;
void ResetBackoffLocked() override;
void FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels,
@ -238,38 +237,19 @@ void PickFirst::UpdateChildRefsLocked() {
child_subchannels_ = std::move(cs);
}
void PickFirst::UpdateLocked(const grpc_channel_args& args,
RefCountedPtr<Config> lb_config) {
void PickFirst::UpdateLocked(UpdateArgs args) {
AutoChildRefsUpdater guard(this);
const ServerAddressList* addresses = FindServerAddressListChannelArg(&args);
if (addresses == nullptr) {
if (subchannel_list_ == nullptr) {
// If we don't have a current subchannel list, go into TRANSIENT FAILURE.
grpc_error* error =
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Missing update in args");
channel_control_helper()->UpdateState(
GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error),
UniquePtr<SubchannelPicker>(New<TransientFailurePicker>(error)));
} else {
// otherwise, keep using the current subchannel list (ignore this update).
gpr_log(GPR_ERROR,
"No valid LB addresses channel arg for Pick First %p update, "
"ignoring.",
this);
}
return;
}
if (grpc_lb_pick_first_trace.enabled()) {
gpr_log(GPR_INFO,
"Pick First %p received update with %" PRIuPTR " addresses", this,
addresses->size());
args.addresses.size());
}
grpc_arg new_arg = grpc_channel_arg_integer_create(
const_cast<char*>(GRPC_ARG_INHIBIT_HEALTH_CHECKING), 1);
grpc_channel_args* new_args =
grpc_channel_args_copy_and_add(&args, &new_arg, 1);
grpc_channel_args_copy_and_add(args.args, &new_arg, 1);
auto subchannel_list = MakeOrphanable<PickFirstSubchannelList>(
this, &grpc_lb_pick_first_trace, *addresses, combiner(), *new_args);
this, &grpc_lb_pick_first_trace, args.addresses, combiner(), *new_args);
grpc_channel_args_destroy(new_args);
if (subchannel_list->num_subchannels() == 0) {
// Empty update or no valid subchannels. Unsubscribe from all current

@ -61,8 +61,7 @@ class RoundRobin : public LoadBalancingPolicy {
const char* name() const override { return kRoundRobin; }
void UpdateLocked(const grpc_channel_args& args,
RefCountedPtr<Config> lb_config) override;
void UpdateLocked(UpdateArgs args) override;
void ResetBackoffLocked() override;
void FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels,
channelz::ChildRefsList* ignored) override;
@ -476,26 +475,11 @@ void RoundRobin::RoundRobinSubchannelData::ProcessConnectivityChangeLocked(
subchannel_list()->UpdateRoundRobinStateFromSubchannelStateCountsLocked();
}
void RoundRobin::UpdateLocked(const grpc_channel_args& args,
RefCountedPtr<Config> lb_config) {
void RoundRobin::UpdateLocked(UpdateArgs args) {
AutoChildRefsUpdater guard(this);
const ServerAddressList* addresses = FindServerAddressListChannelArg(&args);
if (addresses == nullptr) {
gpr_log(GPR_ERROR, "[RR %p] update provided no addresses; ignoring", this);
// If we don't have a current subchannel list, go into TRANSIENT_FAILURE.
// Otherwise, keep using the current subchannel list (ignore this update).
if (subchannel_list_ == nullptr) {
grpc_error* error =
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Missing update in args");
channel_control_helper()->UpdateState(
GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error),
UniquePtr<SubchannelPicker>(New<TransientFailurePicker>(error)));
}
return;
}
if (grpc_lb_round_robin_trace.enabled()) {
gpr_log(GPR_INFO, "[RR %p] received update with %" PRIuPTR " addresses",
this, addresses->size());
this, args.addresses.size());
}
// Replace latest_pending_subchannel_list_.
if (latest_pending_subchannel_list_ != nullptr) {
@ -506,7 +490,7 @@ void RoundRobin::UpdateLocked(const grpc_channel_args& args,
}
}
latest_pending_subchannel_list_ = MakeOrphanable<RoundRobinSubchannelList>(
this, &grpc_lb_round_robin_trace, *addresses, combiner(), args);
this, &grpc_lb_round_robin_trace, args.addresses, combiner(), *args.args);
if (latest_pending_subchannel_list_->num_subchannels() == 0) {
// If the new list is empty, immediately promote the new list to the
// current list and transition to TRANSIENT_FAILURE.

@ -505,7 +505,6 @@ SubchannelList<SubchannelListType, SubchannelDataType>::SubchannelList(
inhibit_health_checking_ = grpc_channel_arg_get_bool(
grpc_channel_args_find(&args, GRPC_ARG_INHIBIT_HEALTH_CHECKING), false);
static const char* keys_to_remove[] = {GRPC_ARG_SUBCHANNEL_ADDRESS,
GRPC_ARG_SERVER_ADDRESS_LIST,
GRPC_ARG_INHIBIT_HEALTH_CHECKING};
// Create a subchannel for each address.
for (size_t i = 0; i < addresses.size(); i++) {

@ -78,6 +78,7 @@
#include "src/core/ext/filters/client_channel/parse_address.h"
#include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h"
#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/ext/filters/client_channel/service_config.h"
#include "src/core/lib/backoff/backoff.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/channel_stack.h"
@ -98,7 +99,6 @@
#include "src/core/lib/surface/call.h"
#include "src/core/lib/surface/channel.h"
#include "src/core/lib/surface/channel_init.h"
#include "src/core/lib/transport/service_config.h"
#include "src/core/lib/transport/static_metadata.h"
#define GRPC_XDS_INITIAL_CONNECT_BACKOFF_SECONDS 1
@ -121,8 +121,7 @@ class XdsLb : public LoadBalancingPolicy {
const char* name() const override { return kXds; }
void UpdateLocked(const grpc_channel_args& args,
RefCountedPtr<Config> lb_config) override;
void UpdateLocked(UpdateArgs args) override;
void ResetBackoffLocked() override;
void FillChildRefsForChannelz(
channelz::ChildRefsList* child_subchannels,
@ -293,7 +292,8 @@ class XdsLb : public LoadBalancingPolicy {
void ShutdownLocked() override;
// Helper function used in UpdateLocked().
void ProcessChannelArgsLocked(const grpc_channel_args& args);
void ProcessAddressesAndChannelArgsLocked(const ServerAddressList& addresses,
const grpc_channel_args& args);
// Parses the xds config given the JSON node of the first child of XdsConfig.
// If parsing succeeds, updates \a balancer_name, and updates \a
@ -539,15 +539,14 @@ void ParseServer(const xds_grpclb_server* server, grpc_resolved_address* addr) {
}
// Returns addresses extracted from \a serverlist.
UniquePtr<ServerAddressList> ProcessServerlist(
const xds_grpclb_serverlist* serverlist) {
auto addresses = MakeUnique<ServerAddressList>();
ServerAddressList ProcessServerlist(const xds_grpclb_serverlist* serverlist) {
ServerAddressList addresses;
for (size_t i = 0; i < serverlist->num_servers; ++i) {
const xds_grpclb_server* server = serverlist->servers[i];
if (!IsServerValid(serverlist->servers[i], i, false)) continue;
grpc_resolved_address addr;
ParseServer(server, &addr);
addresses->emplace_back(addr, nullptr);
addresses.emplace_back(addr, nullptr);
}
return addresses;
}
@ -1082,9 +1081,6 @@ grpc_channel_args* BuildBalancerChannelArgs(const grpc_channel_args* args) {
// the LB channel than for the parent channel. The client channel
// factory will re-add this arg with the right value.
GRPC_ARG_SERVER_URI,
// The resolved addresses, which will be generated by the name resolver
// used in the LB channel.
GRPC_ARG_SERVER_ADDRESS_LIST,
// The LB channel should use the authority indicated by the target
// authority table (see \a grpc_lb_policy_xds_modify_lb_channel_args),
// as opposed to the authority from the parent channel.
@ -1232,17 +1228,10 @@ void XdsLb::FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels,
}
}
void XdsLb::ProcessChannelArgsLocked(const grpc_channel_args& args) {
const ServerAddressList* addresses = FindServerAddressListChannelArg(&args);
if (addresses == nullptr) {
// Ignore this update.
gpr_log(GPR_ERROR,
"[xdslb %p] No valid LB addresses channel arg in update, ignoring.",
this);
return;
}
void XdsLb::ProcessAddressesAndChannelArgsLocked(
const ServerAddressList& addresses, const grpc_channel_args& args) {
// Update fallback address list.
fallback_backend_addresses_ = ExtractBackendAddresses(*addresses);
fallback_backend_addresses_ = ExtractBackendAddresses(addresses);
// Make sure that GRPC_ARG_LB_POLICY_NAME is set in channel args,
// since we use this to trigger the client_load_reporting filter.
static const char* args_to_remove[] = {GRPC_ARG_LB_POLICY_NAME};
@ -1310,17 +1299,16 @@ void XdsLb::ParseLbConfig(Config* xds_config) {
}
}
void XdsLb::UpdateLocked(const grpc_channel_args& args,
RefCountedPtr<Config> lb_config) {
void XdsLb::UpdateLocked(UpdateArgs args) {
const bool is_initial_update = lb_chand_ == nullptr;
ParseLbConfig(lb_config.get());
ParseLbConfig(args.config.get());
// TODO(juanlishen): Pass fallback policy config update after fallback policy
// is added.
if (balancer_name_ == nullptr) {
gpr_log(GPR_ERROR, "[xdslb %p] LB config parsing fails.", this);
return;
}
ProcessChannelArgsLocked(args);
ProcessAddressesAndChannelArgsLocked(args.addresses, *args.args);
// Update the existing child policy.
// Note: We have disabled fallback mode in the code, so this child policy must
// have been created from a serverlist.
@ -1369,17 +1357,7 @@ void XdsLb::OnFallbackTimerLocked(void* arg, grpc_error* error) {
//
grpc_channel_args* XdsLb::CreateChildPolicyArgsLocked() {
// This should never be invoked if we do not have serverlist_, as fallback
// mode is disabled for xDS plugin.
GPR_ASSERT(serverlist_ != nullptr);
GPR_ASSERT(serverlist_->num_servers > 0);
UniquePtr<ServerAddressList> addresses = ProcessServerlist(serverlist_);
GPR_ASSERT(addresses != nullptr);
// Replace the server address list in the channel args that we pass down to
// the subchannel.
static const char* keys_to_remove[] = {GRPC_ARG_SERVER_ADDRESS_LIST};
const grpc_arg args_to_add[] = {
CreateServerAddressListChannelArg(addresses.get()),
// A channel arg indicating if the target is a backend inferred from a
// grpclb load balancer.
grpc_channel_arg_integer_create(
@ -1390,9 +1368,8 @@ grpc_channel_args* XdsLb::CreateChildPolicyArgsLocked() {
grpc_channel_arg_integer_create(
const_cast<char*>(GRPC_ARG_INHIBIT_HEALTH_CHECKING), 1),
};
return grpc_channel_args_copy_and_add_and_remove(
args_, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), args_to_add,
GPR_ARRAY_SIZE(args_to_add));
return grpc_channel_args_copy_and_add(args_, args_to_add,
GPR_ARRAY_SIZE(args_to_add));
}
OrphanablePtr<LoadBalancingPolicy> XdsLb::CreateChildPolicyLocked(
@ -1426,8 +1403,16 @@ OrphanablePtr<LoadBalancingPolicy> XdsLb::CreateChildPolicyLocked(
void XdsLb::CreateOrUpdateChildPolicyLocked() {
if (shutting_down_) return;
grpc_channel_args* args = CreateChildPolicyArgsLocked();
GPR_ASSERT(args != nullptr);
// This should never be invoked if we do not have serverlist_, as fallback
// mode is disabled for xDS plugin.
// TODO(juanlishen): Change this as part of implementing fallback mode.
GPR_ASSERT(serverlist_ != nullptr);
GPR_ASSERT(serverlist_->num_servers > 0);
// Construct update args.
UpdateArgs update_args;
update_args.addresses = ProcessServerlist(serverlist_);
update_args.config = child_policy_config_;
update_args.args = CreateChildPolicyArgsLocked();
// If the child policy name changes, we need to create a new child
// policy. When this happens, we leave child_policy_ as-is and store
// the new child policy in pending_child_policy_. Once the new child
@ -1500,7 +1485,8 @@ void XdsLb::CreateOrUpdateChildPolicyLocked() {
gpr_log(GPR_INFO, "[xdslb %p] Creating new %schild policy %s", this,
child_policy_ == nullptr ? "" : "pending ", child_policy_name);
}
auto new_policy = CreateChildPolicyLocked(child_policy_name, args);
auto new_policy =
CreateChildPolicyLocked(child_policy_name, update_args.args);
auto& lb_policy =
child_policy_ == nullptr ? child_policy_ : pending_child_policy_;
{
@ -1523,9 +1509,7 @@ void XdsLb::CreateOrUpdateChildPolicyLocked() {
policy_to_update == pending_child_policy_.get() ? "pending " : "",
policy_to_update);
}
policy_to_update->UpdateLocked(*args, child_policy_config_);
// Clean up.
grpc_channel_args_destroy(args);
policy_to_update->UpdateLocked(std::move(update_args));
}
//

@ -26,6 +26,10 @@ grpc_core::DebugOnlyTraceFlag grpc_trace_resolver_refcount(false,
namespace grpc_core {
//
// Resolver
//
Resolver::Resolver(grpc_combiner* combiner,
UniquePtr<ResultHandler> result_handler)
: InternallyRefCounted(&grpc_trace_resolver_refcount),
@ -34,4 +38,51 @@ Resolver::Resolver(grpc_combiner* combiner,
Resolver::~Resolver() { GRPC_COMBINER_UNREF(combiner_, "resolver"); }
//
// Resolver::Result
//
Resolver::Result::~Result() {
GRPC_ERROR_UNREF(service_config_error);
grpc_channel_args_destroy(args);
}
Resolver::Result::Result(const Result& other) {
addresses = other.addresses;
service_config = other.service_config;
service_config_error = GRPC_ERROR_REF(other.service_config_error);
args = grpc_channel_args_copy(other.args);
}
Resolver::Result::Result(Result&& other) {
addresses = std::move(other.addresses);
service_config = std::move(other.service_config);
service_config_error = other.service_config_error;
other.service_config_error = GRPC_ERROR_NONE;
args = other.args;
other.args = nullptr;
}
Resolver::Result& Resolver::Result::operator=(const Result& other) {
addresses = other.addresses;
service_config = other.service_config;
GRPC_ERROR_UNREF(service_config_error);
service_config_error = GRPC_ERROR_REF(other.service_config_error);
grpc_channel_args_destroy(args);
args = grpc_channel_args_copy(other.args);
return *this;
}
Resolver::Result& Resolver::Result::operator=(Result&& other) {
addresses = std::move(other.addresses);
service_config = std::move(other.service_config);
GRPC_ERROR_UNREF(service_config_error);
service_config_error = other.service_config_error;
other.service_config_error = GRPC_ERROR_NONE;
grpc_channel_args_destroy(args);
args = other.args;
other.args = nullptr;
return *this;
}
} // namespace grpc_core

@ -23,8 +23,11 @@
#include <grpc/impl/codegen/grpc_types.h>
#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/ext/filters/client_channel/service_config.h"
#include "src/core/lib/gprpp/abstract.h"
#include "src/core/lib/gprpp/orphanable.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/iomgr/combiner.h"
#include "src/core/lib/iomgr/iomgr.h"
@ -46,6 +49,23 @@ namespace grpc_core {
/// combiner passed to the constructor.
class Resolver : public InternallyRefCounted<Resolver> {
public:
/// Results returned by the resolver.
struct Result {
ServerAddressList addresses;
RefCountedPtr<ServiceConfig> service_config;
grpc_error* service_config_error = GRPC_ERROR_NONE;
const grpc_channel_args* args = nullptr;
// TODO(roth): Remove everything below once grpc_error and
// grpc_channel_args are convert to copyable and movable C++ objects.
Result() = default;
~Result();
Result(const Result& other);
Result(Result&& other);
Result& operator=(const Result& other);
Result& operator=(Result&& other);
};
/// A proxy object used by the resolver to return results to the
/// client channel.
class ResultHandler {
@ -53,18 +73,17 @@ class Resolver : public InternallyRefCounted<Resolver> {
virtual ~ResultHandler() {}
/// Returns a result to the channel.
/// The list of addresses will be in GRPC_ARG_SERVER_ADDRESS_LIST.
/// The service config (if any) will be in GRPC_ARG_SERVICE_CONFIG.
/// Takes ownership of \a result.
// TODO(roth): Change this API so that addresses and service config are
// passed explicitly instead of being in channel args.
virtual void ReturnResult(const grpc_channel_args* result) GRPC_ABSTRACT;
/// Takes ownership of \a result.args.
virtual void ReturnResult(Result result) GRPC_ABSTRACT; // NOLINT
/// Returns a transient error to the channel.
/// If the resolver does not set the GRPC_ERROR_INT_GRPC_STATUS
/// attribute on the error, calls will be failed with status UNKNOWN.
virtual void ReturnError(grpc_error* error) GRPC_ABSTRACT;
// TODO(yashkt): As part of the service config error handling
// changes, add a method to parse the service config JSON string.
GRPC_ABSTRACT_BASE_CLASS
};

@ -34,6 +34,7 @@
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
#include "src/core/ext/filters/client_channel/resolver_registry.h"
#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/ext/filters/client_channel/service_config.h"
#include "src/core/lib/backoff/backoff.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/env.h"
@ -45,7 +46,6 @@
#include "src/core/lib/iomgr/resolve_address.h"
#include "src/core/lib/iomgr/timer.h"
#include "src/core/lib/json/json.h"
#include "src/core/lib/transport/service_config.h"
#define GRPC_DNS_INITIAL_CONNECT_BACKOFF_SECONDS 1
#define GRPC_DNS_RECONNECT_BACKOFF_MULTIPLIER 1.6
@ -299,28 +299,21 @@ void AresDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) {
return;
}
if (r->addresses_ != nullptr) {
static const char* args_to_remove[1];
size_t num_args_to_remove = 0;
grpc_arg args_to_add[2];
size_t num_args_to_add = 0;
args_to_add[num_args_to_add++] =
CreateServerAddressListChannelArg(r->addresses_.get());
char* service_config_string = nullptr;
Result result;
result.addresses = std::move(*r->addresses_);
if (r->service_config_json_ != nullptr) {
service_config_string = ChooseServiceConfig(r->service_config_json_);
char* service_config_string =
ChooseServiceConfig(r->service_config_json_);
gpr_free(r->service_config_json_);
if (service_config_string != nullptr) {
GRPC_CARES_TRACE_LOG("resolver:%p selected service config choice: %s",
r, service_config_string);
args_to_remove[num_args_to_remove++] = GRPC_ARG_SERVICE_CONFIG;
args_to_add[num_args_to_add++] = grpc_channel_arg_string_create(
(char*)GRPC_ARG_SERVICE_CONFIG, service_config_string);
result.service_config = ServiceConfig::Create(service_config_string);
}
gpr_free(service_config_string);
}
r->result_handler()->ReturnResult(grpc_channel_args_copy_and_add_and_remove(
r->channel_args_, args_to_remove, num_args_to_remove, args_to_add,
num_args_to_add));
gpr_free(service_config_string);
result.args = grpc_channel_args_copy(r->channel_args_);
r->result_handler()->ReturnResult(std::move(result));
r->addresses_.reset();
// Reset backoff state so that we start from the beginning when the
// next request gets triggered.

@ -169,15 +169,15 @@ void NativeDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) {
return;
}
if (r->addresses_ != nullptr) {
ServerAddressList addresses;
Result result;
for (size_t i = 0; i < r->addresses_->naddrs; ++i) {
addresses.emplace_back(&r->addresses_->addrs[i].addr,
r->addresses_->addrs[i].len, nullptr /* args */);
result.addresses.emplace_back(&r->addresses_->addrs[i].addr,
r->addresses_->addrs[i].len,
nullptr /* args */);
}
grpc_resolved_addresses_destroy(r->addresses_);
grpc_arg new_arg = CreateServerAddressListChannelArg(&addresses);
r->result_handler()->ReturnResult(
grpc_channel_args_copy_and_add(r->channel_args_, &new_arg, 1));
result.args = grpc_channel_args_copy(r->channel_args_);
r->result_handler()->ReturnResult(std::move(result));
// Reset backoff state so that we start from the beginning when the
// next request gets triggered.
r->backoff_.Reset();

@ -69,11 +69,14 @@ class FakeResolver : public Resolver {
// passed-in parameters
grpc_channel_args* channel_args_ = nullptr;
// If not NULL, the next set of resolution results to be returned.
grpc_channel_args* next_results_ = nullptr;
// Results to use for the pretended re-resolution in
// If has_next_result_ is true, next_result_ is the next resolution result
// to be returned.
bool has_next_result_ = false;
Result next_result_;
// Result to use for the pretended re-resolution in
// RequestReresolutionLocked().
grpc_channel_args* reresolution_results_ = nullptr;
bool has_reresolution_result_ = false;
Result reresolution_result_;
// True between the calls to StartLocked() ShutdownLocked().
bool active_ = false;
// if true, return failure
@ -92,19 +95,14 @@ FakeResolver::FakeResolver(ResolverArgs args)
FakeResolverResponseGenerator::GetFromArgs(args.args);
if (response_generator != nullptr) {
response_generator->resolver_ = this;
if (response_generator->response_ != nullptr) {
response_generator->SetResponse(response_generator->response_);
grpc_channel_args_destroy(response_generator->response_);
response_generator->response_ = nullptr;
if (response_generator->has_result_) {
response_generator->SetResponse(std::move(response_generator->result_));
response_generator->has_result_ = false;
}
}
}
FakeResolver::~FakeResolver() {
grpc_channel_args_destroy(next_results_);
grpc_channel_args_destroy(reresolution_results_);
grpc_channel_args_destroy(channel_args_);
}
FakeResolver::~FakeResolver() { grpc_channel_args_destroy(channel_args_); }
void FakeResolver::StartLocked() {
active_ = true;
@ -112,9 +110,9 @@ void FakeResolver::StartLocked() {
}
void FakeResolver::RequestReresolutionLocked() {
if (reresolution_results_ != nullptr || return_failure_) {
grpc_channel_args_destroy(next_results_);
next_results_ = grpc_channel_args_copy(reresolution_results_);
if (has_reresolution_result_ || return_failure_) {
next_result_ = reresolution_result_;
has_next_result_ = true;
// Return the result in a different closure, so that we don't call
// back into the LB policy while it's still processing the previous
// update.
@ -135,14 +133,19 @@ void FakeResolver::MaybeSendResultLocked() {
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Resolver transient failure"),
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE));
return_failure_ = false;
} else if (next_results_ != nullptr) {
} else if (has_next_result_) {
Result result;
result.addresses = std::move(next_result_.addresses);
result.service_config = std::move(next_result_.service_config);
// TODO(roth): Use std::move() once grpc_error is converted to C++.
result.service_config_error = next_result_.service_config_error;
next_result_.service_config_error = GRPC_ERROR_NONE;
// When both next_results_ and channel_args_ contain an arg with the same
// name, only the one in next_results_ will be kept since next_results_ is
// before channel_args_.
result_handler()->ReturnResult(
grpc_channel_args_union(next_results_, channel_args_));
grpc_channel_args_destroy(next_results_);
next_results_ = nullptr;
result.args = grpc_channel_args_union(next_result_.args, channel_args_);
result_handler()->ReturnResult(std::move(result));
has_next_result_ = false;
}
}
@ -160,7 +163,8 @@ void FakeResolver::ReturnReresolutionResult(void* arg, grpc_error* error) {
struct SetResponseClosureArg {
grpc_closure set_response_closure;
FakeResolverResponseGenerator* generator;
grpc_channel_args* response;
Resolver::Result result;
bool has_result = false;
bool immediate = true;
};
@ -168,26 +172,26 @@ void FakeResolverResponseGenerator::SetResponseLocked(void* arg,
grpc_error* error) {
SetResponseClosureArg* closure_arg = static_cast<SetResponseClosureArg*>(arg);
FakeResolver* resolver = closure_arg->generator->resolver_;
grpc_channel_args_destroy(resolver->next_results_);
resolver->next_results_ = closure_arg->response;
resolver->next_result_ = std::move(closure_arg->result);
resolver->has_next_result_ = true;
resolver->MaybeSendResultLocked();
Delete(closure_arg);
}
void FakeResolverResponseGenerator::SetResponse(grpc_channel_args* response) {
GPR_ASSERT(response != nullptr);
void FakeResolverResponseGenerator::SetResponse(Resolver::Result result) {
if (resolver_ != nullptr) {
SetResponseClosureArg* closure_arg = New<SetResponseClosureArg>();
closure_arg->generator = this;
closure_arg->response = grpc_channel_args_copy(response);
closure_arg->result = std::move(result);
GRPC_CLOSURE_SCHED(
GRPC_CLOSURE_INIT(&closure_arg->set_response_closure, SetResponseLocked,
closure_arg,
grpc_combiner_scheduler(resolver_->combiner())),
GRPC_ERROR_NONE);
} else {
GPR_ASSERT(response_ == nullptr);
response_ = grpc_channel_args_copy(response);
GPR_ASSERT(!has_result_);
has_result_ = true;
result_ = std::move(result);
}
}
@ -195,18 +199,29 @@ void FakeResolverResponseGenerator::SetReresolutionResponseLocked(
void* arg, grpc_error* error) {
SetResponseClosureArg* closure_arg = static_cast<SetResponseClosureArg*>(arg);
FakeResolver* resolver = closure_arg->generator->resolver_;
grpc_channel_args_destroy(resolver->reresolution_results_);
resolver->reresolution_results_ = closure_arg->response;
resolver->reresolution_result_ = std::move(closure_arg->result);
resolver->has_reresolution_result_ = closure_arg->has_result;
Delete(closure_arg);
}
void FakeResolverResponseGenerator::SetReresolutionResponse(
grpc_channel_args* response) {
Resolver::Result result) {
GPR_ASSERT(resolver_ != nullptr);
SetResponseClosureArg* closure_arg = New<SetResponseClosureArg>();
closure_arg->generator = this;
closure_arg->result = std::move(result);
closure_arg->has_result = true;
GRPC_CLOSURE_SCHED(
GRPC_CLOSURE_INIT(&closure_arg->set_response_closure,
SetReresolutionResponseLocked, closure_arg,
grpc_combiner_scheduler(resolver_->combiner())),
GRPC_ERROR_NONE);
}
void FakeResolverResponseGenerator::UnsetReresolutionResponse() {
GPR_ASSERT(resolver_ != nullptr);
SetResponseClosureArg* closure_arg = New<SetResponseClosureArg>();
closure_arg->generator = this;
closure_arg->response =
response != nullptr ? grpc_channel_args_copy(response) : nullptr;
GRPC_CLOSURE_SCHED(
GRPC_CLOSURE_INIT(&closure_arg->set_response_closure,
SetReresolutionResponseLocked, closure_arg,

@ -19,6 +19,7 @@
#include <grpc/support/port_platform.h>
#include "src/core/ext/filters/client_channel/resolver.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gprpp/ref_counted.h"
#include "src/core/lib/iomgr/error.h"
@ -44,19 +45,20 @@ class FakeResolverResponseGenerator
FakeResolverResponseGenerator() {}
// Instructs the fake resolver associated with the response generator
// instance to trigger a new resolution with the specified response. If the
// instance to trigger a new resolution with the specified result. If the
// resolver is not available yet, delays response setting until it is. This
// can be called at most once before the resolver is available.
void SetResponse(grpc_channel_args* next_response);
void SetResponse(Resolver::Result result);
// Sets the re-resolution response, which is returned by the fake resolver
// when re-resolution is requested (via \a RequestReresolutionLocked()).
// The new re-resolution response replaces any previous re-resolution
// response that may have been set by a previous call.
// If the re-resolution response is set to NULL, then the fake
// resolver will not return anything when \a RequestReresolutionLocked()
// is called.
void SetReresolutionResponse(grpc_channel_args* response);
void SetReresolutionResponse(Resolver::Result result);
// Unsets the re-resolution response. After this, the fake resolver will
// not return anything when \a RequestReresolutionLocked() is called.
void UnsetReresolutionResponse();
// Tells the resolver to return a transient failure.
void SetFailure();
@ -80,7 +82,8 @@ class FakeResolverResponseGenerator
static void SetFailureLocked(void* arg, grpc_error* error);
FakeResolver* resolver_ = nullptr; // Do not own.
grpc_channel_args* response_ = nullptr;
Resolver::Result result_;
bool has_result_ = false;
};
} // namespace grpc_core

@ -44,8 +44,7 @@ namespace {
class SockaddrResolver : public Resolver {
public:
/// Takes ownership of \a addresses.
explicit SockaddrResolver(ResolverArgs args);
SockaddrResolver(ServerAddressList addresses, ResolverArgs args);
~SockaddrResolver() override;
void StartLocked() override;
@ -53,21 +52,27 @@ class SockaddrResolver : public Resolver {
void ShutdownLocked() override {}
private:
/// channel args
ServerAddressList addresses_;
const grpc_channel_args* channel_args_ = nullptr;
};
SockaddrResolver::SockaddrResolver(ResolverArgs args)
SockaddrResolver::SockaddrResolver(ServerAddressList addresses,
ResolverArgs args)
: Resolver(args.combiner, std::move(args.result_handler)),
channel_args_(args.args) {}
addresses_(std::move(addresses)),
channel_args_(grpc_channel_args_copy(args.args)) {}
SockaddrResolver::~SockaddrResolver() {
grpc_channel_args_destroy(channel_args_);
}
void SockaddrResolver::StartLocked() {
result_handler()->ReturnResult(channel_args_);
Result result;
result.addresses = std::move(addresses_);
// TODO(roth): Use std::move() once channel args is converted to C++.
result.args = channel_args_;
channel_args_ = nullptr;
result_handler()->ReturnResult(std::move(result));
}
//
@ -82,7 +87,7 @@ OrphanablePtr<Resolver> CreateSockaddrResolver(
if (0 != strcmp(args.uri->authority, "")) {
gpr_log(GPR_ERROR, "authority-based URIs not supported by the %s scheme",
args.uri->scheme);
return OrphanablePtr<Resolver>(nullptr);
return nullptr;
}
// Construct addresses.
grpc_slice path_slice =
@ -108,12 +113,9 @@ OrphanablePtr<Resolver> CreateSockaddrResolver(
if (errors_found) {
return OrphanablePtr<Resolver>(nullptr);
}
// Add addresses to channel args.
// Note: SockaddrResolver takes ownership of channel args.
grpc_arg arg = CreateServerAddressListChannelArg(&addresses);
args.args = grpc_channel_args_copy_and_add(args.args, &arg, 1);
// Instantiate resolver.
return OrphanablePtr<Resolver>(New<SockaddrResolver>(std::move(args)));
return OrphanablePtr<Resolver>(
New<SockaddrResolver>(std::move(addresses), std::move(args)));
}
class IPv4ResolverFactory : public ResolverFactory {

@ -62,6 +62,7 @@ class ResolverRegistry {
/// \a args are the channel args to be included in resolver results.
/// \a pollset_set is used to drive I/O in the name resolution process.
/// \a combiner is the combiner under which all resolver calls will be run.
/// \a result_handler is used to return results from the resolver.
static OrphanablePtr<Resolver> CreateResolver(
const char* target, const grpc_channel_args* args,
grpc_pollset_set* pollset_set, grpc_combiner* combiner,

@ -31,6 +31,7 @@
#include "src/core/ext/filters/client_channel/client_channel.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/lib/channel/channel_args.h"
#include "src/core/lib/channel/status_util.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/memory.h"
@ -43,42 +44,64 @@ namespace grpc_core {
namespace internal {
ProcessedResolverResult::ProcessedResolverResult(
const grpc_channel_args& resolver_result, bool parse_retry) {
ProcessServiceConfig(resolver_result, parse_retry);
Resolver::Result* resolver_result, bool parse_retry)
: service_config_(resolver_result->service_config) {
// If resolver did not return a service config, use the default
// specified via the client API.
if (service_config_ == nullptr) {
const char* service_config_json = grpc_channel_arg_get_string(
grpc_channel_args_find(resolver_result->args, GRPC_ARG_SERVICE_CONFIG));
if (service_config_json != nullptr) {
service_config_ = ServiceConfig::Create(service_config_json);
}
} else {
// Add the service config JSON to channel args so that it's
// accessible in the subchannel.
// TODO(roth): Consider whether there's a better way to pass the
// service config down into the subchannel stack, such as maybe via
// call context or metadata. This would avoid the problem of having
// to recreate all subchannels whenever the service config changes.
// It would also avoid the need to pass in the resolver result in
// mutable form, both here and in
// ResolvingLoadBalancingPolicy::ProcessResolverResultCallback().
grpc_arg arg = grpc_channel_arg_string_create(
const_cast<char*>(GRPC_ARG_SERVICE_CONFIG),
const_cast<char*>(service_config_->service_config_json()));
grpc_channel_args* new_args =
grpc_channel_args_copy_and_add(resolver_result->args, &arg, 1);
grpc_channel_args_destroy(resolver_result->args);
resolver_result->args = new_args;
}
// Process service config.
ProcessServiceConfig(*resolver_result, parse_retry);
// If no LB config was found above, just find the LB policy name then.
if (lb_policy_name_ == nullptr) ProcessLbPolicyName(resolver_result);
if (lb_policy_name_ == nullptr) ProcessLbPolicyName(*resolver_result);
}
void ProcessedResolverResult::ProcessServiceConfig(
const grpc_channel_args& resolver_result, bool parse_retry) {
const grpc_arg* channel_arg =
grpc_channel_args_find(&resolver_result, GRPC_ARG_SERVICE_CONFIG);
const char* service_config_json = grpc_channel_arg_get_string(channel_arg);
if (service_config_json != nullptr) {
service_config_json_.reset(gpr_strdup(service_config_json));
service_config_ = grpc_core::ServiceConfig::Create(service_config_json);
if (service_config_ != nullptr) {
if (parse_retry) {
channel_arg =
grpc_channel_args_find(&resolver_result, GRPC_ARG_SERVER_URI);
const char* server_uri = grpc_channel_arg_get_string(channel_arg);
GPR_ASSERT(server_uri != nullptr);
grpc_uri* uri = grpc_uri_parse(server_uri, true);
GPR_ASSERT(uri->path[0] != '\0');
server_name_ = uri->path[0] == '/' ? uri->path + 1 : uri->path;
service_config_->ParseGlobalParams(ParseServiceConfig, this);
grpc_uri_destroy(uri);
} else {
service_config_->ParseGlobalParams(ParseServiceConfig, this);
}
method_params_table_ = service_config_->CreateMethodConfigTable(
ClientChannelMethodParams::CreateFromJson);
}
const Resolver::Result& resolver_result, bool parse_retry) {
if (service_config_ == nullptr) return;
service_config_json_ =
UniquePtr<char>(gpr_strdup(service_config_->service_config_json()));
if (parse_retry) {
const grpc_arg* channel_arg =
grpc_channel_args_find(resolver_result.args, GRPC_ARG_SERVER_URI);
const char* server_uri = grpc_channel_arg_get_string(channel_arg);
GPR_ASSERT(server_uri != nullptr);
grpc_uri* uri = grpc_uri_parse(server_uri, true);
GPR_ASSERT(uri->path[0] != '\0');
server_name_ = uri->path[0] == '/' ? uri->path + 1 : uri->path;
service_config_->ParseGlobalParams(ParseServiceConfig, this);
grpc_uri_destroy(uri);
} else {
service_config_->ParseGlobalParams(ParseServiceConfig, this);
}
method_params_table_ = service_config_->CreateMethodConfigTable(
ClientChannelMethodParams::CreateFromJson);
}
void ProcessedResolverResult::ProcessLbPolicyName(
const grpc_channel_args& resolver_result) {
const Resolver::Result& resolver_result) {
// Prefer the LB policy name found in the service config. Note that this is
// checking the deprecated loadBalancingPolicy field, rather than the new
// loadBalancingConfig field.
@ -96,32 +119,28 @@ void ProcessedResolverResult::ProcessLbPolicyName(
// Otherwise, find the LB policy name set by the client API.
if (lb_policy_name_ == nullptr) {
const grpc_arg* channel_arg =
grpc_channel_args_find(&resolver_result, GRPC_ARG_LB_POLICY_NAME);
grpc_channel_args_find(resolver_result.args, GRPC_ARG_LB_POLICY_NAME);
lb_policy_name_.reset(gpr_strdup(grpc_channel_arg_get_string(channel_arg)));
}
// Special case: If at least one balancer address is present, we use
// the grpclb policy, regardless of what the resolver has returned.
const ServerAddressList* addresses =
FindServerAddressListChannelArg(&resolver_result);
if (addresses != nullptr) {
bool found_balancer_address = false;
for (size_t i = 0; i < addresses->size(); ++i) {
const ServerAddress& address = (*addresses)[i];
if (address.IsBalancer()) {
found_balancer_address = true;
break;
}
bool found_balancer_address = false;
for (size_t i = 0; i < resolver_result.addresses.size(); ++i) {
const ServerAddress& address = resolver_result.addresses[i];
if (address.IsBalancer()) {
found_balancer_address = true;
break;
}
if (found_balancer_address) {
if (lb_policy_name_ != nullptr &&
strcmp(lb_policy_name_.get(), "grpclb") != 0) {
gpr_log(GPR_INFO,
"resolver requested LB policy %s but provided at least one "
"balancer address -- forcing use of grpclb LB policy",
lb_policy_name_.get());
}
lb_policy_name_.reset(gpr_strdup("grpclb"));
}
if (found_balancer_address) {
if (lb_policy_name_ != nullptr &&
strcmp(lb_policy_name_.get(), "grpclb") != 0) {
gpr_log(GPR_INFO,
"resolver requested LB policy %s but provided at least one "
"balancer address -- forcing use of grpclb LB policy",
lb_policy_name_.get());
}
lb_policy_name_.reset(gpr_strdup("grpclb"));
}
// Use pick_first if nothing was specified and we didn't select grpclb
// above.

@ -22,14 +22,15 @@
#include <grpc/support/port_platform.h>
#include "src/core/ext/filters/client_channel/lb_policy.h"
#include "src/core/ext/filters/client_channel/resolver.h"
#include "src/core/ext/filters/client_channel/retry_throttle.h"
#include "src/core/ext/filters/client_channel/service_config.h"
#include "src/core/lib/channel/status_util.h"
#include "src/core/lib/gprpp/ref_counted.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/iomgr/exec_ctx.h" // for grpc_millis
#include "src/core/lib/json/json.h"
#include "src/core/lib/slice/slice_hash_table.h"
#include "src/core/lib/transport/service_config.h"
namespace grpc_core {
namespace internal {
@ -47,8 +48,7 @@ class ProcessedResolverResult {
// Processes the resolver result and populates the relative members
// for later consumption. Tries to parse retry parameters only if parse_retry
// is true.
ProcessedResolverResult(const grpc_channel_args& resolver_result,
bool parse_retry);
ProcessedResolverResult(Resolver::Result* resolver_result, bool parse_retry);
// Getters. Any managed object's ownership is transferred.
UniquePtr<char> service_config_json() {
@ -68,11 +68,11 @@ class ProcessedResolverResult {
private:
// Finds the service config; extracts LB config and (maybe) retry throttle
// params from it.
void ProcessServiceConfig(const grpc_channel_args& resolver_result,
void ProcessServiceConfig(const Resolver::Result& resolver_result,
bool parse_retry);
// Finds the LB policy name (when no LB config was found).
void ProcessLbPolicyName(const grpc_channel_args& resolver_result);
void ProcessLbPolicyName(const Resolver::Result& resolver_result);
// Parses the service config. Intended to be used by
// ServiceConfig::ParseGlobalParams.

@ -38,6 +38,7 @@
#include "src/core/ext/filters/client_channel/resolver_registry.h"
#include "src/core/ext/filters/client_channel/retry_throttle.h"
#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.h"
#include "src/core/ext/filters/deadline/deadline_filter.h"
#include "src/core/lib/backoff/backoff.h"
@ -59,7 +60,6 @@
#include "src/core/lib/transport/error_utils.h"
#include "src/core/lib/transport/metadata.h"
#include "src/core/lib/transport/metadata_batch.h"
#include "src/core/lib/transport/service_config.h"
#include "src/core/lib/transport/static_metadata.h"
#include "src/core/lib/transport/status_metadata.h"
@ -83,8 +83,8 @@ class ResolvingLoadBalancingPolicy::ResolverResultHandler
}
}
void ReturnResult(const grpc_channel_args* result) override {
parent_->OnResolverResultChangedLocked(result);
void ReturnResult(Resolver::Result result) override {
parent_->OnResolverResultChangedLocked(std::move(result));
}
void ReturnError(grpc_error* error) override {
@ -342,7 +342,7 @@ void ResolvingLoadBalancingPolicy::OnResolverError(grpc_error* error) {
void ResolvingLoadBalancingPolicy::CreateOrUpdateLbPolicyLocked(
const char* lb_policy_name, RefCountedPtr<Config> lb_policy_config,
const grpc_channel_args& args, TraceStringVector* trace_strings) {
Resolver::Result result, TraceStringVector* trace_strings) {
// If the child policy name changes, we need to create a new child
// policy. When this happens, we leave child_policy_ as-is and store
// the new child policy in pending_child_policy_. Once the new child
@ -410,7 +410,8 @@ void ResolvingLoadBalancingPolicy::CreateOrUpdateLbPolicyLocked(
gpr_log(GPR_INFO, "resolving_lb=%p: Creating new %schild policy %s", this,
lb_policy_ == nullptr ? "" : "pending ", lb_policy_name);
}
auto new_policy = CreateLbPolicyLocked(lb_policy_name, args, trace_strings);
auto new_policy =
CreateLbPolicyLocked(lb_policy_name, *result.args, trace_strings);
auto& lb_policy = lb_policy_ == nullptr ? lb_policy_ : pending_lb_policy_;
{
MutexLock lock(&lb_policy_mu_);
@ -431,7 +432,13 @@ void ResolvingLoadBalancingPolicy::CreateOrUpdateLbPolicyLocked(
policy_to_update == pending_lb_policy_.get() ? "pending " : "",
policy_to_update);
}
policy_to_update->UpdateLocked(args, std::move(lb_policy_config));
UpdateArgs update_args;
update_args.addresses = std::move(result.addresses);
update_args.config = std::move(lb_policy_config);
// TODO(roth): Once channel args is converted to C++, use std::move() here.
update_args.args = result.args;
result.args = nullptr;
policy_to_update->UpdateLocked(std::move(update_args));
}
// Creates a new LB policy.
@ -479,12 +486,7 @@ ResolvingLoadBalancingPolicy::CreateLbPolicyLocked(
}
void ResolvingLoadBalancingPolicy::MaybeAddTraceMessagesForAddressChangesLocked(
const grpc_channel_args& resolver_result,
TraceStringVector* trace_strings) {
const ServerAddressList* addresses =
FindServerAddressListChannelArg(&resolver_result);
const bool resolution_contains_addresses =
addresses != nullptr && addresses->size() > 0;
bool resolution_contains_addresses, TraceStringVector* trace_strings) {
if (!resolution_contains_addresses &&
previous_resolution_contained_addresses_) {
trace_strings->push_back(gpr_strdup("Address list became empty"));
@ -517,14 +519,11 @@ void ResolvingLoadBalancingPolicy::ConcatenateAndAddChannelTraceLocked(
}
void ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked(
const grpc_channel_args* result) {
Resolver::Result result) {
// Handle race conditions.
if (resolver_ == nullptr) {
grpc_channel_args_destroy(result);
return;
}
if (resolver_ == nullptr) return;
if (tracer_->enabled()) {
gpr_log(GPR_INFO, "resolving_lb=%p: got resolver result %p", this, result);
gpr_log(GPR_INFO, "resolving_lb=%p: got resolver result", this);
}
// We only want to trace the address resolution in the follow cases:
// (a) Address resolution resulted in service config change.
@ -534,15 +533,16 @@ void ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked(
// non-zero to zero.
// (d) Address resolution that causes a new LB policy to be created.
//
// we track a list of strings to eventually be concatenated and traced.
// We track a list of strings to eventually be concatenated and traced.
TraceStringVector trace_strings;
// Parse the resolver result.
const bool resolution_contains_addresses = result.addresses.size() > 0;
// Process the resolver result.
const char* lb_policy_name = nullptr;
RefCountedPtr<Config> lb_policy_config;
bool service_config_changed = false;
if (process_resolver_result_ != nullptr) {
service_config_changed =
process_resolver_result_(process_resolver_result_user_data_, *result,
process_resolver_result_(process_resolver_result_user_data_, &result,
&lb_policy_name, &lb_policy_config);
} else {
lb_policy_name = child_policy_name_.get();
@ -551,7 +551,7 @@ void ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked(
GPR_ASSERT(lb_policy_name != nullptr);
// Create or update LB policy, as needed.
CreateOrUpdateLbPolicyLocked(lb_policy_name, std::move(lb_policy_config),
*result, &trace_strings);
std::move(result), &trace_strings);
// Add channel trace event.
if (channelz_node() != nullptr) {
if (service_config_changed) {
@ -559,11 +559,10 @@ void ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked(
// config in the trace, at the risk of bloating the trace logs.
trace_strings.push_back(gpr_strdup("Service config changed"));
}
MaybeAddTraceMessagesForAddressChangesLocked(*result, &trace_strings);
MaybeAddTraceMessagesForAddressChangesLocked(resolution_contains_addresses,
&trace_strings);
ConcatenateAndAddChannelTraceLocked(&trace_strings);
}
// Clean up.
grpc_channel_args_destroy(result);
}
} // namespace grpc_core

@ -65,8 +65,8 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy {
// lb_policy_name and lb_policy_config to point to the right data.
// Returns true if the service config has changed since the last result.
typedef bool (*ProcessResolverResultCallback)(
void* user_data, const grpc_channel_args& args,
const char** lb_policy_name, RefCountedPtr<Config>* lb_policy_config);
void* user_data, Resolver::Result* result, const char** lb_policy_name,
RefCountedPtr<Config>* lb_policy_config);
// If error is set when this returns, then construction failed, and
// the caller may not use the new object.
ResolvingLoadBalancingPolicy(
@ -79,8 +79,7 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy {
// No-op -- should never get updates from the channel.
// TODO(roth): Need to support updating child LB policy's config for xds
// use case.
void UpdateLocked(const grpc_channel_args& args,
RefCountedPtr<Config> lb_config) override {}
void UpdateLocked(UpdateArgs args) override {}
void ExitIdleLocked() override;
@ -105,17 +104,16 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy {
void OnResolverError(grpc_error* error);
void CreateOrUpdateLbPolicyLocked(const char* lb_policy_name,
RefCountedPtr<Config> lb_policy_config,
const grpc_channel_args& args,
Resolver::Result result,
TraceStringVector* trace_strings);
OrphanablePtr<LoadBalancingPolicy> CreateLbPolicyLocked(
const char* lb_policy_name, const grpc_channel_args& args,
TraceStringVector* trace_strings);
void MaybeAddTraceMessagesForAddressChangesLocked(
const grpc_channel_args& resolver_result,
TraceStringVector* trace_strings);
bool resolution_contains_addresses, TraceStringVector* trace_strings);
void ConcatenateAndAddChannelTraceLocked(
TraceStringVector* trace_strings) const;
void OnResolverResultChangedLocked(const grpc_channel_args* result);
void OnResolverResultChangedLocked(Resolver::Result result);
// Passed in from caller at construction time.
TraceFlag* tracer_;

@ -52,52 +52,4 @@ bool ServerAddress::IsBalancer() const {
grpc_channel_args_find(args_, GRPC_ARG_ADDRESS_IS_BALANCER), false);
}
//
// ServerAddressList
//
namespace {
void* ServerAddressListCopy(void* addresses) {
ServerAddressList* a = static_cast<ServerAddressList*>(addresses);
return New<ServerAddressList>(*a);
}
void ServerAddressListDestroy(void* addresses) {
ServerAddressList* a = static_cast<ServerAddressList*>(addresses);
Delete(a);
}
int ServerAddressListCompare(void* addresses1, void* addresses2) {
ServerAddressList* a1 = static_cast<ServerAddressList*>(addresses1);
ServerAddressList* a2 = static_cast<ServerAddressList*>(addresses2);
if (a1->size() > a2->size()) return 1;
if (a1->size() < a2->size()) return -1;
for (size_t i = 0; i < a1->size(); ++i) {
int retval = (*a1)[i].Cmp((*a2)[i]);
if (retval != 0) return retval;
}
return 0;
}
const grpc_arg_pointer_vtable server_addresses_arg_vtable = {
ServerAddressListCopy, ServerAddressListDestroy, ServerAddressListCompare};
} // namespace
grpc_arg CreateServerAddressListChannelArg(const ServerAddressList* addresses) {
return grpc_channel_arg_pointer_create(
const_cast<char*>(GRPC_ARG_SERVER_ADDRESS_LIST),
const_cast<ServerAddressList*>(addresses), &server_addresses_arg_vtable);
}
ServerAddressList* FindServerAddressListChannelArg(
const grpc_channel_args* channel_args) {
const grpc_arg* lb_addresses_arg =
grpc_channel_args_find(channel_args, GRPC_ARG_SERVER_ADDRESS_LIST);
if (lb_addresses_arg == nullptr || lb_addresses_arg->type != GRPC_ARG_POINTER)
return nullptr;
return static_cast<ServerAddressList*>(lb_addresses_arg->value.pointer.p);
}
} // namespace grpc_core

@ -26,9 +26,6 @@
#include "src/core/lib/iomgr/resolve_address.h"
#include "src/core/lib/uri/uri_parser.h"
// Channel arg key for ServerAddressList.
#define GRPC_ARG_SERVER_ADDRESS_LIST "grpc.server_address_list"
// Channel arg key for a bool indicating whether an address is a grpclb
// load balancer (as opposed to a backend).
#define GRPC_ARG_ADDRESS_IS_BALANCER "grpc.address_is_balancer"
@ -96,13 +93,6 @@ class ServerAddress {
typedef InlinedVector<ServerAddress, 1> ServerAddressList;
// Returns a channel arg containing \a addresses.
grpc_arg CreateServerAddressListChannelArg(const ServerAddressList* addresses);
// Returns the ServerListAddress instance in channel_args or NULL.
ServerAddressList* FindServerAddressListChannelArg(
const grpc_channel_args* channel_args);
} // namespace grpc_core
#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SERVER_ADDRESS_H */

@ -16,7 +16,7 @@
#include <grpc/support/port_platform.h>
#include "src/core/lib/transport/service_config.h"
#include "src/core/ext/filters/client_channel/service_config.h"
#include <string.h>
@ -34,17 +34,22 @@
namespace grpc_core {
RefCountedPtr<ServiceConfig> ServiceConfig::Create(const char* json) {
UniquePtr<char> service_config_json(gpr_strdup(json));
UniquePtr<char> json_string(gpr_strdup(json));
grpc_json* json_tree = grpc_json_parse_string(json_string.get());
if (json_tree == nullptr) {
gpr_log(GPR_INFO, "failed to parse JSON for service config");
return nullptr;
}
return MakeRefCounted<ServiceConfig>(std::move(json_string), json_tree);
return MakeRefCounted<ServiceConfig>(std::move(service_config_json),
std::move(json_string), json_tree);
}
ServiceConfig::ServiceConfig(UniquePtr<char> json_string, grpc_json* json_tree)
: json_string_(std::move(json_string)), json_tree_(json_tree) {}
ServiceConfig::ServiceConfig(UniquePtr<char> service_config_json,
UniquePtr<char> json_string, grpc_json* json_tree)
: service_config_json_(std::move(service_config_json)),
json_string_(std::move(json_string)),
json_tree_(json_tree) {}
ServiceConfig::~ServiceConfig() { grpc_json_destroy(json_tree_); }

@ -14,8 +14,8 @@
// limitations under the License.
//
#ifndef GRPC_CORE_LIB_TRANSPORT_SERVICE_CONFIG_H
#define GRPC_CORE_LIB_TRANSPORT_SERVICE_CONFIG_H
#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SERVICE_CONFIG_H
#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SERVICE_CONFIG_H
#include <grpc/support/port_platform.h>
@ -62,6 +62,8 @@ class ServiceConfig : public RefCounted<ServiceConfig> {
~ServiceConfig();
const char* service_config_json() const { return service_config_json_.get(); }
/// Invokes \a process_json() for each global parameter in the service
/// config. \a arg is passed as the second argument to \a process_json().
template <typename T>
@ -82,7 +84,7 @@ class ServiceConfig : public RefCounted<ServiceConfig> {
using CreateValue = RefCountedPtr<T> (*)(const grpc_json* method_config_json);
template <typename T>
RefCountedPtr<SliceHashTable<RefCountedPtr<T>>> CreateMethodConfigTable(
CreateValue<T> create_value);
CreateValue<T> create_value) const;
/// A helper function for looking up values in the table returned by
/// \a CreateMethodConfigTable().
@ -100,7 +102,8 @@ class ServiceConfig : public RefCounted<ServiceConfig> {
friend T* New(Args&&... args);
// Takes ownership of \a json_tree.
ServiceConfig(UniquePtr<char> json_string, grpc_json* json_tree);
ServiceConfig(UniquePtr<char> service_config_json,
UniquePtr<char> json_string, grpc_json* json_tree);
// Returns the number of names specified in the method config \a json.
static int CountNamesInMethodConfig(grpc_json* json);
@ -117,6 +120,7 @@ class ServiceConfig : public RefCounted<ServiceConfig> {
grpc_json* json, CreateValue<T> create_value,
typename SliceHashTable<RefCountedPtr<T>>::Entry* entries, size_t* idx);
UniquePtr<char> service_config_json_;
UniquePtr<char> json_string_; // Underlying storage for json_tree.
grpc_json* json_tree_;
};
@ -172,7 +176,7 @@ bool ServiceConfig::ParseJsonMethodConfig(
template <typename T>
RefCountedPtr<SliceHashTable<RefCountedPtr<T>>>
ServiceConfig::CreateMethodConfigTable(CreateValue<T> create_value) {
ServiceConfig::CreateMethodConfigTable(CreateValue<T> create_value) const {
// Traverse parsed JSON tree.
if (json_tree_->type != GRPC_JSON_OBJECT || json_tree_->key != nullptr) {
return nullptr;
@ -247,4 +251,4 @@ RefCountedPtr<T> ServiceConfig::MethodConfigTableLookup(
} // namespace grpc_core
#endif /* GRPC_CORE_LIB_TRANSPORT_SERVICE_CONFIG_H */
#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SERVICE_CONFIG_H */

@ -33,6 +33,7 @@
#include "src/core/ext/filters/client_channel/health/health_check_client.h"
#include "src/core/ext/filters/client_channel/parse_address.h"
#include "src/core/ext/filters/client_channel/proxy_mapper_registry.h"
#include "src/core/ext/filters/client_channel/service_config.h"
#include "src/core/ext/filters/client_channel/subchannel_pool_interface.h"
#include "src/core/lib/backoff/backoff.h"
#include "src/core/lib/channel/channel_args.h"
@ -50,7 +51,6 @@
#include "src/core/lib/surface/channel_init.h"
#include "src/core/lib/transport/connectivity_state.h"
#include "src/core/lib/transport/error_utils.h"
#include "src/core/lib/transport/service_config.h"
#include "src/core/lib/transport/status_metadata.h"
#include "src/core/lib/uri/uri_parser.h"

@ -26,13 +26,13 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include "src/core/ext/filters/client_channel/service_config.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/channel_stack_builder.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/ref_counted.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/surface/channel_init.h"
#include "src/core/lib/transport/service_config.h"
typedef struct {
int max_send_size;

@ -1268,7 +1268,9 @@ void grpc_chttp2_complete_closure_step(grpc_chttp2_transport* t,
if (closure->next_data.scratch < CLOSURE_BARRIER_FIRST_REF_BIT) {
if ((t->write_state == GRPC_CHTTP2_WRITE_STATE_IDLE) ||
!(closure->next_data.scratch & CLOSURE_BARRIER_MAY_COVER_WRITE)) {
GRPC_CLOSURE_RUN(closure, closure->error_data.error);
// Using GRPC_CLOSURE_SCHED instead of GRPC_CLOSURE_RUN to avoid running
// closures earlier than when it is safe to do so.
GRPC_CLOSURE_SCHED(closure, closure->error_data.error);
} else {
grpc_closure_list_append(&t->run_after_write, closure,
closure->error_data.error);

@ -118,6 +118,8 @@ grpc_channel_args* grpc_channel_args_copy(const grpc_channel_args* src) {
grpc_channel_args* grpc_channel_args_union(const grpc_channel_args* a,
const grpc_channel_args* b) {
if (a == nullptr) return grpc_channel_args_copy(b);
if (b == nullptr) return grpc_channel_args_copy(a);
const size_t max_out = (a->num_args + b->num_args);
grpc_arg* uniques =
static_cast<grpc_arg*>(gpr_malloc(sizeof(*uniques) * max_out));

@ -624,8 +624,9 @@ static int verify_jwt_signature(EVP_PKEY* key, const char* alg,
gpr_log(GPR_ERROR, "EVP_DigestVerifyUpdate failed.");
goto end;
}
if (EVP_DigestVerifyFinal(md_ctx, GRPC_SLICE_START_PTR(signature),
GRPC_SLICE_LENGTH(signature)) != 1) {
if (EVP_DigestVerifyFinal(
md_ctx, const_cast<uint8_t*>(GRPC_SLICE_START_PTR(signature)),
GRPC_SLICE_LENGTH(signature)) != 1) {
gpr_log(GPR_ERROR, "JWT signature verification failed.");
goto end;
}

@ -111,10 +111,11 @@ void grpc_transport_move_stats(grpc_transport_stream_stats* from,
// currently handling the batch). Once a filter or transport passes control
// of the batch to the next handler, it cannot depend on the contents of
// this struct anymore, because the next handler may reuse it.
typedef struct {
void* extra_arg;
struct grpc_handler_private_op_data {
void* extra_arg = nullptr;
grpc_closure closure;
} grpc_handler_private_op_data;
grpc_handler_private_op_data() { memset(&closure, 0, sizeof(closure)); }
};
typedef struct grpc_transport_stream_op_batch_payload
grpc_transport_stream_op_batch_payload;

@ -39,7 +39,7 @@ namespace Grpc.Core
/// </summary>
/// <param name="peerIdentityPropertyName">Peer identity property name.</param>
/// <param name="properties">Multimap of auth properties by name.</param>
internal AuthContext(string peerIdentityPropertyName, Dictionary<string, List<AuthProperty>> properties)
public AuthContext(string peerIdentityPropertyName, Dictionary<string, List<AuthProperty>> properties)
{
this.peerIdentityPropertyName = peerIdentityPropertyName;
this.properties = GrpcPreconditions.CheckNotNull(properties);

@ -0,0 +1,7 @@
<!-- This file is generated -->
<Project>
<PropertyGroup>
<GrpcCsharpVersion>1.19.1</GrpcCsharpVersion>
<GoogleProtobufVersion>3.6.1</GoogleProtobufVersion>
</PropertyGroup>
</Project>

@ -16,6 +16,8 @@
#endregion
using System.Collections.Generic;
using System.Linq;
using System.Reflection; // UWYU: Object.GetType() extension.
using Microsoft.Build.Framework;
using Moq;
@ -30,6 +32,7 @@ namespace Grpc.Tools.Tests
{
public string LastPathToTool { get; private set; }
public string[] LastResponseFile { get; private set; }
public List<string> StdErrMessages { get; } = new List<string>();
protected override int ExecuteTool(string pathToTool,
string response,
@ -45,8 +48,13 @@ namespace Grpc.Tools.Tests
LastPathToTool = pathToTool;
LastResponseFile = response.Remove(response.Length - 1).Split('\n');
foreach (string message in StdErrMessages)
{
LogEventsFromTextOutput(message, MessageImportance.High);
}
// Do not run the tool, but pretend it ran successfully.
return 0;
return StdErrMessages.Any() ? -1 : 0;
}
};

@ -175,5 +175,86 @@ namespace Grpc.Tools.Tests
Assert.That(_task.LastResponseFile,
Does.Contain("--csharp_out=" + expect));
}
[TestCase(
"../Protos/greet.proto(19) : warning in column=5 : warning : When enum name is stripped and label is PascalCased (Zero) this value label conflicts with Zero.",
"../Protos/greet.proto",
19,
5,
"warning : When enum name is stripped and label is PascalCased (Zero) this value label conflicts with Zero.")]
[TestCase(
"../Protos/greet.proto: warning: Import google/protobuf/empty.proto but not used.",
"../Protos/greet.proto",
0,
0,
"Import google/protobuf/empty.proto but not used.")]
[TestCase("../Protos/greet.proto(14) : error in column=10: \"name\" is already defined in \"Greet.HelloRequest\".", null, 0, 0, null)]
[TestCase("../Protos/greet.proto: Import \"google / protobuf / empty.proto\" was listed twice.", null, 0, 0, null)]
public void WarningsParsed(string stderr, string file, int line, int col, string message)
{
_task.StdErrMessages.Add(stderr);
_mockEngine
.Setup(me => me.LogWarningEvent(It.IsAny<BuildWarningEventArgs>()))
.Callback((BuildWarningEventArgs e) => {
if (file != null)
{
Assert.AreEqual(file, e.File);
Assert.AreEqual(line, e.LineNumber);
Assert.AreEqual(col, e.ColumnNumber);
Assert.AreEqual(message, e.Message);
}
else
{
Assert.Fail($"Error logged by build engine:\n{e.Message}");
}
});
bool result = _task.Execute();
Assert.IsFalse(result);
}
[TestCase(
"../Protos/greet.proto(14) : error in column=10: \"name\" is already defined in \"Greet.HelloRequest\".",
"../Protos/greet.proto",
14,
10,
"\"name\" is already defined in \"Greet.HelloRequest\".")]
[TestCase(
"../Protos/greet.proto: Import \"google / protobuf / empty.proto\" was listed twice.",
"../Protos/greet.proto",
0,
0,
"Import \"google / protobuf / empty.proto\" was listed twice.")]
[TestCase("../Protos/greet.proto(19) : warning in column=5 : warning : When enum name is stripped and label is PascalCased (Zero) this value label conflicts with Zero.", null, 0, 0, null)]
[TestCase("../Protos/greet.proto: warning: Import google/protobuf/empty.proto but not used.", null, 0, 0, null)]
public void ErrorsParsed(string stderr, string file, int line, int col, string message)
{
_task.StdErrMessages.Add(stderr);
_mockEngine
.Setup(me => me.LogErrorEvent(It.IsAny<BuildErrorEventArgs>()))
.Callback((BuildErrorEventArgs e) => {
if (file != null)
{
Assert.AreEqual(file, e.File);
Assert.AreEqual(line, e.LineNumber);
Assert.AreEqual(col, e.ColumnNumber);
Assert.AreEqual(message, e.Message);
}
else
{
// Ignore expected error
// "protoc/protoc.exe" existed with code -1.
if (!e.Message.EndsWith("exited with code -1."))
{
Assert.Fail($"Error logged by build engine:\n{e.Message}");
}
}
});
bool result = _task.Execute();
Assert.IsFalse(result);
}
};
}

@ -16,7 +16,10 @@
#endregion
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
@ -123,6 +126,110 @@ namespace Grpc.Tools
"javanano", "js", "objc",
"php", "python", "ruby" };
static readonly TimeSpan s_regexTimeout = TimeSpan.FromMilliseconds(100);
static readonly List<ErrorListFilter> s_errorListFilters = new List<ErrorListFilter>()
{
// Example warning with location
//../Protos/greet.proto(19) : warning in column=5 : warning : When enum name is stripped and label is PascalCased (Zero),
// this value label conflicts with Zero. This will make the proto fail to compile for some languages, such as C#.
new ErrorListFilter
{
Pattern = new Regex(
pattern: "(?'FILENAME'.+)\\((?'LINE'\\d+)\\) ?: ?warning in column=(?'COLUMN'\\d+) ?: ?(?'TEXT'.*)",
options: RegexOptions.Compiled | RegexOptions.IgnoreCase,
matchTimeout: s_regexTimeout),
LogAction = (log, match) =>
{
int.TryParse(match.Groups["LINE"].Value, out var line);
int.TryParse(match.Groups["COLUMN"].Value, out var column);
log.LogWarning(
subcategory: null,
warningCode: null,
helpKeyword: null,
file: match.Groups["FILENAME"].Value,
lineNumber: line,
columnNumber: column,
endLineNumber: 0,
endColumnNumber: 0,
message: match.Groups["TEXT"].Value);
}
},
// Example error with location
//../Protos/greet.proto(14) : error in column=10: "name" is already defined in "Greet.HelloRequest".
new ErrorListFilter
{
Pattern = new Regex(
pattern: "(?'FILENAME'.+)\\((?'LINE'\\d+)\\) ?: ?error in column=(?'COLUMN'\\d+) ?: ?(?'TEXT'.*)",
options: RegexOptions.Compiled | RegexOptions.IgnoreCase,
matchTimeout: s_regexTimeout),
LogAction = (log, match) =>
{
int.TryParse(match.Groups["LINE"].Value, out var line);
int.TryParse(match.Groups["COLUMN"].Value, out var column);
log.LogError(
subcategory: null,
errorCode: null,
helpKeyword: null,
file: match.Groups["FILENAME"].Value,
lineNumber: line,
columnNumber: column,
endLineNumber: 0,
endColumnNumber: 0,
message: match.Groups["TEXT"].Value);
}
},
// Example warning without location
//../Protos/greet.proto: warning: Import google/protobuf/empty.proto but not used.
new ErrorListFilter
{
Pattern = new Regex(
pattern: "(?'FILENAME'.+): ?warning: ?(?'TEXT'.*)",
options: RegexOptions.Compiled | RegexOptions.IgnoreCase,
matchTimeout: s_regexTimeout),
LogAction = (log, match) =>
{
log.LogWarning(
subcategory: null,
warningCode: null,
helpKeyword: null,
file: match.Groups["FILENAME"].Value,
lineNumber: 0,
columnNumber: 0,
endLineNumber: 0,
endColumnNumber: 0,
message: match.Groups["TEXT"].Value);
}
},
// Example error without location
//../Protos/greet.proto: Import "google/protobuf/empty.proto" was listed twice.
new ErrorListFilter
{
Pattern = new Regex(
pattern: "(?'FILENAME'.+): ?(?'TEXT'.*)",
options: RegexOptions.Compiled | RegexOptions.IgnoreCase,
matchTimeout: s_regexTimeout),
LogAction = (log, match) =>
{
log.LogError(
subcategory: null,
errorCode: null,
helpKeyword: null,
file: match.Groups["FILENAME"].Value,
lineNumber: 0,
columnNumber: 0,
endLineNumber: 0,
endColumnNumber: 0,
message: match.Groups["TEXT"].Value);
}
}
};
/// <summary>
/// Code generator.
/// </summary>
@ -406,6 +513,22 @@ namespace Grpc.Tools
base.LogToolCommand(printer.ToString());
}
protected override void LogEventsFromTextOutput(string singleLine, MessageImportance messageImportance)
{
foreach (ErrorListFilter filter in s_errorListFilters)
{
Match match = filter.Pattern.Match(singleLine);
if (match.Success)
{
filter.LogAction(Log, match);
return;
}
}
base.LogEventsFromTextOutput(singleLine, messageImportance);
}
// Main task entry point.
public override bool Execute()
{
@ -438,5 +561,11 @@ namespace Grpc.Tools
return true;
}
class ErrorListFilter
{
public Regex Pattern { get; set; }
public Action<TaskLoggingHelper, Match> LogAction { get; set; }
}
};
}

@ -271,7 +271,6 @@
GrpcPluginExe="%(_Protobuf_OutOfDateProto.GrpcPluginExe)"
GrpcOutputDir="%(_Protobuf_OutOfDateProto.GrpcOutputDir)"
GrpcOutputOptions="%(_Protobuf_OutOfDateProto._GrpcOutputOptions)"
LogStandardErrorAsError="true"
>
<Output TaskParameter="GeneratedFiles" ItemName="_Protobuf_GeneratedFiles"/>
</ProtoCompile>

@ -3,7 +3,8 @@
{
"src": [
{
"files": ["Grpc.Core/Grpc.Core.csproj",
"files": ["Grpc.Core.Api/Grpc.Core.Api.csproj",
"Grpc.Core/Grpc.Core.csproj",
"Grpc.Auth/Grpc.Auth.csproj",
"Grpc.Core.Testing/Grpc.Core.Testing.csproj",
"Grpc.HealthCheck/Grpc.HealthCheck.csproj",

@ -101,7 +101,7 @@ Pod::Spec.new do |s|
s.preserve_paths = plugin
# Restrict the protoc version to the one supported by this plugin.
s.dependency '!ProtoCompiler', '3.6.0'
s.dependency '!ProtoCompiler', '3.6.1'
# For the Protobuf dependency not to complain:
s.ios.deployment_target = '7.0'
s.osx.deployment_target = '10.9'

@ -36,7 +36,7 @@ Pod::Spec.new do |s|
# exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed
# before them.
s.name = '!ProtoCompiler'
v = '3.6.0'
v = '3.6.1'
s.version = v
s.summary = 'The Protobuf Compiler (protoc) generates Objective-C files from .proto files'
s.description = <<-DESC
@ -112,6 +112,7 @@ Pod::Spec.new do |s|
# For the Protobuf dependency not to complain:
s.ios.deployment_target = '7.0'
s.osx.deployment_target = '10.9'
s.tvos.deployment_target = '10.0'
# This is only for local development of protoc: If the Podfile brings this pod from a local
# directory using `:path`, CocoaPods won't download the zip file and so the compiler won't be

@ -79,7 +79,7 @@ Pod::Spec.new do |s|
:commit => "b29b21a81b32ec273f118f589f46d56ad3332420",
}
s.ios.deployment_target = '5.0'
s.ios.deployment_target = '7.0'
s.osx.deployment_target = '10.7'
s.tvos.deployment_target = '10.0'

@ -30,19 +30,20 @@ cdef grpc_event _next(grpc_completion_queue *c_completion_queue, deadline):
else:
c_deadline = _timespec_from_time(deadline)
with nogil:
while True:
while True:
with nogil:
c_timeout = gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), c_increment)
if gpr_time_cmp(c_timeout, c_deadline) > 0:
c_timeout = c_deadline
c_event = grpc_completion_queue_next(c_completion_queue, c_timeout, NULL)
if (c_event.type != GRPC_QUEUE_TIMEOUT or
gpr_time_cmp(c_timeout, c_deadline) == 0):
break
# Handle any signals
with gil:
cpython.PyErr_CheckSignals()
# Handle any signals
cpython.PyErr_CheckSignals()
return c_event

@ -17,8 +17,6 @@ cimport cpython
import grpc
import threading
from libc.stdint cimport uintptr_t
def _spawn_callback_in_thread(cb_func, args):
ForkManagedThread(target=cb_func, args=args).start()

@ -13,7 +13,17 @@
# limitations under the License.
cimport libc.time
from libc.stdint cimport intptr_t, uint8_t, int32_t, uint32_t, int64_t
ctypedef ssize_t intptr_t
ctypedef size_t uintptr_t
ctypedef signed char int8_t
ctypedef signed short int16_t
ctypedef signed int int32_t
ctypedef signed long long int64_t
ctypedef unsigned char uint8_t
ctypedef unsigned short uint16_t
ctypedef unsigned int uint32_t
ctypedef unsigned long long uint64_t
cdef extern from "grpc/support/alloc.h":

@ -13,8 +13,6 @@
# limitations under the License.
# distutils: language=c++
from libc.stdint cimport uint32_t
cdef extern from "grpc/impl/codegen/slice.h":
struct grpc_slice_buffer:
int count

@ -12,8 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from libc.stdint cimport intptr_t
cdef bytes _slice_bytes(grpc_slice slice):
cdef void *start = grpc_slice_start_ptr(slice)

@ -200,7 +200,6 @@ CORE_SOURCE_FILES = [
'src/core/lib/transport/metadata.cc',
'src/core/lib/transport/metadata_batch.cc',
'src/core/lib/transport/pid_controller.cc',
'src/core/lib/transport/service_config.cc',
'src/core/lib/transport/static_metadata.cc',
'src/core/lib/transport/status_conversion.cc',
'src/core/lib/transport/status_metadata.cc',
@ -336,6 +335,7 @@ CORE_SOURCE_FILES = [
'src/core/ext/filters/client_channel/resolving_lb_policy.cc',
'src/core/ext/filters/client_channel/retry_throttle.cc',
'src/core/ext/filters/client_channel/server_address.cc',
'src/core/ext/filters/client_channel/service_config.cc',
'src/core/ext/filters/client_channel/subchannel.cc',
'src/core/ext/filters/client_channel/subchannel_pool_interface.cc',
'src/core/ext/filters/deadline/deadline_filter.cc',
@ -699,6 +699,7 @@ CORE_SOURCE_FILES = [
'third_party/cares/cares/ares_strcasecmp.c',
'third_party/cares/cares/ares_strdup.c',
'third_party/cares/cares/ares_strerror.c',
'third_party/cares/cares/ares_strsplit.c',
'third_party/cares/cares/ares_timeout.c',
'third_party/cares/cares/ares_version.c',
'third_party/cares/cares/ares_writev.c',

@ -135,7 +135,8 @@ class TestGevent(setuptools.Command):
# This test will stuck while running higher version of gevent
'unit._auth_context_test.AuthContextTest.testSessionResumption',
# TODO(https://github.com/grpc/grpc/issues/15411) enable these tests
'unit._metadata_flags_test',
'unit._channel_ready_future_test.ChannelReadyFutureTest.test_immediately_connectable_channel_connectivity',
"unit._cython._channel_test.ChannelTest.test_single_channel_lonely_connectivity",
'unit._exit_test.ExitTest.test_in_flight_unary_unary_call',
'unit._exit_test.ExitTest.test_in_flight_unary_stream_call',
'unit._exit_test.ExitTest.test_in_flight_stream_unary_call',
@ -143,6 +144,7 @@ class TestGevent(setuptools.Command):
'unit._exit_test.ExitTest.test_in_flight_partial_unary_stream_call',
'unit._exit_test.ExitTest.test_in_flight_partial_stream_unary_call',
'unit._exit_test.ExitTest.test_in_flight_partial_stream_stream_call',
'unit._metadata_flags_test',
'health_check._health_servicer_test.HealthServicerTest.test_cancelled_watch_removed_from_watch_list',
# TODO(https://github.com/grpc/grpc/issues/17330) enable these three tests
'channelz._channelz_servicer_test.ChannelzServicerTest.test_many_subchannels',

@ -61,6 +61,8 @@
def grpc_test_util_files(libs):
out = grpc_lib_files(libs, ("grpc_test_util",), ("src", "headers"))
excl = grpc_private_files(libs)
# Subprocess is not supported in tvOS and not needed by our tests.
excl += ["test/core/util/subprocess_posix.cc"]
return [file for file in out if not file in excl]
def end2end_tests_files(libs):

@ -103,7 +103,7 @@
s.preserve_paths = plugin
# Restrict the protoc version to the one supported by this plugin.
s.dependency '!ProtoCompiler', '3.6.0'
s.dependency '!ProtoCompiler', '3.6.1'
# For the Protobuf dependency not to complain:
s.ios.deployment_target = '7.0'
s.osx.deployment_target = '10.9'

@ -84,7 +84,7 @@
:commit => "b29b21a81b32ec273f118f589f46d56ad3332420",
}
s.ios.deployment_target = '5.0'
s.ios.deployment_target = '7.0'
s.osx.deployment_target = '10.7'
s.tvos.deployment_target = '10.0'

@ -109,26 +109,23 @@ static grpc_core::OrphanablePtr<grpc_core::Resolver> create_resolver(
class ResultHandler : public grpc_core::Resolver::ResultHandler {
public:
struct ResolverOutput {
const grpc_channel_args* result = nullptr;
grpc_core::Resolver::Result result;
grpc_error* error = nullptr;
gpr_event ev;
ResolverOutput() { gpr_event_init(&ev); }
~ResolverOutput() {
grpc_channel_args_destroy(result);
GRPC_ERROR_UNREF(error);
}
~ResolverOutput() { GRPC_ERROR_UNREF(error); }
};
void SetOutput(ResolverOutput* output) {
gpr_atm_rel_store(&output_, reinterpret_cast<gpr_atm>(output));
}
void ReturnResult(const grpc_channel_args* args) override {
void ReturnResult(grpc_core::Resolver::Result result) override {
ResolverOutput* output =
reinterpret_cast<ResolverOutput*>(gpr_atm_acq_load(&output_));
GPR_ASSERT(output != nullptr);
output->result = args;
output->result = std::move(result);
output->error = GRPC_ERROR_NONE;
gpr_event_set(&output->ev, (void*)1);
}
@ -137,7 +134,6 @@ class ResultHandler : public grpc_core::Resolver::ResultHandler {
ResolverOutput* output =
reinterpret_cast<ResolverOutput*>(gpr_atm_acq_load(&output_));
GPR_ASSERT(output != nullptr);
output->result = nullptr;
output->error = error;
gpr_event_set(&output->ev, (void*)1);
}
@ -180,14 +176,14 @@ int main(int argc, char** argv) {
resolver->StartLocked();
grpc_core::ExecCtx::Get()->Flush();
GPR_ASSERT(wait_loop(5, &output1.ev));
GPR_ASSERT(output1.result == nullptr);
GPR_ASSERT(output1.result.addresses.empty());
GPR_ASSERT(output1.error != GRPC_ERROR_NONE);
ResultHandler::ResolverOutput output2;
result_handler->SetOutput(&output2);
grpc_core::ExecCtx::Get()->Flush();
GPR_ASSERT(wait_loop(30, &output2.ev));
GPR_ASSERT(output2.result != nullptr);
GPR_ASSERT(!output2.result.addresses.empty());
GPR_ASSERT(output2.error == GRPC_ERROR_NONE);
GRPC_COMBINER_UNREF(g_combiner, "test");

@ -174,8 +174,7 @@ struct OnResolutionCallbackArg;
class ResultHandler : public grpc_core::Resolver::ResultHandler {
public:
using ResultCallback = void (*)(const grpc_channel_args* result,
OnResolutionCallbackArg* state);
using ResultCallback = void (*)(OnResolutionCallbackArg* state);
void SetCallback(ResultCallback result_cb, OnResolutionCallbackArg* state) {
GPR_ASSERT(result_cb_ == nullptr);
@ -184,14 +183,14 @@ class ResultHandler : public grpc_core::Resolver::ResultHandler {
state_ = state;
}
void ReturnResult(const grpc_channel_args* args) override {
void ReturnResult(grpc_core::Resolver::Result result) override {
GPR_ASSERT(result_cb_ != nullptr);
GPR_ASSERT(state_ != nullptr);
ResultCallback cb = result_cb_;
OnResolutionCallbackArg* state = state_;
result_cb_ = nullptr;
state_ = nullptr;
cb(args, state);
cb(state);
}
void ReturnError(grpc_error* error) override {
@ -213,9 +212,7 @@ struct OnResolutionCallbackArg {
// Set to true by the last callback in the resolution chain.
static bool g_all_callbacks_invoked;
static void on_second_resolution(const grpc_channel_args* result,
OnResolutionCallbackArg* cb_arg) {
grpc_channel_args_destroy(result);
static void on_second_resolution(OnResolutionCallbackArg* cb_arg) {
gpr_log(GPR_INFO, "2nd: g_resolution_count: %d", g_resolution_count);
// The resolution callback was not invoked until new data was
// available, which was delayed until after the cooldown period.
@ -230,9 +227,7 @@ static void on_second_resolution(const grpc_channel_args* result,
g_all_callbacks_invoked = true;
}
static void on_first_resolution(const grpc_channel_args* result,
OnResolutionCallbackArg* cb_arg) {
grpc_channel_args_destroy(result);
static void on_first_resolution(OnResolutionCallbackArg* cb_arg) {
gpr_log(GPR_INFO, "1st: g_resolution_count: %d", g_resolution_count);
// There's one initial system-level resolution and one invocation of a
// notification callback (the current function).

@ -35,32 +35,22 @@
class ResultHandler : public grpc_core::Resolver::ResultHandler {
public:
~ResultHandler() override { grpc_channel_args_destroy(expected_); }
void SetExpectedAndEvent(grpc_channel_args* expected, gpr_event* ev) {
GPR_ASSERT(expected_ == nullptr);
void SetExpectedAndEvent(grpc_core::Resolver::Result expected,
gpr_event* ev) {
GPR_ASSERT(ev_ == nullptr);
expected_ = grpc_channel_args_copy(expected);
expected_ = std::move(expected);
ev_ = ev;
}
void ReturnResult(const grpc_channel_args* args) override {
GPR_ASSERT(expected_ != nullptr);
void ReturnResult(grpc_core::Resolver::Result actual) override {
GPR_ASSERT(ev_ != nullptr);
// We only check the addresses channel arg because that's the only one
// We only check the addresses, because that's the only thing
// explicitly set by the test via
// FakeResolverResponseGenerator::SetResponse().
const grpc_core::ServerAddressList* actual_addresses =
grpc_core::FindServerAddressListChannelArg(args);
const grpc_core::ServerAddressList* expected_addresses =
grpc_core::FindServerAddressListChannelArg(expected_);
GPR_ASSERT(actual_addresses->size() == expected_addresses->size());
for (size_t i = 0; i < expected_addresses->size(); ++i) {
GPR_ASSERT((*actual_addresses)[i] == (*expected_addresses)[i]);
GPR_ASSERT(actual.addresses.size() == expected_.addresses.size());
for (size_t i = 0; i < expected_.addresses.size(); ++i) {
GPR_ASSERT(actual.addresses[i] == expected_.addresses[i]);
}
grpc_channel_args_destroy(args);
grpc_channel_args_destroy(expected_);
expected_ = nullptr;
gpr_event_set(ev_, (void*)1);
ev_ = nullptr;
}
@ -68,7 +58,7 @@ class ResultHandler : public grpc_core::Resolver::ResultHandler {
void ReturnError(grpc_error* error) override {}
private:
grpc_channel_args* expected_ = nullptr;
grpc_core::Resolver::Result expected_;
gpr_event* ev_ = nullptr;
};
@ -92,13 +82,13 @@ static grpc_core::OrphanablePtr<grpc_core::Resolver> build_fake_resolver(
}
// Create a new resolution containing 2 addresses.
static grpc_channel_args* create_new_resolver_result() {
static grpc_core::Resolver::Result create_new_resolver_result() {
static size_t test_counter = 0;
const size_t num_addresses = 2;
char* uri_string;
char* balancer_name;
// Create address list.
grpc_core::ServerAddressList addresses;
grpc_core::Resolver::Result result;
for (size_t i = 0; i < num_addresses; ++i) {
gpr_asprintf(&uri_string, "ipv4:127.0.0.1:100%" PRIuPTR,
test_counter * num_addresses + i);
@ -117,17 +107,13 @@ static grpc_channel_args* create_new_resolver_result() {
}
grpc_channel_args* args = grpc_channel_args_copy_and_add(
nullptr, args_to_add.data(), args_to_add.size());
addresses.emplace_back(address.addr, address.len, args);
result.addresses.emplace_back(address.addr, address.len, args);
gpr_free(balancer_name);
grpc_uri_destroy(uri);
gpr_free(uri_string);
}
// Embed the address list in channel args.
const grpc_arg addresses_arg = CreateServerAddressListChannelArg(&addresses);
grpc_channel_args* results =
grpc_channel_args_copy_and_add(nullptr, &addresses_arg, 1);
++test_counter;
return results;
return result;
}
static void test_fake_resolver() {
@ -147,39 +133,38 @@ static void test_fake_resolver() {
// next_results != NULL, reresolution_results == NULL.
// Expected response is next_results.
gpr_log(GPR_INFO, "TEST 1");
grpc_channel_args* results = create_new_resolver_result();
grpc_core::Resolver::Result result = create_new_resolver_result();
gpr_event ev1;
gpr_event_init(&ev1);
result_handler->SetExpectedAndEvent(results, &ev1);
response_generator->SetResponse(results);
result_handler->SetExpectedAndEvent(result, &ev1);
response_generator->SetResponse(std::move(result));
grpc_core::ExecCtx::Get()->Flush();
GPR_ASSERT(gpr_event_wait(&ev1, grpc_timeout_seconds_to_deadline(5)) !=
nullptr);
grpc_channel_args_destroy(results);
// Test 2: update resolution.
// next_results != NULL, reresolution_results == NULL.
// Expected response is next_results.
gpr_log(GPR_INFO, "TEST 2");
results = create_new_resolver_result();
result = create_new_resolver_result();
gpr_event ev2;
gpr_event_init(&ev2);
result_handler->SetExpectedAndEvent(results, &ev2);
response_generator->SetResponse(results);
result_handler->SetExpectedAndEvent(result, &ev2);
response_generator->SetResponse(std::move(result));
grpc_core::ExecCtx::Get()->Flush();
GPR_ASSERT(gpr_event_wait(&ev2, grpc_timeout_seconds_to_deadline(5)) !=
nullptr);
grpc_channel_args_destroy(results);
// Test 3: normal re-resolution.
// next_results == NULL, reresolution_results != NULL.
// Expected response is reresolution_results.
gpr_log(GPR_INFO, "TEST 3");
grpc_channel_args* reresolution_results = create_new_resolver_result();
grpc_core::Resolver::Result reresolution_result =
create_new_resolver_result();
gpr_event ev3;
gpr_event_init(&ev3);
result_handler->SetExpectedAndEvent(reresolution_results, &ev3);
result_handler->SetExpectedAndEvent(reresolution_result, &ev3);
// Set reresolution_results.
// No result will be returned until re-resolution is requested.
response_generator->SetReresolutionResponse(reresolution_results);
response_generator->SetReresolutionResponse(reresolution_result);
grpc_core::ExecCtx::Get()->Flush();
// Trigger a re-resolution.
resolver->RequestReresolutionLocked();
@ -192,33 +177,31 @@ static void test_fake_resolver() {
gpr_log(GPR_INFO, "TEST 4");
gpr_event ev4;
gpr_event_init(&ev4);
result_handler->SetExpectedAndEvent(reresolution_results, &ev4);
result_handler->SetExpectedAndEvent(std::move(reresolution_result), &ev4);
// Trigger a re-resolution.
resolver->RequestReresolutionLocked();
grpc_core::ExecCtx::Get()->Flush();
GPR_ASSERT(gpr_event_wait(&ev4, grpc_timeout_seconds_to_deadline(5)) !=
nullptr);
grpc_channel_args_destroy(reresolution_results);
// Test 5: normal resolution.
// next_results != NULL, reresolution_results != NULL.
// Expected response is next_results.
gpr_log(GPR_INFO, "TEST 5");
results = create_new_resolver_result();
result = create_new_resolver_result();
gpr_event ev5;
gpr_event_init(&ev5);
result_handler->SetExpectedAndEvent(results, &ev5);
response_generator->SetResponse(results);
result_handler->SetExpectedAndEvent(result, &ev5);
response_generator->SetResponse(std::move(result));
grpc_core::ExecCtx::Get()->Flush();
GPR_ASSERT(gpr_event_wait(&ev5, grpc_timeout_seconds_to_deadline(5)) !=
nullptr);
grpc_channel_args_destroy(results);
// Test 6: no-op.
// Requesting a new resolution without setting the response shouldn't trigger
// the resolution callback.
gpr_log(GPR_INFO, "TEST 6");
gpr_event ev6;
gpr_event_init(&ev6);
result_handler->SetExpectedAndEvent(nullptr, &ev6);
result_handler->SetExpectedAndEvent(grpc_core::Resolver::Result(), &ev6);
GPR_ASSERT(gpr_event_wait(&ev6, grpc_timeout_milliseconds_to_deadline(100)) ==
nullptr);
// Clean up.

@ -32,9 +32,7 @@ static grpc_combiner* g_combiner;
class ResultHandler : public grpc_core::Resolver::ResultHandler {
public:
void ReturnResult(const grpc_channel_args* args) override {
grpc_channel_args_destroy(args);
}
void ReturnResult(grpc_core::Resolver::Result result) override {}
void ReturnError(grpc_error* error) override { GRPC_ERROR_UNREF(error); }
};

@ -28,7 +28,6 @@
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/transport/metadata.h"
#include "src/core/lib/transport/service_config.h"
#include "test/core/end2end/cq_verifier.h"
#include "test/core/util/port.h"

@ -30,7 +30,6 @@
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/transport/metadata.h"
#include "src/core/lib/transport/service_config.h"
#include "test/core/end2end/cq_verifier.h"
#include "test/core/end2end/tests/cancel_test_helpers.h"

@ -30,7 +30,6 @@
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/transport/metadata.h"
#include "src/core/lib/transport/service_config.h"
#include "test/core/end2end/cq_verifier.h"
#include "test/core/end2end/tests/cancel_test_helpers.h"

@ -30,7 +30,6 @@
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/transport/metadata.h"
#include "src/core/lib/transport/service_config.h"
#include "test/core/end2end/cq_verifier.h"

@ -64,9 +64,8 @@ class ForwardingLoadBalancingPolicy : public LoadBalancingPolicy {
~ForwardingLoadBalancingPolicy() override = default;
void UpdateLocked(const grpc_channel_args& args,
RefCountedPtr<Config> lb_config) override {
delegate_->UpdateLocked(args, std::move(lb_config));
void UpdateLocked(UpdateArgs args) override {
delegate_->UpdateLocked(std::move(args));
}
void ExitIdleLocked() override { delegate_->ExitIdleLocked(); }

@ -218,7 +218,7 @@ class ClientChannelStressTest {
void SetNextResolution(const std::vector<AddressData>& address_data) {
grpc_core::ExecCtx exec_ctx;
grpc_core::ServerAddressList addresses;
grpc_core::Resolver::Result result;
for (const auto& addr : address_data) {
char* lb_uri_str;
gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", addr.port);
@ -236,13 +236,11 @@ class ClientChannelStressTest {
}
grpc_channel_args* args = grpc_channel_args_copy_and_add(
nullptr, args_to_add.data(), args_to_add.size());
addresses.emplace_back(address.addr, address.len, args);
result.addresses.emplace_back(address.addr, address.len, args);
grpc_uri_destroy(lb_uri);
gpr_free(lb_uri_str);
}
grpc_arg fake_addresses = CreateServerAddressListChannelArg(&addresses);
grpc_channel_args fake_result = {1, &fake_addresses};
response_generator_->SetResponse(&fake_result);
response_generator_->SetResponse(std::move(result));
}
void KeepSendingRequests() {

@ -79,7 +79,10 @@ class TestScenario {
static std::ostream& operator<<(std::ostream& out,
const TestScenario& scenario) {
return out << "TestScenario{callback_server="
<< (scenario.callback_server ? "true" : "false") << "}";
<< (scenario.callback_server ? "true" : "false") << ",protocol="
<< (scenario.protocol == Protocol::INPROC ? "INPROC" : "TCP")
<< ",intercept=" << (scenario.use_interceptors ? "true" : "false")
<< ",creds=" << scenario.credentials_type << "}";
}
void TestScenario::Log() const {

@ -183,8 +183,8 @@ class ClientLbEnd2endTest : public ::testing::Test {
}
}
grpc_channel_args* BuildFakeResults(const std::vector<int>& ports) {
grpc_core::ServerAddressList addresses;
grpc_core::Resolver::Result BuildFakeResults(const std::vector<int>& ports) {
grpc_core::Resolver::Result result;
for (const int& port : ports) {
char* lb_uri_str;
gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", port);
@ -192,29 +192,22 @@ class ClientLbEnd2endTest : public ::testing::Test {
GPR_ASSERT(lb_uri != nullptr);
grpc_resolved_address address;
GPR_ASSERT(grpc_parse_uri(lb_uri, &address));
addresses.emplace_back(address.addr, address.len, nullptr /* args */);
result.addresses.emplace_back(address.addr, address.len,
nullptr /* args */);
grpc_uri_destroy(lb_uri);
gpr_free(lb_uri_str);
}
const grpc_arg fake_addresses =
CreateServerAddressListChannelArg(&addresses);
grpc_channel_args* fake_results =
grpc_channel_args_copy_and_add(nullptr, &fake_addresses, 1);
return fake_results;
return result;
}
void SetNextResolution(const std::vector<int>& ports) {
grpc_core::ExecCtx exec_ctx;
grpc_channel_args* fake_results = BuildFakeResults(ports);
response_generator_->SetResponse(fake_results);
grpc_channel_args_destroy(fake_results);
response_generator_->SetResponse(BuildFakeResults(ports));
}
void SetNextResolutionUponError(const std::vector<int>& ports) {
grpc_core::ExecCtx exec_ctx;
grpc_channel_args* fake_results = BuildFakeResults(ports);
response_generator_->SetReresolutionResponse(fake_results);
grpc_channel_args_destroy(fake_results);
response_generator_->SetReresolutionResponse(BuildFakeResults(ports));
}
void SetFailureOnReresolution() {

@ -36,6 +36,7 @@
#include "src/core/ext/filters/client_channel/parse_address.h"
#include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h"
#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/ext/filters/client_channel/service_config.h"
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/iomgr/sockaddr.h"
@ -538,28 +539,21 @@ class GrpclbEnd2endTest : public ::testing::Test {
void SetNextResolution(const std::vector<AddressData>& address_data,
const char* service_config_json = nullptr) {
grpc_core::ExecCtx exec_ctx;
grpc_core::ServerAddressList addresses =
CreateLbAddressesFromAddressDataList(address_data);
std::vector<grpc_arg> args = {
CreateServerAddressListChannelArg(&addresses),
};
grpc_core::Resolver::Result result;
result.addresses = CreateLbAddressesFromAddressDataList(address_data);
if (service_config_json != nullptr) {
args.push_back(grpc_channel_arg_string_create(
const_cast<char*>(GRPC_ARG_SERVICE_CONFIG),
const_cast<char*>(service_config_json)));
result.service_config =
grpc_core::ServiceConfig::Create(service_config_json);
}
grpc_channel_args fake_result = {args.size(), args.data()};
response_generator_->SetResponse(&fake_result);
response_generator_->SetResponse(std::move(result));
}
void SetNextReresolutionResponse(
const std::vector<AddressData>& address_data) {
grpc_core::ExecCtx exec_ctx;
grpc_core::ServerAddressList addresses =
CreateLbAddressesFromAddressDataList(address_data);
grpc_arg fake_addresses = CreateServerAddressListChannelArg(&addresses);
grpc_channel_args fake_result = {1, &fake_addresses};
response_generator_->SetReresolutionResponse(&fake_result);
grpc_core::Resolver::Result result;
result.addresses = CreateLbAddressesFromAddressDataList(address_data);
response_generator_->SetReresolutionResponse(std::move(result));
}
const std::vector<int> GetBackendPorts(size_t start_index = 0,

@ -521,21 +521,18 @@ class XdsEnd2endTest : public ::testing::Test {
grpc_core::FakeResolverResponseGenerator*
lb_channel_response_generator = nullptr) {
grpc_core::ExecCtx exec_ctx;
grpc_core::ServerAddressList addresses =
CreateLbAddressesFromPortList(ports);
std::vector<grpc_arg> args = {
CreateServerAddressListChannelArg(&addresses),
grpc_core::FakeResolverResponseGenerator::MakeChannelArg(
lb_channel_response_generator == nullptr
? lb_channel_response_generator_.get()
: lb_channel_response_generator)};
grpc_core::Resolver::Result result;
result.addresses = CreateLbAddressesFromPortList(ports);
if (service_config_json != nullptr) {
args.push_back(grpc_channel_arg_string_create(
const_cast<char*>(GRPC_ARG_SERVICE_CONFIG),
const_cast<char*>(service_config_json)));
result.service_config =
grpc_core::ServiceConfig::Create(service_config_json);
}
grpc_channel_args fake_result = {args.size(), args.data()};
response_generator_->SetResponse(&fake_result);
grpc_arg arg = grpc_core::FakeResolverResponseGenerator::MakeChannelArg(
lb_channel_response_generator == nullptr
? lb_channel_response_generator_.get()
: lb_channel_response_generator);
result.args = grpc_channel_args_copy_and_add(nullptr, &arg, 1);
response_generator_->SetResponse(std::move(result));
}
void SetNextResolutionForLbChannelAllBalancers(
@ -555,30 +552,23 @@ class XdsEnd2endTest : public ::testing::Test {
grpc_core::FakeResolverResponseGenerator* lb_channel_response_generator =
nullptr) {
grpc_core::ExecCtx exec_ctx;
grpc_core::ServerAddressList addresses =
CreateLbAddressesFromPortList(ports);
std::vector<grpc_arg> args = {
CreateServerAddressListChannelArg(&addresses),
};
grpc_core::Resolver::Result result;
result.addresses = CreateLbAddressesFromPortList(ports);
if (service_config_json != nullptr) {
args.push_back(grpc_channel_arg_string_create(
const_cast<char*>(GRPC_ARG_SERVICE_CONFIG),
const_cast<char*>(service_config_json)));
result.service_config =
grpc_core::ServiceConfig::Create(service_config_json);
}
grpc_channel_args fake_result = {args.size(), args.data()};
if (lb_channel_response_generator == nullptr) {
lb_channel_response_generator = lb_channel_response_generator_.get();
}
lb_channel_response_generator->SetResponse(&fake_result);
lb_channel_response_generator->SetResponse(std::move(result));
}
void SetNextReresolutionResponse(const std::vector<int>& ports) {
grpc_core::ExecCtx exec_ctx;
grpc_core::ServerAddressList addresses =
CreateLbAddressesFromPortList(ports);
grpc_arg fake_addresses = CreateServerAddressListChannelArg(&addresses);
grpc_channel_args fake_result = {1, &fake_addresses};
response_generator_->SetReresolutionResponse(&fake_result);
grpc_core::Resolver::Result result;
result.addresses = CreateLbAddressesFromPortList(ports);
response_generator_->SetReresolutionResponse(std::move(result));
}
const std::vector<int> GetBackendPorts(size_t start_index = 0,

@ -172,7 +172,7 @@ class AssertFailureResultHandler : public grpc_core::Resolver::ResultHandler {
gpr_mu_unlock(args_->mu);
}
void ReturnResult(const grpc_channel_args* args) override {
void ReturnResult(grpc_core::Resolver::Result result) override {
GPR_ASSERT(false);
}

@ -239,17 +239,13 @@ void PollPollsetUntilRequestDone(ArgsStruct* args) {
gpr_event_set(&args->ev, (void*)1);
}
void CheckServiceConfigResultLocked(const grpc_channel_args* channel_args,
void CheckServiceConfigResultLocked(const char* service_config_json,
ArgsStruct* args) {
const grpc_arg* service_config_arg =
grpc_channel_args_find(channel_args, GRPC_ARG_SERVICE_CONFIG);
if (args->expected_service_config_string != "") {
GPR_ASSERT(service_config_arg != nullptr);
GPR_ASSERT(service_config_arg->type == GRPC_ARG_STRING);
EXPECT_EQ(service_config_arg->value.string,
args->expected_service_config_string);
GPR_ASSERT(service_config_json != nullptr);
EXPECT_EQ(service_config_json, args->expected_service_config_string);
} else {
GPR_ASSERT(service_config_arg == nullptr);
GPR_ASSERT(service_config_json == nullptr);
}
}
@ -404,14 +400,13 @@ class ResultHandler : public grpc_core::Resolver::ResultHandler {
explicit ResultHandler(ArgsStruct* args) : args_(args) {}
void ReturnResult(const grpc_channel_args* result) override {
void ReturnResult(grpc_core::Resolver::Result result) override {
CheckResult(result);
gpr_atm_rel_store(&args_->done_atm, 1);
gpr_mu_lock(args_->mu);
GRPC_LOG_IF_ERROR("pollset_kick",
grpc_pollset_kick(args_->pollset, nullptr));
gpr_mu_unlock(args_->mu);
grpc_channel_args_destroy(result);
}
void ReturnError(grpc_error* error) override {
@ -419,7 +414,7 @@ class ResultHandler : public grpc_core::Resolver::ResultHandler {
GPR_ASSERT(false);
}
virtual void CheckResult(const grpc_channel_args* channel_args) {}
virtual void CheckResult(const grpc_core::Resolver::Result& result) {}
protected:
ArgsStruct* args_struct() const { return args_; }
@ -438,16 +433,14 @@ class CheckingResultHandler : public ResultHandler {
explicit CheckingResultHandler(ArgsStruct* args) : ResultHandler(args) {}
void CheckResult(const grpc_channel_args* channel_args) override {
void CheckResult(const grpc_core::Resolver::Result& result) override {
ArgsStruct* args = args_struct();
grpc_core::ServerAddressList* addresses =
grpc_core::FindServerAddressListChannelArg(channel_args);
gpr_log(GPR_INFO, "num addrs found: %" PRIdPTR ". expected %" PRIdPTR,
addresses->size(), args->expected_addrs.size());
GPR_ASSERT(addresses->size() == args->expected_addrs.size());
result.addresses.size(), args->expected_addrs.size());
GPR_ASSERT(result.addresses.size() == args->expected_addrs.size());
std::vector<GrpcLBAddress> found_lb_addrs;
for (size_t i = 0; i < addresses->size(); i++) {
grpc_core::ServerAddress& addr = (*addresses)[i];
for (size_t i = 0; i < result.addresses.size(); i++) {
const grpc_core::ServerAddress& addr = result.addresses[i];
char* str;
grpc_sockaddr_to_string(&str, &addr.address(), 1 /* normalize */);
gpr_log(GPR_INFO, "%s", str);
@ -464,9 +457,13 @@ class CheckingResultHandler : public ResultHandler {
}
EXPECT_THAT(args->expected_addrs,
UnorderedElementsAreArray(found_lb_addrs));
CheckServiceConfigResultLocked(channel_args, args);
const char* service_config_json =
result.service_config == nullptr
? nullptr
: result.service_config->service_config_json();
CheckServiceConfigResultLocked(service_config_json, args);
if (args->expected_service_config_string == "") {
CheckLBPolicyResultLocked(channel_args, args);
CheckLBPolicyResultLocked(result.args, args);
}
}
};

@ -24,7 +24,7 @@ apt-get install -t jessie-backports -y libssl-dev
# Install c-ares
cd third_party/cares/cares
git fetch origin
git checkout cares-1_13_0
git checkout cares-1_15_0
mkdir -p cmake/build
cd cmake/build
cmake -DCMAKE_BUILD_TYPE=Release ../..

@ -1 +1 @@
Subproject commit 3be1924221e1326df520f8498d704a5c4c8d0cce
Subproject commit e982924acee7f7313b4baa4ee5ec000c5e373c30

@ -112,6 +112,7 @@ cc_library(
"ares_send.c",
"ares_strcasecmp.c",
"ares_strdup.c",
"ares_strsplit.c",
"ares_strerror.c",
"ares_timeout.c",
"ares_version.c",
@ -141,6 +142,7 @@ cc_library(
"ares_setup.h",
"ares_strcasecmp.h",
"ares_strdup.h",
"ares_strsplit.h",
"ares_version.h",
"bitncmp.h",
"config-win32.h",

@ -338,6 +338,9 @@
/* Define to 1 if you have the ws2tcpip.h header file. */
/* #undef HAVE_WS2TCPIP_H */
/* Define if __system_property_get exists. */
/* #undef HAVE___SYSTEM_PROPERTY_GET */
/* Define to 1 if you need the malloc.h header file even with stdlib.h */
/* #undef NEED_MALLOC_H */

@ -333,6 +333,9 @@
/* Define to 1 if you have the ws2tcpip.h header file. */
/* #undef HAVE_WS2TCPIP_H */
/* Define if __system_property_get exists. */
/* #undef HAVE___SYSTEM_PROPERTY_GET */
/* Define to 1 if you need the malloc.h header file even with stdlib.h */
/* #undef NEED_MALLOC_H */

@ -338,6 +338,9 @@
/* Define to 1 if you have the ws2tcpip.h header file. */
/* #undef HAVE_WS2TCPIP_H */
/* Define if __system_property_get exists. */
/* #undef HAVE___SYSTEM_PROPERTY_GET */
/* Define to the sub-directory where libtool stores uninstalled libraries. */
#define LT_OBJDIR ".libs/"

@ -338,6 +338,9 @@
/* Define to 1 if you have the ws2tcpip.h header file. */
/* #undef HAVE_WS2TCPIP_H */
/* Define if __system_property_get exists. */
/* #undef HAVE___SYSTEM_PROPERTY_GET */
/* Define to 1 if you need the malloc.h header file even with stdlib.h */
/* #undef NEED_MALLOC_H */

@ -338,6 +338,9 @@
/* Define to 1 if you have the ws2tcpip.h header file. */
/* #undef HAVE_WS2TCPIP_H */
/* Define if __system_property_get exists. */
/* #undef HAVE___SYSTEM_PROPERTY_GET */
/* Define to the sub-directory where libtool stores uninstalled libraries. */
#define LT_OBJDIR ".libs/"

@ -331,6 +331,9 @@
/* Define to 1 if you have the ws2tcpip.h header file. */
#define HAVE_WS2TCPIP_H
/* Define if __system_property_get exists. */
/* #undef HAVE___SYSTEM_PROPERTY_GET */
/* Define to 1 if you need the malloc.h header file even with stdlib.h */
/* #undef NEED_MALLOC_H */

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

Loading…
Cancel
Save