Merge remote-tracking branch 'upstream/master' into c++_client_channel_external_watcher

reviewable/pr18476/r2
Mark D. Roth 6 years ago
commit c7dc6e55a6
  1. 122
      BUILD
  2. 15
      BUILD.gn
  3. 73
      CMakeLists.txt
  4. 84
      Makefile
  5. 24
      bazel/grpc_build_system.bzl
  6. 4
      bazel/grpc_deps.bzl
  7. 33
      build.yaml
  8. 2
      config.m4
  9. 2
      config.w32
  10. 5
      doc/environment_variables.md
  11. 3
      doc/g_stands_for.md
  12. 1
      doc/python/sphinx/conf.py
  13. 7
      doc/python/sphinx/grpc_status.rst
  14. 1
      doc/python/sphinx/index.rst
  15. 121
      examples/BUILD
  16. 4
      examples/cpp/helloworld/greeter_async_client.cc
  17. 4
      examples/cpp/helloworld/greeter_async_client2.cc
  18. 4
      examples/cpp/helloworld/greeter_async_server.cc
  19. 31
      examples/cpp/route_guide/helper.cc
  20. 4
      examples/cpp/route_guide/route_guide_client.cc
  21. 4
      examples/cpp/route_guide/route_guide_server.cc
  22. 56
      examples/python/errors/BUILD.bazel
  23. 107
      examples/python/errors/README.md
  24. 56
      examples/python/errors/client.py
  25. 90
      examples/python/errors/server.py
  26. 54
      examples/python/errors/test/_error_handling_example_test.py
  27. 17
      gRPC-C++.podspec
  28. 44
      gRPC-Core.podspec
  29. 8
      gRPC-ProtoRPC.podspec
  30. 2
      gRPC-RxLibrary.podspec
  31. 9
      gRPC.podspec
  32. 1
      grpc.def
  33. 8
      grpc.gemspec
  34. 8
      grpc.gyp
  35. 13
      include/grpc/impl/codegen/byte_buffer.h
  36. 2
      include/grpc/impl/codegen/port_platform.h
  37. 46
      include/grpcpp/create_channel_posix.h
  38. 70
      include/grpcpp/create_channel_posix_impl.h
  39. 13
      include/grpcpp/ext/channelz_service_plugin.h
  40. 41
      include/grpcpp/ext/channelz_service_plugin_impl.h
  41. 9
      include/grpcpp/ext/proto_server_reflection_plugin.h
  42. 5
      include/grpcpp/generic/generic_stub.h
  43. 39
      include/grpcpp/health_check_service_interface.h
  44. 55
      include/grpcpp/health_check_service_interface_impl.h
  45. 20
      include/grpcpp/impl/codegen/async_generic_service.h
  46. 118
      include/grpcpp/impl/codegen/client_callback.h
  47. 2
      include/grpcpp/impl/codegen/core_codegen.h
  48. 2
      include/grpcpp/impl/codegen/core_codegen_interface.h
  49. 18
      include/grpcpp/impl/codegen/proto_buffer_reader.h
  50. 2
      include/grpcpp/impl/codegen/rpc_service_method.h
  51. 182
      include/grpcpp/impl/codegen/server_callback.h
  52. 19
      include/grpcpp/impl/server_builder_option.h
  53. 43
      include/grpcpp/impl/server_builder_option_impl.h
  54. 9
      include/grpcpp/impl/server_builder_plugin.h
  55. 31
      include/grpcpp/impl/server_initializer.h
  56. 57
      include/grpcpp/impl/server_initializer_impl.h
  57. 31
      include/grpcpp/opencensus.h
  58. 51
      include/grpcpp/opencensus_impl.h
  59. 45
      include/grpcpp/resource_quota.h
  60. 68
      include/grpcpp/resource_quota_impl.h
  61. 13
      include/grpcpp/server.h
  62. 13
      include/grpcpp/server_builder.h
  63. 14
      include/grpcpp/server_posix.h
  64. 42
      include/grpcpp/server_posix_impl.h
  65. 9
      include/grpcpp/support/channel_arguments.h
  66. 10
      package.xml
  67. 2
      src/c-ares/gen_build_yaml.py
  68. 16
      src/compiler/objective_c_generator.cc
  69. 2
      src/core/README.md
  70. 6
      src/core/ext/filters/client_channel/client_channel.cc
  71. 43
      src/core/ext/filters/client_channel/lb_policy.cc
  72. 32
      src/core/ext/filters/client_channel/lb_policy.h
  73. 116
      src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc
  74. 2
      src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc
  75. 4
      src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h
  76. 8
      src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc
  77. 56
      src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
  78. 24
      src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc
  79. 1
      src/core/ext/filters/client_channel/lb_policy/subchannel_list.h
  80. 595
      src/core/ext/filters/client_channel/lb_policy/xds/xds.cc
  81. 51
      src/core/ext/filters/client_channel/resolver.cc
  82. 31
      src/core/ext/filters/client_channel/resolver.h
  83. 25
      src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
  84. 12
      src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc
  85. 83
      src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc
  86. 17
      src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h
  87. 26
      src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc
  88. 1
      src/core/ext/filters/client_channel/resolver_registry.h
  89. 115
      src/core/ext/filters/client_channel/resolver_result_parsing.cc
  90. 10
      src/core/ext/filters/client_channel/resolver_result_parsing.h
  91. 49
      src/core/ext/filters/client_channel/resolving_lb_policy.cc
  92. 14
      src/core/ext/filters/client_channel/resolving_lb_policy.h
  93. 48
      src/core/ext/filters/client_channel/server_address.cc
  94. 10
      src/core/ext/filters/client_channel/server_address.h
  95. 13
      src/core/ext/filters/client_channel/service_config.cc
  96. 16
      src/core/ext/filters/client_channel/service_config.h
  97. 2
      src/core/ext/filters/client_channel/subchannel.cc
  98. 2
      src/core/ext/filters/message_size/message_size_filter.cc
  99. 57
      src/core/ext/transport/chttp2/transport/chttp2_transport.cc
  100. 14
      src/core/ext/transport/chttp2/transport/incoming_metadata.cc
  101. Some files were not shown because too many files have changed in this diff Show More

122
BUILD

@ -74,11 +74,11 @@ config_setting(
)
# This should be updated along with build.yaml
g_stands_for = "godric"
g_stands_for = "gandalf"
core_version = "7.0.0"
version = "1.20.0-dev"
version = "1.21.0-dev"
GPR_PUBLIC_HDRS = [
"include/grpc/support/alloc.h",
@ -192,8 +192,8 @@ GRPCXX_PUBLIC_HDRS = [
"include/grpc++/impl/service_type.h",
"include/grpc++/impl/sync_cxx11.h",
"include/grpc++/impl/sync_no_cxx11.h",
"include/grpc++/resource_quota.h",
"include/grpc++/security/auth_context.h",
"include/grpc++/resource_quota.h",
"include/grpc++/security/auth_metadata_processor.h",
"include/grpc++/security/credentials.h",
"include/grpc++/security/server_credentials.h",
@ -220,11 +220,13 @@ GRPCXX_PUBLIC_HDRS = [
"include/grpcpp/completion_queue.h",
"include/grpcpp/create_channel.h",
"include/grpcpp/create_channel_posix.h",
"include/grpcpp/create_channel_posix_impl.h",
"include/grpcpp/ext/health_check_service_server_builder_option.h",
"include/grpcpp/generic/async_generic_service.h",
"include/grpcpp/generic/generic_stub.h",
"include/grpcpp/grpcpp.h",
"include/grpcpp/health_check_service_interface.h",
"include/grpcpp/health_check_service_interface_impl.h",
"include/grpcpp/impl/call.h",
"include/grpcpp/impl/channel_argument_option.h",
"include/grpcpp/impl/client_unary_call.h",
@ -235,12 +237,15 @@ GRPCXX_PUBLIC_HDRS = [
"include/grpcpp/impl/rpc_service_method.h",
"include/grpcpp/impl/serialization_traits.h",
"include/grpcpp/impl/server_builder_option.h",
"include/grpcpp/impl/server_builder_option_impl.h",
"include/grpcpp/impl/server_builder_plugin.h",
"include/grpcpp/impl/server_initializer.h",
"include/grpcpp/impl/server_initializer_impl.h",
"include/grpcpp/impl/service_type.h",
"include/grpcpp/impl/sync_cxx11.h",
"include/grpcpp/impl/sync_no_cxx11.h",
"include/grpcpp/resource_quota.h",
"include/grpcpp/resource_quota_impl.h",
"include/grpcpp/security/auth_context.h",
"include/grpcpp/security/auth_metadata_processor.h",
"include/grpcpp/security/credentials.h",
@ -249,6 +254,7 @@ GRPCXX_PUBLIC_HDRS = [
"include/grpcpp/server_builder.h",
"include/grpcpp/server_context.h",
"include/grpcpp/server_posix.h",
"include/grpcpp/server_posix_impl.h",
"include/grpcpp/support/async_stream.h",
"include/grpcpp/support/async_unary_call.h",
"include/grpcpp/support/byte_buffer.h",
@ -307,7 +313,6 @@ grpc_cc_library(
public_hdrs = GRPC_PUBLIC_HDRS + GRPC_SECURE_PUBLIC_HDRS,
standalone = True,
deps = [
"grpc_cfstream",
"grpc_common",
"grpc_lb_policy_grpclb_secure",
"grpc_lb_policy_xds_secure",
@ -361,7 +366,6 @@ grpc_cc_library(
"gpr",
"grpc",
"grpc++_base",
"grpc_cfstream",
"grpc++_codegen_base",
"grpc++_codegen_base_src",
"grpc++_codegen_proto",
@ -578,8 +582,10 @@ grpc_cc_library(
"src/core/lib/gprpp/abstract.h",
"src/core/lib/gprpp/fork.h",
"src/core/lib/gprpp/manual_constructor.h",
"src/core/lib/gprpp/map.h",
"src/core/lib/gprpp/memory.h",
"src/core/lib/gprpp/mutex_lock.h",
"src/core/lib/gprpp/pair.h",
"src/core/lib/gprpp/thd.h",
"src/core/lib/profiling/timers.h",
],
@ -725,12 +731,15 @@ grpc_cc_library(
"src/core/lib/http/parser.cc",
"src/core/lib/iomgr/buffer_list.cc",
"src/core/lib/iomgr/call_combiner.cc",
"src/core/lib/iomgr/cfstream_handle.cc",
"src/core/lib/iomgr/combiner.cc",
"src/core/lib/iomgr/endpoint.cc",
"src/core/lib/iomgr/endpoint_cfstream.cc",
"src/core/lib/iomgr/endpoint_pair_posix.cc",
"src/core/lib/iomgr/endpoint_pair_uv.cc",
"src/core/lib/iomgr/endpoint_pair_windows.cc",
"src/core/lib/iomgr/error.cc",
"src/core/lib/iomgr/error_cfstream.cc",
"src/core/lib/iomgr/ev_epoll1_linux.cc",
"src/core/lib/iomgr/ev_epollex_linux.cc",
"src/core/lib/iomgr/ev_poll_posix.cc",
@ -751,6 +760,7 @@ grpc_cc_library(
"src/core/lib/iomgr/iomgr_custom.cc",
"src/core/lib/iomgr/iomgr_internal.cc",
"src/core/lib/iomgr/iomgr_posix.cc",
"src/core/lib/iomgr/iomgr_posix_cfstream.cc",
"src/core/lib/iomgr/iomgr_windows.cc",
"src/core/lib/iomgr/is_epollexclusive_available.cc",
"src/core/lib/iomgr/load_file.cc",
@ -777,6 +787,7 @@ grpc_cc_library(
"src/core/lib/iomgr/socket_utils_windows.cc",
"src/core/lib/iomgr/socket_windows.cc",
"src/core/lib/iomgr/tcp_client.cc",
"src/core/lib/iomgr/tcp_client_cfstream.cc",
"src/core/lib/iomgr/tcp_client_custom.cc",
"src/core/lib/iomgr/tcp_client_posix.cc",
"src/core/lib/iomgr/tcp_client_windows.cc",
@ -839,7 +850,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",
@ -877,12 +887,15 @@ grpc_cc_library(
"src/core/lib/iomgr/block_annotate.h",
"src/core/lib/iomgr/buffer_list.h",
"src/core/lib/iomgr/call_combiner.h",
"src/core/lib/iomgr/cfstream_handle.h",
"src/core/lib/iomgr/closure.h",
"src/core/lib/iomgr/combiner.h",
"src/core/lib/iomgr/dynamic_annotations.h",
"src/core/lib/iomgr/endpoint.h",
"src/core/lib/iomgr/endpoint_cfstream.h",
"src/core/lib/iomgr/endpoint_pair.h",
"src/core/lib/iomgr/error.h",
"src/core/lib/iomgr/error_cfstream.h",
"src/core/lib/iomgr/error_internal.h",
"src/core/lib/iomgr/ev_epoll1_linux.h",
"src/core/lib/iomgr/ev_epollex_linux.h",
@ -974,7 +987,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",
@ -1038,27 +1050,6 @@ grpc_cc_library(
],
)
grpc_cc_library(
name = "grpc_cfstream",
srcs = [
"src/core/lib/iomgr/cfstream_handle.cc",
"src/core/lib/iomgr/endpoint_cfstream.cc",
"src/core/lib/iomgr/error_cfstream.cc",
"src/core/lib/iomgr/iomgr_posix_cfstream.cc",
"src/core/lib/iomgr/tcp_client_cfstream.cc",
],
hdrs = [
"src/core/lib/iomgr/cfstream_handle.h",
"src/core/lib/iomgr/endpoint_cfstream.h",
"src/core/lib/iomgr/error_cfstream.h",
],
use_cfstream = True,
deps = [
":gpr_base",
":grpc_base",
],
)
grpc_cc_library(
name = "grpc_client_channel",
srcs = [
@ -1085,6 +1076,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 +1104,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 +1175,7 @@ grpc_cc_library(
language = "c++",
deps = [
"grpc_base",
"grpc_client_channel",
],
)
@ -2219,6 +2213,7 @@ grpc_cc_library(
language = "c++",
public_hdrs = [
"include/grpcpp/ext/channelz_service_plugin.h",
"include/grpcpp/ext/channelz_service_plugin_impl.h",
],
deps = [
":grpc++",
@ -2283,6 +2278,7 @@ grpc_cc_library(
],
hdrs = [
"include/grpcpp/opencensus.h",
"include/grpcpp/opencensus_impl.h",
"src/cpp/ext/filters/census/channel_filter.h",
"src/cpp/ext/filters/census/client_filter.h",
"src/cpp/ext/filters/census/context.h",
@ -2315,32 +2311,65 @@ grpc_cc_library(
grpc_cc_library(
name = "envoy_ads_upb",
srcs = [
"src/core/ext/upb-generated/envoy/api/v2/core/address.upb.c",
"src/core/ext/upb-generated/envoy/api/v2/core/base.upb.c",
"src/core/ext/upb-generated/envoy/api/v2/core/health_check.upb.c",
"src/core/ext/upb-generated/envoy/api/v2/auth/cert.upb.c",
"src/core/ext/upb-generated/envoy/api/v2/cds.upb.c",
"src/core/ext/upb-generated/envoy/api/v2/cluster/circuit_breaker.upb.c",
"src/core/ext/upb-generated/envoy/api/v2/cluster/outlier_detection.upb.c",
"src/core/ext/upb-generated/envoy/api/v2/discovery.upb.c",
"src/core/ext/upb-generated/envoy/api/v2/endpoint/endpoint.upb.c",
"src/core/ext/upb-generated/envoy/api/v2/eds.upb.c",
"src/core/ext/upb-generated/envoy/api/v2/endpoint/endpoint.upb.c",
"src/core/ext/upb-generated/envoy/service/discovery/v2/ads.upb.c",
],
hdrs = [
"src/core/ext/upb-generated/envoy/api/v2/core/address.upb.h",
"src/core/ext/upb-generated/envoy/api/v2/core/base.upb.h",
"src/core/ext/upb-generated/envoy/api/v2/core/health_check.upb.h",
"src/core/ext/upb-generated/envoy/api/v2/auth/cert.upb.h",
"src/core/ext/upb-generated/envoy/api/v2/cds.upb.h",
"src/core/ext/upb-generated/envoy/api/v2/cluster/circuit_breaker.upb.h",
"src/core/ext/upb-generated/envoy/api/v2/cluster/outlier_detection.upb.h",
"src/core/ext/upb-generated/envoy/api/v2/discovery.upb.h",
"src/core/ext/upb-generated/envoy/api/v2/endpoint/endpoint.upb.h",
"src/core/ext/upb-generated/envoy/api/v2/eds.upb.h",
"src/core/ext/upb-generated/envoy/api/v2/endpoint/endpoint.upb.h",
"src/core/ext/upb-generated/envoy/service/discovery/v2/ads.upb.h",
],
language = "c++",
external_deps = [
"upb_lib",
],
language = "c++",
deps = [
":envoy_core_upb",
":envoy_type_upb",
":google_api_upb",
":proto_gen_validate_upb",
],
)
grpc_cc_library(
name = "envoy_core_upb",
srcs = [
"src/core/ext/upb-generated/envoy/api/v2/core/address.upb.c",
"src/core/ext/upb-generated/envoy/api/v2/core/base.upb.c",
"src/core/ext/upb-generated/envoy/api/v2/core/config_source.upb.c",
"src/core/ext/upb-generated/envoy/api/v2/core/grpc_service.upb.c",
"src/core/ext/upb-generated/envoy/api/v2/core/health_check.upb.c",
"src/core/ext/upb-generated/envoy/api/v2/core/protocol.upb.c",
],
hdrs = [
"src/core/ext/upb-generated/envoy/api/v2/core/address.upb.h",
"src/core/ext/upb-generated/envoy/api/v2/core/base.upb.h",
"src/core/ext/upb-generated/envoy/api/v2/core/config_source.upb.h",
"src/core/ext/upb-generated/envoy/api/v2/core/grpc_service.upb.h",
"src/core/ext/upb-generated/envoy/api/v2/core/health_check.upb.h",
"src/core/ext/upb-generated/envoy/api/v2/core/protocol.upb.h",
],
external_deps = [
"upb_lib",
],
language = "c++",
tags = ["no_windows"],
deps = [
":envoy_type_upb",
]
":google_api_upb",
":proto_gen_validate_upb",
],
)
grpc_cc_library(
@ -2353,14 +2382,15 @@ grpc_cc_library(
"src/core/ext/upb-generated/envoy/type/percent.upb.h",
"src/core/ext/upb-generated/envoy/type/range.upb.h",
],
language = "c++",
external_deps = [
"upb_lib",
],
language = "c++",
tags = ["no_windows"],
deps = [
":google_api_upb",
":proto_gen_validate_upb"
]
":proto_gen_validate_upb",
],
)
grpc_cc_library(
@ -2373,13 +2403,14 @@ grpc_cc_library(
"src/core/ext/upb-generated/gogoproto/gogo.upb.h",
"src/core/ext/upb-generated/validate/validate.upb.h",
],
language = "c++",
external_deps = [
"upb_lib",
],
language = "c++",
tags = ["no_windows"],
deps = [
":google_api_upb",
]
],
)
grpc_cc_library(
@ -2390,6 +2421,7 @@ grpc_cc_library(
"src/core/ext/upb-generated/google/protobuf/any.upb.c",
"src/core/ext/upb-generated/google/protobuf/descriptor.upb.c",
"src/core/ext/upb-generated/google/protobuf/duration.upb.c",
"src/core/ext/upb-generated/google/protobuf/empty.upb.c",
"src/core/ext/upb-generated/google/protobuf/struct.upb.c",
"src/core/ext/upb-generated/google/protobuf/timestamp.upb.c",
"src/core/ext/upb-generated/google/protobuf/wrappers.upb.c",
@ -2401,15 +2433,17 @@ grpc_cc_library(
"src/core/ext/upb-generated/google/protobuf/any.upb.h",
"src/core/ext/upb-generated/google/protobuf/descriptor.upb.h",
"src/core/ext/upb-generated/google/protobuf/duration.upb.h",
"src/core/ext/upb-generated/google/protobuf/empty.upb.h",
"src/core/ext/upb-generated/google/protobuf/struct.upb.h",
"src/core/ext/upb-generated/google/protobuf/timestamp.upb.h",
"src/core/ext/upb-generated/google/protobuf/wrappers.upb.h",
"src/core/ext/upb-generated/google/rpc/status.upb.h",
],
language = "c++",
external_deps = [
"upb_lib",
],
language = "c++",
tags = ["no_windows"],
)
grpc_generate_one_off_targets()

@ -184,8 +184,10 @@ config("grpc_config") {
"src/core/lib/gprpp/fork.cc",
"src/core/lib/gprpp/fork.h",
"src/core/lib/gprpp/manual_constructor.h",
"src/core/lib/gprpp/map.h",
"src/core/lib/gprpp/memory.h",
"src/core/lib/gprpp/mutex_lock.h",
"src/core/lib/gprpp/pair.h",
"src/core/lib/gprpp/thd.h",
"src/core/lib/gprpp/thd_posix.cc",
"src/core/lib/gprpp/thd_windows.cc",
@ -329,6 +331,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 +766,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",
@ -1005,11 +1007,13 @@ config("grpc_config") {
"include/grpcpp/completion_queue.h",
"include/grpcpp/create_channel.h",
"include/grpcpp/create_channel_posix.h",
"include/grpcpp/create_channel_posix_impl.h",
"include/grpcpp/ext/health_check_service_server_builder_option.h",
"include/grpcpp/generic/async_generic_service.h",
"include/grpcpp/generic/generic_stub.h",
"include/grpcpp/grpcpp.h",
"include/grpcpp/health_check_service_interface.h",
"include/grpcpp/health_check_service_interface_impl.h",
"include/grpcpp/impl/call.h",
"include/grpcpp/impl/channel_argument_option.h",
"include/grpcpp/impl/client_unary_call.h",
@ -1066,10 +1070,13 @@ config("grpc_config") {
"include/grpcpp/impl/rpc_service_method.h",
"include/grpcpp/impl/serialization_traits.h",
"include/grpcpp/impl/server_builder_option.h",
"include/grpcpp/impl/server_builder_option_impl.h",
"include/grpcpp/impl/server_builder_plugin.h",
"include/grpcpp/impl/server_initializer.h",
"include/grpcpp/impl/server_initializer_impl.h",
"include/grpcpp/impl/service_type.h",
"include/grpcpp/resource_quota.h",
"include/grpcpp/resource_quota_impl.h",
"include/grpcpp/security/auth_context.h",
"include/grpcpp/security/auth_metadata_processor.h",
"include/grpcpp/security/credentials.h",
@ -1078,6 +1085,7 @@ config("grpc_config") {
"include/grpcpp/server_builder.h",
"include/grpcpp/server_context.h",
"include/grpcpp/server_posix.h",
"include/grpcpp/server_posix_impl.h",
"include/grpcpp/support/async_stream.h",
"include/grpcpp/support/async_unary_call.h",
"include/grpcpp/support/byte_buffer.h",
@ -1143,10 +1151,12 @@ config("grpc_config") {
"src/core/lib/gprpp/fork.h",
"src/core/lib/gprpp/inlined_vector.h",
"src/core/lib/gprpp/manual_constructor.h",
"src/core/lib/gprpp/map.h",
"src/core/lib/gprpp/memory.h",
"src/core/lib/gprpp/mutex_lock.h",
"src/core/lib/gprpp/optional.h",
"src/core/lib/gprpp/orphanable.h",
"src/core/lib/gprpp/pair.h",
"src/core/lib/gprpp/ref_counted.h",
"src/core/lib/gprpp/ref_counted_ptr.h",
"src/core/lib/gprpp/thd.h",
@ -1251,7 +1261,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",

@ -24,7 +24,7 @@
cmake_minimum_required(VERSION 2.8)
set(PACKAGE_NAME "grpc")
set(PACKAGE_VERSION "1.20.0-dev")
set(PACKAGE_VERSION "1.21.0-dev")
set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
set(PACKAGE_TARNAME "${PACKAGE_NAME}-${PACKAGE_VERSION}")
set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/")
@ -631,6 +631,7 @@ add_dependencies(buildtests_cxx generic_end2end_test)
add_dependencies(buildtests_cxx golden_file_test)
add_dependencies(buildtests_cxx grpc_alts_credentials_options_test)
add_dependencies(buildtests_cxx grpc_cli)
add_dependencies(buildtests_cxx grpc_core_map_test)
add_dependencies(buildtests_cxx grpc_linux_system_roots_test)
add_dependencies(buildtests_cxx grpc_tool_test)
add_dependencies(buildtests_cxx grpclb_api_test)
@ -1109,7 +1110,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 +1245,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 +1536,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 +1599,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 +1947,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 +1978,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 +2271,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 +2302,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 +2571,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 +2637,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
@ -3000,11 +3001,13 @@ foreach(_hdr
include/grpcpp/completion_queue.h
include/grpcpp/create_channel.h
include/grpcpp/create_channel_posix.h
include/grpcpp/create_channel_posix_impl.h
include/grpcpp/ext/health_check_service_server_builder_option.h
include/grpcpp/generic/async_generic_service.h
include/grpcpp/generic/generic_stub.h
include/grpcpp/grpcpp.h
include/grpcpp/health_check_service_interface.h
include/grpcpp/health_check_service_interface_impl.h
include/grpcpp/impl/call.h
include/grpcpp/impl/channel_argument_option.h
include/grpcpp/impl/client_unary_call.h
@ -3015,10 +3018,13 @@ foreach(_hdr
include/grpcpp/impl/rpc_service_method.h
include/grpcpp/impl/serialization_traits.h
include/grpcpp/impl/server_builder_option.h
include/grpcpp/impl/server_builder_option_impl.h
include/grpcpp/impl/server_builder_plugin.h
include/grpcpp/impl/server_initializer.h
include/grpcpp/impl/server_initializer_impl.h
include/grpcpp/impl/service_type.h
include/grpcpp/resource_quota.h
include/grpcpp/resource_quota_impl.h
include/grpcpp/security/auth_context.h
include/grpcpp/security/auth_metadata_processor.h
include/grpcpp/security/credentials.h
@ -3027,6 +3033,7 @@ foreach(_hdr
include/grpcpp/server_builder.h
include/grpcpp/server_context.h
include/grpcpp/server_posix.h
include/grpcpp/server_posix_impl.h
include/grpcpp/support/async_stream.h
include/grpcpp/support/async_unary_call.h
include/grpcpp/support/byte_buffer.h
@ -3457,7 +3464,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 +3500,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
@ -3591,11 +3598,13 @@ foreach(_hdr
include/grpcpp/completion_queue.h
include/grpcpp/create_channel.h
include/grpcpp/create_channel_posix.h
include/grpcpp/create_channel_posix_impl.h
include/grpcpp/ext/health_check_service_server_builder_option.h
include/grpcpp/generic/async_generic_service.h
include/grpcpp/generic/generic_stub.h
include/grpcpp/grpcpp.h
include/grpcpp/health_check_service_interface.h
include/grpcpp/health_check_service_interface_impl.h
include/grpcpp/impl/call.h
include/grpcpp/impl/channel_argument_option.h
include/grpcpp/impl/client_unary_call.h
@ -3606,10 +3615,13 @@ foreach(_hdr
include/grpcpp/impl/rpc_service_method.h
include/grpcpp/impl/serialization_traits.h
include/grpcpp/impl/server_builder_option.h
include/grpcpp/impl/server_builder_option_impl.h
include/grpcpp/impl/server_builder_plugin.h
include/grpcpp/impl/server_initializer.h
include/grpcpp/impl/server_initializer_impl.h
include/grpcpp/impl/service_type.h
include/grpcpp/resource_quota.h
include/grpcpp/resource_quota_impl.h
include/grpcpp/security/auth_context.h
include/grpcpp/security/auth_metadata_processor.h
include/grpcpp/security/credentials.h
@ -3618,6 +3630,7 @@ foreach(_hdr
include/grpcpp/server_builder.h
include/grpcpp/server_context.h
include/grpcpp/server_posix.h
include/grpcpp/server_posix_impl.h
include/grpcpp/support/async_stream.h
include/grpcpp/support/async_unary_call.h
include/grpcpp/support/byte_buffer.h
@ -4554,11 +4567,13 @@ foreach(_hdr
include/grpcpp/completion_queue.h
include/grpcpp/create_channel.h
include/grpcpp/create_channel_posix.h
include/grpcpp/create_channel_posix_impl.h
include/grpcpp/ext/health_check_service_server_builder_option.h
include/grpcpp/generic/async_generic_service.h
include/grpcpp/generic/generic_stub.h
include/grpcpp/grpcpp.h
include/grpcpp/health_check_service_interface.h
include/grpcpp/health_check_service_interface_impl.h
include/grpcpp/impl/call.h
include/grpcpp/impl/channel_argument_option.h
include/grpcpp/impl/client_unary_call.h
@ -4569,10 +4584,13 @@ foreach(_hdr
include/grpcpp/impl/rpc_service_method.h
include/grpcpp/impl/serialization_traits.h
include/grpcpp/impl/server_builder_option.h
include/grpcpp/impl/server_builder_option_impl.h
include/grpcpp/impl/server_builder_plugin.h
include/grpcpp/impl/server_initializer.h
include/grpcpp/impl/server_initializer_impl.h
include/grpcpp/impl/service_type.h
include/grpcpp/resource_quota.h
include/grpcpp/resource_quota_impl.h
include/grpcpp/security/auth_context.h
include/grpcpp/security/auth_metadata_processor.h
include/grpcpp/security/credentials.h
@ -4581,6 +4599,7 @@ foreach(_hdr
include/grpcpp/server_builder.h
include/grpcpp/server_context.h
include/grpcpp/server_posix.h
include/grpcpp/server_posix_impl.h
include/grpcpp/support/async_stream.h
include/grpcpp/support/async_unary_call.h
include/grpcpp/support/byte_buffer.h
@ -4965,6 +4984,7 @@ target_link_libraries(grpcpp_channelz
foreach(_hdr
include/grpcpp/ext/channelz_service_plugin.h
include/grpcpp/ext/channelz_service_plugin_impl.h
)
string(REPLACE "include/" "" _path ${_hdr})
get_filename_component(_path ${_path} PATH)
@ -13455,6 +13475,45 @@ target_link_libraries(grpc_cli
)
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(grpc_core_map_test
test/core/gprpp/map_test.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
)
target_include_directories(grpc_core_map_test
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR}
PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR}
PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR}
PRIVATE ${_gRPC_CARES_INCLUDE_DIR}
PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR}
PRIVATE third_party/googletest/googletest/include
PRIVATE third_party/googletest/googletest
PRIVATE third_party/googletest/googlemock/include
PRIVATE third_party/googletest/googlemock
PRIVATE ${_gRPC_PROTO_GENS_DIR}
)
target_link_libraries(grpc_core_map_test
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util
grpc++
grpc
gpr
${_gRPC_GFLAGS_LIBRARIES}
)
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_CODEGEN)

@ -460,8 +460,8 @@ Q = @
endif
CORE_VERSION = 7.0.0
CPP_VERSION = 1.20.0-dev
CSHARP_VERSION = 1.20.0-dev
CPP_VERSION = 1.21.0-dev
CSHARP_VERSION = 1.21.0-dev
CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES))
CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS)
@ -1209,6 +1209,7 @@ generic_end2end_test: $(BINDIR)/$(CONFIG)/generic_end2end_test
golden_file_test: $(BINDIR)/$(CONFIG)/golden_file_test
grpc_alts_credentials_options_test: $(BINDIR)/$(CONFIG)/grpc_alts_credentials_options_test
grpc_cli: $(BINDIR)/$(CONFIG)/grpc_cli
grpc_core_map_test: $(BINDIR)/$(CONFIG)/grpc_core_map_test
grpc_cpp_plugin: $(BINDIR)/$(CONFIG)/grpc_cpp_plugin
grpc_csharp_plugin: $(BINDIR)/$(CONFIG)/grpc_csharp_plugin
grpc_linux_system_roots_test: $(BINDIR)/$(CONFIG)/grpc_linux_system_roots_test
@ -1680,6 +1681,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/golden_file_test \
$(BINDIR)/$(CONFIG)/grpc_alts_credentials_options_test \
$(BINDIR)/$(CONFIG)/grpc_cli \
$(BINDIR)/$(CONFIG)/grpc_core_map_test \
$(BINDIR)/$(CONFIG)/grpc_linux_system_roots_test \
$(BINDIR)/$(CONFIG)/grpc_tool_test \
$(BINDIR)/$(CONFIG)/grpclb_api_test \
@ -1821,6 +1823,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/golden_file_test \
$(BINDIR)/$(CONFIG)/grpc_alts_credentials_options_test \
$(BINDIR)/$(CONFIG)/grpc_cli \
$(BINDIR)/$(CONFIG)/grpc_core_map_test \
$(BINDIR)/$(CONFIG)/grpc_linux_system_roots_test \
$(BINDIR)/$(CONFIG)/grpc_tool_test \
$(BINDIR)/$(CONFIG)/grpclb_api_test \
@ -2311,6 +2314,8 @@ test_cxx: buildtests_cxx
$(Q) $(BINDIR)/$(CONFIG)/golden_file_test || ( echo test golden_file_test failed ; exit 1 )
$(E) "[RUN] Testing grpc_alts_credentials_options_test"
$(Q) $(BINDIR)/$(CONFIG)/grpc_alts_credentials_options_test || ( echo test grpc_alts_credentials_options_test failed ; exit 1 )
$(E) "[RUN] Testing grpc_core_map_test"
$(Q) $(BINDIR)/$(CONFIG)/grpc_core_map_test || ( echo test grpc_core_map_test failed ; exit 1 )
$(E) "[RUN] Testing grpc_linux_system_roots_test"
$(Q) $(BINDIR)/$(CONFIG)/grpc_linux_system_roots_test || ( echo test grpc_linux_system_roots_test failed ; exit 1 )
$(E) "[RUN] Testing grpc_tool_test"
@ -3556,7 +3561,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 +3696,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 +3981,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 +4044,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 +4385,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 +4416,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 +4696,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 +4727,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 +4970,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 +5036,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 \
@ -5327,11 +5332,13 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/completion_queue.h \
include/grpcpp/create_channel.h \
include/grpcpp/create_channel_posix.h \
include/grpcpp/create_channel_posix_impl.h \
include/grpcpp/ext/health_check_service_server_builder_option.h \
include/grpcpp/generic/async_generic_service.h \
include/grpcpp/generic/generic_stub.h \
include/grpcpp/grpcpp.h \
include/grpcpp/health_check_service_interface.h \
include/grpcpp/health_check_service_interface_impl.h \
include/grpcpp/impl/call.h \
include/grpcpp/impl/channel_argument_option.h \
include/grpcpp/impl/client_unary_call.h \
@ -5342,10 +5349,13 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/impl/rpc_service_method.h \
include/grpcpp/impl/serialization_traits.h \
include/grpcpp/impl/server_builder_option.h \
include/grpcpp/impl/server_builder_option_impl.h \
include/grpcpp/impl/server_builder_plugin.h \
include/grpcpp/impl/server_initializer.h \
include/grpcpp/impl/server_initializer_impl.h \
include/grpcpp/impl/service_type.h \
include/grpcpp/resource_quota.h \
include/grpcpp/resource_quota_impl.h \
include/grpcpp/security/auth_context.h \
include/grpcpp/security/auth_metadata_processor.h \
include/grpcpp/security/credentials.h \
@ -5354,6 +5364,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/server_builder.h \
include/grpcpp/server_context.h \
include/grpcpp/server_posix.h \
include/grpcpp/server_posix_impl.h \
include/grpcpp/support/async_stream.h \
include/grpcpp/support/async_unary_call.h \
include/grpcpp/support/byte_buffer.h \
@ -5828,7 +5839,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 +5875,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 \
@ -5926,11 +5937,13 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/completion_queue.h \
include/grpcpp/create_channel.h \
include/grpcpp/create_channel_posix.h \
include/grpcpp/create_channel_posix_impl.h \
include/grpcpp/ext/health_check_service_server_builder_option.h \
include/grpcpp/generic/async_generic_service.h \
include/grpcpp/generic/generic_stub.h \
include/grpcpp/grpcpp.h \
include/grpcpp/health_check_service_interface.h \
include/grpcpp/health_check_service_interface_impl.h \
include/grpcpp/impl/call.h \
include/grpcpp/impl/channel_argument_option.h \
include/grpcpp/impl/client_unary_call.h \
@ -5941,10 +5954,13 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/impl/rpc_service_method.h \
include/grpcpp/impl/serialization_traits.h \
include/grpcpp/impl/server_builder_option.h \
include/grpcpp/impl/server_builder_option_impl.h \
include/grpcpp/impl/server_builder_plugin.h \
include/grpcpp/impl/server_initializer.h \
include/grpcpp/impl/server_initializer_impl.h \
include/grpcpp/impl/service_type.h \
include/grpcpp/resource_quota.h \
include/grpcpp/resource_quota_impl.h \
include/grpcpp/security/auth_context.h \
include/grpcpp/security/auth_metadata_processor.h \
include/grpcpp/security/credentials.h \
@ -5953,6 +5969,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/server_builder.h \
include/grpcpp/server_context.h \
include/grpcpp/server_posix.h \
include/grpcpp/server_posix_impl.h \
include/grpcpp/support/async_stream.h \
include/grpcpp/support/async_unary_call.h \
include/grpcpp/support/byte_buffer.h \
@ -6838,11 +6855,13 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/completion_queue.h \
include/grpcpp/create_channel.h \
include/grpcpp/create_channel_posix.h \
include/grpcpp/create_channel_posix_impl.h \
include/grpcpp/ext/health_check_service_server_builder_option.h \
include/grpcpp/generic/async_generic_service.h \
include/grpcpp/generic/generic_stub.h \
include/grpcpp/grpcpp.h \
include/grpcpp/health_check_service_interface.h \
include/grpcpp/health_check_service_interface_impl.h \
include/grpcpp/impl/call.h \
include/grpcpp/impl/channel_argument_option.h \
include/grpcpp/impl/client_unary_call.h \
@ -6853,10 +6872,13 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/impl/rpc_service_method.h \
include/grpcpp/impl/serialization_traits.h \
include/grpcpp/impl/server_builder_option.h \
include/grpcpp/impl/server_builder_option_impl.h \
include/grpcpp/impl/server_builder_plugin.h \
include/grpcpp/impl/server_initializer.h \
include/grpcpp/impl/server_initializer_impl.h \
include/grpcpp/impl/service_type.h \
include/grpcpp/resource_quota.h \
include/grpcpp/resource_quota_impl.h \
include/grpcpp/security/auth_context.h \
include/grpcpp/security/auth_metadata_processor.h \
include/grpcpp/security/credentials.h \
@ -6865,6 +6887,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/server_builder.h \
include/grpcpp/server_context.h \
include/grpcpp/server_posix.h \
include/grpcpp/server_posix_impl.h \
include/grpcpp/support/async_stream.h \
include/grpcpp/support/async_unary_call.h \
include/grpcpp/support/byte_buffer.h \
@ -7218,6 +7241,7 @@ LIBGRPCPP_CHANNELZ_SRC = \
PUBLIC_HEADERS_CXX += \
include/grpcpp/ext/channelz_service_plugin.h \
include/grpcpp/ext/channelz_service_plugin_impl.h \
LIBGRPCPP_CHANNELZ_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPCPP_CHANNELZ_SRC))))
@ -8227,6 +8251,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 \
@ -16420,6 +16445,49 @@ endif
endif
GRPC_CORE_MAP_TEST_SRC = \
test/core/gprpp/map_test.cc \
GRPC_CORE_MAP_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GRPC_CORE_MAP_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/grpc_core_map_test: openssl_dep_error
else
ifeq ($(NO_PROTOBUF),true)
# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/grpc_core_map_test: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/grpc_core_map_test: $(PROTOBUF_DEP) $(GRPC_CORE_MAP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LDXX) $(LDFLAGS) $(GRPC_CORE_MAP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/grpc_core_map_test
endif
endif
$(OBJDIR)/$(CONFIG)/test/core/gprpp/map_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_grpc_core_map_test: $(GRPC_CORE_MAP_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(GRPC_CORE_MAP_TEST_OBJS:.o=.dep)
endif
endif
GRPC_CPP_PLUGIN_SRC = \
src/compiler/cpp_plugin.cc \

@ -80,7 +80,8 @@ def grpc_cc_library(
visibility = None,
alwayslink = 0,
data = [],
use_cfstream = False):
use_cfstream = False,
tags = []):
copts = []
if use_cfstream:
copts = if_mac(["-DGRPC_CFSTREAM"])
@ -117,6 +118,7 @@ def grpc_cc_library(
],
alwayslink = alwayslink,
data = data,
tags = tags,
)
def grpc_proto_plugin(name, srcs = [], deps = []):
@ -149,7 +151,6 @@ def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data
if language.upper() == "C":
copts = copts + if_not_windows(["-std=c99"])
args = {
"name": name,
"srcs": srcs,
"args": args,
"data": data,
@ -161,7 +162,17 @@ def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data
"exec_compatible_with": exec_compatible_with,
}
if uses_polling:
native.cc_test(testonly = True, tags = ["manual"], **args)
# Only run targets with pollers for non-MSVC
# TODO(yfen): Enable MSVC for poller-enabled targets without pollers
native.cc_test(
name = name,
testonly = True,
tags = [
"manual",
"no_windows",
],
**args
)
for poller in POLLERS:
native.sh_test(
name = name + "@poller=" + poller,
@ -175,13 +186,13 @@ def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data
poller,
"$(location %s)" % name,
] + args["args"],
tags = tags,
tags = (tags + ["no_windows"]),
exec_compatible_with = exec_compatible_with,
)
else:
native.cc_test(**args)
native.cc_test(tags = tags, **args)
def grpc_cc_binary(name, srcs = [], deps = [], external_deps = [], args = [], data = [], language = "C++", testonly = False, linkshared = False, linkopts = []):
def grpc_cc_binary(name, srcs = [], deps = [], external_deps = [], args = [], data = [], language = "C++", testonly = False, linkshared = False, linkopts = [], tags = []):
copts = []
if language.upper() == "C":
copts = ["-std=c99"]
@ -195,6 +206,7 @@ def grpc_cc_binary(name, srcs = [], deps = [], external_deps = [], args = [], da
deps = deps + _get_external_deps(external_deps),
copts = copts,
linkopts = if_not_windows(["-pthread"]) + linkopts,
tags = tags,
)
def grpc_generate_one_off_targets():

@ -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():

@ -13,8 +13,8 @@ settings:
'#09': Per-language overrides are possible with (eg) ruby_version tag here
'#10': See the expand_version.py for all the quirks here
core_version: 7.0.0
g_stands_for: godric
version: 1.20.0-dev
g_stands_for: gandalf
version: 1.21.0-dev
filegroups:
- name: alts_proto
headers:
@ -194,8 +194,10 @@ filegroups:
- src/core/lib/gprpp/atomic.h
- src/core/lib/gprpp/fork.h
- src/core/lib/gprpp/manual_constructor.h
- src/core/lib/gprpp/map.h
- src/core/lib/gprpp/memory.h
- src/core/lib/gprpp/mutex_lock.h
- src/core/lib/gprpp/pair.h
- src/core/lib/gprpp/thd.h
- src/core/lib/profiling/timers.h
uses:
@ -372,7 +374,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 +531,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 +590,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 +617,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
@ -1345,11 +1347,13 @@ filegroups:
- include/grpcpp/completion_queue.h
- include/grpcpp/create_channel.h
- include/grpcpp/create_channel_posix.h
- include/grpcpp/create_channel_posix_impl.h
- include/grpcpp/ext/health_check_service_server_builder_option.h
- include/grpcpp/generic/async_generic_service.h
- include/grpcpp/generic/generic_stub.h
- include/grpcpp/grpcpp.h
- include/grpcpp/health_check_service_interface.h
- include/grpcpp/health_check_service_interface_impl.h
- include/grpcpp/impl/call.h
- include/grpcpp/impl/channel_argument_option.h
- include/grpcpp/impl/client_unary_call.h
@ -1360,10 +1364,13 @@ filegroups:
- include/grpcpp/impl/rpc_service_method.h
- include/grpcpp/impl/serialization_traits.h
- include/grpcpp/impl/server_builder_option.h
- include/grpcpp/impl/server_builder_option_impl.h
- include/grpcpp/impl/server_builder_plugin.h
- include/grpcpp/impl/server_initializer.h
- include/grpcpp/impl/server_initializer_impl.h
- include/grpcpp/impl/service_type.h
- include/grpcpp/resource_quota.h
- include/grpcpp/resource_quota_impl.h
- include/grpcpp/security/auth_context.h
- include/grpcpp/security/auth_metadata_processor.h
- include/grpcpp/security/credentials.h
@ -1372,6 +1379,7 @@ filegroups:
- include/grpcpp/server_builder.h
- include/grpcpp/server_context.h
- include/grpcpp/server_posix.h
- include/grpcpp/server_posix_impl.h
- include/grpcpp/support/async_stream.h
- include/grpcpp/support/async_unary_call.h
- include/grpcpp/support/byte_buffer.h
@ -1917,6 +1925,7 @@ libs:
language: c++
public_headers:
- include/grpcpp/ext/channelz_service_plugin.h
- include/grpcpp/ext/channelz_service_plugin_impl.h
headers:
- src/cpp/server/channelz/channelz_service.h
src:
@ -4735,6 +4744,22 @@ targets:
- grpc
- gpr
- grpc++_test_config
- name: grpc_core_map_test
gtest: true
build: test
language: c++
headers:
- test/core/gprpp/map_tester.h
src:
- test/core/gprpp/map_test.cc
deps:
- grpc_test_util
- grpc++
- grpc
- gpr
uses:
- grpc++_test
uses_polling: false
- name: grpc_cpp_plugin
build: protoc
language: c++

@ -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

@ -19,4 +19,5 @@
- 1.17 'g' stands for ['gizmo'](https://github.com/grpc/grpc/tree/v1.17.x)
- 1.18 'g' stands for ['goose'](https://github.com/grpc/grpc/tree/v1.18.x)
- 1.19 'g' stands for ['gold'](https://github.com/grpc/grpc/tree/v1.19.x)
- 1.20 'g' stands for ['godric'](https://github.com/grpc/grpc/tree/master)
- 1.20 'g' stands for ['godric'](https://github.com/grpc/grpc/tree/v1.20.x)
- 1.21 'g' stands for ['gandalf'](https://github.com/grpc/grpc/tree/master)

@ -22,6 +22,7 @@ sys.path.insert(0, os.path.join(PYTHON_FOLDER, 'grpcio'))
sys.path.insert(0, os.path.join(PYTHON_FOLDER, 'grpcio_channelz'))
sys.path.insert(0, os.path.join(PYTHON_FOLDER, 'grpcio_health_checking'))
sys.path.insert(0, os.path.join(PYTHON_FOLDER, 'grpcio_reflection'))
sys.path.insert(0, os.path.join(PYTHON_FOLDER, 'grpcio_status'))
sys.path.insert(0, os.path.join(PYTHON_FOLDER, 'grpcio_testing'))
# -- Project information -----------------------------------------------------

@ -0,0 +1,7 @@
gRPC Status
====================
Module Contents
---------------
.. automodule:: grpc_status.rpc_status

@ -13,6 +13,7 @@ API Reference
grpc_channelz
grpc_health_checking
grpc_reflection
grpc_status
grpc_testing
glossary

@ -16,7 +16,9 @@ licenses(["notice"]) # 3-clause BSD
package(default_visibility = ["//visibility:public"])
load("@grpc_python_dependencies//:requirements.bzl", "requirement")
load("//bazel:grpc_build_system.bzl", "grpc_proto_library")
load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library")
grpc_proto_library(
name = "auth_sample",
@ -43,60 +45,121 @@ grpc_proto_library(
srcs = ["protos/keyvaluestore.proto"],
)
py_proto_library(
name = "py_helloworld",
protos = ["protos/helloworld.proto"],
with_grpc = True,
deps = [requirement('protobuf'),],
)
cc_binary(
name = "greeter_client",
srcs = ["cpp/helloworld/greeter_client.cc"],
defines = ["BAZEL_BUILD"],
deps = [":helloworld", "//:grpc++"],
deps = [
":helloworld",
"//:grpc++",
],
)
cc_binary(
name = "greeter_async_client",
srcs = ["cpp/helloworld/greeter_async_client.cc"],
defines = ["BAZEL_BUILD"],
deps = [
":helloworld",
"//:grpc++",
],
)
cc_binary(
name = "greeter_async_client2",
srcs = ["cpp/helloworld/greeter_async_client2.cc"],
defines = ["BAZEL_BUILD"],
deps = [
":helloworld",
"//:grpc++",
],
)
cc_binary(
name = "greeter_server",
srcs = ["cpp/helloworld/greeter_server.cc"],
defines = ["BAZEL_BUILD"],
deps = [":helloworld", "//:grpc++"],
deps = [
":helloworld",
"//:grpc++",
],
)
cc_binary(
name = "greeter_async_server",
srcs = ["cpp/helloworld/greeter_async_server.cc"],
defines = ["BAZEL_BUILD"],
deps = [
":helloworld",
"//:grpc++",
],
)
cc_binary(
name = "metadata_client",
srcs = ["cpp/metadata/greeter_client.cc"],
defines = ["BAZEL_BUILD"],
deps = [":helloworld", "//:grpc++"],
deps = [
":helloworld",
"//:grpc++",
],
)
cc_binary(
name = "metadata_server",
srcs = ["cpp/metadata/greeter_server.cc"],
defines = ["BAZEL_BUILD"],
deps = [":helloworld", "//:grpc++"],
deps = [
":helloworld",
"//:grpc++",
],
)
cc_binary(
name = "lb_client",
srcs = ["cpp/load_balancing/greeter_client.cc"],
defines = ["BAZEL_BUILD"],
deps = [":helloworld", "//:grpc++"],
deps = [
":helloworld",
"//:grpc++",
],
)
cc_binary(
name = "lb_server",
srcs = ["cpp/load_balancing/greeter_server.cc"],
defines = ["BAZEL_BUILD"],
deps = [":helloworld", "//:grpc++"],
deps = [
":helloworld",
"//:grpc++",
],
)
cc_binary(
name = "compression_client",
srcs = ["cpp/compression/greeter_client.cc"],
defines = ["BAZEL_BUILD"],
deps = [":helloworld", "//:grpc++"],
deps = [
":helloworld",
"//:grpc++",
],
)
cc_binary(
name = "compression_server",
srcs = ["cpp/compression/greeter_server.cc"],
defines = ["BAZEL_BUILD"],
deps = [":helloworld", "//:grpc++"],
deps = [
":helloworld",
"//:grpc++",
],
)
cc_binary(
@ -104,12 +167,48 @@ cc_binary(
srcs = ["cpp/keyvaluestore/caching_interceptor.h",
"cpp/keyvaluestore/client.cc"],
defines = ["BAZEL_BUILD"],
deps = [":keyvaluestore", "//:grpc++"],
deps = [
":keyvaluestore",
"//:grpc++",
],
)
cc_binary(
name = "keyvaluestore_server",
srcs = ["cpp/keyvaluestore/server.cc"],
defines = ["BAZEL_BUILD"],
deps = [":keyvaluestore", "//:grpc++"],
)
deps = [
":keyvaluestore",
"//:grpc++",
],
)
cc_binary(
name = "route_guide_client",
srcs = [
"cpp/route_guide/helper.cc",
"cpp/route_guide/helper.h",
"cpp/route_guide/route_guide_client.cc",
],
data = ["cpp/route_guide/route_guide_db.json"],
defines = ["BAZEL_BUILD"],
deps = [
":route_guide",
"//:grpc++",
],
)
cc_binary(
name = "route_guide_server",
srcs = [
"cpp/route_guide/helper.cc",
"cpp/route_guide/helper.h",
"cpp/route_guide/route_guide_server.cc",
],
data = ["cpp/route_guide/route_guide_db.json"],
defines = ["BAZEL_BUILD"],
deps = [
":route_guide",
"//:grpc++",
],
)

@ -23,7 +23,11 @@
#include <grpcpp/grpcpp.h>
#include <grpc/support/log.h>
#ifdef BAZEL_BUILD
#include "examples/protos/helloworld.grpc.pb.h"
#else
#include "helloworld.grpc.pb.h"
#endif
using grpc::Channel;
using grpc::ClientAsyncResponseReader;

@ -24,7 +24,11 @@
#include <grpc/support/log.h>
#include <thread>
#ifdef BAZEL_BUILD
#include "examples/protos/helloworld.grpc.pb.h"
#else
#include "helloworld.grpc.pb.h"
#endif
using grpc::Channel;
using grpc::ClientAsyncResponseReader;

@ -24,7 +24,11 @@
#include <grpcpp/grpcpp.h>
#include <grpc/support/log.h>
#ifdef BAZEL_BUILD
#include "examples/protos/helloworld.grpc.pb.h"
#else
#include "helloworld.grpc.pb.h"
#endif
using grpc::Server;
using grpc::ServerAsyncResponseWriter;

@ -23,7 +23,11 @@
#include <sstream>
#include <string>
#include <vector>
#ifdef BAZEL_BUILD
#include "examples/protos/route_guide.grpc.pb.h"
#else
#include "route_guide.grpc.pb.h"
#endif
namespace routeguide {
@ -35,13 +39,16 @@ std::string GetDbFileContent(int argc, char** argv) {
size_t start_position = argv_1.find(arg_str);
if (start_position != std::string::npos) {
start_position += arg_str.size();
if (argv_1[start_position] == ' ' ||
argv_1[start_position] == '=') {
if (argv_1[start_position] == ' ' || argv_1[start_position] == '=') {
db_path = argv_1.substr(start_position + 1);
}
}
} else {
#ifdef BAZEL_BUILD
db_path = "cpp/route_guide/route_guide_db.json";
#else
db_path = "route_guide_db.json";
#endif
}
std::ifstream db_file(db_path);
if (!db_file.is_open()) {
@ -60,17 +67,13 @@ class Parser {
public:
explicit Parser(const std::string& db) : db_(db) {
// Remove all spaces.
db_.erase(
std::remove_if(db_.begin(), db_.end(), isspace),
db_.end());
db_.erase(std::remove_if(db_.begin(), db_.end(), isspace), db_.end());
if (!Match("[")) {
SetFailedAndReturnFalse();
}
}
bool Finished() {
return current_ >= db_.size();
}
bool Finished() { return current_ >= db_.size(); }
bool TryParseOne(Feature* feature) {
if (failed_ || Finished() || !Match("{")) {
@ -96,7 +99,7 @@ class Parser {
if (current_ == db_.size()) {
return SetFailedAndReturnFalse();
}
feature->set_name(db_.substr(name_start, current_-name_start-1));
feature->set_name(db_.substr(name_start, current_ - name_start - 1));
if (!Match("},")) {
if (db_[current_ - 1] == ']' && current_ == db_.size()) {
return true;
@ -107,7 +110,6 @@ class Parser {
}
private:
bool SetFailedAndReturnFalse() {
failed_ = true;
return false;
@ -121,7 +123,8 @@ class Parser {
void ReadLong(long* l) {
size_t start = current_;
while (current_ != db_.size() && db_[current_] != ',' && db_[current_] != '}') {
while (current_ != db_.size() && db_[current_] != ',' &&
db_[current_] != '}') {
current_++;
}
// It will throw an exception if fails.
@ -154,10 +157,8 @@ void ParseDb(const std::string& db, std::vector<Feature>* feature_list) {
break;
}
}
std::cout << "DB parsed, loaded " << feature_list->size()
<< " features." << std::endl;
std::cout << "DB parsed, loaded " << feature_list->size() << " features."
<< std::endl;
}
} // namespace routeguide

@ -29,7 +29,11 @@
#include <grpcpp/create_channel.h>
#include <grpcpp/security/credentials.h>
#include "helper.h"
#ifdef BAZEL_BUILD
#include "examples/protos/route_guide.grpc.pb.h"
#else
#include "route_guide.grpc.pb.h"
#endif
using grpc::Channel;
using grpc::ClientContext;

@ -29,7 +29,11 @@
#include <grpcpp/server_context.h>
#include <grpcpp/security/server_credentials.h>
#include "helper.h"
#ifdef BAZEL_BUILD
#include "examples/protos/route_guide.grpc.pb.h"
#else
#include "route_guide.grpc.pb.h"
#endif
using grpc::Server;
using grpc::ServerBuilder;

@ -0,0 +1,56 @@
# Copyright 2019 The gRPC Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
load("@grpc_python_dependencies//:requirements.bzl", "requirement")
py_library(
name = "client",
testonly = 1,
srcs = ["client.py"],
deps = [
"//src/python/grpcio/grpc:grpcio",
"//src/python/grpcio_status/grpc_status:grpc_status",
"//examples:py_helloworld",
requirement('googleapis-common-protos'),
],
)
py_library(
name = "server",
testonly = 1,
srcs = ["server.py"],
deps = [
"//src/python/grpcio/grpc:grpcio",
"//src/python/grpcio_status/grpc_status:grpc_status",
"//examples:py_helloworld",
] + select({
"//conditions:default": [requirement("futures")],
"//:python3": [],
}),
)
py_test(
name = "test/_error_handling_example_test",
srcs = ["test/_error_handling_example_test.py"],
deps = [
":client",
":server",
"//src/python/grpcio_tests/tests:bazel_namespace_package_hack",
],
size = "small",
imports = [
"../../../src/python/grpcio_status",
"../../../src/python/grpcio_tests",
],
)

@ -0,0 +1,107 @@
# gRPC Python Error Handling Example
The goal of this example is sending error status from server that is more complicated than a code and detail string.
The definition for an RPC method in proto files contains request message and response message. There are many error states that can be shared across RPC methods (e.g. stack trace, insufficient quota). Using a different path to handle error will make the code more maintainable.
Ideally, the final status of an RPC should be described in the trailing headers of HTTP2, and gRPC Python provides helper functions in `grpcio-status` package to assist the packing and unpacking of error status.
### Requirement
```
grpcio>=1.18.0
grpcio-status>=1.18.0
googleapis-common-protos>=1.5.5
```
### Error Detail Proto
You may provide any custom proto message as error detail in your implementation. Here are protos are defined by Google Cloud Library Team:
* [code.proto]([https://github.com/googleapis/api-common-protos/blob/master/google/rpc/code.proto](https://github.com/googleapis/api-common-protos/blob/87185dfffad4afa5a33a8c153f0e1ea53b4f85dc/google/rpc/code.proto)) contains definition of RPC error codes.
* [error_details.proto]([https://github.com/googleapis/api-common-protos/blob/master/google/rpc/error_details.proto](https://github.com/googleapis/api-common-protos/blob/87185dfffad4afa5a33a8c153f0e1ea53b4f85dc/google/rpc/error_details.proto)) contains definitions of common error details.
### Definition of Status Proto
Here is the definition of Status proto. For full text, please see [status.proto](https://github.com/googleapis/api-common-protos/blob/87185dfffad4afa5a33a8c153f0e1ea53b4f85dc/google/rpc/status.proto).
```proto
// The `Status` type defines a logical error model that is suitable for different
// programming environments, including REST APIs and RPC APIs. It is used by
// [gRPC](https://github.com/grpc). The error model is designed to be:
//
// - Simple to use and understand for most users
// - Flexible enough to meet unexpected needs
//
// # Overview
//
// The `Status` message contains three pieces of data: error code, error message,
// and error details. The error code should be an enum value of
// [google.rpc.Code][google.rpc.Code], but it may accept additional error codes if needed. The
// error message should be a developer-facing English message that helps
// developers *understand* and *resolve* the error. If a localized user-facing
// error message is needed, put the localized message in the error details or
// localize it in the client. The optional error details may contain arbitrary
// information about the error. There is a predefined set of error detail types
// in the package `google.rpc` that can be used for common error conditions.
//
// # Language mapping
//
// The `Status` message is the logical representation of the error model, but it
// is not necessarily the actual wire format. When the `Status` message is
// exposed in different client libraries and different wire protocols, it can be
// mapped differently. For example, it will likely be mapped to some exceptions
// in Java, but more likely mapped to some error codes in C.
//
// # Other uses
//
// The error model and the `Status` message can be used in a variety of
// environments, either with or without APIs, to provide a
// consistent developer experience across different environments.
//
// Example uses of this error model include:
//
// - Partial errors. If a service needs to return partial errors to the client,
// it may embed the `Status` in the normal response to indicate the partial
// errors.
//
// - Workflow errors. A typical workflow has multiple steps. Each step may
// have a `Status` message for error reporting.
//
// - Batch operations. If a client uses batch request and batch response, the
// `Status` message should be used directly inside batch response, one for
// each error sub-response.
//
// - Asynchronous operations. If an API call embeds asynchronous operation
// results in its response, the status of those operations should be
// represented directly using the `Status` message.
//
// - Logging. If some API errors are stored in logs, the message `Status` could
// be used directly after any stripping needed for security/privacy reasons.
message Status {
// The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code].
int32 code = 1;
// A developer-facing error message, which should be in English. Any
// user-facing error message should be localized and sent in the
// [google.rpc.Status.details][google.rpc.Status.details] field, or localized by the client.
string message = 2;
// A list of messages that carry the error details. There is a common set of
// message types for APIs to use.
repeated google.protobuf.Any details = 3;
}
```
### Usage of Well-Known-Proto `Any`
Please check [ProtoBuf Document: Any](https://developers.google.com/protocol-buffers/docs/reference/python-generated#any)
```Python
any_message.Pack(message)
any_message.Unpack(message)
assert any_message.Is(message.DESCRIPTOR)
```

@ -0,0 +1,56 @@
# Copyright 2019 The gRPC Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""This example handles rich error status in client-side."""
from __future__ import print_function
import logging
import grpc
from grpc_status import rpc_status
from google.rpc import error_details_pb2
from examples.protos import helloworld_pb2
from examples.protos import helloworld_pb2_grpc
_LOGGER = logging.getLogger(__name__)
def process(stub):
try:
response = stub.SayHello(helloworld_pb2.HelloRequest(name='Alice'))
_LOGGER.info('Call success: %s', response.message)
except grpc.RpcError as rpc_error:
_LOGGER.error('Call failure: %s', rpc_error)
status = rpc_status.from_call(rpc_error)
for detail in status.details:
if detail.Is(error_details_pb2.QuotaFailure.DESCRIPTOR):
info = error_details_pb2.QuotaFailure()
detail.Unpack(info)
_LOGGER.error('Quota failure: %s', info)
else:
raise RuntimeError('Unexpected failure: %s' % detail)
def main():
# NOTE(gRPC Python Team): .close() is possible on a channel and should be
# used in circumstances in which the with statement does not fit the needs
# of the code.
with grpc.insecure_channel('localhost:50051') as channel:
stub = helloworld_pb2_grpc.GreeterStub(channel)
process(stub)
if __name__ == '__main__':
logging.basicConfig()
main()

@ -0,0 +1,90 @@
# Copyright 2019 The gRPC Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""This example sends out rich error status from server-side."""
from concurrent import futures
import time
import logging
import threading
import grpc
from grpc_status import rpc_status
from google.protobuf import any_pb2
from google.rpc import code_pb2, status_pb2, error_details_pb2
from examples.protos import helloworld_pb2
from examples.protos import helloworld_pb2_grpc
_ONE_DAY_IN_SECONDS = 60 * 60 * 24
def create_greet_limit_exceed_error_status(name):
detail = any_pb2.Any()
detail.Pack(
error_details_pb2.QuotaFailure(
violations=[
error_details_pb2.QuotaFailure.Violation(
subject="name: %s" % name,
description="Limit one greeting per person",
)
],))
return status_pb2.Status(
code=code_pb2.RESOURCE_EXHAUSTED,
message='Request limit exceeded.',
details=[detail],
)
class LimitedGreeter(helloworld_pb2_grpc.GreeterServicer):
def __init__(self):
self._lock = threading.RLock()
self._greeted = set()
def SayHello(self, request, context):
with self._lock:
if request.name in self._greeted:
rich_status = create_greet_limit_exceed_error_status(
request.name)
context.abort_with_status(rpc_status.to_status(rich_status))
else:
self._greeted.add(request.name)
return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name)
def create_server(server_address):
server = grpc.server(futures.ThreadPoolExecutor())
helloworld_pb2_grpc.add_GreeterServicer_to_server(LimitedGreeter(), server)
port = server.add_insecure_port(server_address)
return server, port
def serve(server):
server.start()
try:
while True:
time.sleep(_ONE_DAY_IN_SECONDS)
except KeyboardInterrupt:
server.stop(None)
def main():
server, unused_port = create_server('[::]:50051')
serve(server)
if __name__ == '__main__':
logging.basicConfig()
main()

@ -0,0 +1,54 @@
# Copyright 2019 The gRPC Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Tests of the error handling example."""
# NOTE(lidiz) This module only exists in Bazel BUILD file, for more details
# please refer to comments in the "bazel_namespace_package_hack" module.
try:
from tests import bazel_namespace_package_hack
bazel_namespace_package_hack.sys_path_to_site_dir_hack()
except ImportError:
pass
import unittest
import logging
import grpc
from examples.protos import helloworld_pb2_grpc
from examples.python.errors import client as error_handling_client
from examples.python.errors import server as error_handling_server
class ErrorHandlingExampleTest(unittest.TestCase):
def setUp(self):
self._server, port = error_handling_server.create_server('[::]:0')
self._server.start()
self._channel = grpc.insecure_channel('localhost:%d' % port)
def tearDown(self):
self._channel.close()
self._server.stop(None)
def test_error_handling_example(self):
stub = helloworld_pb2_grpc.GreeterStub(self._channel)
error_handling_client.process(stub)
error_handling_client.process(stub)
# No unhandled exception raised, test passed!
if __name__ == '__main__':
logging.basicConfig()
unittest.main(verbosity=2)

@ -23,7 +23,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-C++'
# TODO (mxyan): use version that match gRPC version when pod is stabilized
# version = '1.20.0-dev'
# version = '1.21.0-dev'
version = '0.0.8-dev'
s.version = version
s.summary = 'gRPC C++ library'
@ -31,7 +31,7 @@ Pod::Spec.new do |s|
s.license = 'Apache License, Version 2.0'
s.authors = { 'The gRPC contributors' => 'grpc-packages@google.com' }
grpc_version = '1.20.0-dev'
grpc_version = '1.21.0-dev'
s.source = {
:git => 'https://github.com/grpc/grpc.git',
@ -86,11 +86,13 @@ Pod::Spec.new do |s|
'include/grpcpp/completion_queue.h',
'include/grpcpp/create_channel.h',
'include/grpcpp/create_channel_posix.h',
'include/grpcpp/create_channel_posix_impl.h',
'include/grpcpp/ext/health_check_service_server_builder_option.h',
'include/grpcpp/generic/async_generic_service.h',
'include/grpcpp/generic/generic_stub.h',
'include/grpcpp/grpcpp.h',
'include/grpcpp/health_check_service_interface.h',
'include/grpcpp/health_check_service_interface_impl.h',
'include/grpcpp/impl/call.h',
'include/grpcpp/impl/channel_argument_option.h',
'include/grpcpp/impl/client_unary_call.h',
@ -101,10 +103,13 @@ Pod::Spec.new do |s|
'include/grpcpp/impl/rpc_service_method.h',
'include/grpcpp/impl/serialization_traits.h',
'include/grpcpp/impl/server_builder_option.h',
'include/grpcpp/impl/server_builder_option_impl.h',
'include/grpcpp/impl/server_builder_plugin.h',
'include/grpcpp/impl/server_initializer.h',
'include/grpcpp/impl/server_initializer_impl.h',
'include/grpcpp/impl/service_type.h',
'include/grpcpp/resource_quota.h',
'include/grpcpp/resource_quota_impl.h',
'include/grpcpp/security/auth_context.h',
'include/grpcpp/security/auth_metadata_processor.h',
'include/grpcpp/security/credentials.h',
@ -113,6 +118,7 @@ Pod::Spec.new do |s|
'include/grpcpp/server_builder.h',
'include/grpcpp/server_context.h',
'include/grpcpp/server_posix.h',
'include/grpcpp/server_posix_impl.h',
'include/grpcpp/support/async_stream.h',
'include/grpcpp/support/async_unary_call.h',
'include/grpcpp/support/byte_buffer.h',
@ -253,8 +259,10 @@ Pod::Spec.new do |s|
'src/core/lib/gprpp/atomic.h',
'src/core/lib/gprpp/fork.h',
'src/core/lib/gprpp/manual_constructor.h',
'src/core/lib/gprpp/map.h',
'src/core/lib/gprpp/memory.h',
'src/core/lib/gprpp/mutex_lock.h',
'src/core/lib/gprpp/pair.h',
'src/core/lib/gprpp/thd.h',
'src/core/lib/profiling/timers.h',
'src/core/ext/transport/chttp2/transport/bin_decoder.h',
@ -367,6 +375,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 +518,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',
@ -568,8 +576,10 @@ Pod::Spec.new do |s|
'src/core/lib/gprpp/atomic.h',
'src/core/lib/gprpp/fork.h',
'src/core/lib/gprpp/manual_constructor.h',
'src/core/lib/gprpp/map.h',
'src/core/lib/gprpp/memory.h',
'src/core/lib/gprpp/mutex_lock.h',
'src/core/lib/gprpp/pair.h',
'src/core/lib/gprpp/thd.h',
'src/core/lib/profiling/timers.h',
'src/core/lib/avl/avl.h',
@ -700,7 +710,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',

@ -22,7 +22,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-Core'
version = '1.20.0-dev'
version = '1.21.0-dev'
s.version = version
s.summary = 'Core cross-platform gRPC library, written in C'
s.homepage = 'https://grpc.io'
@ -208,8 +208,10 @@ Pod::Spec.new do |s|
'src/core/lib/gprpp/atomic.h',
'src/core/lib/gprpp/fork.h',
'src/core/lib/gprpp/manual_constructor.h',
'src/core/lib/gprpp/map.h',
'src/core/lib/gprpp/memory.h',
'src/core/lib/gprpp/mutex_lock.h',
'src/core/lib/gprpp/pair.h',
'src/core/lib/gprpp/thd.h',
'src/core/lib/profiling/timers.h',
'src/core/lib/gpr/alloc.cc',
@ -361,6 +363,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 +506,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 +676,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 +808,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',
@ -855,7 +857,15 @@ Pod::Spec.new do |s|
'src/core/ext/filters/http/client_authority_filter.cc',
'src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc',
'src/core/ext/filters/workarounds/workaround_utils.cc',
'src/core/plugin_registry/grpc_plugin_registry.cc'
'src/core/plugin_registry/grpc_plugin_registry.cc',
'src/core/lib/iomgr/cfstream_handle.cc',
'src/core/lib/iomgr/endpoint_cfstream.cc',
'src/core/lib/iomgr/error_cfstream.cc',
'src/core/lib/iomgr/iomgr_posix_cfstream.cc',
'src/core/lib/iomgr/tcp_client_cfstream.cc',
'src/core/lib/iomgr/cfstream_handle.h',
'src/core/lib/iomgr/endpoint_cfstream.h',
'src/core/lib/iomgr/error_cfstream.h'
ss.private_header_files = 'src/core/lib/gpr/alloc.h',
'src/core/lib/gpr/arena.h',
@ -877,8 +887,10 @@ Pod::Spec.new do |s|
'src/core/lib/gprpp/atomic.h',
'src/core/lib/gprpp/fork.h',
'src/core/lib/gprpp/manual_constructor.h',
'src/core/lib/gprpp/map.h',
'src/core/lib/gprpp/memory.h',
'src/core/lib/gprpp/mutex_lock.h',
'src/core/lib/gprpp/pair.h',
'src/core/lib/gprpp/thd.h',
'src/core/lib/profiling/timers.h',
'src/core/ext/transport/chttp2/transport/bin_decoder.h',
@ -991,6 +1003,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 +1146,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',
@ -1160,26 +1172,15 @@ Pod::Spec.new do |s|
'src/core/ext/filters/message_size/message_size_filter.h',
'src/core/ext/filters/http/client_authority_filter.h',
'src/core/ext/filters/workarounds/workaround_cronet_compression_filter.h',
'src/core/ext/filters/workarounds/workaround_utils.h'
'src/core/ext/filters/workarounds/workaround_utils.h',
'src/core/lib/iomgr/cfstream_handle.h',
'src/core/lib/iomgr/endpoint_cfstream.h',
'src/core/lib/iomgr/error_cfstream.h'
end
# CFStream is now default. Leaving this subspec only for compatibility purpose.
s.subspec 'CFStream-Implementation' do |ss|
ss.header_mappings_dir = '.'
ss.dependency "#{s.name}/Implementation", version
ss.pod_target_xcconfig = {
'GCC_PREPROCESSOR_DEFINITIONS' => 'GRPC_CFSTREAM=1'
}
ss.source_files = 'src/core/lib/iomgr/cfstream_handle.cc',
'src/core/lib/iomgr/endpoint_cfstream.cc',
'src/core/lib/iomgr/error_cfstream.cc',
'src/core/lib/iomgr/iomgr_posix_cfstream.cc',
'src/core/lib/iomgr/tcp_client_cfstream.cc',
'src/core/lib/iomgr/cfstream_handle.h',
'src/core/lib/iomgr/endpoint_cfstream.h',
'src/core/lib/iomgr/error_cfstream.h'
ss.private_header_files = 'src/core/lib/iomgr/cfstream_handle.h',
'src/core/lib/iomgr/endpoint_cfstream.h',
'src/core/lib/iomgr/error_cfstream.h'
end
s.subspec 'Cronet-Interface' do |ss|
@ -1235,7 +1236,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',

@ -21,7 +21,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-ProtoRPC'
version = '1.20.0-dev'
version = '1.21.0-dev'
s.version = version
s.summary = 'RPC library for Protocol Buffers, based on gRPC'
s.homepage = 'https://grpc.io'
@ -53,12 +53,10 @@ Pod::Spec.new do |s|
ss.source_files = "#{src_dir}/*.{h,m}"
end
# CFStream is now default. Leaving this subspec only for compatibility purpose.
s.subspec 'CFStream' do |ss|
ss.dependency 'gRPC/CFStream', version
ss.dependency "#{s.name}/Main", version
ss.pod_target_xcconfig = {
'GCC_PREPROCESSOR_DEFINITIONS' => 'GRPC_CFSTREAM=1'
}
end
s.pod_target_xcconfig = {

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

@ -20,7 +20,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC'
version = '1.20.0-dev'
version = '1.21.0-dev'
s.version = version
s.summary = 'gRPC client library for iOS/OSX'
s.homepage = 'https://grpc.io'
@ -64,14 +64,9 @@ Pod::Spec.new do |s|
ss.dependency 'gRPC-Core', version
end
# This subspec is mutually exclusive with the `Main` subspec
# CFStream is now default. Leaving this subspec only for compatibility purpose.
s.subspec 'CFStream' do |ss|
ss.dependency 'gRPC-Core/CFStream-Implementation', version
ss.dependency "#{s.name}/Main", version
ss.pod_target_xcconfig = {
'GCC_PREPROCESSOR_DEFINITIONS' => 'GRPC_CFSTREAM=1'
}
end
s.subspec 'GID' do |ss|

@ -149,6 +149,7 @@ EXPORTS
grpc_byte_buffer_reader_init
grpc_byte_buffer_reader_destroy
grpc_byte_buffer_reader_next
grpc_byte_buffer_reader_peek
grpc_byte_buffer_reader_readall
grpc_raw_byte_buffer_from_reader
gpr_log_severity_string

@ -102,8 +102,10 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/gprpp/atomic.h )
s.files += %w( src/core/lib/gprpp/fork.h )
s.files += %w( src/core/lib/gprpp/manual_constructor.h )
s.files += %w( src/core/lib/gprpp/map.h )
s.files += %w( src/core/lib/gprpp/memory.h )
s.files += %w( src/core/lib/gprpp/mutex_lock.h )
s.files += %w( src/core/lib/gprpp/pair.h )
s.files += %w( src/core/lib/gprpp/thd.h )
s.files += %w( src/core/lib/profiling/timers.h )
s.files += %w( src/core/lib/gpr/alloc.cc )
@ -295,6 +297,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 +440,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 +610,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 +745,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 +1268,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 +1320,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,6 +73,19 @@ GRPCAPI void grpc_byte_buffer_reader_destroy(grpc_byte_buffer_reader* reader);
GRPCAPI int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader* reader,
grpc_slice* slice);
/** EXPERIMENTAL API - This function may be removed and changed, in the future.
*
* Updates \a slice with the next piece of data from from \a reader and returns
* 1. Returns 0 at the end of the stream. Caller is responsible for making sure
* the slice pointer remains valid when accessed.
*
* NOTE: Do not use this function unless the caller can guarantee that the
* underlying grpc_byte_buffer outlasts the use of the slice. This is only
* safe when the underlying grpc_byte_buffer remains immutable while slice
* is being accessed. */
GRPCAPI int grpc_byte_buffer_reader_peek(grpc_byte_buffer_reader* reader,
grpc_slice** slice);
/** Merge all data from \a reader into single slice */
GRPCAPI grpc_slice
grpc_byte_buffer_reader_readall(grpc_byte_buffer_reader* reader);

@ -193,6 +193,7 @@
#define GPR_PLATFORM_STRING "ios"
#define GPR_CPU_IPHONE 1
#define GPR_PTHREAD_TLS 1
#define GRPC_CFSTREAM 1
/* the c-ares resolver isnt safe to enable on iOS */
#define GRPC_ARES 0
#else /* TARGET_OS_IPHONE */
@ -235,7 +236,6 @@
#define GPR_POSIX_SYNC 1
#define GPR_POSIX_TIME 1
#define GPR_GETPID_IN_UNISTD_H 1
/* TODO(mxyan): Remove when CFStream becomes default */
#ifndef GRPC_CFSTREAM
#define GPR_SUPPORT_CHANNELS_FROM_FD 1
#endif

@ -1,6 +1,6 @@
/*
*
* Copyright 2016 gRPC authors.
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -19,46 +19,34 @@
#ifndef GRPCPP_CREATE_CHANNEL_POSIX_H
#define GRPCPP_CREATE_CHANNEL_POSIX_H
#include <memory>
#include <grpc/support/port_platform.h>
#include <grpcpp/channel.h>
#include <grpcpp/support/channel_arguments.h>
#include <grpcpp/create_channel_posix_impl.h>
namespace grpc {
#ifdef GPR_SUPPORT_CHANNELS_FROM_FD
/// Create a new \a Channel communicating over the given file descriptor.
///
/// \param target The name of the target.
/// \param fd The file descriptor representing a socket.
std::shared_ptr<Channel> CreateInsecureChannelFromFd(const grpc::string& target,
int fd);
static inline std::shared_ptr<Channel> CreateInsecureChannelFromFd(
const grpc::string& target, int fd) {
return ::grpc_impl::CreateInsecureChannelFromFd(target, fd);
}
/// Create a new \a Channel communicating over given file descriptor with custom
/// channel arguments.
///
/// \param target The name of the target.
/// \param fd The file descriptor representing a socket.
/// \param args Options for channel creation.
std::shared_ptr<Channel> CreateCustomInsecureChannelFromFd(
const grpc::string& target, int fd, const ChannelArguments& args);
static inline std::shared_ptr<Channel> CreateCustomInsecureChannelFromFd(
const grpc::string& target, int fd, const ChannelArguments& args) {
return ::grpc_impl::CreateCustomInsecureChannelFromFd(target, fd, args);
}
namespace experimental {
/// Create a new \a Channel communicating over given file descriptor with custom
/// channel arguments.
///
/// \param target The name of the target.
/// \param fd The file descriptor representing a socket.
/// \param args Options for channel creation.
/// \param interceptor_creators Vector of interceptor factory objects.
std::shared_ptr<Channel> CreateCustomInsecureChannelWithInterceptorsFromFd(
static inline std::shared_ptr<Channel>
CreateCustomInsecureChannelWithInterceptorsFromFd(
const grpc::string& target, int fd, const ChannelArguments& args,
std::unique_ptr<std::vector<
std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>
interceptor_creators);
interceptor_creators) {
return ::grpc_impl::experimental::
CreateCustomInsecureChannelWithInterceptorsFromFd(
target, fd, args, std::move(interceptor_creators));
}
} // namespace experimental

@ -0,0 +1,70 @@
/*
*
* Copyright 2016 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef GRPCPP_CREATE_CHANNEL_POSIX_IMPL_H
#define GRPCPP_CREATE_CHANNEL_POSIX_IMPL_H
#include <memory>
#include <grpc/support/port_platform.h>
#include <grpcpp/channel.h>
#include <grpcpp/support/channel_arguments.h>
namespace grpc_impl {
#ifdef GPR_SUPPORT_CHANNELS_FROM_FD
/// Create a new \a Channel communicating over the given file descriptor.
///
/// \param target The name of the target.
/// \param fd The file descriptor representing a socket.
std::shared_ptr<grpc::Channel> CreateInsecureChannelFromFd(
const grpc::string& target, int fd);
/// Create a new \a Channel communicating over given file descriptor with custom
/// channel arguments.
///
/// \param target The name of the target.
/// \param fd The file descriptor representing a socket.
/// \param args Options for channel creation.
std::shared_ptr<grpc::Channel> CreateCustomInsecureChannelFromFd(
const grpc::string& target, int fd, const grpc::ChannelArguments& args);
namespace experimental {
/// Create a new \a Channel communicating over given file descriptor with custom
/// channel arguments.
///
/// \param target The name of the target.
/// \param fd The file descriptor representing a socket.
/// \param args Options for channel creation.
/// \param interceptor_creators Vector of interceptor factory objects.
std::shared_ptr<grpc::Channel>
CreateCustomInsecureChannelWithInterceptorsFromFd(
const grpc::string& target, int fd, const grpc::ChannelArguments& args,
std::unique_ptr<std::vector<
std::unique_ptr<grpc::experimental::ClientInterceptorFactoryInterface>>>
interceptor_creators);
} // namespace experimental
#endif // GPR_SUPPORT_CHANNELS_FROM_FD
} // namespace grpc_impl
#endif // GRPCPP_CREATE_CHANNEL_POSIX_IMPL_H

@ -19,20 +19,15 @@
#ifndef GRPCPP_EXT_CHANNELZ_SERVICE_PLUGIN_H
#define GRPCPP_EXT_CHANNELZ_SERVICE_PLUGIN_H
#include <grpc/support/port_platform.h>
#include <grpcpp/impl/server_builder_plugin.h>
#include <grpcpp/impl/server_initializer.h>
#include <grpcpp/support/config.h>
#include <grpcpp/ext/channelz_service_plugin_impl.h>
namespace grpc {
namespace channelz {
namespace experimental {
/// Add channelz server plugin to \a ServerBuilder. This function should
/// be called at static initialization time. This service is experimental
/// for now. Track progress in https://github.com/grpc/grpc/issues/15988.
void InitChannelzService();
static inline void InitChannelzService() {
::grpc_impl::channelz::experimental::InitChannelzService();
}
} // namespace experimental
} // namespace channelz

@ -0,0 +1,41 @@
/*
*
* Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef GRPCPP_EXT_CHANNELZ_SERVICE_PLUGIN_IMPL_H
#define GRPCPP_EXT_CHANNELZ_SERVICE_PLUGIN_IMPL_H
#include <grpc/support/port_platform.h>
#include <grpcpp/impl/server_builder_plugin.h>
#include <grpcpp/impl/server_initializer.h>
#include <grpcpp/support/config.h>
namespace grpc_impl {
namespace channelz {
namespace experimental {
/// Add channelz server plugin to \a ServerBuilder. This function should
/// be called at static initialization time. This service is experimental
/// for now. Track progress in https://github.com/grpc/grpc/issues/15988.
void InitChannelzService();
} // namespace experimental
} // namespace channelz
} // namespace grpc_impl
#endif // GRPCPP_EXT_CHANNELZ_SERVICE_PLUGIN_IMPL_H

@ -22,8 +22,11 @@
#include <grpcpp/impl/server_builder_plugin.h>
#include <grpcpp/support/config.h>
namespace grpc {
namespace grpc_impl {
class ServerInitializer;
}
namespace grpc {
class ProtoServerReflection;
} // namespace grpc
@ -34,8 +37,8 @@ class ProtoServerReflectionPlugin : public ::grpc::ServerBuilderPlugin {
public:
ProtoServerReflectionPlugin();
::grpc::string name() override;
void InitServer(::grpc::ServerInitializer* si) override;
void Finish(::grpc::ServerInitializer* si) override;
void InitServer(::grpc_impl::ServerInitializer* si) override;
void Finish(::grpc_impl::ServerInitializer* si) override;
void ChangeArguments(const ::grpc::string& name, void* value) override;
bool has_async_methods() const override;
bool has_sync_methods() const override;

@ -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);

@ -1,6 +1,6 @@
/*
*
* Copyright 2016 gRPC authors.
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -19,39 +19,22 @@
#ifndef GRPCPP_HEALTH_CHECK_SERVICE_INTERFACE_H
#define GRPCPP_HEALTH_CHECK_SERVICE_INTERFACE_H
#include <grpcpp/support/config.h>
#include <grpcpp/health_check_service_interface_impl.h>
namespace grpc {
const char kHealthCheckServiceInterfaceArg[] =
"grpc.health_check_service_interface";
/// The gRPC server uses this interface to expose the health checking service
/// without depending on protobuf.
class HealthCheckServiceInterface {
public:
virtual ~HealthCheckServiceInterface() {}
/// Set or change the serving status of the given \a service_name.
virtual void SetServingStatus(const grpc::string& service_name,
bool serving) = 0;
/// Apply to all registered service names.
virtual void SetServingStatus(bool serving) = 0;
/// Set all registered service names to not serving and prevent future
/// state changes.
virtual void Shutdown() {}
};
/// Enable/disable the default health checking service. This applies to all C++
/// servers created afterwards. For each server, user can override the default
/// with a HealthCheckServiceServerBuilderOption.
/// NOT thread safe.
void EnableDefaultHealthCheckService(bool enable);
/// Returns whether the default health checking service is enabled.
/// NOT thread safe.
bool DefaultHealthCheckServiceEnabled();
typedef ::grpc_impl::HealthCheckServiceInterface HealthCheckServiceInterface;
static inline void EnableDefaultHealthCheckService(bool enable) {
::grpc_impl::EnableDefaultHealthCheckService(enable);
}
static inline bool DefaultHealthCheckServiceEnabled() {
return ::grpc_impl::DefaultHealthCheckServiceEnabled();
}
} // namespace grpc

@ -0,0 +1,55 @@
/*
*
* Copyright 2016 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef GRPCPP_HEALTH_CHECK_SERVICE_INTERFACE_IMPL_H
#define GRPCPP_HEALTH_CHECK_SERVICE_INTERFACE_IMPL_H
#include <grpcpp/support/config.h>
namespace grpc_impl {
/// The gRPC server uses this interface to expose the health checking service
/// without depending on protobuf.
class HealthCheckServiceInterface {
public:
virtual ~HealthCheckServiceInterface() {}
/// Set or change the serving status of the given \a service_name.
virtual void SetServingStatus(const grpc::string& service_name,
bool serving) = 0;
/// Apply to all registered service names.
virtual void SetServingStatus(bool serving) = 0;
/// Set all registered service names to not serving and prevent future
/// state changes.
virtual void Shutdown() {}
};
/// Enable/disable the default health checking service. This applies to all C++
/// servers created afterwards. For each server, user can override the default
/// with a HealthCheckServiceServerBuilderOption.
/// NOT thread safe.
void EnableDefaultHealthCheckService(bool enable);
/// Returns whether the default health checking service is enabled.
/// NOT thread safe.
bool DefaultHealthCheckServiceEnabled();
} // namespace grpc_impl
#endif // GRPCPP_HEALTH_CHECK_SERVICE_INTERFACE_IMPL_H

@ -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; }

@ -85,6 +85,8 @@ class CoreCodegen final : public CoreCodegenInterface {
grpc_byte_buffer_reader* reader) override;
int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader* reader,
grpc_slice* slice) override;
int grpc_byte_buffer_reader_peek(grpc_byte_buffer_reader* reader,
grpc_slice** slice) override;
grpc_byte_buffer* grpc_raw_byte_buffer_create(grpc_slice* slice,
size_t nslices) override;

@ -92,6 +92,8 @@ class CoreCodegenInterface {
grpc_byte_buffer_reader* reader) = 0;
virtual int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader* reader,
grpc_slice* slice) = 0;
virtual int grpc_byte_buffer_reader_peek(grpc_byte_buffer_reader* reader,
grpc_slice** slice) = 0;
virtual grpc_byte_buffer* grpc_raw_byte_buffer_create(grpc_slice* slice,
size_t nslices) = 0;

@ -73,7 +73,7 @@ class ProtoBufferReader : public ::grpc::protobuf::io::ZeroCopyInputStream {
}
/// If we have backed up previously, we need to return the backed-up slice
if (backup_count_ > 0) {
*data = GRPC_SLICE_START_PTR(slice_) + GRPC_SLICE_LENGTH(slice_) -
*data = GRPC_SLICE_START_PTR(*slice_) + GRPC_SLICE_LENGTH(*slice_) -
backup_count_;
GPR_CODEGEN_ASSERT(backup_count_ <= INT_MAX);
*size = (int)backup_count_;
@ -81,15 +81,14 @@ class ProtoBufferReader : public ::grpc::protobuf::io::ZeroCopyInputStream {
return true;
}
/// Otherwise get the next slice from the byte buffer reader
if (!g_core_codegen_interface->grpc_byte_buffer_reader_next(&reader_,
if (!g_core_codegen_interface->grpc_byte_buffer_reader_peek(&reader_,
&slice_)) {
return false;
}
g_core_codegen_interface->grpc_slice_unref(slice_);
*data = GRPC_SLICE_START_PTR(slice_);
*data = GRPC_SLICE_START_PTR(*slice_);
// On win x64, int is only 32bit
GPR_CODEGEN_ASSERT(GRPC_SLICE_LENGTH(slice_) <= INT_MAX);
byte_count_ += * size = (int)GRPC_SLICE_LENGTH(slice_);
GPR_CODEGEN_ASSERT(GRPC_SLICE_LENGTH(*slice_) <= INT_MAX);
byte_count_ += * size = (int)GRPC_SLICE_LENGTH(*slice_);
return true;
}
@ -100,7 +99,7 @@ class ProtoBufferReader : public ::grpc::protobuf::io::ZeroCopyInputStream {
/// bytes that have already been returned by the last call of Next.
/// So do the backup and have that ready for a later Next.
void BackUp(int count) override {
GPR_CODEGEN_ASSERT(count <= static_cast<int>(GRPC_SLICE_LENGTH(slice_)));
GPR_CODEGEN_ASSERT(count <= static_cast<int>(GRPC_SLICE_LENGTH(*slice_)));
backup_count_ = count;
}
@ -135,14 +134,15 @@ class ProtoBufferReader : public ::grpc::protobuf::io::ZeroCopyInputStream {
int64_t backup_count() { return backup_count_; }
void set_backup_count(int64_t backup_count) { backup_count_ = backup_count; }
grpc_byte_buffer_reader* reader() { return &reader_; }
grpc_slice* slice() { return &slice_; }
grpc_slice* slice() { return slice_; }
grpc_slice** mutable_slice_ptr() { return &slice_; }
private:
int64_t byte_count_; ///< total bytes read since object creation
int64_t backup_count_; ///< how far backed up in the stream we are
grpc_byte_buffer_reader reader_; ///< internal object to read \a grpc_slice
///< from the \a grpc_byte_buffer
grpc_slice slice_; ///< current slice passed back to the caller
grpc_slice* slice_; ///< current slice passed back to the caller
Status status_; ///< status of the entire object
};

@ -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,128 @@ 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. The library guarantees that
// OnStarted will be called for any reactor that has been created using a
// method handler registered on a service. No operation initiation method may be
// called until after 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) {}
/// Do NOT call any operation initiation method (names that start with Start)
/// until after the library has called OnStarted on this object.
/// 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 and that it is now
/// ok to call any operation initation method.
///
/// \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 +298,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 +330,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; }

@ -1,6 +1,6 @@
/*
*
* Copyright 2015 gRPC authors.
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -19,24 +19,11 @@
#ifndef GRPCPP_IMPL_SERVER_BUILDER_OPTION_H
#define GRPCPP_IMPL_SERVER_BUILDER_OPTION_H
#include <map>
#include <memory>
#include <grpcpp/impl/server_builder_plugin.h>
#include <grpcpp/support/channel_arguments.h>
#include <grpcpp/impl/server_builder_option_impl.h>
namespace grpc {
/// Interface to pass an option to a \a ServerBuilder.
class ServerBuilderOption {
public:
virtual ~ServerBuilderOption() {}
/// Alter the \a ChannelArguments used to create the gRPC server.
virtual void UpdateArguments(ChannelArguments* args) = 0;
/// Alter the ServerBuilderPlugin map that will be added into ServerBuilder.
virtual void UpdatePlugins(
std::vector<std::unique_ptr<ServerBuilderPlugin>>* plugins) = 0;
};
typedef ::grpc_impl::ServerBuilderOption ServerBuilderOption;
} // namespace grpc

@ -0,0 +1,43 @@
/*
*
* Copyright 2015 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef GRPCPP_IMPL_SERVER_BUILDER_OPTION_IMPL_H
#define GRPCPP_IMPL_SERVER_BUILDER_OPTION_IMPL_H
#include <map>
#include <memory>
#include <grpcpp/impl/server_builder_plugin.h>
#include <grpcpp/support/channel_arguments.h>
namespace grpc_impl {
/// Interface to pass an option to a \a ServerBuilder.
class ServerBuilderOption {
public:
virtual ~ServerBuilderOption() {}
/// Alter the \a ChannelArguments used to create the gRPC server.
virtual void UpdateArguments(grpc::ChannelArguments* args) = 0;
/// Alter the ServerBuilderPlugin map that will be added into ServerBuilder.
virtual void UpdatePlugins(
std::vector<std::unique_ptr<grpc::ServerBuilderPlugin>>* plugins) = 0;
};
} // namespace grpc_impl
#endif // GRPCPP_IMPL_SERVER_BUILDER_OPTION_IMPL_H

@ -23,10 +23,13 @@
#include <grpcpp/support/config.h>
namespace grpc_impl {
class ServerInitializer;
}
namespace grpc {
class ServerBuilder;
class ServerInitializer;
class ChannelArguments;
/// This interface is meant for internal usage only. Implementations of this
@ -44,10 +47,10 @@ class ServerBuilderPlugin {
/// InitServer will be called in ServerBuilder::BuildAndStart(), after the
/// Server instance is created.
virtual void InitServer(ServerInitializer* si) = 0;
virtual void InitServer(grpc_impl::ServerInitializer* si) = 0;
/// Finish will be called at the end of ServerBuilder::BuildAndStart().
virtual void Finish(ServerInitializer* si) = 0;
virtual void Finish(grpc_impl::ServerInitializer* si) = 0;
/// ChangeArguments is an interface that can be used in
/// ServerBuilderOption::UpdatePlugins

@ -1,6 +1,6 @@
/*
*
* Copyright 2016 gRPC authors.
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -19,36 +19,11 @@
#ifndef GRPCPP_IMPL_SERVER_INITIALIZER_H
#define GRPCPP_IMPL_SERVER_INITIALIZER_H
#include <memory>
#include <vector>
#include <grpcpp/server.h>
#include <grpcpp/impl/server_initializer_impl.h>
namespace grpc {
class Server;
class Service;
class ServerInitializer {
public:
ServerInitializer(Server* server) : server_(server) {}
bool RegisterService(std::shared_ptr<Service> service) {
if (!server_->RegisterService(nullptr, service.get())) {
return false;
}
default_services_.push_back(service);
return true;
}
const std::vector<grpc::string>* GetServiceList() {
return &server_->services_;
}
private:
Server* server_;
std::vector<std::shared_ptr<Service> > default_services_;
};
typedef ::grpc_impl::ServerInitializer ServerInitializer;
} // namespace grpc

@ -0,0 +1,57 @@
/*
*
* Copyright 2016 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef GRPCPP_IMPL_SERVER_INITIALIZER_IMPL_H
#define GRPCPP_IMPL_SERVER_INITIALIZER_IMPL_H
#include <memory>
#include <vector>
#include <grpcpp/server.h>
namespace grpc {
class Server;
class Service;
} // namespace grpc
namespace grpc_impl {
class ServerInitializer {
public:
ServerInitializer(grpc::Server* server) : server_(server) {}
bool RegisterService(std::shared_ptr<grpc::Service> service) {
if (!server_->RegisterService(nullptr, service.get())) {
return false;
}
default_services_.push_back(service);
return true;
}
const std::vector<grpc::string>* GetServiceList() {
return &server_->services_;
}
private:
grpc::Server* server_;
std::vector<std::shared_ptr<grpc::Service> > default_services_;
};
} // namespace grpc_impl
#endif // GRPCPP_IMPL_SERVER_INITIALIZER_IMPL_H

@ -19,29 +19,20 @@
#ifndef GRPCPP_OPENCENSUS_H
#define GRPCPP_OPENCENSUS_H
#include "opencensus/trace/span.h"
#include "grpcpp/opencensus_impl.h"
namespace grpc {
// These symbols in this file will not be included in the binary unless
// grpc_opencensus_plugin build target was added as a dependency. At the moment
// it is only setup to be built with Bazel.
// Registers the OpenCensus plugin with gRPC, so that it will be used for future
// RPCs. This must be called before any views are created.
void RegisterOpenCensusPlugin();
// RPC stats definitions, defined by
// https://github.com/census-instrumentation/opencensus-specs/blob/master/stats/gRPC.md
// Registers the cumulative gRPC views so that they will be exported by any
// registered stats exporter. For on-task stats, construct a View using the
// ViewDescriptors below.
void RegisterOpenCensusViewsForExport();
class ServerContext;
// Returns the tracing Span for the current RPC.
::opencensus::trace::Span GetSpanFromServerContext(ServerContext* context);
static inline void RegisterOpenCensusPlugin() {
::grpc_impl::RegisterOpenCensusPlugin();
}
static inline void RegisterOpenCensusViewsForExport() {
::grpc_impl::RegisterOpenCensusViewsForExport();
}
static inline ::opencensus::trace::Span GetSpanFromServerContext(
ServerContext* context) {
return ::grpc_impl::GetSpanFromServerContext(context);
}
} // namespace grpc

@ -0,0 +1,51 @@
/*
*
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef GRPCPP_OPENCENSUS_IMPL_H
#define GRPCPP_OPENCENSUS_IMPL_H
#include "opencensus/trace/span.h"
namespace grpc {
class ServerContext;
}
namespace grpc_impl {
// These symbols in this file will not be included in the binary unless
// grpc_opencensus_plugin build target was added as a dependency. At the moment
// it is only setup to be built with Bazel.
// Registers the OpenCensus plugin with gRPC, so that it will be used for future
// RPCs. This must be called before any views are created.
void RegisterOpenCensusPlugin();
// RPC stats definitions, defined by
// https://github.com/census-instrumentation/opencensus-specs/blob/master/stats/gRPC.md
// Registers the cumulative gRPC views so that they will be exported by any
// registered stats exporter. For on-task stats, construct a View using the
// ViewDescriptors below.
void RegisterOpenCensusViewsForExport();
// Returns the tracing Span for the current RPC.
::opencensus::trace::Span GetSpanFromServerContext(
grpc::ServerContext* context);
} // namespace grpc_impl
#endif // GRPCPP_OPENCENSUS_IMPL_H

@ -1,6 +1,6 @@
/*
*
* Copyright 2016 gRPC authors.
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -19,50 +19,11 @@
#ifndef GRPCPP_RESOURCE_QUOTA_H
#define GRPCPP_RESOURCE_QUOTA_H
struct grpc_resource_quota;
#include <grpcpp/impl/codegen/config.h>
#include <grpcpp/impl/codegen/grpc_library.h>
#include <grpcpp/resource_quota_impl.h>
namespace grpc {
/// ResourceQuota represents a bound on memory and thread usage by the gRPC
/// library. A ResourceQuota can be attached to a server (via \a ServerBuilder),
/// or a client channel (via \a ChannelArguments).
/// gRPC will attempt to keep memory and threads used by all attached entities
/// below the ResourceQuota bound.
class ResourceQuota final : private GrpcLibraryCodegen {
public:
/// \param name - a unique name for this ResourceQuota.
explicit ResourceQuota(const grpc::string& name);
ResourceQuota();
~ResourceQuota();
/// Resize this \a ResourceQuota to a new size. If \a new_size is smaller
/// than the current size of the pool, memory usage will be monotonically
/// decreased until it falls under \a new_size.
/// No time bound is given for this to occur however.
ResourceQuota& Resize(size_t new_size);
/// Set the max number of threads that can be allocated from this
/// ResourceQuota object.
///
/// If the new_max_threads value is smaller than the current value, no new
/// threads are allocated until the number of active threads fall below
/// new_max_threads. There is no time bound on when this may happen i.e none
/// of the current threads are forcefully destroyed and all threads run their
/// normal course.
ResourceQuota& SetMaxThreads(int new_max_threads);
grpc_resource_quota* c_resource_quota() const { return impl_; }
private:
ResourceQuota(const ResourceQuota& rhs);
ResourceQuota& operator=(const ResourceQuota& rhs);
grpc_resource_quota* const impl_;
};
typedef ::grpc_impl::ResourceQuota ResourceQuota;
} // namespace grpc
#endif // GRPCPP_RESOURCE_QUOTA_H

@ -0,0 +1,68 @@
/*
*
* Copyright 2016 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef GRPCPP_RESOURCE_QUOTA_IMPL_H
#define GRPCPP_RESOURCE_QUOTA_IMPL_H
struct grpc_resource_quota;
#include <grpcpp/impl/codegen/config.h>
#include <grpcpp/impl/codegen/grpc_library.h>
namespace grpc_impl {
/// ResourceQuota represents a bound on memory and thread usage by the gRPC
/// library. A ResourceQuota can be attached to a server (via \a ServerBuilder),
/// or a client channel (via \a ChannelArguments).
/// gRPC will attempt to keep memory and threads used by all attached entities
/// below the ResourceQuota bound.
class ResourceQuota final : private ::grpc::GrpcLibraryCodegen {
public:
/// \param name - a unique name for this ResourceQuota.
explicit ResourceQuota(const grpc::string& name);
ResourceQuota();
~ResourceQuota();
/// Resize this \a ResourceQuota to a new size. If \a new_size is smaller
/// than the current size of the pool, memory usage will be monotonically
/// decreased until it falls under \a new_size.
/// No time bound is given for this to occur however.
ResourceQuota& Resize(size_t new_size);
/// Set the max number of threads that can be allocated from this
/// ResourceQuota object.
///
/// If the new_max_threads value is smaller than the current value, no new
/// threads are allocated until the number of active threads fall below
/// new_max_threads. There is no time bound on when this may happen i.e none
/// of the current threads are forcefully destroyed and all threads run their
/// normal course.
ResourceQuota& SetMaxThreads(int new_max_threads);
grpc_resource_quota* c_resource_quota() const { return impl_; }
private:
ResourceQuota(const ResourceQuota& rhs);
ResourceQuota& operator=(const ResourceQuota& rhs);
grpc_resource_quota* const impl_;
};
} // namespace grpc_impl
#endif // GRPCPP_RESOURCE_QUOTA_IMPL_H

@ -28,6 +28,7 @@
#include <grpc/compression.h>
#include <grpc/support/atm.h>
#include <grpcpp/completion_queue.h>
#include <grpcpp/health_check_service_interface.h>
#include <grpcpp/impl/call.h>
#include <grpcpp/impl/codegen/client_interceptor.h>
#include <grpcpp/impl/codegen/grpc_library.h>
@ -40,12 +41,14 @@
struct grpc_server;
namespace grpc_impl {
class ServerInitializer;
}
namespace grpc {
class AsyncGenericService;
class HealthCheckServiceInterface;
class ServerContext;
class ServerInitializer;
/// Represents a gRPC server.
///
@ -199,7 +202,7 @@ class Server : public ServerInterface, private GrpcLibraryCodegen {
friend class AsyncGenericService;
friend class ServerBuilder;
friend class ServerInitializer;
friend class grpc_impl::ServerInitializer;
class SyncRequest;
class CallbackRequestBase;
@ -257,7 +260,7 @@ class Server : public ServerInterface, private GrpcLibraryCodegen {
CompletionQueue* CallbackCQ() override;
ServerInitializer* initializer();
grpc_impl::ServerInitializer* initializer();
// A vector of interceptor factory objects.
// This should be destroyed after health_check_service_ and this requirement
@ -321,7 +324,7 @@ class Server : public ServerInterface, private GrpcLibraryCodegen {
// Pointer to the wrapped grpc_server.
grpc_server* server_;
std::unique_ptr<ServerInitializer> server_initializer_;
std::unique_ptr<grpc_impl::ServerInitializer> server_initializer_;
std::unique_ptr<HealthCheckServiceInterface> health_check_service_;
bool health_check_service_disabled_;

@ -35,10 +35,14 @@
struct grpc_resource_quota;
namespace grpc_impl {
class ResourceQuota;
}
namespace grpc {
class AsyncGenericService;
class ResourceQuota;
class CompletionQueue;
class Server;
class ServerCompletionQueue;
@ -186,7 +190,8 @@ class ServerBuilder {
grpc_compression_algorithm algorithm);
/// Set the attached buffer pool for this server
ServerBuilder& SetResourceQuota(const ResourceQuota& resource_quota);
ServerBuilder& SetResourceQuota(
const ::grpc_impl::ResourceQuota& resource_quota);
ServerBuilder& SetOption(std::unique_ptr<ServerBuilderOption> option);
@ -231,6 +236,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);

@ -19,21 +19,15 @@
#ifndef GRPCPP_SERVER_POSIX_H
#define GRPCPP_SERVER_POSIX_H
#include <memory>
#include <grpc/support/port_platform.h>
#include <grpcpp/server.h>
#include <grpcpp/server_posix_impl.h>
namespace grpc {
#ifdef GPR_SUPPORT_CHANNELS_FROM_FD
/// Add a new client to a \a Server communicating over the given
/// file descriptor.
///
/// \param server The server to add the client to.
/// \param fd The file descriptor representing a socket.
void AddInsecureChannelFromFd(Server* server, int fd);
static inline void AddInsecureChannelFromFd(Server* server, int fd) {
::grpc_impl::AddInsecureChannelFromFd(server, fd);
}
#endif // GPR_SUPPORT_CHANNELS_FROM_FD

@ -0,0 +1,42 @@
/*
*
* Copyright 2016 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef GRPCPP_SERVER_POSIX_IMPL_H
#define GRPCPP_SERVER_POSIX_IMPL_H
#include <memory>
#include <grpc/support/port_platform.h>
#include <grpcpp/server.h>
namespace grpc_impl {
#ifdef GPR_SUPPORT_CHANNELS_FROM_FD
/// Add a new client to a \a Server communicating over the given
/// file descriptor.
///
/// \param server The server to add the client to.
/// \param fd The file descriptor representing a socket.
void AddInsecureChannelFromFd(grpc::Server* server, int fd);
#endif // GPR_SUPPORT_CHANNELS_FROM_FD
} // namespace grpc
#endif // GRPCPP_SERVER_POSIX_IMPL_H

@ -26,13 +26,16 @@
#include <grpc/grpc.h>
#include <grpcpp/support/config.h>
namespace grpc_impl {
class ResourceQuota;
}
namespace grpc {
namespace testing {
class ChannelArgumentsTest;
} // namespace testing
class ResourceQuota;
/// Options for channel creation. The user can use generic setters to pass
/// key value pairs down to C channel creation code. For gRPC related options,
/// concrete setters are provided.
@ -83,7 +86,7 @@ class ChannelArguments {
void SetUserAgentPrefix(const grpc::string& user_agent_prefix);
/// Set the buffer pool to be attached to the constructed channel.
void SetResourceQuota(const ResourceQuota& resource_quota);
void SetResourceQuota(const ::grpc_impl::ResourceQuota& resource_quota);
/// Set the max receive and send message sizes.
void SetMaxReceiveMessageSize(int size);

@ -13,8 +13,8 @@
<date>2018-01-19</date>
<time>16:06:07</time>
<version>
<release>1.20.0dev</release>
<api>1.20.0dev</api>
<release>1.21.0dev</release>
<api>1.21.0dev</api>
</version>
<stability>
<release>beta</release>
@ -107,8 +107,10 @@
<file baseinstalldir="/" name="src/core/lib/gprpp/atomic.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/fork.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/manual_constructor.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/map.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/memory.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/mutex_lock.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/pair.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/thd.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/profiling/timers.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/alloc.cc" role="src" />
@ -300,6 +302,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 +445,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 +615,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 +750,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",

@ -70,6 +70,10 @@ static void PrintAllComments(const DescriptorType* desc, Printer* printer) {
}
printer->Print("\n");
}
printer->Print(" *\n");
printer->Print(
" * This method belongs to a set of APIs that have been deprecated. Using"
" the v2 API is recommended.\n");
printer->Print(" */\n");
}
@ -278,6 +282,13 @@ void PrintMethodImplementations(Printer* printer,
map< ::grpc::string, ::grpc::string> vars = {
{"service_class", ServiceClassName(service)}};
printer.Print(vars,
"/**\n"
" * The methods in this protocol belong to a set of old APIs "
"that have been deprecated. They do not\n"
" * recognize call options provided in the initializer. Using "
"the v2 protocol is recommended.\n"
" */\n");
printer.Print(vars, "@protocol $service_class$ <NSObject>\n\n");
for (int i = 0; i < service->method_count(); i++) {
PrintMethodDeclarations(&printer, service->method(i));
@ -329,10 +340,13 @@ void PrintMethodImplementations(Printer* printer,
"callOptions:(GRPCCallOptions "
"*_Nullable)callOptions"
" NS_DESIGNATED_INITIALIZER;\n");
printer.Print("- (instancetype)initWithHost:(NSString *)host;\n");
printer.Print(
"+ (instancetype)serviceWithHost:(NSString *)host "
"callOptions:(GRPCCallOptions *_Nullable)callOptions;\n");
printer.Print(
"// The following methods belong to a set of old APIs that have been "
"deprecated.\n");
printer.Print("- (instancetype)initWithHost:(NSString *)host;\n");
printer.Print("+ (instancetype)serviceWithHost:(NSString *)host;\n");
printer.Print("@end\n");

@ -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"
@ -62,7 +63,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"
@ -416,11 +416,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,
@ -189,8 +188,14 @@ void PickFirst::ShutdownLocked() {
void PickFirst::ExitIdleLocked() {
if (idle_) {
idle_ = false;
if (subchannel_list_ != nullptr &&
subchannel_list_->num_subchannels() > 0) {
if (subchannel_list_ == nullptr ||
subchannel_list_->num_subchannels() == 0) {
grpc_error* error =
GRPC_ERROR_CREATE_FROM_STATIC_STRING("No addresses to connect to");
channel_control_helper()->UpdateState(
GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error),
UniquePtr<SubchannelPicker>(New<TransientFailurePicker>(error)));
} else {
subchannel_list_->subchannel(0)
->CheckConnectivityStateAndStartWatchingLocked();
}
@ -238,48 +243,35 @@ 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
// subchannels and put the channel in TRANSIENT_FAILURE.
// subchannels.
subchannel_list_ = std::move(subchannel_list); // Empty list.
selected_ = nullptr;
grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update");
channel_control_helper()->UpdateState(
GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error),
UniquePtr<SubchannelPicker>(New<TransientFailurePicker>(error)));
// If not idle, put the channel in TRANSIENT_FAILURE.
// (If we are idle, then this will happen in ExitIdleLocked() if we
// haven't gotten a non-empty update by the time the application tries
// to start a new call.)
if (!idle_) {
grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update");
channel_control_helper()->UpdateState(
GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error),
UniquePtr<SubchannelPicker>(New<TransientFailurePicker>(error)));
}
return;
}
// If one of the subchannels in the new list is already in state

@ -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++) {

@ -68,7 +68,9 @@
#include <grpc/support/string_util.h>
#include <grpc/support/time.h>
#include "include/grpc/support/alloc.h"
#include "src/core/ext/filters/client_channel/client_channel.h"
#include "src/core/ext/filters/client_channel/lb_policy.h"
#include "src/core/ext/filters/client_channel/lb_policy/xds/xds.h"
#include "src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h"
#include "src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h"
@ -78,12 +80,14 @@
#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"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/manual_constructor.h"
#include "src/core/lib/gprpp/map.h"
#include "src/core/lib/gprpp/memory.h"
#include "src/core/lib/gprpp/mutex_lock.h"
#include "src/core/lib/gprpp/orphanable.h"
@ -98,7 +102,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
@ -114,6 +117,7 @@ TraceFlag grpc_lb_xds_trace(false, "xds");
namespace {
constexpr char kXds[] = "xds_experimental";
constexpr char kDefaultLocalityName[] = "xds_default_locality";
class XdsLb : public LoadBalancingPolicy {
public:
@ -121,14 +125,16 @@ 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,
channelz::ChildRefsList* child_channels) override;
private:
struct LocalityServerlistEntry;
using LocalityList = InlinedVector<UniquePtr<LocalityServerlistEntry>, 1>;
/// Contains a channel to the LB server and all the data related to the
/// channel.
class BalancerChannelState
@ -267,25 +273,88 @@ class XdsLb : public LoadBalancingPolicy {
RefCountedPtr<XdsLbClientStats> client_stats_;
};
class Helper : public ChannelControlHelper {
class LocalityMap {
public:
explicit Helper(RefCountedPtr<XdsLb> parent) : parent_(std::move(parent)) {}
class LocalityEntry : public InternallyRefCounted<LocalityEntry> {
public:
explicit LocalityEntry(RefCountedPtr<XdsLb> parent)
: parent_(std::move(parent)) {
gpr_mu_init(&child_policy_mu_);
}
~LocalityEntry() { gpr_mu_destroy(&child_policy_mu_); }
void UpdateLocked(xds_grpclb_serverlist* serverlist,
LoadBalancingPolicy::Config* child_policy_config,
const grpc_channel_args* args);
void ShutdownLocked();
void ResetBackoffLocked();
void FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels,
channelz::ChildRefsList* child_channels);
void Orphan() override;
private:
class Helper : public ChannelControlHelper {
public:
explicit Helper(RefCountedPtr<LocalityEntry> entry)
: entry_(std::move(entry)) {}
Subchannel* CreateSubchannel(const grpc_channel_args& args) override;
grpc_channel* CreateChannel(const char* target,
const grpc_channel_args& args) override;
void UpdateState(grpc_connectivity_state state, grpc_error* state_error,
UniquePtr<SubchannelPicker> picker) override;
void RequestReresolution() override;
void set_child(LoadBalancingPolicy* child) { child_ = child; }
private:
bool CalledByPendingChild() const;
bool CalledByCurrentChild() const;
RefCountedPtr<LocalityEntry> entry_;
LoadBalancingPolicy* child_ = nullptr;
};
// Methods for dealing with the child policy.
OrphanablePtr<LoadBalancingPolicy> CreateChildPolicyLocked(
const char* name, const grpc_channel_args* args);
grpc_channel_args* CreateChildPolicyArgsLocked(
const grpc_channel_args* args);
OrphanablePtr<LoadBalancingPolicy> child_policy_;
OrphanablePtr<LoadBalancingPolicy> pending_child_policy_;
// Lock held when modifying the value of child_policy_ or
// pending_child_policy_.
gpr_mu child_policy_mu_;
RefCountedPtr<XdsLb> parent_;
};
Subchannel* CreateSubchannel(const grpc_channel_args& args) override;
grpc_channel* CreateChannel(const char* target,
const grpc_channel_args& args) override;
void UpdateState(grpc_connectivity_state state, grpc_error* state_error,
UniquePtr<SubchannelPicker> picker) override;
void RequestReresolution() override;
LocalityMap() { gpr_mu_init(&child_refs_mu_); }
~LocalityMap() { gpr_mu_destroy(&child_refs_mu_); }
void set_child(LoadBalancingPolicy* child) { child_ = child; }
void UpdateLocked(const LocalityList& locality_list,
LoadBalancingPolicy::Config* child_policy_config,
const grpc_channel_args* args, XdsLb* parent);
void ShutdownLocked();
void ResetBackoffLocked();
void FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels,
channelz::ChildRefsList* child_channels);
private:
bool CalledByPendingChild() const;
bool CalledByCurrentChild() const;
void PruneLocalities(const LocalityList& locality_list);
Map<UniquePtr<char>, OrphanablePtr<LocalityEntry>, StringLess> map_;
// Lock held while filling child refs for all localities
// inside the map
gpr_mu child_refs_mu_;
};
RefCountedPtr<XdsLb> parent_;
LoadBalancingPolicy* child_ = nullptr;
struct LocalityServerlistEntry {
~LocalityServerlistEntry() {
gpr_free(locality_name);
xds_grpclb_destroy_serverlist(serverlist);
}
char* locality_name;
// The deserialized response from the balancer. May be nullptr until one
// such response has arrived.
xds_grpclb_serverlist* serverlist;
};
~XdsLb();
@ -293,7 +362,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
@ -309,12 +379,6 @@ class XdsLb : public LoadBalancingPolicy {
// Callback to enter fallback mode.
static void OnFallbackTimerLocked(void* arg, grpc_error* error);
// Methods for dealing with the child policy.
void CreateOrUpdateChildPolicyLocked();
grpc_channel_args* CreateChildPolicyArgsLocked();
OrphanablePtr<LoadBalancingPolicy> CreateChildPolicyLocked(
const char* name, const grpc_channel_args* args);
// Who the client is trying to communicate with.
const char* server_name_ = nullptr;
@ -338,10 +402,6 @@ class XdsLb : public LoadBalancingPolicy {
// Timeout in milliseconds for the LB call. 0 means no deadline.
int lb_call_timeout_ms_ = 0;
// The deserialized response from the balancer. May be nullptr until one
// such response has arrived.
xds_grpclb_serverlist* serverlist_ = nullptr;
// Timeout in milliseconds for before using fallback backend addresses.
// 0 means not using fallback.
RefCountedPtr<Config> fallback_policy_config_;
@ -355,11 +415,12 @@ class XdsLb : public LoadBalancingPolicy {
// The policy to use for the backends.
RefCountedPtr<Config> child_policy_config_;
OrphanablePtr<LoadBalancingPolicy> child_policy_;
OrphanablePtr<LoadBalancingPolicy> pending_child_policy_;
// Lock held when modifying the value of child_policy_ or
// pending_child_policy_.
gpr_mu child_policy_mu_;
// Map of policies to use in the backend
LocalityMap locality_map_;
LocalityList locality_serverlist_;
// TODO(mhaidry) : Add a pending locality map that may be swapped with the
// the current one when new localities in the pending map are ready
// to accept connections
};
//
@ -378,105 +439,6 @@ XdsLb::PickResult XdsLb::Picker::Pick(PickArgs* pick, grpc_error** error) {
return result;
}
//
// XdsLb::Helper
//
bool XdsLb::Helper::CalledByPendingChild() const {
GPR_ASSERT(child_ != nullptr);
return child_ == parent_->pending_child_policy_.get();
}
bool XdsLb::Helper::CalledByCurrentChild() const {
GPR_ASSERT(child_ != nullptr);
return child_ == parent_->child_policy_.get();
}
Subchannel* XdsLb::Helper::CreateSubchannel(const grpc_channel_args& args) {
if (parent_->shutting_down_ ||
(!CalledByPendingChild() && !CalledByCurrentChild())) {
return nullptr;
}
return parent_->channel_control_helper()->CreateSubchannel(args);
}
grpc_channel* XdsLb::Helper::CreateChannel(const char* target,
const grpc_channel_args& args) {
if (parent_->shutting_down_ ||
(!CalledByPendingChild() && !CalledByCurrentChild())) {
return nullptr;
}
return parent_->channel_control_helper()->CreateChannel(target, args);
}
void XdsLb::Helper::UpdateState(grpc_connectivity_state state,
grpc_error* state_error,
UniquePtr<SubchannelPicker> picker) {
if (parent_->shutting_down_) {
GRPC_ERROR_UNREF(state_error);
return;
}
// If this request is from the pending child policy, ignore it until
// it reports READY, at which point we swap it into place.
if (CalledByPendingChild()) {
if (grpc_lb_xds_trace.enabled()) {
gpr_log(GPR_INFO,
"[xdslb %p helper %p] pending child policy %p reports state=%s",
parent_.get(), this, parent_->pending_child_policy_.get(),
grpc_connectivity_state_name(state));
}
if (state != GRPC_CHANNEL_READY) {
GRPC_ERROR_UNREF(state_error);
return;
}
grpc_pollset_set_del_pollset_set(
parent_->child_policy_->interested_parties(),
parent_->interested_parties());
MutexLock lock(&parent_->child_policy_mu_);
parent_->child_policy_ = std::move(parent_->pending_child_policy_);
} else if (!CalledByCurrentChild()) {
// This request is from an outdated child, so ignore it.
GRPC_ERROR_UNREF(state_error);
return;
}
// TODO(juanlishen): When in fallback mode, pass the child picker
// through without wrapping it. (Or maybe use a different helper for
// the fallback policy?)
GPR_ASSERT(parent_->lb_chand_ != nullptr);
RefCountedPtr<XdsLbClientStats> client_stats =
parent_->lb_chand_->lb_calld() == nullptr
? nullptr
: parent_->lb_chand_->lb_calld()->client_stats();
parent_->channel_control_helper()->UpdateState(
state, state_error,
UniquePtr<SubchannelPicker>(
New<Picker>(std::move(picker), std::move(client_stats))));
}
void XdsLb::Helper::RequestReresolution() {
if (parent_->shutting_down_) return;
// If there is a pending child policy, ignore re-resolution requests
// from the current child policy (or any outdated child).
if (parent_->pending_child_policy_ != nullptr && !CalledByPendingChild()) {
return;
}
if (grpc_lb_xds_trace.enabled()) {
gpr_log(GPR_INFO,
"[xdslb %p] Re-resolution requested from the internal RR policy "
"(%p).",
parent_.get(), parent_->child_policy_.get());
}
GPR_ASSERT(parent_->lb_chand_ != nullptr);
// If we are talking to a balancer, we expect to get updated addresses
// from the balancer, so we can ignore the re-resolution request from
// the child policy. Otherwise, pass the re-resolution request up to the
// channel.
if (parent_->lb_chand_->lb_calld() == nullptr ||
!parent_->lb_chand_->lb_calld()->seen_initial_response()) {
parent_->channel_control_helper()->RequestReresolution();
}
}
//
// serverlist parsing code
//
@ -539,15 +501,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;
}
@ -952,7 +913,9 @@ void XdsLb::BalancerChannelState::BalancerCallState::
self.release();
lb_calld->ScheduleNextClientLoadReportLocked();
}
if (xds_grpclb_serverlist_equals(xdslb_policy->serverlist_, serverlist)) {
if (!xdslb_policy->locality_serverlist_.empty() &&
xds_grpclb_serverlist_equals(
xdslb_policy->locality_serverlist_[0]->serverlist, serverlist)) {
if (grpc_lb_xds_trace.enabled()) {
gpr_log(GPR_INFO,
"[xdslb %p] Incoming server list identical to current, "
@ -961,21 +924,31 @@ void XdsLb::BalancerChannelState::BalancerCallState::
}
xds_grpclb_destroy_serverlist(serverlist);
} else { /* new serverlist */
if (xdslb_policy->serverlist_ != nullptr) {
if (!xdslb_policy->locality_serverlist_.empty()) {
/* dispose of the old serverlist */
xds_grpclb_destroy_serverlist(xdslb_policy->serverlist_);
xds_grpclb_destroy_serverlist(
xdslb_policy->locality_serverlist_[0]->serverlist);
} else {
/* or dispose of the fallback */
xdslb_policy->fallback_backend_addresses_.reset();
if (xdslb_policy->fallback_timer_callback_pending_) {
grpc_timer_cancel(&xdslb_policy->lb_fallback_timer_);
}
/* Initialize locality serverlist, currently the list only handles
* one child */
xdslb_policy->locality_serverlist_.emplace_back(
MakeUnique<LocalityServerlistEntry>());
xdslb_policy->locality_serverlist_[0]->locality_name =
static_cast<char*>(gpr_strdup(kDefaultLocalityName));
}
// and update the copy in the XdsLb instance. This
// serverlist instance will be destroyed either upon the next
// update or when the XdsLb instance is destroyed.
xdslb_policy->serverlist_ = serverlist;
xdslb_policy->CreateOrUpdateChildPolicyLocked();
xdslb_policy->locality_serverlist_[0]->serverlist = serverlist;
xdslb_policy->locality_map_.UpdateLocked(
xdslb_policy->locality_serverlist_,
xdslb_policy->child_policy_config_.get(), xdslb_policy->args_,
xdslb_policy);
}
} else {
if (grpc_lb_xds_trace.enabled()) {
@ -1082,9 +1055,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.
@ -1116,9 +1086,11 @@ grpc_channel_args* BuildBalancerChannelArgs(const grpc_channel_args* args) {
// ctor and dtor
//
XdsLb::XdsLb(Args args) : LoadBalancingPolicy(std::move(args)) {
XdsLb::XdsLb(Args args)
: LoadBalancingPolicy(std::move(args)),
locality_map_(),
locality_serverlist_() {
gpr_mu_init(&lb_chand_mu_);
gpr_mu_init(&child_policy_mu_);
// Record server name.
const grpc_arg* arg = grpc_channel_args_find(args.args, GRPC_ARG_SERVER_URI);
const char* server_uri = grpc_channel_arg_get_string(arg);
@ -1145,10 +1117,7 @@ XdsLb::~XdsLb() {
gpr_mu_destroy(&lb_chand_mu_);
gpr_free((void*)server_name_);
grpc_channel_args_destroy(args_);
if (serverlist_ != nullptr) {
xds_grpclb_destroy_serverlist(serverlist_);
}
gpr_mu_destroy(&child_policy_mu_);
locality_serverlist_.clear();
}
void XdsLb::ShutdownLocked() {
@ -1156,19 +1125,7 @@ void XdsLb::ShutdownLocked() {
if (fallback_timer_callback_pending_) {
grpc_timer_cancel(&lb_fallback_timer_);
}
if (child_policy_ != nullptr) {
grpc_pollset_set_del_pollset_set(child_policy_->interested_parties(),
interested_parties());
}
if (pending_child_policy_ != nullptr) {
grpc_pollset_set_del_pollset_set(
pending_child_policy_->interested_parties(), interested_parties());
}
{
MutexLock lock(&child_policy_mu_);
child_policy_.reset();
pending_child_policy_.reset();
}
locality_map_.ShutdownLocked();
// We destroy the LB channel here instead of in our destructor because
// destroying the channel triggers a last callback to
// OnBalancerChannelConnectivityChangedLocked(), and we need to be
@ -1191,30 +1148,13 @@ void XdsLb::ResetBackoffLocked() {
if (pending_lb_chand_ != nullptr) {
grpc_channel_reset_connect_backoff(pending_lb_chand_->channel());
}
if (child_policy_ != nullptr) {
child_policy_->ResetBackoffLocked();
}
if (pending_child_policy_ != nullptr) {
pending_child_policy_->ResetBackoffLocked();
}
locality_map_.ResetBackoffLocked();
}
void XdsLb::FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels,
channelz::ChildRefsList* child_channels) {
{
// Delegate to the child_policy_ to fill the children subchannels.
// This must be done holding child_policy_mu_, since this method does not
// run in the combiner.
MutexLock lock(&child_policy_mu_);
if (child_policy_ != nullptr) {
child_policy_->FillChildRefsForChannelz(child_subchannels,
child_channels);
}
if (pending_child_policy_ != nullptr) {
pending_child_policy_->FillChildRefsForChannelz(child_subchannels,
child_channels);
}
}
// Delegate to the child_policy_ to fill the children subchannels.
locality_map_.FillChildRefsForChannelz(child_subchannels, child_channels);
MutexLock lock(&lb_chand_mu_);
if (lb_chand_ != nullptr) {
grpc_core::channelz::ChannelNode* channel_node =
@ -1232,17 +1172,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,26 +1243,26 @@ 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.
// TODO(vpowar): Handle the fallback_address changes when we add support for
// fallback in xDS.
if (child_policy_ != nullptr) CreateOrUpdateChildPolicyLocked();
locality_map_.UpdateLocked(locality_serverlist_, child_policy_config_.get(),
args_, this);
// If this is the initial update, start the fallback timer.
if (is_initial_update) {
if (lb_fallback_timeout_ms_ > 0 && serverlist_ == nullptr &&
if (lb_fallback_timeout_ms_ > 0 && locality_serverlist_.empty() &&
!fallback_timer_callback_pending_) {
grpc_millis deadline = ExecCtx::Get()->Now() + lb_fallback_timeout_ms_;
Ref(DEBUG_LOCATION, "on_fallback_timer").release(); // Held by closure
@ -1353,8 +1286,8 @@ void XdsLb::OnFallbackTimerLocked(void* arg, grpc_error* error) {
xdslb_policy->fallback_timer_callback_pending_ = false;
// If we receive a serverlist after the timer fires but before this callback
// actually runs, don't fall back.
if (xdslb_policy->serverlist_ == nullptr && !xdslb_policy->shutting_down_ &&
error == GRPC_ERROR_NONE) {
if (xdslb_policy->locality_serverlist_.empty() &&
!xdslb_policy->shutting_down_ && error == GRPC_ERROR_NONE) {
if (grpc_lb_xds_trace.enabled()) {
gpr_log(GPR_INFO,
"[xdslb %p] Fallback timer fired. Not using fallback backends",
@ -1364,22 +1297,71 @@ void XdsLb::OnFallbackTimerLocked(void* arg, grpc_error* error) {
xdslb_policy->Unref(DEBUG_LOCATION, "on_fallback_timer");
}
//
// code for interacting with the child policy
//
void XdsLb::LocalityMap::PruneLocalities(const LocalityList& locality_list) {
for (auto iter = map_.begin(); iter != map_.end();) {
bool found = false;
for (size_t i = 0; i < locality_list.size(); i++) {
if (!gpr_stricmp(locality_list[i]->locality_name, iter->first.get())) {
found = true;
}
}
if (!found) { // Remove entries not present in the locality list
MutexLock lock(&child_refs_mu_);
iter = map_.erase(iter);
} else
iter++;
}
}
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};
void XdsLb::LocalityMap::UpdateLocked(
const LocalityList& locality_serverlist,
LoadBalancingPolicy::Config* child_policy_config,
const grpc_channel_args* args, XdsLb* parent) {
if (parent->shutting_down_) return;
for (size_t i = 0; i < locality_serverlist.size(); i++) {
UniquePtr<char> locality_name(
gpr_strdup(locality_serverlist[i]->locality_name));
auto iter = map_.find(locality_name);
if (iter == map_.end()) {
OrphanablePtr<LocalityEntry> new_entry =
MakeOrphanable<LocalityEntry>(parent->Ref());
MutexLock lock(&child_refs_mu_);
iter = map_.emplace(std::move(locality_name), std::move(new_entry)).first;
}
// Don't create new child policies if not directed to
xds_grpclb_serverlist* serverlist =
parent->locality_serverlist_[i]->serverlist;
iter->second->UpdateLocked(serverlist, child_policy_config, args);
}
PruneLocalities(locality_serverlist);
}
void grpc_core::XdsLb::LocalityMap::ShutdownLocked() {
MutexLock lock(&child_refs_mu_);
map_.clear();
}
void grpc_core::XdsLb::LocalityMap::ResetBackoffLocked() {
for (auto iter = map_.begin(); iter != map_.end(); iter++) {
iter->second->ResetBackoffLocked();
}
}
void grpc_core::XdsLb::LocalityMap::FillChildRefsForChannelz(
channelz::ChildRefsList* child_subchannels,
channelz::ChildRefsList* child_channels) {
MutexLock lock(&child_refs_mu_);
for (auto iter = map_.begin(); iter != map_.end(); iter++) {
iter->second->FillChildRefsForChannelz(child_subchannels, child_channels);
}
}
// Locality Entry child policy methods
grpc_channel_args*
XdsLb::LocalityMap::LocalityEntry::CreateChildPolicyArgsLocked(
const grpc_channel_args* args_in) {
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,16 +1372,16 @@ 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_in, args_to_add,
GPR_ARRAY_SIZE(args_to_add));
}
OrphanablePtr<LoadBalancingPolicy> XdsLb::CreateChildPolicyLocked(
OrphanablePtr<LoadBalancingPolicy>
XdsLb::LocalityMap::LocalityEntry::CreateChildPolicyLocked(
const char* name, const grpc_channel_args* args) {
Helper* helper = New<Helper>(Ref());
Helper* helper = New<Helper>(this->Ref());
LoadBalancingPolicy::Args lb_policy_args;
lb_policy_args.combiner = combiner();
lb_policy_args.combiner = parent_->combiner();
lb_policy_args.args = args;
lb_policy_args.channel_control_helper =
UniquePtr<ChannelControlHelper>(helper);
@ -1420,14 +1402,27 @@ OrphanablePtr<LoadBalancingPolicy> XdsLb::CreateChildPolicyLocked(
// child policy. This will make the child policy progress upon activity on xDS
// LB, which in turn is tied to the application's call.
grpc_pollset_set_add_pollset_set(lb_policy->interested_parties(),
interested_parties());
parent_->interested_parties());
return lb_policy;
}
void XdsLb::CreateOrUpdateChildPolicyLocked() {
if (shutting_down_) return;
grpc_channel_args* args = CreateChildPolicyArgsLocked();
GPR_ASSERT(args != nullptr);
void XdsLb::LocalityMap::LocalityEntry::UpdateLocked(
xds_grpclb_serverlist* serverlist,
LoadBalancingPolicy::Config* child_policy_config,
const grpc_channel_args* args_in) {
if (parent_->shutting_down_) return;
// 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 == nullptr ? nullptr : child_policy_config->Ref();
update_args.args = CreateChildPolicyArgsLocked(args_in);
// 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
@ -1479,9 +1474,9 @@ void XdsLb::CreateOrUpdateChildPolicyLocked() {
// when the new child transitions into state READY.
// TODO(juanlishen): If the child policy is not configured via service config,
// use whatever algorithm is specified by the balancer.
const char* child_policy_name = child_policy_config_ == nullptr
const char* child_policy_name = child_policy_config == nullptr
? "round_robin"
: child_policy_config_->name();
: child_policy_config->name();
const bool create_policy =
// case 1
child_policy_ == nullptr ||
@ -1500,7 +1495,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 +1519,146 @@ 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));
}
void XdsLb::LocalityMap::LocalityEntry::ShutdownLocked() {
// Remove the child policy's interested_parties pollset_set from the
// xDS policy.
grpc_pollset_set_del_pollset_set(child_policy_->interested_parties(),
parent_->interested_parties());
if (pending_child_policy_ != nullptr) {
grpc_pollset_set_del_pollset_set(
pending_child_policy_->interested_parties(),
parent_->interested_parties());
}
{
MutexLock lock(&child_policy_mu_);
child_policy_.reset();
pending_child_policy_.reset();
}
}
void XdsLb::LocalityMap::LocalityEntry::ResetBackoffLocked() {
child_policy_->ResetBackoffLocked();
if (pending_child_policy_ != nullptr) {
pending_child_policy_->ResetBackoffLocked();
}
}
void XdsLb::LocalityMap::LocalityEntry::FillChildRefsForChannelz(
channelz::ChildRefsList* child_subchannels,
channelz::ChildRefsList* child_channels) {
MutexLock lock(&child_policy_mu_);
child_policy_->FillChildRefsForChannelz(child_subchannels, child_channels);
if (pending_child_policy_ != nullptr) {
pending_child_policy_->FillChildRefsForChannelz(child_subchannels,
child_channels);
}
}
void XdsLb::LocalityMap::LocalityEntry::Orphan() {
ShutdownLocked();
Unref();
}
//
// LocalityEntry::Helper implementation
//
bool XdsLb::LocalityMap::LocalityEntry::Helper::CalledByPendingChild() const {
GPR_ASSERT(child_ != nullptr);
return child_ == entry_->pending_child_policy_.get();
}
bool XdsLb::LocalityMap::LocalityEntry::Helper::CalledByCurrentChild() const {
GPR_ASSERT(child_ != nullptr);
return child_ == entry_->child_policy_.get();
}
Subchannel* XdsLb::LocalityMap::LocalityEntry::Helper::CreateSubchannel(
const grpc_channel_args& args) {
if (entry_->parent_->shutting_down_ ||
(!CalledByPendingChild() && !CalledByCurrentChild())) {
return nullptr;
}
return entry_->parent_->channel_control_helper()->CreateSubchannel(args);
}
grpc_channel* XdsLb::LocalityMap::LocalityEntry::Helper::CreateChannel(
const char* target, const grpc_channel_args& args) {
if (entry_->parent_->shutting_down_ ||
(!CalledByPendingChild() && !CalledByCurrentChild())) {
return nullptr;
}
return entry_->parent_->channel_control_helper()->CreateChannel(target, args);
}
void XdsLb::LocalityMap::LocalityEntry::Helper::UpdateState(
grpc_connectivity_state state, grpc_error* state_error,
UniquePtr<SubchannelPicker> picker) {
if (entry_->parent_->shutting_down_) {
GRPC_ERROR_UNREF(state_error);
return;
}
// If this request is from the pending child policy, ignore it until
// it reports READY, at which point we swap it into place.
if (CalledByPendingChild()) {
if (grpc_lb_xds_trace.enabled()) {
gpr_log(GPR_INFO,
"[xdslb %p helper %p] pending child policy %p reports state=%s",
entry_->parent_.get(), this, entry_->pending_child_policy_.get(),
grpc_connectivity_state_name(state));
}
if (state != GRPC_CHANNEL_READY) {
GRPC_ERROR_UNREF(state_error);
return;
}
grpc_pollset_set_del_pollset_set(
entry_->child_policy_->interested_parties(),
entry_->parent_->interested_parties());
MutexLock lock(&entry_->child_policy_mu_);
entry_->child_policy_ = std::move(entry_->pending_child_policy_);
} else if (!CalledByCurrentChild()) {
// This request is from an outdated child, so ignore it.
GRPC_ERROR_UNREF(state_error);
return;
}
// TODO(juanlishen): When in fallback mode, pass the child picker
// through without wrapping it. (Or maybe use a different helper for
// the fallback policy?)
GPR_ASSERT(entry_->parent_->lb_chand_ != nullptr);
RefCountedPtr<XdsLbClientStats> client_stats =
entry_->parent_->lb_chand_->lb_calld() == nullptr
? nullptr
: entry_->parent_->lb_chand_->lb_calld()->client_stats();
entry_->parent_->channel_control_helper()->UpdateState(
state, state_error,
UniquePtr<SubchannelPicker>(
New<Picker>(std::move(picker), std::move(client_stats))));
}
void XdsLb::LocalityMap::LocalityEntry::Helper::RequestReresolution() {
if (entry_->parent_->shutting_down_) return;
// If there is a pending child policy, ignore re-resolution requests
// from the current child policy (or any outdated child).
if (entry_->pending_child_policy_ != nullptr && !CalledByPendingChild()) {
return;
}
if (grpc_lb_xds_trace.enabled()) {
gpr_log(GPR_INFO,
"[xdslb %p] Re-resolution requested from the internal RR policy "
"(%p).",
entry_->parent_.get(), entry_->child_policy_.get());
}
GPR_ASSERT(entry_->parent_->lb_chand_ != nullptr);
// If we are talking to a balancer, we expect to get updated addresses
// from the balancer, so we can ignore the re-resolution request from
// the child policy. Otherwise, pass the re-resolution request up to the
// channel.
if (entry_->parent_->lb_chand_->lb_calld() == nullptr ||
!entry_->parent_->lb_chand_->lb_calld()->seen_initial_response()) {
entry_->parent_->channel_control_helper()->RequestReresolution();
}
}
//

@ -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;

@ -645,17 +645,22 @@ void grpc_chttp2_stream_unref(grpc_chttp2_stream* s) {
}
#endif
grpc_chttp2_stream::grpc_chttp2_stream(grpc_chttp2_transport* t,
grpc_stream_refcount* refcount,
const void* server_data,
gpr_arena* arena)
: t(t), refcount(refcount), metadata_buffer{{arena}, {arena}} {
grpc_chttp2_stream::Reffer::Reffer(grpc_chttp2_stream* s) {
/* We reserve one 'active stream' that's dropped when the stream is
read-closed. The others are for Chttp2IncomingByteStreams that are
actively reading */
GRPC_CHTTP2_STREAM_REF(this, "chttp2");
GRPC_CHTTP2_REF_TRANSPORT(t, "stream");
GRPC_CHTTP2_STREAM_REF(s, "chttp2");
GRPC_CHTTP2_REF_TRANSPORT(s->t, "stream");
}
grpc_chttp2_stream::grpc_chttp2_stream(grpc_chttp2_transport* t,
grpc_stream_refcount* refcount,
const void* server_data,
gpr_arena* arena)
: t(t),
refcount(refcount),
reffer(this),
metadata_buffer{{arena}, {arena}} {
if (server_data) {
id = static_cast<uint32_t>((uintptr_t)server_data);
*t->accepting_stream = this;
@ -678,7 +683,7 @@ grpc_chttp2_stream::grpc_chttp2_stream(grpc_chttp2_transport* t,
grpc_slice_buffer_init(&decompressed_data_buffer);
GRPC_CLOSURE_INIT(&complete_fetch_locked, ::complete_fetch_locked, this,
grpc_schedule_on_exec_ctx);
grpc_combiner_scheduler(t->combiner));
GRPC_CLOSURE_INIT(&reset_byte_stream, ::reset_byte_stream, this,
grpc_combiner_scheduler(t->combiner));
}
@ -1268,7 +1273,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);
@ -1363,8 +1370,6 @@ static void complete_fetch_locked(void* gs, grpc_error* error) {
}
}
static void do_nothing(void* arg, grpc_error* error) {}
static void log_metadata(const grpc_metadata_batch* md_batch, uint32_t id,
bool is_client, bool is_initial) {
for (grpc_linked_mdelem* md = md_batch->list.head; md != nullptr;
@ -1409,21 +1414,14 @@ static void perform_stream_op_locked(void* stream_op,
}
grpc_closure* on_complete = op->on_complete;
// TODO(roth): This is a hack needed because we use data inside of the
// closure itself to do the barrier calculation (i.e., to ensure that
// we don't schedule the closure until all ops in the batch have been
// completed). This can go away once we move to a new C++ closure API
// that provides the ability to create a barrier closure.
if (on_complete == nullptr) {
on_complete = GRPC_CLOSURE_INIT(&op->handler_private.closure, do_nothing,
nullptr, grpc_schedule_on_exec_ctx);
// on_complete will be null if and only if there are no send ops in the batch.
if (on_complete != nullptr) {
// This batch has send ops. Use final_data as a barrier until enqueue time;
// the inital counter is dropped at the end of this function.
on_complete->next_data.scratch = CLOSURE_BARRIER_FIRST_REF_BIT;
on_complete->error_data.error = GRPC_ERROR_NONE;
}
/* use final_data as a barrier until enqueue time; the inital counter is
dropped at the end of this function */
on_complete->next_data.scratch = CLOSURE_BARRIER_FIRST_REF_BIT;
on_complete->error_data.error = GRPC_ERROR_NONE;
if (op->cancel_stream) {
GRPC_STATS_INC_HTTP2_OP_CANCEL();
grpc_chttp2_cancel_stream(t, s, op_payload->cancel_stream.cancel_error);
@ -1672,8 +1670,10 @@ static void perform_stream_op_locked(void* stream_op,
grpc_chttp2_maybe_complete_recv_trailing_metadata(t, s);
}
grpc_chttp2_complete_closure_step(t, s, &on_complete, GRPC_ERROR_NONE,
"op->on_complete");
if (on_complete != nullptr) {
grpc_chttp2_complete_closure_step(t, s, &on_complete, GRPC_ERROR_NONE,
"op->on_complete");
}
GRPC_CHTTP2_STREAM_UNREF(s, "perform_stream_op");
}
@ -2603,6 +2603,9 @@ static void start_bdp_ping_locked(void* tp, grpc_error* error) {
gpr_log(GPR_INFO, "%s: Start BDP ping err=%s", t->peer_string,
grpc_error_string(error));
}
if (error != GRPC_ERROR_NONE || t->closed_with_error != GRPC_ERROR_NONE) {
return;
}
/* Reset the keepalive ping timer */
if (t->keepalive_state == GRPC_CHTTP2_KEEPALIVE_STATE_WAITING) {
grpc_timer_cancel(&t->keepalive_ping_timer);
@ -2616,7 +2619,7 @@ static void finish_bdp_ping_locked(void* tp, grpc_error* error) {
gpr_log(GPR_INFO, "%s: Complete BDP ping err=%s", t->peer_string,
grpc_error_string(error));
}
if (error != GRPC_ERROR_NONE) {
if (error != GRPC_ERROR_NONE || t->closed_with_error != GRPC_ERROR_NONE) {
GRPC_CHTTP2_UNREF_TRANSPORT(t, "bdp_ping");
return;
}

@ -30,11 +30,15 @@
grpc_error* grpc_chttp2_incoming_metadata_buffer_add(
grpc_chttp2_incoming_metadata_buffer* buffer, grpc_mdelem elem) {
buffer->size += GRPC_MDELEM_LENGTH(elem);
return grpc_metadata_batch_add_tail(
&buffer->batch,
static_cast<grpc_linked_mdelem*>(
gpr_arena_alloc(buffer->arena, sizeof(grpc_linked_mdelem))),
elem);
grpc_linked_mdelem* storage;
if (buffer->count < buffer->kPreallocatedMDElem) {
storage = &buffer->preallocated_mdelems[buffer->count];
buffer->count++;
} else {
storage = static_cast<grpc_linked_mdelem*>(
gpr_arena_alloc(buffer->arena, sizeof(grpc_linked_mdelem)));
}
return grpc_metadata_batch_add_tail(&buffer->batch, storage, elem);
}
grpc_error* grpc_chttp2_incoming_metadata_buffer_replace_or_add(

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

Loading…
Cancel
Save