Merge branch 'grpc_namespace_channel_new' into grpc_namespace_completion_queue

pull/18731/head
Karthik Ravi Shankar 6 years ago
commit 9eec789a4d
  1. 8
      .gitignore
  2. 30
      .vscode/launch.json
  3. 14
      BUILD
  4. 22
      BUILD.gn
  5. 135
      CMakeLists.txt
  6. 13
      CONTRIBUTING.md
  7. 167
      Makefile
  8. 26
      WORKSPACE
  9. 5
      bazel/grpc_build_system.bzl
  10. 29
      bazel/grpc_deps.bzl
  11. 48
      build.yaml
  12. 8
      config.m4
  13. 8
      config.w32
  14. 2
      doc/core/grpc-polling-engines.md
  15. 11
      doc/environment_variables.md
  16. 2
      examples/csharp/HelloworldXamarin/iOS/AppDelegate.cs
  17. 48
      examples/objective-c/auth_sample/MakeRPCViewController.m
  18. 35
      examples/objective-c/helloworld/main.m
  19. 33
      examples/objective-c/helloworld_macos/main.m
  20. 247
      examples/objective-c/route_guide/ViewControllers.m
  21. 32
      examples/python/wait_for_ready/BUILD.bazel
  22. 32
      examples/python/wait_for_ready/README.md
  23. 26
      examples/python/wait_for_ready/test/_wait_for_ready_example_test.py
  24. 114
      examples/python/wait_for_ready/wait_for_ready_example.py
  25. 2
      examples/ruby/without_protobuf/echo_client.rb
  26. 15
      gRPC-C++.podspec
  27. 33
      gRPC-Core.podspec
  28. 13
      grpc.gemspec
  29. 26
      grpc.gyp
  30. 2
      include/grpc/grpc_security.h
  31. 7
      include/grpc/impl/codegen/grpc_types.h
  32. 10
      include/grpc/impl/codegen/port_platform.h
  33. 22
      include/grpc/impl/codegen/slice.h
  34. 2
      include/grpc/slice.h
  35. 85
      include/grpcpp/channel.h
  36. 125
      include/grpcpp/channel_impl.h
  37. 8
      include/grpcpp/create_channel.h
  38. 12
      include/grpcpp/create_channel_impl.h
  39. 6
      include/grpcpp/generic/generic_stub_impl.h
  40. 12
      include/grpcpp/impl/codegen/async_stream.h
  41. 2
      include/grpcpp/impl/codegen/channel_interface.h
  42. 160
      include/grpcpp/impl/codegen/client_callback.h
  43. 22
      include/grpcpp/impl/codegen/client_context.h
  44. 6
      include/grpcpp/impl/codegen/client_interceptor.h
  45. 4
      include/grpcpp/impl/codegen/completion_queue_impl.h
  46. 55
      include/grpcpp/impl/codegen/message_allocator.h
  47. 12
      include/grpcpp/impl/codegen/method_handler_impl.h
  48. 8
      include/grpcpp/impl/codegen/rpc_service_method.h
  49. 114
      include/grpcpp/impl/codegen/server_callback.h
  50. 5
      include/grpcpp/impl/codegen/server_interface.h
  51. 5
      include/grpcpp/impl/codegen/service_type.h
  52. 17
      include/grpcpp/impl/codegen/sync.h
  53. 6
      include/grpcpp/impl/codegen/sync_stream.h
  54. 5
      include/grpcpp/impl/server_builder_plugin.h
  55. 321
      include/grpcpp/security/credentials.h
  56. 281
      include/grpcpp/security/credentials_impl.h
  57. 1
      include/grpcpp/server.h
  58. 123
      include/grpcpp/support/channel_arguments.h
  59. 152
      include/grpcpp/support/channel_arguments_impl.h
  60. 24
      include/grpcpp/support/message_allocator.h
  61. 13
      package.xml
  62. 109
      src/compiler/cpp_generator.cc
  63. 4
      src/compiler/cpp_generator.h
  64. 10
      src/compiler/cpp_plugin.cc
  65. 16
      src/compiler/objective_c_generator.cc
  66. 30
      src/compiler/protobuf_plugin.h
  67. 36
      src/compiler/python_generator.cc
  68. 2
      src/compiler/python_generator.h
  69. 34
      src/compiler/python_generator_helpers.h
  70. 7
      src/compiler/schema_interface.h
  71. 3252
      src/core/ext/filters/client_channel/client_channel.cc
  72. 5
      src/core/ext/filters/client_channel/client_channel_channelz.cc
  73. 2
      src/core/ext/filters/client_channel/client_channel_plugin.cc
  74. 24
      src/core/ext/filters/client_channel/health/health_check_client.cc
  75. 6
      src/core/ext/filters/client_channel/health/health_check_client.h
  76. 2
      src/core/ext/filters/client_channel/http_connect_handshaker.h
  77. 26
      src/core/ext/filters/client_channel/lb_policy.cc
  78. 41
      src/core/ext/filters/client_channel/lb_policy.h
  79. 137
      src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc
  80. 81
      src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
  81. 62
      src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc
  82. 12
      src/core/ext/filters/client_channel/lb_policy/subchannel_list.h
  83. 945
      src/core/ext/filters/client_channel/lb_policy/xds/xds.cc
  84. 5
      src/core/ext/filters/client_channel/lb_policy_factory.h
  85. 107
      src/core/ext/filters/client_channel/lb_policy_registry.cc
  86. 11
      src/core/ext/filters/client_channel/lb_policy_registry.h
  87. 8
      src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
  88. 3
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc
  89. 589
      src/core/ext/filters/client_channel/resolver_result_parsing.cc
  90. 183
      src/core/ext/filters/client_channel/resolver_result_parsing.h
  91. 36
      src/core/ext/filters/client_channel/resolving_lb_policy.cc
  92. 26
      src/core/ext/filters/client_channel/resolving_lb_policy.h
  93. 79
      src/core/ext/filters/client_channel/service_config.cc
  94. 273
      src/core/ext/filters/client_channel/service_config.h
  95. 79
      src/core/ext/filters/client_channel/subchannel.cc
  96. 11
      src/core/ext/filters/client_channel/subchannel.h
  97. 7
      src/core/ext/filters/deadline/deadline_filter.cc
  98. 5
      src/core/ext/filters/deadline/deadline_filter.h
  99. 12
      src/core/ext/filters/http/client/http_client_filter.cc
  100. 2
      src/core/ext/filters/http/client/http_client_filter.h
  101. Some files were not shown because too many files have changed in this diff Show More

8
.gitignore vendored

@ -134,3 +134,11 @@ bm_*.json
# cmake build files
/cmake/build
# Visual Studio Code artifacts
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json

@ -1,30 +0,0 @@
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Mocha Tests",
"cwd": "${workspaceRoot}",
"runtimeExecutable": "${workspaceRoot}/node_modules/.bin/mocha",
"windows": {
"runtimeExecutable": "${workspaceRoot}/node_modules/.bin/mocha.cmd"
},
"runtimeArgs": [
"-u",
"tdd",
"--timeout",
"999999",
"--colors",
"${workspaceRoot}/src/node/test"
],
"internalConsoleOptions": "openOnSessionStart"
},
{
"type": "node",
"request": "attach",
"name": "Attach to Process",
"port": 5858
}
]
}

14
BUILD

@ -216,6 +216,7 @@ GRPCXX_PUBLIC_HDRS = [
"include/grpcpp/alarm.h",
"include/grpcpp/alarm_impl.h",
"include/grpcpp/channel.h",
"include/grpcpp/channel_impl.h",
"include/grpcpp/client_context.h",
"include/grpcpp/completion_queue.h",
"include/grpcpp/create_channel.h",
@ -252,6 +253,7 @@ GRPCXX_PUBLIC_HDRS = [
"include/grpcpp/security/auth_metadata_processor.h",
"include/grpcpp/security/auth_metadata_processor_impl.h",
"include/grpcpp/security/credentials.h",
"include/grpcpp/security/credentials_impl.h",
"include/grpcpp/security/server_credentials.h",
"include/grpcpp/security/server_credentials_impl.h",
"include/grpcpp/server.h",
@ -264,10 +266,12 @@ GRPCXX_PUBLIC_HDRS = [
"include/grpcpp/support/async_unary_call.h",
"include/grpcpp/support/byte_buffer.h",
"include/grpcpp/support/channel_arguments.h",
"include/grpcpp/support/channel_arguments_impl.h",
"include/grpcpp/support/client_callback.h",
"include/grpcpp/support/client_interceptor.h",
"include/grpcpp/support/config.h",
"include/grpcpp/support/interceptor.h",
"include/grpcpp/support/message_allocator.h",
"include/grpcpp/support/proto_buffer_reader.h",
"include/grpcpp/support/proto_buffer_writer.h",
"include/grpcpp/support/server_callback.h",
@ -540,7 +544,6 @@ grpc_cc_library(
name = "gpr_base",
srcs = [
"src/core/lib/gpr/alloc.cc",
"src/core/lib/gpr/arena.cc",
"src/core/lib/gpr/atm.cc",
"src/core/lib/gpr/cpu_iphone.cc",
"src/core/lib/gpr/cpu_linux.cc",
@ -573,6 +576,7 @@ grpc_cc_library(
"src/core/lib/gpr/tmpfile_posix.cc",
"src/core/lib/gpr/tmpfile_windows.cc",
"src/core/lib/gpr/wrap_memcpy.cc",
"src/core/lib/gprpp/arena.cc",
"src/core/lib/gprpp/fork.cc",
"src/core/lib/gprpp/thd_posix.cc",
"src/core/lib/gprpp/thd_windows.cc",
@ -597,6 +601,8 @@ grpc_cc_library(
"src/core/lib/gpr/tmpfile.h",
"src/core/lib/gpr/useful.h",
"src/core/lib/gprpp/abstract.h",
"src/core/lib/gprpp/arena.h",
"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",
@ -736,6 +742,7 @@ grpc_cc_library(
"src/core/lib/channel/handshaker_registry.cc",
"src/core/lib/channel/status_util.cc",
"src/core/lib/compression/compression.cc",
"src/core/lib/compression/compression_args.cc",
"src/core/lib/compression/compression_internal.cc",
"src/core/lib/compression/message_compress.cc",
"src/core/lib/compression/stream_compression.cc",
@ -891,6 +898,7 @@ grpc_cc_library(
"src/core/lib/channel/handshaker_registry.h",
"src/core/lib/channel/status_util.h",
"src/core/lib/compression/algorithm_metadata.h",
"src/core/lib/compression/compression_args.h",
"src/core/lib/compression/compression_internal.h",
"src/core/lib/compression/message_compress.h",
"src/core/lib/compression/stream_compression.h",
@ -2137,6 +2145,7 @@ grpc_cc_library(
"include/grpcpp/impl/codegen/intercepted_channel.h",
"include/grpcpp/impl/codegen/interceptor.h",
"include/grpcpp/impl/codegen/interceptor_common.h",
"include/grpcpp/impl/codegen/message_allocator.h",
"include/grpcpp/impl/codegen/metadata_map.h",
"include/grpcpp/impl/codegen/method_handler_impl.h",
"include/grpcpp/impl/codegen/rpc_method.h",
@ -2347,7 +2356,8 @@ grpc_cc_library(
":envoy_core_upb",
":google_api_upb",
":proto_gen_validate_upb",
]
],
tags = ["no_windows"],
)
grpc_cc_library(

@ -131,7 +131,6 @@ config("grpc_config") {
"include/grpc/support/time.h",
"src/core/lib/gpr/alloc.cc",
"src/core/lib/gpr/alloc.h",
"src/core/lib/gpr/arena.cc",
"src/core/lib/gpr/arena.h",
"src/core/lib/gpr/atm.cc",
"src/core/lib/gpr/cpu_iphone.cc",
@ -180,6 +179,8 @@ config("grpc_config") {
"src/core/lib/gpr/useful.h",
"src/core/lib/gpr/wrap_memcpy.cc",
"src/core/lib/gprpp/abstract.h",
"src/core/lib/gprpp/arena.cc",
"src/core/lib/gprpp/arena.h",
"src/core/lib/gprpp/atomic.h",
"src/core/lib/gprpp/fork.cc",
"src/core/lib/gprpp/fork.h",
@ -445,6 +446,8 @@ config("grpc_config") {
"src/core/lib/channel/status_util.h",
"src/core/lib/compression/algorithm_metadata.h",
"src/core/lib/compression/compression.cc",
"src/core/lib/compression/compression_args.cc",
"src/core/lib/compression/compression_args.h",
"src/core/lib/compression/compression_internal.cc",
"src/core/lib/compression/compression_internal.h",
"src/core/lib/compression/message_compress.cc",
@ -479,18 +482,24 @@ config("grpc_config") {
"src/core/lib/iomgr/buffer_list.h",
"src/core/lib/iomgr/call_combiner.cc",
"src/core/lib/iomgr/call_combiner.h",
"src/core/lib/iomgr/cfstream_handle.cc",
"src/core/lib/iomgr/cfstream_handle.h",
"src/core/lib/iomgr/closure.h",
"src/core/lib/iomgr/combiner.cc",
"src/core/lib/iomgr/combiner.h",
"src/core/lib/iomgr/dynamic_annotations.h",
"src/core/lib/iomgr/endpoint.cc",
"src/core/lib/iomgr/endpoint.h",
"src/core/lib/iomgr/endpoint_cfstream.cc",
"src/core/lib/iomgr/endpoint_cfstream.h",
"src/core/lib/iomgr/endpoint_pair.h",
"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.h",
"src/core/lib/iomgr/error_cfstream.cc",
"src/core/lib/iomgr/error_cfstream.h",
"src/core/lib/iomgr/error_internal.h",
"src/core/lib/iomgr/ev_epoll1_linux.cc",
"src/core/lib/iomgr/ev_epoll1_linux.h",
@ -526,6 +535,7 @@ config("grpc_config") {
"src/core/lib/iomgr/iomgr_internal.h",
"src/core/lib/iomgr/iomgr_posix.cc",
"src/core/lib/iomgr/iomgr_posix.h",
"src/core/lib/iomgr/iomgr_posix_cfstream.cc",
"src/core/lib/iomgr/iomgr_uv.cc",
"src/core/lib/iomgr/iomgr_windows.cc",
"src/core/lib/iomgr/is_epollexclusive_available.cc",
@ -581,6 +591,7 @@ config("grpc_config") {
"src/core/lib/iomgr/sys_epoll_wrapper.h",
"src/core/lib/iomgr/tcp_client.cc",
"src/core/lib/iomgr/tcp_client.h",
"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_posix.h",
@ -1046,6 +1057,7 @@ config("grpc_config") {
"include/grpcpp/impl/codegen/intercepted_channel.h",
"include/grpcpp/impl/codegen/interceptor.h",
"include/grpcpp/impl/codegen/interceptor_common.h",
"include/grpcpp/impl/codegen/message_allocator.h",
"include/grpcpp/impl/codegen/metadata_map.h",
"include/grpcpp/impl/codegen/method_handler_impl.h",
"include/grpcpp/impl/codegen/proto_buffer_reader.h",
@ -1085,6 +1097,7 @@ config("grpc_config") {
"include/grpcpp/security/auth_metadata_processor.h",
"include/grpcpp/security/auth_metadata_processor_impl.h",
"include/grpcpp/security/credentials.h",
"include/grpcpp/security/credentials_impl.h",
"include/grpcpp/security/server_credentials.h",
"include/grpcpp/security/server_credentials_impl.h",
"include/grpcpp/server.h",
@ -1097,10 +1110,12 @@ config("grpc_config") {
"include/grpcpp/support/async_unary_call.h",
"include/grpcpp/support/byte_buffer.h",
"include/grpcpp/support/channel_arguments.h",
"include/grpcpp/support/channel_arguments_impl.h",
"include/grpcpp/support/client_callback.h",
"include/grpcpp/support/client_interceptor.h",
"include/grpcpp/support/config.h",
"include/grpcpp/support/interceptor.h",
"include/grpcpp/support/message_allocator.h",
"include/grpcpp/support/proto_buffer_reader.h",
"include/grpcpp/support/proto_buffer_writer.h",
"include/grpcpp/support/server_callback.h",
@ -1128,6 +1143,7 @@ config("grpc_config") {
"src/core/lib/channel/handshaker_registry.h",
"src/core/lib/channel/status_util.h",
"src/core/lib/compression/algorithm_metadata.h",
"src/core/lib/compression/compression_args.h",
"src/core/lib/compression/compression_internal.h",
"src/core/lib/compression/message_compress.h",
"src/core/lib/compression/stream_compression.h",
@ -1153,6 +1169,7 @@ config("grpc_config") {
"src/core/lib/gpr/tmpfile.h",
"src/core/lib/gpr/useful.h",
"src/core/lib/gprpp/abstract.h",
"src/core/lib/gprpp/arena.h",
"src/core/lib/gprpp/atomic.h",
"src/core/lib/gprpp/debug_location.h",
"src/core/lib/gprpp/fork.h",
@ -1173,12 +1190,15 @@ config("grpc_config") {
"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",

@ -484,6 +484,7 @@ add_dependencies(buildtests_c h2_sockpair+trace_test)
add_dependencies(buildtests_c h2_sockpair_1byte_test)
add_dependencies(buildtests_c h2_spiffe_test)
add_dependencies(buildtests_c h2_ssl_test)
add_dependencies(buildtests_c h2_ssl_cred_reload_test)
add_dependencies(buildtests_c h2_ssl_proxy_test)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_c h2_uds_test)
@ -660,6 +661,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx json_run_localhost)
endif()
add_dependencies(buildtests_cxx memory_test)
add_dependencies(buildtests_cxx message_allocator_end2end_test)
add_dependencies(buildtests_cxx metrics_client)
add_dependencies(buildtests_cxx mock_test)
add_dependencies(buildtests_cxx nonblocking_test)
@ -837,7 +839,6 @@ endif (gRPC_BUILD_TESTS)
add_library(gpr
src/core/lib/gpr/alloc.cc
src/core/lib/gpr/arena.cc
src/core/lib/gpr/atm.cc
src/core/lib/gpr/cpu_iphone.cc
src/core/lib/gpr/cpu_linux.cc
@ -870,6 +871,7 @@ add_library(gpr
src/core/lib/gpr/tmpfile_posix.cc
src/core/lib/gpr/tmpfile_windows.cc
src/core/lib/gpr/wrap_memcpy.cc
src/core/lib/gprpp/arena.cc
src/core/lib/gprpp/fork.cc
src/core/lib/gprpp/thd_posix.cc
src/core/lib/gprpp/thd_windows.cc
@ -982,6 +984,7 @@ add_library(grpc
src/core/lib/channel/handshaker_registry.cc
src/core/lib/channel/status_util.cc
src/core/lib/compression/compression.cc
src/core/lib/compression/compression_args.cc
src/core/lib/compression/compression_internal.cc
src/core/lib/compression/message_compress.cc
src/core/lib/compression/stream_compression.cc
@ -994,12 +997,15 @@ add_library(grpc
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
@ -1020,6 +1026,7 @@ add_library(grpc
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_uv.cc
src/core/lib/iomgr/iomgr_windows.cc
src/core/lib/iomgr/is_epollexclusive_available.cc
@ -1048,6 +1055,7 @@ add_library(grpc
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
@ -1408,6 +1416,7 @@ add_library(grpc_cronet
src/core/lib/channel/handshaker_registry.cc
src/core/lib/channel/status_util.cc
src/core/lib/compression/compression.cc
src/core/lib/compression/compression_args.cc
src/core/lib/compression/compression_internal.cc
src/core/lib/compression/message_compress.cc
src/core/lib/compression/stream_compression.cc
@ -1420,12 +1429,15 @@ add_library(grpc_cronet
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
@ -1446,6 +1458,7 @@ add_library(grpc_cronet
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_uv.cc
src/core/lib/iomgr/iomgr_windows.cc
src/core/lib/iomgr/is_epollexclusive_available.cc
@ -1474,6 +1487,7 @@ add_library(grpc_cronet
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
@ -1819,6 +1833,7 @@ add_library(grpc_test_util
src/core/lib/channel/handshaker_registry.cc
src/core/lib/channel/status_util.cc
src/core/lib/compression/compression.cc
src/core/lib/compression/compression_args.cc
src/core/lib/compression/compression_internal.cc
src/core/lib/compression/message_compress.cc
src/core/lib/compression/stream_compression.cc
@ -1831,12 +1846,15 @@ add_library(grpc_test_util
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
@ -1857,6 +1875,7 @@ add_library(grpc_test_util
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_uv.cc
src/core/lib/iomgr/iomgr_windows.cc
src/core/lib/iomgr/is_epollexclusive_available.cc
@ -1885,6 +1904,7 @@ add_library(grpc_test_util
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
@ -2143,6 +2163,7 @@ add_library(grpc_test_util_unsecure
src/core/lib/channel/handshaker_registry.cc
src/core/lib/channel/status_util.cc
src/core/lib/compression/compression.cc
src/core/lib/compression/compression_args.cc
src/core/lib/compression/compression_internal.cc
src/core/lib/compression/message_compress.cc
src/core/lib/compression/stream_compression.cc
@ -2155,12 +2176,15 @@ add_library(grpc_test_util_unsecure
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
@ -2181,6 +2205,7 @@ add_library(grpc_test_util_unsecure
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_uv.cc
src/core/lib/iomgr/iomgr_windows.cc
src/core/lib/iomgr/is_epollexclusive_available.cc
@ -2209,6 +2234,7 @@ add_library(grpc_test_util_unsecure
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
@ -2443,6 +2469,7 @@ add_library(grpc_unsecure
src/core/lib/channel/handshaker_registry.cc
src/core/lib/channel/status_util.cc
src/core/lib/compression/compression.cc
src/core/lib/compression/compression_args.cc
src/core/lib/compression/compression_internal.cc
src/core/lib/compression/message_compress.cc
src/core/lib/compression/stream_compression.cc
@ -2455,12 +2482,15 @@ add_library(grpc_unsecure
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
@ -2481,6 +2511,7 @@ add_library(grpc_unsecure
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_uv.cc
src/core/lib/iomgr/iomgr_windows.cc
src/core/lib/iomgr/is_epollexclusive_available.cc
@ -2509,6 +2540,7 @@ add_library(grpc_unsecure
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
@ -2998,6 +3030,7 @@ foreach(_hdr
include/grpcpp/alarm.h
include/grpcpp/alarm_impl.h
include/grpcpp/channel.h
include/grpcpp/channel_impl.h
include/grpcpp/client_context.h
include/grpcpp/completion_queue.h
include/grpcpp/create_channel.h
@ -3032,6 +3065,7 @@ foreach(_hdr
include/grpcpp/security/auth_metadata_processor.h
include/grpcpp/security/auth_metadata_processor_impl.h
include/grpcpp/security/credentials.h
include/grpcpp/security/credentials_impl.h
include/grpcpp/security/server_credentials.h
include/grpcpp/security/server_credentials_impl.h
include/grpcpp/server.h
@ -3044,10 +3078,12 @@ foreach(_hdr
include/grpcpp/support/async_unary_call.h
include/grpcpp/support/byte_buffer.h
include/grpcpp/support/channel_arguments.h
include/grpcpp/support/channel_arguments_impl.h
include/grpcpp/support/client_callback.h
include/grpcpp/support/client_interceptor.h
include/grpcpp/support/config.h
include/grpcpp/support/interceptor.h
include/grpcpp/support/message_allocator.h
include/grpcpp/support/proto_buffer_reader.h
include/grpcpp/support/proto_buffer_writer.h
include/grpcpp/support/server_callback.h
@ -3164,6 +3200,7 @@ foreach(_hdr
include/grpcpp/impl/codegen/intercepted_channel.h
include/grpcpp/impl/codegen/interceptor.h
include/grpcpp/impl/codegen/interceptor_common.h
include/grpcpp/impl/codegen/message_allocator.h
include/grpcpp/impl/codegen/metadata_map.h
include/grpcpp/impl/codegen/method_handler_impl.h
include/grpcpp/impl/codegen/rpc_method.h
@ -3343,6 +3380,7 @@ add_library(grpc++_cronet
src/core/lib/channel/handshaker_registry.cc
src/core/lib/channel/status_util.cc
src/core/lib/compression/compression.cc
src/core/lib/compression/compression_args.cc
src/core/lib/compression/compression_internal.cc
src/core/lib/compression/message_compress.cc
src/core/lib/compression/stream_compression.cc
@ -3355,12 +3393,15 @@ add_library(grpc++_cronet
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
@ -3381,6 +3422,7 @@ add_library(grpc++_cronet
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_uv.cc
src/core/lib/iomgr/iomgr_windows.cc
src/core/lib/iomgr/is_epollexclusive_available.cc
@ -3409,6 +3451,7 @@ add_library(grpc++_cronet
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
@ -3602,6 +3645,7 @@ foreach(_hdr
include/grpcpp/alarm.h
include/grpcpp/alarm_impl.h
include/grpcpp/channel.h
include/grpcpp/channel_impl.h
include/grpcpp/client_context.h
include/grpcpp/completion_queue.h
include/grpcpp/create_channel.h
@ -3636,6 +3680,7 @@ foreach(_hdr
include/grpcpp/security/auth_metadata_processor.h
include/grpcpp/security/auth_metadata_processor_impl.h
include/grpcpp/security/credentials.h
include/grpcpp/security/credentials_impl.h
include/grpcpp/security/server_credentials.h
include/grpcpp/security/server_credentials_impl.h
include/grpcpp/server.h
@ -3648,10 +3693,12 @@ foreach(_hdr
include/grpcpp/support/async_unary_call.h
include/grpcpp/support/byte_buffer.h
include/grpcpp/support/channel_arguments.h
include/grpcpp/support/channel_arguments_impl.h
include/grpcpp/support/client_callback.h
include/grpcpp/support/client_interceptor.h
include/grpcpp/support/config.h
include/grpcpp/support/interceptor.h
include/grpcpp/support/message_allocator.h
include/grpcpp/support/proto_buffer_reader.h
include/grpcpp/support/proto_buffer_writer.h
include/grpcpp/support/server_callback.h
@ -3768,6 +3815,7 @@ foreach(_hdr
include/grpcpp/impl/codegen/intercepted_channel.h
include/grpcpp/impl/codegen/interceptor.h
include/grpcpp/impl/codegen/interceptor_common.h
include/grpcpp/impl/codegen/message_allocator.h
include/grpcpp/impl/codegen/metadata_map.h
include/grpcpp/impl/codegen/method_handler_impl.h
include/grpcpp/impl/codegen/rpc_method.h
@ -4202,6 +4250,7 @@ foreach(_hdr
include/grpcpp/impl/codegen/intercepted_channel.h
include/grpcpp/impl/codegen/interceptor.h
include/grpcpp/impl/codegen/interceptor_common.h
include/grpcpp/impl/codegen/message_allocator.h
include/grpcpp/impl/codegen/metadata_map.h
include/grpcpp/impl/codegen/method_handler_impl.h
include/grpcpp/impl/codegen/rpc_method.h
@ -4400,6 +4449,7 @@ foreach(_hdr
include/grpcpp/impl/codegen/intercepted_channel.h
include/grpcpp/impl/codegen/interceptor.h
include/grpcpp/impl/codegen/interceptor_common.h
include/grpcpp/impl/codegen/message_allocator.h
include/grpcpp/impl/codegen/metadata_map.h
include/grpcpp/impl/codegen/method_handler_impl.h
include/grpcpp/impl/codegen/rpc_method.h
@ -4584,6 +4634,7 @@ foreach(_hdr
include/grpcpp/alarm.h
include/grpcpp/alarm_impl.h
include/grpcpp/channel.h
include/grpcpp/channel_impl.h
include/grpcpp/client_context.h
include/grpcpp/completion_queue.h
include/grpcpp/create_channel.h
@ -4618,6 +4669,7 @@ foreach(_hdr
include/grpcpp/security/auth_metadata_processor.h
include/grpcpp/security/auth_metadata_processor_impl.h
include/grpcpp/security/credentials.h
include/grpcpp/security/credentials_impl.h
include/grpcpp/security/server_credentials.h
include/grpcpp/security/server_credentials_impl.h
include/grpcpp/server.h
@ -4630,10 +4682,12 @@ foreach(_hdr
include/grpcpp/support/async_unary_call.h
include/grpcpp/support/byte_buffer.h
include/grpcpp/support/channel_arguments.h
include/grpcpp/support/channel_arguments_impl.h
include/grpcpp/support/client_callback.h
include/grpcpp/support/client_interceptor.h
include/grpcpp/support/config.h
include/grpcpp/support/interceptor.h
include/grpcpp/support/message_allocator.h
include/grpcpp/support/proto_buffer_reader.h
include/grpcpp/support/proto_buffer_writer.h
include/grpcpp/support/server_callback.h
@ -4750,6 +4804,7 @@ foreach(_hdr
include/grpcpp/impl/codegen/intercepted_channel.h
include/grpcpp/impl/codegen/interceptor.h
include/grpcpp/impl/codegen/interceptor_common.h
include/grpcpp/impl/codegen/message_allocator.h
include/grpcpp/impl/codegen/metadata_map.h
include/grpcpp/impl/codegen/method_handler_impl.h
include/grpcpp/impl/codegen/rpc_method.h
@ -12679,6 +12734,7 @@ target_include_directories(client_crash_test_server
target_link_libraries(client_crash_test_server
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
grpc++_test_config
grpc++_test_util
grpc_test_util
grpc++
@ -13418,6 +13474,7 @@ target_include_directories(golden_file_test
target_link_libraries(golden_file_test
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
grpc++_test_config
grpc++
grpc
gpr
@ -14499,6 +14556,46 @@ target_link_libraries(memory_test
)
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(message_allocator_end2end_test
test/cpp/end2end/message_allocator_end2end_test.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
)
target_include_directories(message_allocator_end2end_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(message_allocator_end2end_test
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
grpc++_test_util
grpc_test_util
grpc++
grpc
gpr
${_gRPC_GFLAGS_LIBRARIES}
)
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
@ -15622,6 +15719,7 @@ target_include_directories(server_crash_test_client
target_link_libraries(server_crash_test_client
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
grpc++_test_config
grpc++_test_util
grpc_test_util
grpc++
@ -17683,6 +17781,41 @@ target_link_libraries(h2_ssl_test
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(h2_ssl_cred_reload_test
test/core/end2end/fixtures/h2_ssl_cred_reload.cc
)
target_include_directories(h2_ssl_cred_reload_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}
)
target_link_libraries(h2_ssl_cred_reload_test
${_gRPC_ALLTARGETS_LIBRARIES}
end2end_tests
grpc_test_util
grpc
gpr
)
# avoid dependency on libstdc++
if (_gRPC_CORE_NOSTDCXX_FLAGS)
set_target_properties(h2_ssl_cred_reload_test PROPERTIES LINKER_LANGUAGE C)
target_compile_options(h2_ssl_cred_reload_test PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}>)
endif()
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(h2_ssl_proxy_test
test/core/end2end/fixtures/h2_ssl_proxy.cc
)

@ -110,5 +110,16 @@ How to get your contributions merged smoothly and quickly.
- Exceptions to the rules can be made if there's a compelling reason for doing
so.
## Obtaining Commit Access
We grant Commit Access to contributors based on the following criteria:
* Sustained contribution to the gRPC project.
* Deep understanding of the areas contributed to, and good consideration of various reliability, usability and performance tradeoffs.
* Contributions demonstrate that obtaining Commit Access will significantly reduce friction for the contributors or others.
In addition to submitting PRs, a Contributor with Commit Access can:
* Review PRs and merge once other checks and criteria pass.
* Triage bugs and PRs and assign appropriate labels and reviewers.
### Obtaining Commit Access without Code Contributions
The [gRPC organization](https://github.com/grpc) is comprised of multiple repositories and commit access is usually restricted to one or more of these repositories. Some repositories such as the [grpc.github.io](https://github.com/grpc/grpc.github.io/) do not have code, but the same principle of sustained, high quality contributions, with a good understanding of the fundamentals, apply.

@ -478,11 +478,11 @@ LDFLAGS += $(EXTRA_LDFLAGS)
DEFINES += $(EXTRA_DEFINES)
LDLIBS += $(EXTRA_LDLIBS)
HOST_CPPFLAGS = $(CPPFLAGS)
HOST_CFLAGS = $(CFLAGS)
HOST_CXXFLAGS = $(CXXFLAGS)
HOST_LDFLAGS = $(LDFLAGS)
HOST_LDLIBS = $(LDLIBS)
HOST_CPPFLAGS += $(CPPFLAGS)
HOST_CFLAGS += $(CFLAGS)
HOST_CXXFLAGS += $(CXXFLAGS)
HOST_LDFLAGS += $(LDFLAGS)
HOST_LDLIBS += $(LDLIBS)
# These are automatically computed variables.
# There shouldn't be any need to change anything from now on.
@ -1233,6 +1233,7 @@ interop_server: $(BINDIR)/$(CONFIG)/interop_server
interop_test: $(BINDIR)/$(CONFIG)/interop_test
json_run_localhost: $(BINDIR)/$(CONFIG)/json_run_localhost
memory_test: $(BINDIR)/$(CONFIG)/memory_test
message_allocator_end2end_test: $(BINDIR)/$(CONFIG)/message_allocator_end2end_test
metrics_client: $(BINDIR)/$(CONFIG)/metrics_client
mock_test: $(BINDIR)/$(CONFIG)/mock_test
nonblocking_test: $(BINDIR)/$(CONFIG)/nonblocking_test
@ -1316,6 +1317,7 @@ h2_sockpair+trace_test: $(BINDIR)/$(CONFIG)/h2_sockpair+trace_test
h2_sockpair_1byte_test: $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_test
h2_spiffe_test: $(BINDIR)/$(CONFIG)/h2_spiffe_test
h2_ssl_test: $(BINDIR)/$(CONFIG)/h2_ssl_test
h2_ssl_cred_reload_test: $(BINDIR)/$(CONFIG)/h2_ssl_cred_reload_test
h2_ssl_proxy_test: $(BINDIR)/$(CONFIG)/h2_ssl_proxy_test
h2_uds_test: $(BINDIR)/$(CONFIG)/h2_uds_test
inproc_test: $(BINDIR)/$(CONFIG)/inproc_test
@ -1579,6 +1581,7 @@ buildtests_c: privatelibs_c \
$(BINDIR)/$(CONFIG)/h2_sockpair_1byte_test \
$(BINDIR)/$(CONFIG)/h2_spiffe_test \
$(BINDIR)/$(CONFIG)/h2_ssl_test \
$(BINDIR)/$(CONFIG)/h2_ssl_cred_reload_test \
$(BINDIR)/$(CONFIG)/h2_ssl_proxy_test \
$(BINDIR)/$(CONFIG)/h2_uds_test \
$(BINDIR)/$(CONFIG)/inproc_test \
@ -1699,6 +1702,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/interop_test \
$(BINDIR)/$(CONFIG)/json_run_localhost \
$(BINDIR)/$(CONFIG)/memory_test \
$(BINDIR)/$(CONFIG)/message_allocator_end2end_test \
$(BINDIR)/$(CONFIG)/metrics_client \
$(BINDIR)/$(CONFIG)/mock_test \
$(BINDIR)/$(CONFIG)/nonblocking_test \
@ -1842,6 +1846,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/interop_test \
$(BINDIR)/$(CONFIG)/json_run_localhost \
$(BINDIR)/$(CONFIG)/memory_test \
$(BINDIR)/$(CONFIG)/message_allocator_end2end_test \
$(BINDIR)/$(CONFIG)/metrics_client \
$(BINDIR)/$(CONFIG)/mock_test \
$(BINDIR)/$(CONFIG)/nonblocking_test \
@ -2341,6 +2346,8 @@ test_cxx: buildtests_cxx
$(Q) $(BINDIR)/$(CONFIG)/interop_test || ( echo test interop_test failed ; exit 1 )
$(E) "[RUN] Testing memory_test"
$(Q) $(BINDIR)/$(CONFIG)/memory_test || ( echo test memory_test failed ; exit 1 )
$(E) "[RUN] Testing message_allocator_end2end_test"
$(Q) $(BINDIR)/$(CONFIG)/message_allocator_end2end_test || ( echo test message_allocator_end2end_test failed ; exit 1 )
$(E) "[RUN] Testing mock_test"
$(Q) $(BINDIR)/$(CONFIG)/mock_test || ( echo test mock_test failed ; exit 1 )
$(E) "[RUN] Testing nonblocking_test"
@ -3313,7 +3320,6 @@ endif
LIBGPR_SRC = \
src/core/lib/gpr/alloc.cc \
src/core/lib/gpr/arena.cc \
src/core/lib/gpr/atm.cc \
src/core/lib/gpr/cpu_iphone.cc \
src/core/lib/gpr/cpu_linux.cc \
@ -3346,6 +3352,7 @@ LIBGPR_SRC = \
src/core/lib/gpr/tmpfile_posix.cc \
src/core/lib/gpr/tmpfile_windows.cc \
src/core/lib/gpr/wrap_memcpy.cc \
src/core/lib/gprpp/arena.cc \
src/core/lib/gprpp/fork.cc \
src/core/lib/gprpp/thd_posix.cc \
src/core/lib/gprpp/thd_windows.cc \
@ -3437,6 +3444,7 @@ LIBGRPC_SRC = \
src/core/lib/channel/handshaker_registry.cc \
src/core/lib/channel/status_util.cc \
src/core/lib/compression/compression.cc \
src/core/lib/compression/compression_args.cc \
src/core/lib/compression/compression_internal.cc \
src/core/lib/compression/message_compress.cc \
src/core/lib/compression/stream_compression.cc \
@ -3449,12 +3457,15 @@ LIBGRPC_SRC = \
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 \
@ -3475,6 +3486,7 @@ LIBGRPC_SRC = \
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_uv.cc \
src/core/lib/iomgr/iomgr_windows.cc \
src/core/lib/iomgr/is_epollexclusive_available.cc \
@ -3503,6 +3515,7 @@ LIBGRPC_SRC = \
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 \
@ -3857,6 +3870,7 @@ LIBGRPC_CRONET_SRC = \
src/core/lib/channel/handshaker_registry.cc \
src/core/lib/channel/status_util.cc \
src/core/lib/compression/compression.cc \
src/core/lib/compression/compression_args.cc \
src/core/lib/compression/compression_internal.cc \
src/core/lib/compression/message_compress.cc \
src/core/lib/compression/stream_compression.cc \
@ -3869,12 +3883,15 @@ LIBGRPC_CRONET_SRC = \
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 \
@ -3895,6 +3912,7 @@ LIBGRPC_CRONET_SRC = \
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_uv.cc \
src/core/lib/iomgr/iomgr_windows.cc \
src/core/lib/iomgr/is_epollexclusive_available.cc \
@ -3923,6 +3941,7 @@ LIBGRPC_CRONET_SRC = \
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 \
@ -4261,6 +4280,7 @@ LIBGRPC_TEST_UTIL_SRC = \
src/core/lib/channel/handshaker_registry.cc \
src/core/lib/channel/status_util.cc \
src/core/lib/compression/compression.cc \
src/core/lib/compression/compression_args.cc \
src/core/lib/compression/compression_internal.cc \
src/core/lib/compression/message_compress.cc \
src/core/lib/compression/stream_compression.cc \
@ -4273,12 +4293,15 @@ LIBGRPC_TEST_UTIL_SRC = \
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 \
@ -4299,6 +4322,7 @@ LIBGRPC_TEST_UTIL_SRC = \
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_uv.cc \
src/core/lib/iomgr/iomgr_windows.cc \
src/core/lib/iomgr/is_epollexclusive_available.cc \
@ -4327,6 +4351,7 @@ LIBGRPC_TEST_UTIL_SRC = \
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 \
@ -4572,6 +4597,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \
src/core/lib/channel/handshaker_registry.cc \
src/core/lib/channel/status_util.cc \
src/core/lib/compression/compression.cc \
src/core/lib/compression/compression_args.cc \
src/core/lib/compression/compression_internal.cc \
src/core/lib/compression/message_compress.cc \
src/core/lib/compression/stream_compression.cc \
@ -4584,12 +4610,15 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \
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 \
@ -4610,6 +4639,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \
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_uv.cc \
src/core/lib/iomgr/iomgr_windows.cc \
src/core/lib/iomgr/is_epollexclusive_available.cc \
@ -4638,6 +4668,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \
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 \
@ -4846,6 +4877,7 @@ LIBGRPC_UNSECURE_SRC = \
src/core/lib/channel/handshaker_registry.cc \
src/core/lib/channel/status_util.cc \
src/core/lib/compression/compression.cc \
src/core/lib/compression/compression_args.cc \
src/core/lib/compression/compression_internal.cc \
src/core/lib/compression/message_compress.cc \
src/core/lib/compression/stream_compression.cc \
@ -4858,12 +4890,15 @@ LIBGRPC_UNSECURE_SRC = \
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 \
@ -4884,6 +4919,7 @@ LIBGRPC_UNSECURE_SRC = \
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_uv.cc \
src/core/lib/iomgr/iomgr_windows.cc \
src/core/lib/iomgr/is_epollexclusive_available.cc \
@ -4912,6 +4948,7 @@ LIBGRPC_UNSECURE_SRC = \
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 \
@ -5333,6 +5370,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/alarm.h \
include/grpcpp/alarm_impl.h \
include/grpcpp/channel.h \
include/grpcpp/channel_impl.h \
include/grpcpp/client_context.h \
include/grpcpp/completion_queue.h \
include/grpcpp/create_channel.h \
@ -5367,6 +5405,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/security/auth_metadata_processor.h \
include/grpcpp/security/auth_metadata_processor_impl.h \
include/grpcpp/security/credentials.h \
include/grpcpp/security/credentials_impl.h \
include/grpcpp/security/server_credentials.h \
include/grpcpp/security/server_credentials_impl.h \
include/grpcpp/server.h \
@ -5379,10 +5418,12 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/support/async_unary_call.h \
include/grpcpp/support/byte_buffer.h \
include/grpcpp/support/channel_arguments.h \
include/grpcpp/support/channel_arguments_impl.h \
include/grpcpp/support/client_callback.h \
include/grpcpp/support/client_interceptor.h \
include/grpcpp/support/config.h \
include/grpcpp/support/interceptor.h \
include/grpcpp/support/message_allocator.h \
include/grpcpp/support/proto_buffer_reader.h \
include/grpcpp/support/proto_buffer_writer.h \
include/grpcpp/support/server_callback.h \
@ -5499,6 +5540,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/impl/codegen/intercepted_channel.h \
include/grpcpp/impl/codegen/interceptor.h \
include/grpcpp/impl/codegen/interceptor_common.h \
include/grpcpp/impl/codegen/message_allocator.h \
include/grpcpp/impl/codegen/metadata_map.h \
include/grpcpp/impl/codegen/method_handler_impl.h \
include/grpcpp/impl/codegen/rpc_method.h \
@ -5722,6 +5764,7 @@ LIBGRPC++_CRONET_SRC = \
src/core/lib/channel/handshaker_registry.cc \
src/core/lib/channel/status_util.cc \
src/core/lib/compression/compression.cc \
src/core/lib/compression/compression_args.cc \
src/core/lib/compression/compression_internal.cc \
src/core/lib/compression/message_compress.cc \
src/core/lib/compression/stream_compression.cc \
@ -5734,12 +5777,15 @@ LIBGRPC++_CRONET_SRC = \
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 \
@ -5760,6 +5806,7 @@ LIBGRPC++_CRONET_SRC = \
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_uv.cc \
src/core/lib/iomgr/iomgr_windows.cc \
src/core/lib/iomgr/is_epollexclusive_available.cc \
@ -5788,6 +5835,7 @@ LIBGRPC++_CRONET_SRC = \
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 \
@ -5945,6 +5993,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/alarm.h \
include/grpcpp/alarm_impl.h \
include/grpcpp/channel.h \
include/grpcpp/channel_impl.h \
include/grpcpp/client_context.h \
include/grpcpp/completion_queue.h \
include/grpcpp/create_channel.h \
@ -5979,6 +6028,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/security/auth_metadata_processor.h \
include/grpcpp/security/auth_metadata_processor_impl.h \
include/grpcpp/security/credentials.h \
include/grpcpp/security/credentials_impl.h \
include/grpcpp/security/server_credentials.h \
include/grpcpp/security/server_credentials_impl.h \
include/grpcpp/server.h \
@ -5991,10 +6041,12 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/support/async_unary_call.h \
include/grpcpp/support/byte_buffer.h \
include/grpcpp/support/channel_arguments.h \
include/grpcpp/support/channel_arguments_impl.h \
include/grpcpp/support/client_callback.h \
include/grpcpp/support/client_interceptor.h \
include/grpcpp/support/config.h \
include/grpcpp/support/interceptor.h \
include/grpcpp/support/message_allocator.h \
include/grpcpp/support/proto_buffer_reader.h \
include/grpcpp/support/proto_buffer_writer.h \
include/grpcpp/support/server_callback.h \
@ -6111,6 +6163,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/impl/codegen/intercepted_channel.h \
include/grpcpp/impl/codegen/interceptor.h \
include/grpcpp/impl/codegen/interceptor_common.h \
include/grpcpp/impl/codegen/message_allocator.h \
include/grpcpp/impl/codegen/metadata_map.h \
include/grpcpp/impl/codegen/method_handler_impl.h \
include/grpcpp/impl/codegen/rpc_method.h \
@ -6517,6 +6570,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/impl/codegen/intercepted_channel.h \
include/grpcpp/impl/codegen/interceptor.h \
include/grpcpp/impl/codegen/interceptor_common.h \
include/grpcpp/impl/codegen/message_allocator.h \
include/grpcpp/impl/codegen/metadata_map.h \
include/grpcpp/impl/codegen/method_handler_impl.h \
include/grpcpp/impl/codegen/rpc_method.h \
@ -6686,6 +6740,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/impl/codegen/intercepted_channel.h \
include/grpcpp/impl/codegen/interceptor.h \
include/grpcpp/impl/codegen/interceptor_common.h \
include/grpcpp/impl/codegen/message_allocator.h \
include/grpcpp/impl/codegen/metadata_map.h \
include/grpcpp/impl/codegen/method_handler_impl.h \
include/grpcpp/impl/codegen/rpc_method.h \
@ -6876,6 +6931,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/alarm.h \
include/grpcpp/alarm_impl.h \
include/grpcpp/channel.h \
include/grpcpp/channel_impl.h \
include/grpcpp/client_context.h \
include/grpcpp/completion_queue.h \
include/grpcpp/create_channel.h \
@ -6910,6 +6966,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/security/auth_metadata_processor.h \
include/grpcpp/security/auth_metadata_processor_impl.h \
include/grpcpp/security/credentials.h \
include/grpcpp/security/credentials_impl.h \
include/grpcpp/security/server_credentials.h \
include/grpcpp/security/server_credentials_impl.h \
include/grpcpp/server.h \
@ -6922,10 +6979,12 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/support/async_unary_call.h \
include/grpcpp/support/byte_buffer.h \
include/grpcpp/support/channel_arguments.h \
include/grpcpp/support/channel_arguments_impl.h \
include/grpcpp/support/client_callback.h \
include/grpcpp/support/client_interceptor.h \
include/grpcpp/support/config.h \
include/grpcpp/support/interceptor.h \
include/grpcpp/support/message_allocator.h \
include/grpcpp/support/proto_buffer_reader.h \
include/grpcpp/support/proto_buffer_writer.h \
include/grpcpp/support/server_callback.h \
@ -7042,6 +7101,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/impl/codegen/intercepted_channel.h \
include/grpcpp/impl/codegen/interceptor.h \
include/grpcpp/impl/codegen/interceptor_common.h \
include/grpcpp/impl/codegen/message_allocator.h \
include/grpcpp/impl/codegen/metadata_map.h \
include/grpcpp/impl/codegen/method_handler_impl.h \
include/grpcpp/impl/codegen/rpc_method.h \
@ -15621,16 +15681,16 @@ $(BINDIR)/$(CONFIG)/client_crash_test_server: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/client_crash_test_server: $(PROTOBUF_DEP) $(CLIENT_CRASH_TEST_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(BINDIR)/$(CONFIG)/client_crash_test_server: $(PROTOBUF_DEP) $(CLIENT_CRASH_TEST_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(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) $(CLIENT_CRASH_TEST_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(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)/client_crash_test_server
$(Q) $(LDXX) $(LDFLAGS) $(CLIENT_CRASH_TEST_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(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)/client_crash_test_server
endif
endif
$(OBJDIR)/$(CONFIG)/test/cpp/end2end/client_crash_test_server.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(OBJDIR)/$(CONFIG)/test/cpp/end2end/client_crash_test_server.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_client_crash_test_server: $(CLIENT_CRASH_TEST_SERVER_OBJS:.o=.dep)
@ -16368,18 +16428,18 @@ $(BINDIR)/$(CONFIG)/golden_file_test: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/golden_file_test: $(PROTOBUF_DEP) $(GOLDEN_FILE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(BINDIR)/$(CONFIG)/golden_file_test: $(PROTOBUF_DEP) $(GOLDEN_FILE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LDXX) $(LDFLAGS) $(GOLDEN_FILE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/golden_file_test
$(Q) $(LDXX) $(LDFLAGS) $(GOLDEN_FILE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/golden_file_test
endif
endif
$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/compiler_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/compiler_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(OBJDIR)/$(CONFIG)/test/cpp/codegen/golden_file_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(OBJDIR)/$(CONFIG)/test/cpp/codegen/golden_file_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_golden_file_test: $(GOLDEN_FILE_TEST_OBJS:.o=.dep)
@ -17404,6 +17464,49 @@ endif
endif
MESSAGE_ALLOCATOR_END2END_TEST_SRC = \
test/cpp/end2end/message_allocator_end2end_test.cc \
MESSAGE_ALLOCATOR_END2END_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(MESSAGE_ALLOCATOR_END2END_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/message_allocator_end2end_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)/message_allocator_end2end_test: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/message_allocator_end2end_test: $(PROTOBUF_DEP) $(MESSAGE_ALLOCATOR_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(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) $(MESSAGE_ALLOCATOR_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(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)/message_allocator_end2end_test
endif
endif
$(OBJDIR)/$(CONFIG)/test/cpp/end2end/message_allocator_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_message_allocator_end2end_test: $(MESSAGE_ALLOCATOR_END2END_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(MESSAGE_ALLOCATOR_END2END_TEST_OBJS:.o=.dep)
endif
endif
METRICS_CLIENT_SRC = \
$(GENDIR)/src/proto/grpc/testing/metrics.pb.cc $(GENDIR)/src/proto/grpc/testing/metrics.grpc.pb.cc \
test/cpp/interop/metrics_client.cc \
@ -18541,16 +18644,16 @@ $(BINDIR)/$(CONFIG)/server_crash_test_client: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/server_crash_test_client: $(PROTOBUF_DEP) $(SERVER_CRASH_TEST_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(BINDIR)/$(CONFIG)/server_crash_test_client: $(PROTOBUF_DEP) $(SERVER_CRASH_TEST_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(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) $(SERVER_CRASH_TEST_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(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)/server_crash_test_client
$(Q) $(LDXX) $(LDFLAGS) $(SERVER_CRASH_TEST_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(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)/server_crash_test_client
endif
endif
$(OBJDIR)/$(CONFIG)/test/cpp/end2end/server_crash_test_client.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(OBJDIR)/$(CONFIG)/test/cpp/end2end/server_crash_test_client.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_server_crash_test_client: $(SERVER_CRASH_TEST_CLIENT_OBJS:.o=.dep)
@ -20671,6 +20774,38 @@ endif
endif
H2_SSL_CRED_RELOAD_TEST_SRC = \
test/core/end2end/fixtures/h2_ssl_cred_reload.cc \
H2_SSL_CRED_RELOAD_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_SSL_CRED_RELOAD_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/h2_ssl_cred_reload_test: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/h2_ssl_cred_reload_test: $(H2_SSL_CRED_RELOAD_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LD) $(LDFLAGS) $(H2_SSL_CRED_RELOAD_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_ssl_cred_reload_test
endif
$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_ssl_cred_reload.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_h2_ssl_cred_reload_test: $(H2_SSL_CRED_RELOAD_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(H2_SSL_CRED_RELOAD_TEST_OBJS:.o=.dep)
endif
endif
H2_SSL_PROXY_TEST_SRC = \
test/core/end2end/fixtures/h2_ssl_proxy.cc \

@ -9,13 +9,12 @@ grpc_deps()
grpc_test_only_deps()
register_execution_platforms(
"//third_party/toolchains:rbe_ubuntu1604",
"//third_party/toolchains:rbe_ubuntu1604_large",
"//third_party/toolchains:local",
"//third_party/toolchains:local_large",
"//third_party/toolchains:rbe_windows",
)
register_toolchains(
"//third_party/toolchains:cc-toolchain-clang-x86_64-default",
"//third_party/toolchains/bazel_0.23.2_rbe_windows:cc-toolchain-x64_windows",
)
@ -52,3 +51,24 @@ http_archive(
load("//bazel:grpc_python_deps.bzl", "grpc_python_deps")
grpc_python_deps()
load("@bazel_toolchains//rules:rbe_repo.bzl", "rbe_autoconfig")
# Create toolchain configuration for remote execution.
rbe_autoconfig(
name = "rbe_default",
)
load("@bazel_toolchains//rules:environments.bzl", "clang_env")
load("@bazel_skylib//lib:dicts.bzl", "dicts")
# Create msan toolchain configuration for remote execution.
rbe_autoconfig(
name = "rbe_msan",
env = dicts.add(
clang_env(),
{
"BAZEL_LINKOPTS": "-lc++:-lc++abi:-lm",
},
),
)

@ -112,10 +112,7 @@ def grpc_cc_library(
visibility = visibility,
testonly = testonly,
linkopts = linkopts,
includes = [
"include",
"src/core/ext/upb-generated",
],
includes = ["include"] + if_not_windows(["src/core/ext/upb-generated"]),
alwayslink = alwayslink,
data = data,
tags = tags,

@ -110,6 +110,8 @@ def grpc_deps():
http_archive(
name = "boringssl",
# on the chromium-stable-with-bazel branch
# NOTE: This URL generates a tarball containing dynamic date
# information, so the sha256 is not consistent.
url = "https://boringssl.googlesource.com/boringssl/+archive/afc30d43eef92979b05776ec0963c9cede5fb80f.tar.gz",
)
@ -117,6 +119,7 @@ def grpc_deps():
http_archive(
name = "com_github_madler_zlib",
build_file = "@com_github_grpc_grpc//third_party:zlib.BUILD",
sha256 = "6d4d6640ca3121620995ee255945161821218752b551a1a180f4215f7d124d45",
strip_prefix = "zlib-cacf7f1d4e3d44d871b605da3b647f07d718623f",
url = "https://github.com/madler/zlib/archive/cacf7f1d4e3d44d871b605da3b647f07d718623f.tar.gz",
)
@ -124,6 +127,7 @@ def grpc_deps():
if "com_google_protobuf" not in native.existing_rules():
http_archive(
name = "com_google_protobuf",
sha256 = "cf9e2fb1d2cd30ec9d51ff1749045208bd641f290f64b85046485934b0e03783",
strip_prefix = "protobuf-582743bf40c5d3639a70f98f183914a2c0cd0680",
url = "https://github.com/google/protobuf/archive/582743bf40c5d3639a70f98f183914a2c0cd0680.tar.gz",
)
@ -132,6 +136,7 @@ def grpc_deps():
http_archive(
name = "com_github_nanopb_nanopb",
build_file = "@com_github_grpc_grpc//third_party:nanopb.BUILD",
sha256 = "8bbbb1e78d4ddb0a1919276924ab10d11b631df48b657d960e0c795a25515735",
strip_prefix = "nanopb-f8ac463766281625ad710900479130c7fcb4d63b",
url = "https://github.com/nanopb/nanopb/archive/f8ac463766281625ad710900479130c7fcb4d63b.tar.gz",
)
@ -140,6 +145,7 @@ def grpc_deps():
http_archive(
name = "com_github_google_googletest",
build_file = "@com_github_grpc_grpc//third_party:gtest.BUILD",
sha256 = "175a22300b3450e27e5f2e6f95cc9abca74617cbc21a1e0ed19bdfbd22ea0305",
strip_prefix = "googletest-ec44c6c1675c25b9827aacd08c02433cccde7780",
url = "https://github.com/google/googletest/archive/ec44c6c1675c25b9827aacd08c02433cccde7780.tar.gz",
)
@ -147,6 +153,7 @@ def grpc_deps():
if "com_github_gflags_gflags" not in native.existing_rules():
http_archive(
name = "com_github_gflags_gflags",
sha256 = "63ae70ea3e05780f7547d03503a53de3a7d2d83ad1caaa443a31cb20aea28654",
strip_prefix = "gflags-28f50e0fed19872e0fd50dd23ce2ee8cd759338e",
url = "https://github.com/gflags/gflags/archive/28f50e0fed19872e0fd50dd23ce2ee8cd759338e.tar.gz",
)
@ -154,6 +161,7 @@ def grpc_deps():
if "com_github_google_benchmark" not in native.existing_rules():
http_archive(
name = "com_github_google_benchmark",
sha256 = "c7682e9007ddfd94072647abab3e89ffd9084089460ae47d67060974467b58bf",
strip_prefix = "benchmark-e776aa0275e293707b6a0901e0e8d8a8a3679508",
url = "https://github.com/google/benchmark/archive/e776aa0275e293707b6a0901e0e8d8a8a3679508.tar.gz",
)
@ -162,6 +170,7 @@ def grpc_deps():
http_archive(
name = "com_github_cares_cares",
build_file = "@com_github_grpc_grpc//third_party:cares/cares.BUILD",
sha256 = "e8c2751ddc70fed9dc6f999acd92e232d5846f009ee1674f8aee81f19b2b915a",
strip_prefix = "c-ares-e982924acee7f7313b4baa4ee5ec000c5e373c30",
url = "https://github.com/c-ares/c-ares/archive/e982924acee7f7313b4baa4ee5ec000c5e373c30.tar.gz",
)
@ -169,19 +178,20 @@ def grpc_deps():
if "com_google_absl" not in native.existing_rules():
http_archive(
name = "com_google_absl",
sha256 = "5fe2a3a8f8378e81d4d3db6541f48030e04233ccd2d6c7e9d981ed577b314ae8",
strip_prefix = "abseil-cpp-308ce31528a7edfa39f5f6d36142278a0ae1bf45",
url = "https://github.com/abseil/abseil-cpp/archive/308ce31528a7edfa39f5f6d36142278a0ae1bf45.tar.gz",
)
if "com_github_bazelbuild_bazeltoolchains" not in native.existing_rules():
if "bazel_toolchains" not in native.existing_rules():
http_archive(
name = "com_github_bazelbuild_bazeltoolchains",
strip_prefix = "bazel-toolchains-37419a124bdb9af2fec5b99a973d359b6b899b61",
name = "bazel_toolchains",
sha256 = "67335b3563d9b67dc2550b8f27cc689b64fadac491e69ce78763d9ba894cc5cc",
strip_prefix = "bazel-toolchains-cddc376d428ada2927ad359211c3e356bd9c9fbb",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/37419a124bdb9af2fec5b99a973d359b6b899b61.tar.gz",
"https://github.com/bazelbuild/bazel-toolchains/archive/37419a124bdb9af2fec5b99a973d359b6b899b61.tar.gz",
"https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/cddc376d428ada2927ad359211c3e356bd9c9fbb.tar.gz",
"https://github.com/bazelbuild/bazel-toolchains/archive/cddc376d428ada2927ad359211c3e356bd9c9fbb.tar.gz",
],
sha256 = "ee854b5de299138c1f4a2edb5573d22b21d975acfc7aa938f36d30b49ef97498",
)
if "bazel_skylib" not in native.existing_rules():
@ -195,6 +205,7 @@ def grpc_deps():
if "io_opencensus_cpp" not in native.existing_rules():
http_archive(
name = "io_opencensus_cpp",
sha256 = "3436ca23dc1b3345186defd0f46d64244079ba3d3234a0c5d6ef5e8d5d06c8b5",
strip_prefix = "opencensus-cpp-9b1e354e89bf3d92aedc00af45b418ce870f3d77",
url = "https://github.com/census-instrumentation/opencensus-cpp/archive/9b1e354e89bf3d92aedc00af45b418ce870f3d77.tar.gz",
)
@ -202,6 +213,7 @@ def grpc_deps():
if "upb" not in native.existing_rules():
http_archive(
name = "upb",
sha256 = "0e749a8973968397f849a3b42e28ee9c85dc418c2477954c2a6a4495f323241d",
strip_prefix = "upb-ed9faae0993704b033c594b072d65e1bf19207fa",
url = "https://github.com/google/upb/archive/ed9faae0993704b033c594b072d65e1bf19207fa.tar.gz",
)
@ -223,6 +235,7 @@ def grpc_test_only_deps():
if "com_github_twisted_twisted" not in native.existing_rules():
http_archive(
name = "com_github_twisted_twisted",
sha256 = "ca17699d0d62eafc5c28daf2c7d0a18e62ae77b4137300b6c7d7868b39b06139",
strip_prefix = "twisted-twisted-17.5.0",
url = "https://github.com/twisted/twisted/archive/twisted-17.5.0.zip",
build_file = "@com_github_grpc_grpc//third_party:twisted.BUILD",
@ -231,6 +244,7 @@ def grpc_test_only_deps():
if "com_github_yaml_pyyaml" not in native.existing_rules():
http_archive(
name = "com_github_yaml_pyyaml",
sha256 = "6b4314b1b2051ddb9d4fcd1634e1fa9c1bb4012954273c9ff3ef689f6ec6c93e",
strip_prefix = "pyyaml-3.12",
url = "https://github.com/yaml/pyyaml/archive/3.12.zip",
build_file = "@com_github_grpc_grpc//third_party:yaml.BUILD",
@ -239,6 +253,7 @@ def grpc_test_only_deps():
if "com_github_twisted_incremental" not in native.existing_rules():
http_archive(
name = "com_github_twisted_incremental",
sha256 = "f0ca93359ee70243ff7fbf2d904a6291810bd88cb80ed4aca6fa77f318a41a36",
strip_prefix = "incremental-incremental-17.5.0",
url = "https://github.com/twisted/incremental/archive/incremental-17.5.0.zip",
build_file = "@com_github_grpc_grpc//third_party:incremental.BUILD",
@ -247,6 +262,7 @@ def grpc_test_only_deps():
if "com_github_zopefoundation_zope_interface" not in native.existing_rules():
http_archive(
name = "com_github_zopefoundation_zope_interface",
sha256 = "e9579fc6149294339897be3aa9ecd8a29217c0b013fe6f44fcdae00e3204198a",
strip_prefix = "zope.interface-4.4.3",
url = "https://github.com/zopefoundation/zope.interface/archive/4.4.3.zip",
build_file = "@com_github_grpc_grpc//third_party:zope_interface.BUILD",
@ -255,6 +271,7 @@ def grpc_test_only_deps():
if "com_github_twisted_constantly" not in native.existing_rules():
http_archive(
name = "com_github_twisted_constantly",
sha256 = "2702cd322161a579d2c0dbf94af4e57712eedc7bd7bbbdc554a230544f7d346c",
strip_prefix = "constantly-15.1.0",
url = "https://github.com/twisted/constantly/archive/15.1.0.zip",
build_file = "@com_github_grpc_grpc//third_party:constantly.BUILD",

@ -114,7 +114,6 @@ filegroups:
- name: gpr_base
src:
- src/core/lib/gpr/alloc.cc
- src/core/lib/gpr/arena.cc
- src/core/lib/gpr/atm.cc
- src/core/lib/gpr/cpu_iphone.cc
- src/core/lib/gpr/cpu_linux.cc
@ -147,6 +146,7 @@ filegroups:
- src/core/lib/gpr/tmpfile_posix.cc
- src/core/lib/gpr/tmpfile_windows.cc
- src/core/lib/gpr/wrap_memcpy.cc
- src/core/lib/gprpp/arena.cc
- src/core/lib/gprpp/fork.cc
- src/core/lib/gprpp/thd_posix.cc
- src/core/lib/gprpp/thd_windows.cc
@ -191,6 +191,7 @@ filegroups:
- src/core/lib/gpr/tmpfile.h
- src/core/lib/gpr/useful.h
- src/core/lib/gprpp/abstract.h
- src/core/lib/gprpp/arena.h
- src/core/lib/gprpp/atomic.h
- src/core/lib/gprpp/fork.h
- src/core/lib/gprpp/manual_constructor.h
@ -245,6 +246,7 @@ filegroups:
- src/core/lib/channel/handshaker_registry.cc
- src/core/lib/channel/status_util.cc
- src/core/lib/compression/compression.cc
- src/core/lib/compression/compression_args.cc
- src/core/lib/compression/compression_internal.cc
- src/core/lib/compression/message_compress.cc
- src/core/lib/compression/stream_compression.cc
@ -257,12 +259,15 @@ filegroups:
- 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
@ -283,6 +288,7 @@ filegroups:
- 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_uv.cc
- src/core/lib/iomgr/iomgr_windows.cc
- src/core/lib/iomgr/is_epollexclusive_available.cc
@ -311,6 +317,7 @@ filegroups:
- 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
@ -418,6 +425,7 @@ filegroups:
- src/core/lib/channel/handshaker_registry.h
- src/core/lib/channel/status_util.h
- src/core/lib/compression/algorithm_metadata.h
- src/core/lib/compression/compression_args.h
- src/core/lib/compression/compression_internal.h
- src/core/lib/compression/message_compress.h
- src/core/lib/compression/stream_compression.h
@ -437,12 +445,15 @@ filegroups:
- 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
@ -543,20 +554,6 @@ filegroups:
uses:
- grpc_codegen
- grpc_trace_headers
- name: grpc_cfstream
headers:
- src/core/lib/iomgr/cfstream_handle.h
- src/core/lib/iomgr/endpoint_cfstream.h
- src/core/lib/iomgr/error_cfstream.h
src:
- 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
uses:
- grpc_base_headers
- gpr_base_headers
- name: grpc_client_authority_filter
headers:
- src/core/ext/filters/http/client_authority_filter.h
@ -1257,6 +1254,7 @@ filegroups:
- include/grpcpp/impl/codegen/intercepted_channel.h
- include/grpcpp/impl/codegen/interceptor.h
- include/grpcpp/impl/codegen/interceptor_common.h
- include/grpcpp/impl/codegen/message_allocator.h
- include/grpcpp/impl/codegen/metadata_map.h
- include/grpcpp/impl/codegen/method_handler_impl.h
- include/grpcpp/impl/codegen/rpc_method.h
@ -1345,6 +1343,7 @@ filegroups:
- include/grpcpp/alarm.h
- include/grpcpp/alarm_impl.h
- include/grpcpp/channel.h
- include/grpcpp/channel_impl.h
- include/grpcpp/client_context.h
- include/grpcpp/completion_queue.h
- include/grpcpp/create_channel.h
@ -1379,6 +1378,7 @@ filegroups:
- include/grpcpp/security/auth_metadata_processor.h
- include/grpcpp/security/auth_metadata_processor_impl.h
- include/grpcpp/security/credentials.h
- include/grpcpp/security/credentials_impl.h
- include/grpcpp/security/server_credentials.h
- include/grpcpp/security/server_credentials_impl.h
- include/grpcpp/server.h
@ -1391,10 +1391,12 @@ filegroups:
- include/grpcpp/support/async_unary_call.h
- include/grpcpp/support/byte_buffer.h
- include/grpcpp/support/channel_arguments.h
- include/grpcpp/support/channel_arguments_impl.h
- include/grpcpp/support/client_callback.h
- include/grpcpp/support/client_interceptor.h
- include/grpcpp/support/config.h
- include/grpcpp/support/interceptor.h
- include/grpcpp/support/message_allocator.h
- include/grpcpp/support/proto_buffer_reader.h
- include/grpcpp/support/proto_buffer_writer.h
- include/grpcpp/support/server_callback.h
@ -4519,6 +4521,7 @@ targets:
src:
- test/cpp/end2end/client_crash_test_server.cc
deps:
- grpc++_test_config
- grpc++_test_util
- grpc_test_util
- grpc++
@ -4731,6 +4734,7 @@ targets:
- src/proto/grpc/testing/compiler_test.proto
- test/cpp/codegen/golden_file_test.cc
deps:
- grpc++_test_config
- grpc++
- grpc
- gpr
@ -5068,6 +5072,19 @@ targets:
uses:
- grpc++_test
uses_polling: false
- name: message_allocator_end2end_test
gtest: true
cpu_cost: 0.5
build: test
language: c++
src:
- test/cpp/end2end/message_allocator_end2end_test.cc
deps:
- grpc++_test_util
- grpc_test_util
- grpc++
- grpc
- gpr
- name: metrics_client
build: test
run: false
@ -5433,6 +5450,7 @@ targets:
src:
- test/cpp/end2end/server_crash_test_client.cc
deps:
- grpc++_test_config
- grpc++_test_util
- grpc_test_util
- grpc++

@ -45,7 +45,6 @@ if test "$PHP_GRPC" != "no"; then
third_party/address_sorting/address_sorting_posix.c \
third_party/address_sorting/address_sorting_windows.c \
src/core/lib/gpr/alloc.cc \
src/core/lib/gpr/arena.cc \
src/core/lib/gpr/atm.cc \
src/core/lib/gpr/cpu_iphone.cc \
src/core/lib/gpr/cpu_linux.cc \
@ -78,6 +77,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/gpr/tmpfile_posix.cc \
src/core/lib/gpr/tmpfile_windows.cc \
src/core/lib/gpr/wrap_memcpy.cc \
src/core/lib/gprpp/arena.cc \
src/core/lib/gprpp/fork.cc \
src/core/lib/gprpp/thd_posix.cc \
src/core/lib/gprpp/thd_windows.cc \
@ -97,6 +97,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/channel/handshaker_registry.cc \
src/core/lib/channel/status_util.cc \
src/core/lib/compression/compression.cc \
src/core/lib/compression/compression_args.cc \
src/core/lib/compression/compression_internal.cc \
src/core/lib/compression/message_compress.cc \
src/core/lib/compression/stream_compression.cc \
@ -109,12 +110,15 @@ if test "$PHP_GRPC" != "no"; then
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 \
@ -135,6 +139,7 @@ if test "$PHP_GRPC" != "no"; then
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_uv.cc \
src/core/lib/iomgr/iomgr_windows.cc \
src/core/lib/iomgr/is_epollexclusive_available.cc \
@ -163,6 +168,7 @@ if test "$PHP_GRPC" != "no"; then
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 \

@ -20,7 +20,6 @@ if (PHP_GRPC != "no") {
"third_party\\address_sorting\\address_sorting_posix.c " +
"third_party\\address_sorting\\address_sorting_windows.c " +
"src\\core\\lib\\gpr\\alloc.cc " +
"src\\core\\lib\\gpr\\arena.cc " +
"src\\core\\lib\\gpr\\atm.cc " +
"src\\core\\lib\\gpr\\cpu_iphone.cc " +
"src\\core\\lib\\gpr\\cpu_linux.cc " +
@ -53,6 +52,7 @@ if (PHP_GRPC != "no") {
"src\\core\\lib\\gpr\\tmpfile_posix.cc " +
"src\\core\\lib\\gpr\\tmpfile_windows.cc " +
"src\\core\\lib\\gpr\\wrap_memcpy.cc " +
"src\\core\\lib\\gprpp\\arena.cc " +
"src\\core\\lib\\gprpp\\fork.cc " +
"src\\core\\lib\\gprpp\\thd_posix.cc " +
"src\\core\\lib\\gprpp\\thd_windows.cc " +
@ -72,6 +72,7 @@ if (PHP_GRPC != "no") {
"src\\core\\lib\\channel\\handshaker_registry.cc " +
"src\\core\\lib\\channel\\status_util.cc " +
"src\\core\\lib\\compression\\compression.cc " +
"src\\core\\lib\\compression\\compression_args.cc " +
"src\\core\\lib\\compression\\compression_internal.cc " +
"src\\core\\lib\\compression\\message_compress.cc " +
"src\\core\\lib\\compression\\stream_compression.cc " +
@ -84,12 +85,15 @@ if (PHP_GRPC != "no") {
"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 " +
@ -110,6 +114,7 @@ if (PHP_GRPC != "no") {
"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_uv.cc " +
"src\\core\\lib\\iomgr\\iomgr_windows.cc " +
"src\\core\\lib\\iomgr\\is_epollexclusive_available.cc " +
@ -138,6 +143,7 @@ if (PHP_GRPC != "no") {
"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 " +

@ -135,7 +135,7 @@ Code at `src/core/lib/iomgr/ev_epollex_posix.cc`
- The same FD can be in multiple `Pollable`s (even if one of the `Pollable`s is of type PO_FD)
- There cannot be two `Pollable`s of type PO_FD for the same fd
- Why do we need `Pollable` of type PO_FD and PO_EMTPY ?
- Why do we need `Pollable` of type PO_FD and PO_EMPTY ?
- The main reason is the Sync client API
- We create one new completion queue per call. If we didn’t have PO_EMPTY and PO_FD type pollables, then every call on a given channel will effectively have to create a `Pollable` and hence an epollset. This is because every completion queue automatically creates a pollset and the channel fd will have to be put in that pollset. This clearly requires an epollset to put that fd. Creating an epollset per call (even if we delete the epollset once the call is completed) would mean a lot of sys calls to create/delete epoll fds. This is clearly not a good idea.
- With these new types of `Pollable`s, all pollsets (corresponding to the new per-call completion queue) will initially point to PO_EMPTY global epollset. Then once the channel fd is added to the pollset, the pollset will point to the `Pollable` of type PO_FD containing just that fd (i.e it will reuse the existing `Pollable`). This way, the epoll fd creation/deletion churn is avoided.

@ -50,6 +50,7 @@ some configuration as environment variables that can be set.
resolver and load balancing policy interaction
- compression - traces compression operations
- connectivity_state - traces connectivity state changes to channels
- cronet - traces state in the cronet transport engine
- executor - traces grpc's internal thread pool ('the executor')
- fd_trace - traces fd create(), shutdown() and close() calls for channel fds.
Also traces epoll fd create()/close() calls in epollex polling engine
@ -145,13 +146,3 @@ some configuration as environment variables that can be set.
* grpc_cfstream
set to 1 to turn on CFStream experiment. With this experiment gRPC uses CFStream API to make TCP
connections. The option is only available on iOS platform and when macro GRPC_CFSTREAM is defined.
* GRPC_ARENA_INIT_STRATEGY
Selects the initialization strategy for blocks allocated in the arena. Valid
values are:
- no_init (default): Do not initialize the arena block.
- zero_init: Initialize the arena blocks with 0.
- non_zero_init: Initialize the arena blocks with a non-zero value.
NOTE: This environment variable is experimental and will be removed. Thus, it
should not be relied upon.

@ -53,7 +53,7 @@ namespace HelloworldXamarin.iOS
public override void DidEnterBackground(UIApplication application)
{
// Use this method to release shared resources, save user data, invalidate timers and store the application state.
// If your application supports background exection this method is called instead of WillTerminate when the user quits.
// If your application supports background execution this method is called instead of WillTerminate when the user quits.
}
public override void WillEnterForeground(UIApplication application)

@ -46,8 +46,16 @@ static NSString * const kTestHostAddress = @"grpc-test.sandbox.googleapis.com";
}
@end
@interface MakeRPCViewController ()<GRPCProtoResponseHandler>
@end
@implementation MakeRPCViewController
- (dispatch_queue_t)dispatchQueue {
return dispatch_get_main_queue();
}
- (void)viewWillAppear:(BOOL)animated {
// Create a service client and a proto request as usual.
@ -57,28 +65,30 @@ static NSString * const kTestHostAddress = @"grpc-test.sandbox.googleapis.com";
request.fillUsername = YES;
request.fillOauthScope = YES;
// Create a not-yet-started RPC. We want to set the request headers on this object before starting
// it.
ProtoRPC *call =
[client RPCToUnaryCallWithRequest:request handler:^(AUTHResponse *response, NSError *error) {
if (response) {
// This test server responds with the email and scope of the access token it receives.
self.mainLabel.text = [NSString stringWithFormat:@"Used scope: %@ on behalf of user %@",
response.oauthScope, response.username];
} else {
self.mainLabel.text = error.UIDescription;
}
}];
// Set the access token to be used.
NSString *accessToken = GIDSignIn.sharedInstance.currentUser.authentication.accessToken;
call.requestHeaders[@"Authorization"] = [@"Bearer " stringByAppendingString:accessToken];
// Start the RPC.
// Set the request header with call options
GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
options.oauth2AccessToken = GIDSignIn.sharedInstance.currentUser.authentication.accessToken;
GRPCUnaryProtoCall *call = [client unaryCallWithMessage:request
responseHandler:self
callOptions:options];
[call start];
self.mainLabel.text = @"Waiting for RPC to complete...";
}
- (void)didReceiveProtoMessage:(GPBMessage *)message {
AUTHResponse *response = (AUTHResponse *)message;
if (response) {
// This test server responds with the email and scope of the access token it receives.
self.mainLabel.text = [NSString stringWithFormat:@"Used scope: %@ on behalf of user %@",
response.oauthScope, response.username];
}
}
- (void)didCloseWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error {
if (error) {
self.mainLabel.text = error.UIDescription;
}
}
@end

@ -25,20 +25,41 @@
static NSString * const kHostAddress = @"localhost:50051";
@interface HLWResponseHandler : NSObject<GRPCProtoResponseHandler>
@end
// A response handler object dispatching messages to main queue
@implementation HLWResponseHandler
- (dispatch_queue_t)dispatchQueue {
return dispatch_get_main_queue();
}
- (void)didReceiveProtoMessage:(GPBMessage *)message {
NSLog(@"%@", message);
}
@end
int main(int argc, char * argv[]) {
@autoreleasepool {
[GRPCCall useInsecureConnectionsForHost:kHostAddress];
[GRPCCall setUserAgentPrefix:@"HelloWorld/1.0" forHost:kHostAddress];
HLWGreeter *client = [[HLWGreeter alloc] initWithHost:kHostAddress];
HLWHelloRequest *request = [HLWHelloRequest message];
request.name = @"Objective-C";
[client sayHelloWithRequest:request handler:^(HLWHelloReply *response, NSError *error) {
NSLog(@"%@", response.message);
}];
GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
// this example does not use TLS (secure channel); use insecure channel instead
options.transportType = GRPCTransportTypeInsecure;
options.userAgentPrefix = @"HelloWorld/1.0";
GRPCUnaryProtoCall *call = [client sayHelloWithMessage:request
responseHandler:[[HLWResponseHandler alloc] init]
callOptions:options];
[call start];
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}

@ -24,19 +24,40 @@
static NSString * const kHostAddress = @"localhost:50051";
@interface HLWResponseHandler : NSObject<GRPCProtoResponseHandler>
@end
// A response handler object dispatching messages to main queue
@implementation HLWResponseHandler
- (dispatch_queue_t)dispatchQueue {
return dispatch_get_main_queue();
}
- (void)didReceiveProtoMessage:(GPBMessage *)message {
NSLog(@"%@", message);
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
[GRPCCall useInsecureConnectionsForHost:kHostAddress];
[GRPCCall setUserAgentPrefix:@"HelloWorld/1.0" forHost:kHostAddress];
HLWGreeter *client = [[HLWGreeter alloc] initWithHost:kHostAddress];
HLWHelloRequest *request = [HLWHelloRequest message];
request.name = @"Objective-C";
[client sayHelloWithRequest:request handler:^(HLWHelloReply *response, NSError *error) {
NSLog(@"%@", response.message);
}];
GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
// this example does not use TLS (secure channel); use insecure channel instead
options.transportType = GRPCTransportTypeInsecure;
options.userAgentPrefix = @"HelloWorld/1.0";
GRPCUnaryProtoCall *call = [client sayHelloWithMessage:request
responseHandler:[[HLWResponseHandler alloc] init]
callOptions:options];
[call start];
}
return NSApplicationMain(argc, argv);

@ -17,10 +17,7 @@
*/
#import <UIKit/UIKit.h>
#import <GRPCClient/GRPCCall+Tests.h>
#import <RouteGuide/RouteGuide.pbrpc.h>
#import <RxLibrary/GRXWriter+Immediate.h>
#import <RxLibrary/GRXWriter+Transformations.h>
static NSString * const kHostAddress = @"localhost:50051";
@ -65,7 +62,7 @@ static NSString * const kHostAddress = @"localhost:50051";
* Run the getFeature demo. Calls getFeature with a point known to have a feature and a point known
* not to have a feature.
*/
@interface GetFeatureViewController : UIViewController
@interface GetFeatureViewController : UIViewController<GRPCProtoResponseHandler>
@property (weak, nonatomic) IBOutlet UILabel *outputLabel;
@ -75,39 +72,56 @@ static NSString * const kHostAddress = @"localhost:50051";
RTGRouteGuide *_service;
}
- (void)execRequest {
void (^handler)(RTGFeature *response, NSError *error) = ^(RTGFeature *response, NSError *error) {
// TODO(makdharma): Remove boilerplate by consolidating into one log function.
if (response.name.length) {
NSString *str =[NSString stringWithFormat:@"%@\nFound feature called %@ at %@.", self.outputLabel.text, response.location, response.name];
self.outputLabel.text = str;
NSLog(@"Found feature called %@ at %@.", response.name, response.location);
} else if (response) {
NSString *str =[NSString stringWithFormat:@"%@\nFound no features at %@", self.outputLabel.text,response.location];
self.outputLabel.text = str;
NSLog(@"Found no features at %@", response.location);
} else {
NSString *str =[NSString stringWithFormat:@"%@\nRPC error: %@", self.outputLabel.text, error];
self.outputLabel.text = str;
NSLog(@"RPC error: %@", error);
}
};
- (dispatch_queue_t)dispatchQueue {
return dispatch_get_main_queue();
}
- (void)didReceiveProtoMessage:(GPBMessage *)message {
RTGFeature *response = (RTGFeature *)message;
// TODO(makdharma): Remove boilerplate by consolidating into one log function.
if (response.name.length != 0) {
NSString *str =[NSString stringWithFormat:@"%@\nFound feature called %@ at %@.", self.outputLabel.text, response.location, response.name];
self.outputLabel.text = str;
NSLog(@"Found feature called %@ at %@.", response.name, response.location);
} else if (response) {
NSString *str =[NSString stringWithFormat:@"%@\nFound no features at %@", self.outputLabel.text,response.location];
self.outputLabel.text = str;
NSLog(@"Found no features at %@", response.location);
}
}
- (void)didCloseWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error {
if (error) {
NSString *str =[NSString stringWithFormat:@"%@\nRPC error: %@", self.outputLabel.text, error];
self.outputLabel.text = str;
NSLog(@"RPC error: %@", error);
}
}
- (void)execRequest {
RTGPoint *point = [RTGPoint message];
point.latitude = 409146138;
point.longitude = -746188906;
[_service getFeatureWithRequest:point handler:handler];
[_service getFeatureWithRequest:[RTGPoint message] handler:handler];
GRPCUnaryProtoCall *call = [_service getFeatureWithMessage:point
responseHandler:self
callOptions:nil];
[call start];
call = [_service getFeatureWithMessage:[RTGPoint message]
responseHandler:self
callOptions:nil];
[call start];
}
- (void)viewDidLoad {
[super viewDidLoad];
// This only needs to be done once per host, before creating service objects for that host.
[GRPCCall useInsecureConnectionsForHost:kHostAddress];
GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
options.transportType = GRPCTransportTypeInsecure;
_service = [[RTGRouteGuide alloc] initWithHost:kHostAddress];
_service = [[RTGRouteGuide alloc] initWithHost:kHostAddress callOptions:options];
}
- (void)viewDidAppear:(BOOL)animated {
@ -126,7 +140,7 @@ static NSString * const kHostAddress = @"localhost:50051";
* Run the listFeatures demo. Calls listFeatures with a rectangle containing all of the features in
* the pre-generated database. Prints each response as it comes in.
*/
@interface ListFeaturesViewController : UIViewController
@interface ListFeaturesViewController : UIViewController<GRPCProtoResponseHandler>
@property (weak, nonatomic) IBOutlet UILabel *outputLabel;
@ -136,6 +150,10 @@ static NSString * const kHostAddress = @"localhost:50051";
RTGRouteGuide *_service;
}
- (dispatch_queue_t)dispatchQueue {
return dispatch_get_main_queue();
}
- (void)execRequest {
RTGRectangle *rectangle = [RTGRectangle message];
rectangle.lo.latitude = 405E6;
@ -144,24 +162,36 @@ static NSString * const kHostAddress = @"localhost:50051";
rectangle.hi.longitude = -745E6;
NSLog(@"Looking for features between %@ and %@", rectangle.lo, rectangle.hi);
[_service listFeaturesWithRequest:rectangle
eventHandler:^(BOOL done, RTGFeature *response, NSError *error) {
if (response) {
NSString *str =[NSString stringWithFormat:@"%@\nFound feature at %@ called %@.", self.outputLabel.text, response.location, response.name];
self.outputLabel.text = str;
NSLog(@"Found feature at %@ called %@.", response.location, response.name);
} else if (error) {
NSString *str =[NSString stringWithFormat:@"%@\nRPC error: %@", self.outputLabel.text, error];
self.outputLabel.text = str;
NSLog(@"RPC error: %@", error);
}
}];
GRPCUnaryProtoCall *call = [_service listFeaturesWithMessage:rectangle
responseHandler:self
callOptions:nil];
[call start];
}
- (void)didReceiveProtoMessage:(GPBMessage *)message {
RTGFeature *response = (RTGFeature *)message;
if (response) {
NSString *str =[NSString stringWithFormat:@"%@\nFound feature at %@ called %@.", self.outputLabel.text, response.location, response.name];
self.outputLabel.text = str;
NSLog(@"Found feature at %@ called %@.", response.location, response.name);
}
}
- (void)didCloseWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error {
if (error) {
NSString *str =[NSString stringWithFormat:@"%@\nRPC error: %@", self.outputLabel.text, error];
self.outputLabel.text = str;
NSLog(@"RPC error: %@", error);
}
}
- (void)viewDidLoad {
[super viewDidLoad];
_service = [[RTGRouteGuide alloc] initWithHost:kHostAddress];
GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
options.transportType = GRPCTransportTypeInsecure;
_service = [[RTGRouteGuide alloc] initWithHost:kHostAddress callOptions:options];
}
- (void)viewDidAppear:(BOOL)animated {
@ -173,7 +203,6 @@ static NSString * const kHostAddress = @"localhost:50051";
@end
#pragma mark Demo: Record Route
/**
@ -181,7 +210,7 @@ static NSString * const kHostAddress = @"localhost:50051";
* database with a variable delay in between. Prints the statistics when they are sent from the
* server.
*/
@interface RecordRouteViewController : UIViewController
@interface RecordRouteViewController : UIViewController<GRPCProtoResponseHandler>
@property (weak, nonatomic) IBOutlet UILabel *outputLabel;
@ -191,47 +220,71 @@ static NSString * const kHostAddress = @"localhost:50051";
RTGRouteGuide *_service;
}
- (dispatch_queue_t)dispatchQueue {
return dispatch_get_main_queue();
}
- (void)execRequest {
NSString *dataBasePath = [NSBundle.mainBundle pathForResource:@"route_guide_db"
ofType:@"json"];
NSData *dataBaseContent = [NSData dataWithContentsOfFile:dataBasePath];
NSArray *features = [NSJSONSerialization JSONObjectWithData:dataBaseContent options:0 error:NULL];
NSError *error;
NSArray *features = [NSJSONSerialization JSONObjectWithData:dataBaseContent options:0 error:&error];
if (error) {
NSLog(@"Error reading database.");
NSString *str = @"Error reading database.";
self.outputLabel.text = str;
return;
}
GRXWriter *locations = [[GRXWriter writerWithContainer:features] map:^id(id feature) {
GRPCStreamingProtoCall *call = [_service recordRouteWithResponseHandler:self
callOptions:nil];
[call start];
for (id feature in features) {
RTGPoint *location = [RTGPoint message];
location.longitude = [((NSNumber *) feature[@"location"][@"longitude"]) intValue];
location.latitude = [((NSNumber *) feature[@"location"][@"latitude"]) intValue];
NSString *str =[NSString stringWithFormat:@"%@\nVisiting point %@", self.outputLabel.text, location];
self.outputLabel.text = str;
NSLog(@"Visiting point %@", location);
return location;
}];
[_service recordRouteWithRequestsWriter:locations
handler:^(RTGRouteSummary *response, NSError *error) {
if (response) {
NSString *str =[NSString stringWithFormat:
@"%@\nFinished trip with %i points\nPassed %i features\n"
"Travelled %i meters\nIt took %i seconds",
self.outputLabel.text, response.pointCount, response.featureCount,
response.distance, response.elapsedTime];
self.outputLabel.text = str;
NSLog(@"Finished trip with %i points", response.pointCount);
NSLog(@"Passed %i features", response.featureCount);
NSLog(@"Travelled %i meters", response.distance);
NSLog(@"It took %i seconds", response.elapsedTime);
} else {
NSString *str =[NSString stringWithFormat:@"%@\nRPC error: %@", self.outputLabel.text, error];
self.outputLabel.text = str;
NSLog(@"RPC error: %@", error);
}
}];
[call writeMessage:location];
}
[call finish];
}
- (void)didReceiveProtoMessage:(GPBMessage *)message {
RTGRouteSummary *response = (RTGRouteSummary *)message;
if (response) {
NSString *str =[NSString stringWithFormat:
@"%@\nFinished trip with %i points\nPassed %i features\n"
"Travelled %i meters\nIt took %i seconds",
self.outputLabel.text, response.pointCount, response.featureCount,
response.distance, response.elapsedTime];
self.outputLabel.text = str;
NSLog(@"Finished trip with %i points", response.pointCount);
NSLog(@"Passed %i features", response.featureCount);
NSLog(@"Travelled %i meters", response.distance);
NSLog(@"It took %i seconds", response.elapsedTime);
}
}
- (void)didCloseWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error {
if (error) {
NSString *str =[NSString stringWithFormat:@"%@\nRPC error: %@", self.outputLabel.text, error];
self.outputLabel.text = str;
NSLog(@"RPC error: %@", error);
}
}
- (void)viewDidLoad {
[super viewDidLoad];
_service = [[RTGRouteGuide alloc] initWithHost:kHostAddress];
GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
options.transportType = GRPCTransportTypeInsecure;
_service = [[RTGRouteGuide alloc] initWithHost:kHostAddress callOptions:options];
}
- (void)viewDidAppear:(BOOL)animated {
@ -250,7 +303,7 @@ static NSString * const kHostAddress = @"localhost:50051";
* Run the routeChat demo. Send some chat messages, and print any chat messages that are sent from
* the server.
*/
@interface RouteChatViewController : UIViewController
@interface RouteChatViewController : UIViewController<GRPCProtoResponseHandler>
@property (weak, nonatomic) IBOutlet UILabel *outputLabel;
@ -260,38 +313,52 @@ static NSString * const kHostAddress = @"localhost:50051";
RTGRouteGuide *_service;
}
- (dispatch_queue_t)dispatchQueue {
return dispatch_get_main_queue();
}
- (void)execRequest {
NSArray *notes = @[[RTGRouteNote noteWithMessage:@"First message" latitude:0 longitude:0],
[RTGRouteNote noteWithMessage:@"Second message" latitude:0 longitude:1],
[RTGRouteNote noteWithMessage:@"Third message" latitude:1 longitude:0],
[RTGRouteNote noteWithMessage:@"Fourth message" latitude:0 longitude:0]];
GRXWriter *notesWriter = [[GRXWriter writerWithContainer:notes] map:^id(RTGRouteNote *note) {
NSLog(@"Sending message %@ at %@", note.message, note.location);
return note;
}];
[_service routeChatWithRequestsWriter:notesWriter
eventHandler:^(BOOL done, RTGRouteNote *note, NSError *error) {
if (note) {
NSString *str =[NSString stringWithFormat:@"%@\nGot message %@ at %@",
self.outputLabel.text, note.message, note.location];
self.outputLabel.text = str;
NSLog(@"Got message %@ at %@", note.message, note.location);
} else if (error) {
NSString *str =[NSString stringWithFormat:@"%@\nRPC error: %@", self.outputLabel.text, error];
self.outputLabel.text = str;
NSLog(@"RPC error: %@", error);
}
if (done) {
NSLog(@"Chat ended.");
}
}];
GRPCStreamingProtoCall *call = [_service routeChatWithResponseHandler:self
callOptions:nil];
[call start];
for (RTGRouteNote *note in notes) {
[call writeMessage:note];
}
[call finish];
}
- (void)didReceiveProtoMessage:(GPBMessage *)message {
RTGRouteNote *note = (RTGRouteNote *)message;
if (note) {
NSString *str =[NSString stringWithFormat:@"%@\nGot message %@ at %@",
self.outputLabel.text, note.message, note.location];
self.outputLabel.text = str;
NSLog(@"Got message %@ at %@", note.message, note.location);
}
}
- (void)didCloseWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error {
if (!error) {
NSLog(@"Chat ended.");
} else {
NSString *str =[NSString stringWithFormat:@"%@\nRPC error: %@", self.outputLabel.text, error];
self.outputLabel.text = str;
NSLog(@"RPC error: %@", error);
}
}
- (void)viewDidLoad {
[super viewDidLoad];
_service = [[RTGRouteGuide alloc] initWithHost:kHostAddress];
GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
options.transportType = GRPCTransportTypeInsecure;
_service = [[RTGRouteGuide alloc] initWithHost:kHostAddress callOptions:options];
}
- (void)viewDidAppear:(BOOL)animated {

@ -0,0 +1,32 @@
# 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 = "wait_for_ready_example",
testonly = 1,
srcs = ["wait_for_ready_example.py"],
deps = [
"//src/python/grpcio/grpc:grpcio",
"//examples:py_helloworld",
],
)
py_test(
name = "test/_wait_for_ready_example_test",
srcs = ["test/_wait_for_ready_example_test.py"],
deps = [":wait_for_ready_example",],
size = "small",
)

@ -0,0 +1,32 @@
# gRPC Python Example for Wait-for-ready
The default behavior of an RPC is to fail instantly if the server is not ready yet. This example demonstrates how to change that behavior.
### Definition of 'wait-for-ready' semantics
> If an RPC is issued but the channel is in TRANSIENT_FAILURE or SHUTDOWN states, the RPC is unable to be transmitted promptly. By default, gRPC implementations SHOULD fail such RPCs immediately. This is known as "fail fast," but the usage of the term is historical. RPCs SHOULD NOT fail as a result of the channel being in other states (CONNECTING, READY, or IDLE).
>
> gRPC implementations MAY provide a per-RPC option to not fail RPCs as a result of the channel being in TRANSIENT_FAILURE state. Instead, the implementation queues the RPCs until the channel is READY. This is known as "wait for ready." The RPCs SHOULD still fail before READY if there are unrelated reasons, such as the channel is SHUTDOWN or the RPC's deadline is reached.
>
> From https://github.com/grpc/grpc/blob/master/doc/wait-for-ready.md
### Use cases for 'wait-for-ready'
When developers spin up gRPC clients and servers at the same time, it is very like to fail first couple RPC calls due to unavailability of the server. If developers failed to prepare for this situation, the result can be catastrophic. But with 'wait-for-ready' semantics, developers can initialize the client and server in any order, especially useful in testing.
Also, developers may ensure the server is up before starting client. But in some cases like transient network failure may result in a temporary unavailability of the server. With 'wait-for-ready' semantics, those RPC calls will automatically wait until the server is ready to accept incoming requests.
### DEMO Snippets
```Python
# Per RPC level
stub = ...Stub(...)
stub.important_transaction_1(..., wait_for_ready=True)
stub.unimportant_transaction_2(...)
stub.important_transaction_3(..., wait_for_ready=True)
stub.unimportant_transaction_4(...)
# The unimportant transactions can be status report, or health check, etc.
```

@ -1,5 +1,4 @@
#!/bin/sh
# Copyright 2019 gRPC authors.
# 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.
@ -12,18 +11,21 @@
# 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 wait-for-ready example."""
set -e
import unittest
import logging
cd "$(dirname "$0")/../../.."
from examples.python.wait_for_ready import wait_for_ready_example
#
# Prevent the use of synchronization and threading constructs from std:: since
# the code should be using grpc_core::Mutex, grpc::internal::Mutex,
# grpc_core::Thread, etc.
#
egrep -Irn \
'std::(mutex|condition_variable|lock_guard|unique_lock|thread)' \
include/grpc include/grpcpp src/core src/cpp | diff - /dev/null
class WaitForReadyExampleTest(unittest.TestCase):
def test_wait_for_ready_example(self):
wait_for_ready_example.main()
# No unhandled exception raised, no deadlock, test passed!
if __name__ == '__main__':
logging.basicConfig()
unittest.main(verbosity=2)

@ -0,0 +1,114 @@
# 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.
"""The Python example of utilizing wait-for-ready flag."""
from __future__ import print_function
import logging
from concurrent import futures
from contextlib import contextmanager
import socket
import threading
import grpc
from examples.protos import helloworld_pb2
from examples.protos import helloworld_pb2_grpc
_LOGGER = logging.getLogger(__name__)
_LOGGER.setLevel(logging.INFO)
_ONE_DAY_IN_SECONDS = 60 * 60 * 24
@contextmanager
def get_free_loopback_tcp_port():
tcp_socket = socket.socket(socket.AF_INET6)
tcp_socket.bind(('', 0))
address_tuple = tcp_socket.getsockname()
yield "[::1]:%s" % (address_tuple[1])
tcp_socket.close()
class Greeter(helloworld_pb2_grpc.GreeterServicer):
def SayHello(self, request, unused_context):
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(Greeter(), server)
bound_port = server.add_insecure_port(server_address)
assert bound_port == int(server_address.split(':')[-1])
return server
def process(stub, wait_for_ready=None):
try:
response = stub.SayHello(
helloworld_pb2.HelloRequest(name='you'),
wait_for_ready=wait_for_ready)
message = response.message
except grpc.RpcError as rpc_error:
assert rpc_error.code() == grpc.StatusCode.UNAVAILABLE
assert not wait_for_ready
message = rpc_error
else:
assert wait_for_ready
_LOGGER.info("Wait-for-ready %s, client received: %s", "enabled"
if wait_for_ready else "disabled", message)
def main():
# Pick a random free port
with get_free_loopback_tcp_port() as server_address:
# Register connectivity event to notify main thread
transient_failure_event = threading.Event()
def wait_for_transient_failure(channel_connectivity):
if channel_connectivity == grpc.ChannelConnectivity.TRANSIENT_FAILURE:
transient_failure_event.set()
# Create gRPC channel
channel = grpc.insecure_channel(server_address)
channel.subscribe(wait_for_transient_failure)
stub = helloworld_pb2_grpc.GreeterStub(channel)
# Fire an RPC without wait_for_ready
thread_disabled_wait_for_ready = threading.Thread(
target=process, args=(stub, False))
thread_disabled_wait_for_ready.start()
# Fire an RPC with wait_for_ready
thread_enabled_wait_for_ready = threading.Thread(
target=process, args=(stub, True))
thread_enabled_wait_for_ready.start()
# Wait for the channel entering TRANSIENT FAILURE state.
transient_failure_event.wait()
server = create_server(server_address)
server.start()
# Expected to fail with StatusCode.UNAVAILABLE.
thread_disabled_wait_for_ready.join()
# Expected to success.
thread_enabled_wait_for_ready.join()
server.stop(None)
channel.close()
if __name__ == '__main__':
logging.basicConfig(level=logging.INFO)
main()

@ -28,7 +28,7 @@ def main
stub = EchoWithoutProtobuf::Stub.new('localhost:50051', :this_channel_is_insecure)
user = ARGV.size > 0 ? ARGV[0] : 'world'
message = stub.echo("hello #{user}")
p "Reponse: #{message}"
p "Response: #{message}"
end
main

@ -82,6 +82,7 @@ Pod::Spec.new do |s|
ss.source_files = 'include/grpcpp/alarm.h',
'include/grpcpp/alarm_impl.h',
'include/grpcpp/channel.h',
'include/grpcpp/channel_impl.h',
'include/grpcpp/client_context.h',
'include/grpcpp/completion_queue.h',
'include/grpcpp/create_channel.h',
@ -116,6 +117,7 @@ Pod::Spec.new do |s|
'include/grpcpp/security/auth_metadata_processor.h',
'include/grpcpp/security/auth_metadata_processor_impl.h',
'include/grpcpp/security/credentials.h',
'include/grpcpp/security/credentials_impl.h',
'include/grpcpp/security/server_credentials.h',
'include/grpcpp/security/server_credentials_impl.h',
'include/grpcpp/server.h',
@ -128,10 +130,12 @@ Pod::Spec.new do |s|
'include/grpcpp/support/async_unary_call.h',
'include/grpcpp/support/byte_buffer.h',
'include/grpcpp/support/channel_arguments.h',
'include/grpcpp/support/channel_arguments_impl.h',
'include/grpcpp/support/client_callback.h',
'include/grpcpp/support/client_interceptor.h',
'include/grpcpp/support/config.h',
'include/grpcpp/support/interceptor.h',
'include/grpcpp/support/message_allocator.h',
'include/grpcpp/support/proto_buffer_reader.h',
'include/grpcpp/support/proto_buffer_writer.h',
'include/grpcpp/support/server_callback.h',
@ -167,6 +171,7 @@ Pod::Spec.new do |s|
'include/grpcpp/impl/codegen/intercepted_channel.h',
'include/grpcpp/impl/codegen/interceptor.h',
'include/grpcpp/impl/codegen/interceptor_common.h',
'include/grpcpp/impl/codegen/message_allocator.h',
'include/grpcpp/impl/codegen/metadata_map.h',
'include/grpcpp/impl/codegen/method_handler_impl.h',
'include/grpcpp/impl/codegen/rpc_method.h',
@ -263,6 +268,7 @@ Pod::Spec.new do |s|
'src/core/lib/gpr/tmpfile.h',
'src/core/lib/gpr/useful.h',
'src/core/lib/gprpp/abstract.h',
'src/core/lib/gprpp/arena.h',
'src/core/lib/gprpp/atomic.h',
'src/core/lib/gprpp/fork.h',
'src/core/lib/gprpp/manual_constructor.h',
@ -412,6 +418,7 @@ Pod::Spec.new do |s|
'src/core/lib/channel/handshaker_registry.h',
'src/core/lib/channel/status_util.h',
'src/core/lib/compression/algorithm_metadata.h',
'src/core/lib/compression/compression_args.h',
'src/core/lib/compression/compression_internal.h',
'src/core/lib/compression/message_compress.h',
'src/core/lib/compression/stream_compression.h',
@ -431,12 +438,15 @@ Pod::Spec.new do |s|
'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',
@ -580,6 +590,7 @@ Pod::Spec.new do |s|
'src/core/lib/gpr/tmpfile.h',
'src/core/lib/gpr/useful.h',
'src/core/lib/gprpp/abstract.h',
'src/core/lib/gprpp/arena.h',
'src/core/lib/gprpp/atomic.h',
'src/core/lib/gprpp/fork.h',
'src/core/lib/gprpp/manual_constructor.h',
@ -604,6 +615,7 @@ Pod::Spec.new do |s|
'src/core/lib/channel/handshaker_registry.h',
'src/core/lib/channel/status_util.h',
'src/core/lib/compression/algorithm_metadata.h',
'src/core/lib/compression/compression_args.h',
'src/core/lib/compression/compression_internal.h',
'src/core/lib/compression/message_compress.h',
'src/core/lib/compression/stream_compression.h',
@ -623,12 +635,15 @@ Pod::Spec.new do |s|
'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',

@ -205,6 +205,7 @@ Pod::Spec.new do |s|
'src/core/lib/gpr/tmpfile.h',
'src/core/lib/gpr/useful.h',
'src/core/lib/gprpp/abstract.h',
'src/core/lib/gprpp/arena.h',
'src/core/lib/gprpp/atomic.h',
'src/core/lib/gprpp/fork.h',
'src/core/lib/gprpp/manual_constructor.h',
@ -215,7 +216,6 @@ Pod::Spec.new do |s|
'src/core/lib/gprpp/thd.h',
'src/core/lib/profiling/timers.h',
'src/core/lib/gpr/alloc.cc',
'src/core/lib/gpr/arena.cc',
'src/core/lib/gpr/atm.cc',
'src/core/lib/gpr/cpu_iphone.cc',
'src/core/lib/gpr/cpu_linux.cc',
@ -248,6 +248,7 @@ Pod::Spec.new do |s|
'src/core/lib/gpr/tmpfile_posix.cc',
'src/core/lib/gpr/tmpfile_windows.cc',
'src/core/lib/gpr/wrap_memcpy.cc',
'src/core/lib/gprpp/arena.cc',
'src/core/lib/gprpp/fork.cc',
'src/core/lib/gprpp/thd_posix.cc',
'src/core/lib/gprpp/thd_windows.cc',
@ -393,6 +394,7 @@ Pod::Spec.new do |s|
'src/core/lib/channel/handshaker_registry.h',
'src/core/lib/channel/status_util.h',
'src/core/lib/compression/algorithm_metadata.h',
'src/core/lib/compression/compression_args.h',
'src/core/lib/compression/compression_internal.h',
'src/core/lib/compression/message_compress.h',
'src/core/lib/compression/stream_compression.h',
@ -412,12 +414,15 @@ Pod::Spec.new do |s|
'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',
@ -547,6 +552,7 @@ Pod::Spec.new do |s|
'src/core/lib/channel/handshaker_registry.cc',
'src/core/lib/channel/status_util.cc',
'src/core/lib/compression/compression.cc',
'src/core/lib/compression/compression_args.cc',
'src/core/lib/compression/compression_internal.cc',
'src/core/lib/compression/message_compress.cc',
'src/core/lib/compression/stream_compression.cc',
@ -559,12 +565,15 @@ Pod::Spec.new do |s|
'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',
@ -585,6 +594,7 @@ Pod::Spec.new do |s|
'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_uv.cc',
'src/core/lib/iomgr/iomgr_windows.cc',
'src/core/lib/iomgr/is_epollexclusive_available.cc',
@ -613,6 +623,7 @@ Pod::Spec.new do |s|
'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',
@ -857,15 +868,7 @@ 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/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'
'src/core/plugin_registry/grpc_plugin_registry.cc'
ss.private_header_files = 'src/core/lib/gpr/alloc.h',
'src/core/lib/gpr/arena.h',
@ -884,6 +887,7 @@ Pod::Spec.new do |s|
'src/core/lib/gpr/tmpfile.h',
'src/core/lib/gpr/useful.h',
'src/core/lib/gprpp/abstract.h',
'src/core/lib/gprpp/arena.h',
'src/core/lib/gprpp/atomic.h',
'src/core/lib/gprpp/fork.h',
'src/core/lib/gprpp/manual_constructor.h',
@ -1033,6 +1037,7 @@ Pod::Spec.new do |s|
'src/core/lib/channel/handshaker_registry.h',
'src/core/lib/channel/status_util.h',
'src/core/lib/compression/algorithm_metadata.h',
'src/core/lib/compression/compression_args.h',
'src/core/lib/compression/compression_internal.h',
'src/core/lib/compression/message_compress.h',
'src/core/lib/compression/stream_compression.h',
@ -1052,12 +1057,15 @@ Pod::Spec.new do |s|
'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',
@ -1172,10 +1180,7 @@ 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/lib/iomgr/cfstream_handle.h',
'src/core/lib/iomgr/endpoint_cfstream.h',
'src/core/lib/iomgr/error_cfstream.h'
'src/core/ext/filters/workarounds/workaround_utils.h'
end
# CFStream is now default. Leaving this subspec only for compatibility purpose.

@ -99,6 +99,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/gpr/tmpfile.h )
s.files += %w( src/core/lib/gpr/useful.h )
s.files += %w( src/core/lib/gprpp/abstract.h )
s.files += %w( src/core/lib/gprpp/arena.h )
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 )
@ -109,7 +110,6 @@ Gem::Specification.new do |s|
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 )
s.files += %w( src/core/lib/gpr/arena.cc )
s.files += %w( src/core/lib/gpr/atm.cc )
s.files += %w( src/core/lib/gpr/cpu_iphone.cc )
s.files += %w( src/core/lib/gpr/cpu_linux.cc )
@ -142,6 +142,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/gpr/tmpfile_posix.cc )
s.files += %w( src/core/lib/gpr/tmpfile_windows.cc )
s.files += %w( src/core/lib/gpr/wrap_memcpy.cc )
s.files += %w( src/core/lib/gprpp/arena.cc )
s.files += %w( src/core/lib/gprpp/fork.cc )
s.files += %w( src/core/lib/gprpp/thd_posix.cc )
s.files += %w( src/core/lib/gprpp/thd_windows.cc )
@ -327,6 +328,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/channel/handshaker_registry.h )
s.files += %w( src/core/lib/channel/status_util.h )
s.files += %w( src/core/lib/compression/algorithm_metadata.h )
s.files += %w( src/core/lib/compression/compression_args.h )
s.files += %w( src/core/lib/compression/compression_internal.h )
s.files += %w( src/core/lib/compression/message_compress.h )
s.files += %w( src/core/lib/compression/stream_compression.h )
@ -346,12 +348,15 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/iomgr/block_annotate.h )
s.files += %w( src/core/lib/iomgr/buffer_list.h )
s.files += %w( src/core/lib/iomgr/call_combiner.h )
s.files += %w( src/core/lib/iomgr/cfstream_handle.h )
s.files += %w( src/core/lib/iomgr/closure.h )
s.files += %w( src/core/lib/iomgr/combiner.h )
s.files += %w( src/core/lib/iomgr/dynamic_annotations.h )
s.files += %w( src/core/lib/iomgr/endpoint.h )
s.files += %w( src/core/lib/iomgr/endpoint_cfstream.h )
s.files += %w( src/core/lib/iomgr/endpoint_pair.h )
s.files += %w( src/core/lib/iomgr/error.h )
s.files += %w( src/core/lib/iomgr/error_cfstream.h )
s.files += %w( src/core/lib/iomgr/error_internal.h )
s.files += %w( src/core/lib/iomgr/ev_epoll1_linux.h )
s.files += %w( src/core/lib/iomgr/ev_epollex_linux.h )
@ -481,6 +486,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/channel/handshaker_registry.cc )
s.files += %w( src/core/lib/channel/status_util.cc )
s.files += %w( src/core/lib/compression/compression.cc )
s.files += %w( src/core/lib/compression/compression_args.cc )
s.files += %w( src/core/lib/compression/compression_internal.cc )
s.files += %w( src/core/lib/compression/message_compress.cc )
s.files += %w( src/core/lib/compression/stream_compression.cc )
@ -493,12 +499,15 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/http/parser.cc )
s.files += %w( src/core/lib/iomgr/buffer_list.cc )
s.files += %w( src/core/lib/iomgr/call_combiner.cc )
s.files += %w( src/core/lib/iomgr/cfstream_handle.cc )
s.files += %w( src/core/lib/iomgr/combiner.cc )
s.files += %w( src/core/lib/iomgr/endpoint.cc )
s.files += %w( src/core/lib/iomgr/endpoint_cfstream.cc )
s.files += %w( src/core/lib/iomgr/endpoint_pair_posix.cc )
s.files += %w( src/core/lib/iomgr/endpoint_pair_uv.cc )
s.files += %w( src/core/lib/iomgr/endpoint_pair_windows.cc )
s.files += %w( src/core/lib/iomgr/error.cc )
s.files += %w( src/core/lib/iomgr/error_cfstream.cc )
s.files += %w( src/core/lib/iomgr/ev_epoll1_linux.cc )
s.files += %w( src/core/lib/iomgr/ev_epollex_linux.cc )
s.files += %w( src/core/lib/iomgr/ev_poll_posix.cc )
@ -519,6 +528,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/iomgr/iomgr_custom.cc )
s.files += %w( src/core/lib/iomgr/iomgr_internal.cc )
s.files += %w( src/core/lib/iomgr/iomgr_posix.cc )
s.files += %w( src/core/lib/iomgr/iomgr_posix_cfstream.cc )
s.files += %w( src/core/lib/iomgr/iomgr_uv.cc )
s.files += %w( src/core/lib/iomgr/iomgr_windows.cc )
s.files += %w( src/core/lib/iomgr/is_epollexclusive_available.cc )
@ -547,6 +557,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/iomgr/socket_utils_windows.cc )
s.files += %w( src/core/lib/iomgr/socket_windows.cc )
s.files += %w( src/core/lib/iomgr/tcp_client.cc )
s.files += %w( src/core/lib/iomgr/tcp_client_cfstream.cc )
s.files += %w( src/core/lib/iomgr/tcp_client_custom.cc )
s.files += %w( src/core/lib/iomgr/tcp_client_posix.cc )
s.files += %w( src/core/lib/iomgr/tcp_client_windows.cc )

@ -218,7 +218,6 @@
],
'sources': [
'src/core/lib/gpr/alloc.cc',
'src/core/lib/gpr/arena.cc',
'src/core/lib/gpr/atm.cc',
'src/core/lib/gpr/cpu_iphone.cc',
'src/core/lib/gpr/cpu_linux.cc',
@ -251,6 +250,7 @@
'src/core/lib/gpr/tmpfile_posix.cc',
'src/core/lib/gpr/tmpfile_windows.cc',
'src/core/lib/gpr/wrap_memcpy.cc',
'src/core/lib/gprpp/arena.cc',
'src/core/lib/gprpp/fork.cc',
'src/core/lib/gprpp/thd_posix.cc',
'src/core/lib/gprpp/thd_windows.cc',
@ -279,6 +279,7 @@
'src/core/lib/channel/handshaker_registry.cc',
'src/core/lib/channel/status_util.cc',
'src/core/lib/compression/compression.cc',
'src/core/lib/compression/compression_args.cc',
'src/core/lib/compression/compression_internal.cc',
'src/core/lib/compression/message_compress.cc',
'src/core/lib/compression/stream_compression.cc',
@ -291,12 +292,15 @@
'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',
@ -317,6 +321,7 @@
'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_uv.cc',
'src/core/lib/iomgr/iomgr_windows.cc',
'src/core/lib/iomgr/is_epollexclusive_available.cc',
@ -345,6 +350,7 @@
'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',
@ -646,6 +652,7 @@
'src/core/lib/channel/handshaker_registry.cc',
'src/core/lib/channel/status_util.cc',
'src/core/lib/compression/compression.cc',
'src/core/lib/compression/compression_args.cc',
'src/core/lib/compression/compression_internal.cc',
'src/core/lib/compression/message_compress.cc',
'src/core/lib/compression/stream_compression.cc',
@ -658,12 +665,15 @@
'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',
@ -684,6 +694,7 @@
'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_uv.cc',
'src/core/lib/iomgr/iomgr_windows.cc',
'src/core/lib/iomgr/is_epollexclusive_available.cc',
@ -712,6 +723,7 @@
'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',
@ -890,6 +902,7 @@
'src/core/lib/channel/handshaker_registry.cc',
'src/core/lib/channel/status_util.cc',
'src/core/lib/compression/compression.cc',
'src/core/lib/compression/compression_args.cc',
'src/core/lib/compression/compression_internal.cc',
'src/core/lib/compression/message_compress.cc',
'src/core/lib/compression/stream_compression.cc',
@ -902,12 +915,15 @@
'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',
@ -928,6 +944,7 @@
'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_uv.cc',
'src/core/lib/iomgr/iomgr_windows.cc',
'src/core/lib/iomgr/is_epollexclusive_available.cc',
@ -956,6 +973,7 @@
'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',
@ -1110,6 +1128,7 @@
'src/core/lib/channel/handshaker_registry.cc',
'src/core/lib/channel/status_util.cc',
'src/core/lib/compression/compression.cc',
'src/core/lib/compression/compression_args.cc',
'src/core/lib/compression/compression_internal.cc',
'src/core/lib/compression/message_compress.cc',
'src/core/lib/compression/stream_compression.cc',
@ -1122,12 +1141,15 @@
'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',
@ -1148,6 +1170,7 @@
'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_uv.cc',
'src/core/lib/iomgr/iomgr_windows.cc',
'src/core/lib/iomgr/is_epollexclusive_available.cc',
@ -1176,6 +1199,7 @@
'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',

@ -264,7 +264,7 @@ GRPCAPI grpc_call_credentials* grpc_google_refresh_token_credentials_create(
const char* json_refresh_token, void* reserved);
/** Creates an Oauth2 Access Token credentials with an access token that was
aquired by an out of band mechanism. */
acquired by an out of band mechanism. */
GRPCAPI grpc_call_credentials* grpc_access_token_credentials_create(
const char* access_token, void* reserved);

@ -315,11 +315,11 @@ typedef struct {
#define GRPC_ARG_GRPCLB_CALL_TIMEOUT_MS "grpc.grpclb_call_timeout_ms"
/* Timeout in milliseconds to wait for the serverlist from the grpclb load
balancer before using fallback backend addresses from the resolver.
If 0, fallback will never be used. Default value is 10000. */
If 0, enter fallback mode immediately. Default value is 10000. */
#define GRPC_ARG_GRPCLB_FALLBACK_TIMEOUT_MS "grpc.grpclb_fallback_timeout_ms"
/* Timeout in milliseconds to wait for the serverlist from the xDS load
balancer before using fallback backend addresses from the resolver.
If 0, fallback will never be used. Default value is 10000. */
If 0, enter fallback mode immediately. Default value is 10000. */
#define GRPC_ARG_XDS_FALLBACK_TIMEOUT_MS "grpc.xds_fallback_timeout_ms"
/** If non-zero, grpc server's cronet compression workaround will be enabled */
#define GRPC_ARG_WORKAROUND_CRONET_COMPRESSION \
@ -494,7 +494,8 @@ typedef struct grpc_event {
field is guaranteed to be 0 */
int success;
/** The tag passed to grpc_call_start_batch etc to start this operation.
Only GRPC_OP_COMPLETE has a tag. */
*Only* GRPC_OP_COMPLETE has a tag. For all other grpc_completion_type
values, tag is uninitialized. */
void* tag;
} grpc_event;

@ -115,6 +115,7 @@
#define GPR_POSIX_SUBPROCESS 1
#define GPR_POSIX_SYNC 1
#define GPR_POSIX_TIME 1
#define GPR_HAS_PTHREAD_H 1
#define GPR_GETPID_IN_UNISTD_H 1
#ifdef _LP64
#define GPR_ARCH_64 1
@ -144,6 +145,7 @@
#define GPR_POSIX_SUBPROCESS 1
#define GPR_POSIX_SYNC 1
#define GPR_POSIX_TIME 1
#define GPR_HAS_PTHREAD_H 1
#define GPR_GETPID_IN_UNISTD_H 1
#define GPR_SUPPORT_CHANNELS_FROM_FD 1
#elif defined(__linux__)
@ -170,6 +172,7 @@
#define GPR_POSIX_SUBPROCESS 1
#define GPR_POSIX_SYNC 1
#define GPR_POSIX_TIME 1
#define GPR_HAS_PTHREAD_H 1
#define GPR_GETPID_IN_UNISTD_H 1
#ifdef _LP64
#define GPR_ARCH_64 1
@ -235,6 +238,7 @@
#define GPR_POSIX_SUBPROCESS 1
#define GPR_POSIX_SYNC 1
#define GPR_POSIX_TIME 1
#define GPR_HAS_PTHREAD_H 1
#define GPR_GETPID_IN_UNISTD_H 1
#ifndef GRPC_CFSTREAM
#define GPR_SUPPORT_CHANNELS_FROM_FD 1
@ -260,6 +264,7 @@
#define GPR_POSIX_SUBPROCESS 1
#define GPR_POSIX_SYNC 1
#define GPR_POSIX_TIME 1
#define GPR_HAS_PTHREAD_H 1
#define GPR_GETPID_IN_UNISTD_H 1
#define GPR_SUPPORT_CHANNELS_FROM_FD 1
#ifdef _LP64
@ -283,6 +288,7 @@
#define GPR_POSIX_SUBPROCESS 1
#define GPR_POSIX_SYNC 1
#define GPR_POSIX_TIME 1
#define GPR_HAS_PTHREAD_H 1
#define GPR_GETPID_IN_UNISTD_H 1
#define GPR_SUPPORT_CHANNELS_FROM_FD 1
#ifdef _LP64
@ -303,6 +309,7 @@
#define GPR_POSIX_SUBPROCESS 1
#define GPR_POSIX_SYNC 1
#define GPR_POSIX_TIME 1
#define GPR_HAS_PTHREAD_H 1
#define GPR_GETPID_IN_UNISTD_H 1
#ifdef _LP64
#define GPR_ARCH_64 1
@ -325,6 +332,7 @@
#define GPR_POSIX_SUBPROCESS 1
#define GPR_POSIX_SYNC 1
#define GPR_POSIX_TIME 1
#define GPR_HAS_PTHREAD_H 1
#define GPR_GETPID_IN_UNISTD_H 1
#ifdef _LP64
#define GPR_ARCH_64 1
@ -353,6 +361,7 @@
#define GPR_POSIX_SUBPROCESS 1
#define GPR_POSIX_SYNC 1
#define GPR_POSIX_TIME 1
#define GPR_HAS_PTHREAD_H 1
#define GPR_GETPID_IN_UNISTD_H 1
#ifdef _LP64
#define GPR_ARCH_64 1
@ -378,6 +387,7 @@
#define GPR_POSIX_SYNC 1
#define GPR_POSIX_STRING 1
#define GPR_POSIX_TIME 1
#define GPR_HAS_PTHREAD_H 1
#define GPR_GETPID_IN_UNISTD_H 1
#else
#error "Could not auto-detect platform"

@ -40,27 +40,6 @@ typedef struct grpc_slice grpc_slice;
reference ownership semantics (who should call unref?) and mutability
constraints (is the callee allowed to modify the slice?) */
typedef struct grpc_slice_refcount_vtable {
void (*ref)(void*);
void (*unref)(void*);
int (*eq)(grpc_slice a, grpc_slice b);
uint32_t (*hash)(grpc_slice slice);
} grpc_slice_refcount_vtable;
/** Reference count container for grpc_slice. Contains function pointers to
increment and decrement reference counts. Implementations should cleanup
when the reference count drops to zero.
Typically client code should not touch this, and use grpc_slice_malloc,
grpc_slice_new, or grpc_slice_new_with_len instead. */
typedef struct grpc_slice_refcount {
const grpc_slice_refcount_vtable* vtable;
/** If a subset of this slice is taken, use this pointer for the refcount.
Typically points back to the refcount itself, however iterning
implementations can use this to avoid a verification step on each hash
or equality check */
struct grpc_slice_refcount* sub_refcount;
} grpc_slice_refcount;
/* Inlined half of grpc_slice is allowed to expand the size of the overall type
by this many bytes */
#define GRPC_SLICE_INLINE_EXTRA_SIZE sizeof(void*)
@ -68,6 +47,7 @@ typedef struct grpc_slice_refcount {
#define GRPC_SLICE_INLINED_SIZE \
(sizeof(size_t) + sizeof(uint8_t*) - 1 + GRPC_SLICE_INLINE_EXTRA_SIZE)
struct grpc_slice_refcount;
/** A grpc_slice s, if initialized, represents the byte range
s.bytes[0..s.length-1].

@ -147,7 +147,7 @@ GPRAPI int grpc_slice_buf_start_eq(grpc_slice a, const void* b, size_t blen);
GPRAPI int grpc_slice_rchr(grpc_slice s, char c);
GPRAPI int grpc_slice_chr(grpc_slice s, char c);
/** return the index of the first occurance of \a needle in \a haystack, or -1
/** return the index of the first occurrence of \a needle in \a haystack, or -1
if it's not found */
GPRAPI int grpc_slice_slice(grpc_slice haystack, grpc_slice needle);

@ -19,22 +19,12 @@
#ifndef GRPCPP_CHANNEL_H
#define GRPCPP_CHANNEL_H
#include <memory>
#include <mutex>
#include <grpc/grpc.h>
#include <grpcpp/impl/call.h>
#include <grpcpp/impl/codegen/channel_interface.h>
#include <grpcpp/impl/codegen/client_interceptor.h>
#include <grpcpp/impl/codegen/completion_queue.h>
#include <grpcpp/impl/codegen/config.h>
#include <grpcpp/impl/codegen/grpc_library.h>
#include <grpcpp/impl/codegen/sync.h>
struct grpc_channel;
#include <grpcpp/channel_impl.h>
namespace grpc {
typedef ::grpc_impl::Channel Channel;
namespace experimental {
/// Resets the channel's connection backoff.
/// TODO(roth): Once we see whether this proves useful, either create a gRFC
@ -42,75 +32,6 @@ namespace experimental {
void ChannelResetConnectionBackoff(Channel* channel);
} // namespace experimental
/// Channels represent a connection to an endpoint. Created by \a CreateChannel.
class Channel final : public ChannelInterface,
public internal::CallHook,
public std::enable_shared_from_this<Channel>,
private GrpcLibraryCodegen {
public:
~Channel();
/// Get the current channel state. If the channel is in IDLE and
/// \a try_to_connect is set to true, try to connect.
grpc_connectivity_state GetState(bool try_to_connect) override;
/// Returns the LB policy name, or the empty string if not yet available.
grpc::string GetLoadBalancingPolicyName() const;
/// Returns the service config in JSON form, or the empty string if
/// not available.
grpc::string GetServiceConfigJSON() const;
private:
template <class InputMessage, class OutputMessage>
friend class internal::BlockingUnaryCallImpl;
friend void experimental::ChannelResetConnectionBackoff(Channel* channel);
friend std::shared_ptr<Channel> CreateChannelInternal(
const grpc::string& host, grpc_channel* c_channel,
std::vector<
std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
interceptor_creators);
friend class internal::InterceptedChannel;
Channel(const grpc::string& host, grpc_channel* c_channel,
std::vector<
std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
interceptor_creators);
internal::Call CreateCall(const internal::RpcMethod& method,
ClientContext* context,
CompletionQueue* cq) override;
void PerformOpsOnCall(internal::CallOpSetInterface* ops,
internal::Call* call) override;
void* RegisterMethod(const char* method) override;
void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed,
gpr_timespec deadline, CompletionQueue* cq,
void* tag) override;
bool WaitForStateChangeImpl(grpc_connectivity_state last_observed,
gpr_timespec deadline) override;
CompletionQueue* CallbackCQ() override;
internal::Call CreateCallInternal(const internal::RpcMethod& method,
ClientContext* context, CompletionQueue* cq,
size_t interceptor_pos) override;
const grpc::string host_;
grpc_channel* const c_channel_; // owned
// mu_ protects callback_cq_ (the per-channel callbackable completion queue)
grpc::internal::Mutex mu_;
// callback_cq_ references the callbackable completion queue associated
// with this channel (if any). It is set on the first call to CallbackCQ().
// It is _not owned_ by the channel; ownership belongs with its internal
// shutdown callback tag (invoked when the CQ is fully shutdown).
CompletionQueue* callback_cq_ = nullptr;
std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
interceptor_creators_;
};
} // namespace grpc
#endif // GRPCPP_CHANNEL_H

@ -0,0 +1,125 @@
/*
*
* 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_CHANNEL_IMPL_H
#define GRPCPP_CHANNEL_IMPL_H
#include <memory>
#include <mutex>
#include <grpc/grpc.h>
#include <grpcpp/impl/call.h>
#include <grpcpp/impl/codegen/channel_interface.h>
#include <grpcpp/impl/codegen/completion_queue.h>
#include <grpcpp/impl/codegen/client_interceptor.h>
#include <grpcpp/impl/codegen/config.h>
#include <grpcpp/impl/codegen/grpc_library.h>
#include <grpcpp/impl/codegen/sync.h>
struct grpc_channel;
namespace grpc {
std::shared_ptr<::grpc_impl::Channel> CreateChannelInternal(
const grpc::string& host, grpc_channel* c_channel,
std::vector<
std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
interceptor_creators);
} // namespace grpc
namespace grpc_impl {
namespace experimental {
/// Resets the channel's connection backoff.
/// TODO(roth): Once we see whether this proves useful, either create a gRFC
/// and change this to be a method of the Channel class, or remove it.
void ChannelResetConnectionBackoff(Channel* channel);
} // namespace experimental
/// Channels represent a connection to an endpoint. Created by \a CreateChannel.
class Channel final : public ::grpc::ChannelInterface,
public ::grpc::internal::CallHook,
public std::enable_shared_from_this<Channel>,
private ::grpc::GrpcLibraryCodegen {
public:
~Channel();
/// Get the current channel state. If the channel is in IDLE and
/// \a try_to_connect is set to true, try to connect.
grpc_connectivity_state GetState(bool try_to_connect) override;
/// Returns the LB policy name, or the empty string if not yet available.
grpc::string GetLoadBalancingPolicyName() const;
/// Returns the service config in JSON form, or the empty string if
/// not available.
grpc::string GetServiceConfigJSON() const;
private:
template <class InputMessage, class OutputMessage>
friend class ::grpc::internal::BlockingUnaryCallImpl;
friend void experimental::ChannelResetConnectionBackoff(Channel* channel);
friend std::shared_ptr<Channel> grpc::CreateChannelInternal(
const grpc::string& host, grpc_channel* c_channel,
std::vector<std::unique_ptr<
::grpc::experimental::ClientInterceptorFactoryInterface>>
interceptor_creators);
friend class ::grpc::internal::InterceptedChannel;
Channel(const grpc::string& host, grpc_channel* c_channel,
std::vector<std::unique_ptr<
::grpc::experimental::ClientInterceptorFactoryInterface>>
interceptor_creators);
::grpc::internal::Call CreateCall(const ::grpc::internal::RpcMethod& method,
::grpc::ClientContext* context,
::grpc::CompletionQueue* cq) override;
void PerformOpsOnCall(::grpc::internal::CallOpSetInterface* ops,
::grpc::internal::Call* call) override;
void* RegisterMethod(const char* method) override;
void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed,
gpr_timespec deadline,
::grpc::CompletionQueue* cq, void* tag) override;
bool WaitForStateChangeImpl(grpc_connectivity_state last_observed,
gpr_timespec deadline) override;
::grpc::CompletionQueue* CallbackCQ() override;
::grpc::internal::Call CreateCallInternal(
const ::grpc::internal::RpcMethod& method, ::grpc::ClientContext* context,
::grpc::CompletionQueue* cq, size_t interceptor_pos) override;
const grpc::string host_;
grpc_channel* const c_channel_; // owned
// mu_ protects callback_cq_ (the per-channel callbackable completion queue)
grpc::internal::Mutex mu_;
// callback_cq_ references the callbackable completion queue associated
// with this channel (if any). It is set on the first call to CallbackCQ().
// It is _not owned_ by the channel; ownership belongs with its internal
// shutdown callback tag (invoked when the CQ is fully shutdown).
::grpc::CompletionQueue* callback_cq_ = nullptr;
std::vector<
std::unique_ptr<::grpc::experimental::ClientInterceptorFactoryInterface>>
interceptor_creators_;
};
} // namespace grpc_impl
#endif // GRPCPP_CHANNEL_IMPL_H

@ -20,25 +20,27 @@
#define GRPCPP_CREATE_CHANNEL_H
#include <grpcpp/create_channel_impl.h>
#include <grpcpp/support/channel_arguments.h>
namespace grpc {
static inline std::shared_ptr<::grpc::Channel> CreateChannel(
const grpc::string& target,
const std::shared_ptr<ChannelCredentials>& creds) {
return ::grpc_impl::CreateChannel(target, creds);
return ::grpc_impl::CreateChannelImpl(target, creds);
}
static inline std::shared_ptr<::grpc::Channel> CreateCustomChannel(
const grpc::string& target,
const std::shared_ptr<ChannelCredentials>& creds,
const ChannelArguments& args) {
return ::grpc_impl::CreateCustomChannel(target, creds, args);
return ::grpc_impl::CreateCustomChannelImpl(target, creds, args);
}
namespace experimental {
static inline std::shared_ptr<::grpc::Channel> CreateCustomChannelWithInterceptors(
static inline std::shared_ptr<::grpc::Channel>
CreateCustomChannelWithInterceptors(
const grpc::string& target,
const std::shared_ptr<ChannelCredentials>& creds,
const ChannelArguments& args,

@ -34,9 +34,9 @@ namespace grpc_impl {
/// \param creds Credentials to use for the created channel. If it does not
/// hold an object or is invalid, a lame channel (one on which all operations
/// fail) is returned.
std::shared_ptr<::grpc::Channel> CreateChannel(
std::shared_ptr<::grpc::Channel> CreateChannelImpl(
const grpc::string& target,
const std::shared_ptr<grpc::ChannelCredentials>& creds);
const std::shared_ptr<::grpc::ChannelCredentials>& creds);
/// Create a new \em custom \a Channel pointing to \a target.
///
@ -48,10 +48,10 @@ std::shared_ptr<::grpc::Channel> CreateChannel(
/// hold an object or is invalid, a lame channel (one on which all operations
/// fail) is returned.
/// \param args Options for channel creation.
std::shared_ptr<::grpc::Channel> CreateCustomChannel(
std::shared_ptr<::grpc::Channel> CreateCustomChannelImpl(
const grpc::string& target,
const std::shared_ptr<grpc::ChannelCredentials>& creds,
const grpc::ChannelArguments& args);
const std::shared_ptr<::grpc::ChannelCredentials>& creds,
const ::grpc::ChannelArguments& args);
namespace experimental {
/// Create a new \em custom \a Channel pointing to \a target with \a
@ -68,7 +68,7 @@ namespace experimental {
std::shared_ptr<::grpc::Channel> CreateCustomChannelWithInterceptors(
const grpc::string& target,
const std::shared_ptr<grpc::ChannelCredentials>& creds,
const grpc::ChannelArguments& args,
const ::grpc::ChannelArguments& args,
std::vector<
std::unique_ptr<grpc::experimental::ClientInterceptorFactoryInterface>>
interceptor_creators);

@ -82,6 +82,12 @@ class GenericStub final {
const grpc::ByteBuffer* request, grpc::ByteBuffer* response,
std::function<void(grpc::Status)> on_completion);
/// 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(grpc::ClientContext* context, const grpc::string& method,
const grpc::ByteBuffer* request, grpc::ByteBuffer* response,
grpc::experimental::ClientUnaryReactor* reactor);
/// 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.

@ -659,7 +659,7 @@ class ServerAsyncReaderInterface
/// some failure occurred when trying to do so.
///
/// gRPC doesn't take ownership or a reference to \a msg or \a status, so it
/// is safe to to deallocate once Finish returns.
/// is safe to deallocate once Finish returns.
///
/// \param[in] tag Tag identifying this request.
/// \param[in] status To be sent to the client as the result of this call.
@ -733,7 +733,7 @@ class ServerAsyncReader final : public ServerAsyncReaderInterface<W, R> {
/// Note: \a msg is not sent if \a status has a non-OK code.
///
/// gRPC doesn't take ownership or a reference to \a msg and \a status, so it
/// is safe to to deallocate once Finish returns.
/// is safe to deallocate once Finish returns.
void Finish(const W& msg, const Status& status, void* tag) override {
finish_ops_.set_output_tag(tag);
if (!ctx_->sent_initial_metadata_) {
@ -828,7 +828,7 @@ class ServerAsyncWriterInterface
/// in a single step.
///
/// gRPC doesn't take ownership or a reference to \a msg and \a status, so it
/// is safe to to deallocate once WriteAndFinish returns.
/// is safe to deallocate once WriteAndFinish returns.
///
/// \param[in] msg The message to be written.
/// \param[in] options The WriteOptions to be used to write this message.
@ -895,7 +895,7 @@ class ServerAsyncWriter final : public ServerAsyncWriterInterface<W> {
/// Note: \a status must have an OK code.
///
/// gRPC doesn't take ownership or a reference to \a msg and \a status, so it
/// is safe to to deallocate once WriteAndFinish returns.
/// is safe to deallocate once WriteAndFinish returns.
void WriteAndFinish(const W& msg, WriteOptions options, const Status& status,
void* tag) override {
write_ops_.set_output_tag(tag);
@ -991,7 +991,7 @@ class ServerAsyncReaderWriterInterface
/// single step.
///
/// gRPC doesn't take ownership or a reference to \a msg and \a status, so it
/// is safe to to deallocate once WriteAndFinish returns.
/// is safe to deallocate once WriteAndFinish returns.
///
/// \param[in] msg The message to be written.
/// \param[in] options The WriteOptions to be used to write this message.
@ -1066,7 +1066,7 @@ class ServerAsyncReaderWriter final
/// Note: \a status must have an OK code.
//
/// gRPC doesn't take ownership or a reference to \a msg and \a status, so it
/// is safe to to deallocate once WriteAndFinish returns.
/// is safe to deallocate once WriteAndFinish returns.
void WriteAndFinish(const W& msg, WriteOptions options, const Status& status,
void* tag) override {
write_ops_.set_output_tag(tag);

@ -61,6 +61,7 @@ template <class R>
class ClientCallbackReaderFactory;
template <class W>
class ClientCallbackWriterFactory;
class ClientCallbackUnaryFactory;
class InterceptedChannel;
} // namespace internal
@ -120,6 +121,7 @@ class ChannelInterface {
friend class ::grpc::internal::ClientCallbackReaderFactory;
template <class W>
friend class ::grpc::internal::ClientCallbackWriterFactory;
friend class ::grpc::internal::ClientCallbackUnaryFactory;
template <class InputMessage, class OutputMessage>
friend class ::grpc::internal::BlockingUnaryCallImpl;
template <class InputMessage, class OutputMessage>

@ -29,9 +29,12 @@
#include <grpcpp/impl/codegen/core_codegen_interface.h>
#include <grpcpp/impl/codegen/status.h>
namespace grpc_impl {
class Channel;
}
namespace grpc {
class Channel;
class ClientContext;
namespace internal {
@ -99,6 +102,7 @@ template <class Response>
class ClientReadReactor;
template <class Request>
class ClientWriteReactor;
class ClientUnaryReactor;
// NOTE: The streaming objects are not actually implemented in the public API.
// These interfaces are provided for mocking only. Typical applications
@ -156,6 +160,15 @@ class ClientCallbackWriter {
}
};
class ClientCallbackUnary {
public:
virtual ~ClientCallbackUnary() {}
virtual void StartCall() = 0;
protected:
void BindReactor(ClientUnaryReactor* reactor);
};
// 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
@ -345,6 +358,36 @@ class ClientWriteReactor {
ClientCallbackWriter<Request>* writer_;
};
/// \a ClientUnaryReactor is a reactor-style interface for a unary RPC.
/// This is _not_ a common way of invoking a unary RPC. In practice, this
/// option should be used only if the unary RPC wants to receive initial
/// metadata without waiting for the response to complete. Most deployments of
/// RPC systems do not use this option, but it is needed for generality.
/// All public methods behave as in ClientBidiReactor.
/// StartCall is included for consistency with the other reactor flavors: even
/// though there are no StartRead or StartWrite operations to queue before the
/// call (that is part of the unary call itself) and there is no reactor object
/// being created as a result of this call, we keep a consistent 2-phase
/// initiation API among all the reactor flavors.
class ClientUnaryReactor {
public:
virtual ~ClientUnaryReactor() {}
void StartCall() { call_->StartCall(); }
virtual void OnDone(const Status& s) {}
virtual void OnReadInitialMetadataDone(bool ok) {}
private:
friend class ClientCallbackUnary;
void BindCall(ClientCallbackUnary* call) { call_ = call; }
ClientCallbackUnary* call_;
};
// Define function out-of-line from class to avoid forward declaration issue
inline void ClientCallbackUnary::BindReactor(ClientUnaryReactor* reactor) {
reactor->BindCall(this);
}
} // namespace experimental
namespace internal {
@ -511,9 +554,9 @@ class ClientCallbackReaderWriterImpl
this->BindReactor(reactor);
}
ClientContext* context_;
ClientContext* const context_;
Call call_;
::grpc::experimental::ClientBidiReactor<Request, Response>* reactor_;
::grpc::experimental::ClientBidiReactor<Request, Response>* const reactor_;
CallOpSet<CallOpSendInitialMetadata, CallOpRecvInitialMetadata> start_ops_;
CallbackWithSuccessTag start_tag_;
@ -650,9 +693,9 @@ class ClientCallbackReaderImpl
start_ops_.ClientSendClose();
}
ClientContext* context_;
ClientContext* const context_;
Call call_;
::grpc::experimental::ClientReadReactor<Response>* reactor_;
::grpc::experimental::ClientReadReactor<Response>* const reactor_;
CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage, CallOpClientSendClose,
CallOpRecvInitialMetadata>
@ -823,9 +866,9 @@ class ClientCallbackWriterImpl
finish_ops_.AllowNoMessage();
}
ClientContext* context_;
ClientContext* const context_;
Call call_;
::grpc::experimental::ClientWriteReactor<Request>* reactor_;
::grpc::experimental::ClientWriteReactor<Request>* const reactor_;
CallOpSet<CallOpSendInitialMetadata, CallOpRecvInitialMetadata> start_ops_;
CallbackWithSuccessTag start_tag_;
@ -866,6 +909,109 @@ class ClientCallbackWriterFactory {
}
};
class ClientCallbackUnaryImpl final
: public ::grpc::experimental::ClientCallbackUnary {
public:
// always allocated against a call arena, no memory free required
static void operator delete(void* ptr, std::size_t size) {
assert(size == sizeof(ClientCallbackUnaryImpl));
}
// This operator should never be called as the memory should be freed as part
// of the arena destruction. It only exists to provide a matching operator
// delete to the operator new so that some compilers will not complain (see
// https://github.com/grpc/grpc/issues/11301) Note at the time of adding this
// there are no tests catching the compiler warning.
static void operator delete(void*, void*) { assert(0); }
void StartCall() override {
// This call initiates two batches, each with a callback
// 1. Send initial metadata + write + writes done + recv initial metadata
// 2. Read message, recv trailing metadata
started_ = true;
start_tag_.Set(call_.call(),
[this](bool ok) {
reactor_->OnReadInitialMetadataDone(ok);
MaybeFinish();
},
&start_ops_);
start_ops_.SendInitialMetadata(&context_->send_initial_metadata_,
context_->initial_metadata_flags());
start_ops_.RecvInitialMetadata(context_);
start_ops_.set_core_cq_tag(&start_tag_);
call_.PerformOps(&start_ops_);
finish_tag_.Set(call_.call(), [this](bool ok) { MaybeFinish(); },
&finish_ops_);
finish_ops_.ClientRecvStatus(context_, &finish_status_);
finish_ops_.set_core_cq_tag(&finish_tag_);
call_.PerformOps(&finish_ops_);
}
void MaybeFinish() {
if (--callbacks_outstanding_ == 0) {
Status s = std::move(finish_status_);
auto* reactor = reactor_;
auto* call = call_.call();
this->~ClientCallbackUnaryImpl();
g_core_codegen_interface->grpc_call_unref(call);
reactor->OnDone(s);
}
}
private:
friend class ClientCallbackUnaryFactory;
template <class Request, class Response>
ClientCallbackUnaryImpl(Call call, ClientContext* context, Request* request,
Response* response,
::grpc::experimental::ClientUnaryReactor* reactor)
: context_(context), call_(call), reactor_(reactor) {
this->BindReactor(reactor);
// TODO(vjpai): don't assert
GPR_CODEGEN_ASSERT(start_ops_.SendMessagePtr(request).ok());
start_ops_.ClientSendClose();
finish_ops_.RecvMessage(response);
finish_ops_.AllowNoMessage();
}
ClientContext* const context_;
Call call_;
::grpc::experimental::ClientUnaryReactor* const reactor_;
CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage, CallOpClientSendClose,
CallOpRecvInitialMetadata>
start_ops_;
CallbackWithSuccessTag start_tag_;
CallOpSet<CallOpGenericRecvMessage, CallOpClientRecvStatus> finish_ops_;
CallbackWithSuccessTag finish_tag_;
Status finish_status_;
// This call will have 2 callbacks: start and finish
std::atomic_int callbacks_outstanding_{2};
bool started_{false};
};
class ClientCallbackUnaryFactory {
public:
template <class Request, class Response>
static void Create(ChannelInterface* channel,
const ::grpc::internal::RpcMethod& method,
ClientContext* context, const Request* request,
Response* response,
::grpc::experimental::ClientUnaryReactor* reactor) {
Call call = channel->CreateCall(method, context, channel->CallbackCQ());
g_core_codegen_interface->grpc_call_ref(call.call());
new (g_core_codegen_interface->grpc_call_arena_alloc(
call.call(), sizeof(ClientCallbackUnaryImpl)))
ClientCallbackUnaryImpl(call, context, request, response, reactor);
}
};
} // namespace internal
} // namespace grpc

@ -57,11 +57,15 @@
struct census_context;
struct grpc_call;
namespace grpc {
namespace grpc_impl {
class CallCredentials;
class Channel;
class CompletionQueue;
} // namespace grpc_impl
namespace grpc {
class ChannelInterface;
class CallCredentials;
class ClientContext;
namespace internal {
@ -78,6 +82,7 @@ template <class Response>
class ClientCallbackReaderImpl;
template <class Request>
class ClientCallbackWriterImpl;
class ClientCallbackUnaryImpl;
} // namespace internal
template <class R>
@ -304,7 +309,8 @@ class ClientContext {
/// call.
///
/// \see https://grpc.io/docs/guides/auth.html
void set_credentials(const std::shared_ptr<CallCredentials>& creds) {
void set_credentials(
const std::shared_ptr<grpc_impl::CallCredentials>& creds) {
creds_ = creds;
}
@ -391,7 +397,7 @@ class ClientContext {
friend class ::grpc::testing::InteropClientContextInspector;
friend class ::grpc::internal::CallOpClientRecvStatus;
friend class ::grpc::internal::CallOpRecvInitialMetadata;
friend class Channel;
friend class ::grpc_impl::Channel;
template <class R>
friend class ::grpc::ClientReader;
template <class W>
@ -416,6 +422,7 @@ class ClientContext {
friend class ::grpc::internal::ClientCallbackReaderImpl;
template <class Request>
friend class ::grpc::internal::ClientCallbackWriterImpl;
friend class ::grpc::internal::ClientCallbackUnaryImpl;
// Used by friend class CallOpClientRecvStatus
void set_debug_error_string(const grpc::string& debug_error_string) {
@ -423,7 +430,8 @@ class ClientContext {
}
grpc_call* call() const { return call_; }
void set_call(grpc_call* call, const std::shared_ptr<Channel>& channel);
void set_call(grpc_call* call,
const std::shared_ptr<::grpc_impl::Channel>& channel);
experimental::ClientRpcInfo* set_client_rpc_info(
const char* method, internal::RpcMethod::RpcType type,
@ -456,13 +464,13 @@ class ClientContext {
bool wait_for_ready_explicitly_set_;
bool idempotent_;
bool cacheable_;
std::shared_ptr<Channel> channel_;
std::shared_ptr<::grpc_impl::Channel> channel_;
grpc::internal::Mutex mu_;
grpc_call* call_;
bool call_canceled_;
gpr_timespec deadline_;
grpc::string authority_;
std::shared_ptr<CallCredentials> creds_;
std::shared_ptr<grpc_impl::CallCredentials> creds_;
mutable std::shared_ptr<const AuthContext> auth_context_;
struct census_context* census_context_;
std::multimap<grpc::string, grpc::string> send_initial_metadata_;

@ -26,10 +26,14 @@
#include <grpcpp/impl/codegen/rpc_method.h>
#include <grpcpp/impl/codegen/string_ref.h>
namespace grpc_impl {
class Channel;
}
namespace grpc {
class ClientContext;
class Channel;
namespace internal {
class InterceptorBatchMethodsImpl;

@ -43,11 +43,11 @@ struct grpc_completion_queue;
namespace grpc_impl {
class Channel;
class ServerBuilder;
} // namespace grpc_impl
namespace grpc {
class Channel;
class Server;
template <class R>
class ClientReader;
@ -284,7 +284,7 @@ class CompletionQueue : private ::grpc::GrpcLibraryCodegen {
friend class ::grpc::internal::BlockingUnaryCallImpl;
// Friends that need access to constructor for callback CQ
friend class ::grpc::Channel;
friend class ::grpc_impl::Channel;
// For access to Register/CompleteAvalanching
template <class Op1, class Op2, class Op3, class Op4, class Op5, class Op6>

@ -0,0 +1,55 @@
/*
*
* 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_IMPL_CODEGEN_MESSAGE_ALLOCATOR_H
#define GRPCPP_IMPL_CODEGEN_MESSAGE_ALLOCATOR_H
namespace grpc {
namespace experimental {
// This is per rpc struct for the allocator. We can potentially put the grpc
// call arena in here in the future.
template <typename RequestT, typename ResponseT>
struct RpcAllocatorInfo {
RequestT* request;
ResponseT* response;
// per rpc allocator internal state. MessageAllocator can set it when
// AllocateMessages is called and use it later.
void* allocator_state;
};
// Implementations need to be thread-safe
template <typename RequestT, typename ResponseT>
class MessageAllocator {
public:
virtual ~MessageAllocator() = default;
// Allocate both request and response
virtual void AllocateMessages(
RpcAllocatorInfo<RequestT, ResponseT>* info) = 0;
// Optional: deallocate request early, called by
// ServerCallbackRpcController::ReleaseRequest
virtual void DeallocateRequest(RpcAllocatorInfo<RequestT, ResponseT>* info) {}
// Deallocate response and request (if applicable)
virtual void DeallocateMessages(
RpcAllocatorInfo<RequestT, ResponseT>* info) = 0;
};
} // namespace experimental
} // namespace grpc
#endif // GRPCPP_IMPL_CODEGEN_MESSAGE_ALLOCATOR_H

@ -86,8 +86,8 @@ class RpcMethodHandler : public MethodHandler {
param.call->cq()->Pluck(&ops);
}
void* Deserialize(grpc_call* call, grpc_byte_buffer* req,
Status* status) final {
void* Deserialize(grpc_call* call, grpc_byte_buffer* req, Status* status,
void** handler_data) final {
ByteBuffer buf;
buf.set_buffer(req);
auto* request = new (g_core_codegen_interface->grpc_call_arena_alloc(
@ -191,8 +191,8 @@ class ServerStreamingHandler : public MethodHandler {
param.call->cq()->Pluck(&ops);
}
void* Deserialize(grpc_call* call, grpc_byte_buffer* req,
Status* status) final {
void* Deserialize(grpc_call* call, grpc_byte_buffer* req, Status* status,
void** handler_data) final {
ByteBuffer buf;
buf.set_buffer(req);
auto* request = new (g_core_codegen_interface->grpc_call_arena_alloc(
@ -327,8 +327,8 @@ class ErrorMethodHandler : public MethodHandler {
param.call->cq()->Pluck(&ops);
}
void* Deserialize(grpc_call* call, grpc_byte_buffer* req,
Status* status) final {
void* Deserialize(grpc_call* call, grpc_byte_buffer* req, Status* status,
void** handler_data) final {
// We have to destroy any request payload
if (req != nullptr) {
g_core_codegen_interface->grpc_byte_buffer_destroy(req);

@ -46,21 +46,25 @@ 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 handler_data: internal data for the handler.
/// \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,
Status req_status, std::function<void()> requester)
Status req_status, void* handler_data,
std::function<void()> requester)
: call(c),
server_context(context),
request(req),
status(req_status),
internal_data(handler_data),
call_requester(std::move(requester)) {}
~HandlerParameter() {}
Call* call;
ServerContext* server_context;
void* request;
Status status;
void* internal_data;
std::function<void()> call_requester;
};
virtual void RunHandler(const HandlerParameter& param) = 0;
@ -71,7 +75,7 @@ class MethodHandler {
pointer after calling RunHandler. Ownership of the deserialized request is
retained by the handler. Returns nullptr if deserialization failed. */
virtual void* Deserialize(grpc_call* call, grpc_byte_buffer* req,
Status* status) {
Status* status, void** handler_data) {
GPR_CODEGEN_ASSERT(req == nullptr);
return nullptr;
}

@ -28,6 +28,7 @@
#include <grpcpp/impl/codegen/callback_common.h>
#include <grpcpp/impl/codegen/config.h>
#include <grpcpp/impl/codegen/core_codegen_interface.h>
#include <grpcpp/impl/codegen/message_allocator.h>
#include <grpcpp/impl/codegen/server_context.h>
#include <grpcpp/impl/codegen/server_interface.h>
#include <grpcpp/impl/codegen/status.h>
@ -135,6 +136,14 @@ class ServerCallbackRpcController {
/// to be called before the callback completes.
virtual void SetCancelCallback(std::function<void()> callback) = 0;
virtual void ClearCancelCallback() = 0;
// NOTE: This is an API for advanced users who need custom allocators.
// Optionally deallocate request early to reduce the size of working set.
// A custom MessageAllocator needs to be registered to make use of this.
virtual void FreeRequest() = 0;
// NOTE: This is an API for advanced users who need custom allocators.
// Get and maybe mutate the allocator state associated with the current RPC.
virtual void* GetAllocatorState() = 0;
};
// NOTE: The actual streaming object classes are provided
@ -364,7 +373,7 @@ class ServerReadReactor : public internal::ServerReactor {
ServerCallbackReader<Request>* reader_;
};
/// \a ServerReadReactor is the interface for a server-streaming RPC.
/// \a ServerWriteReactor is the interface for a server-streaming RPC.
template <class Request, class Response>
class ServerWriteReactor : public internal::ServerReactor {
public:
@ -447,17 +456,24 @@ class CallbackUnaryHandler : public MethodHandler {
experimental::ServerCallbackRpcController*)>
func)
: func_(func) {}
void SetMessageAllocator(
experimental::MessageAllocator<RequestType, ResponseType>* allocator) {
allocator_ = allocator;
}
void RunHandler(const HandlerParameter& param) final {
// Arena allocate a controller structure (that includes request/response)
g_core_codegen_interface->grpc_call_ref(param.call->call());
auto* allocator_info =
static_cast<experimental::RpcAllocatorInfo<RequestType, ResponseType>*>(
param.internal_data);
auto* controller = new (g_core_codegen_interface->grpc_call_arena_alloc(
param.call->call(), sizeof(ServerCallbackRpcControllerImpl)))
ServerCallbackRpcControllerImpl(
param.server_context, param.call,
static_cast<RequestType*>(param.request),
std::move(param.call_requester));
ServerCallbackRpcControllerImpl(param.server_context, param.call,
allocator_info, allocator_,
std::move(param.call_requester));
Status status = param.status;
if (status.ok()) {
// Call the actual function handler and expect the user to call finish
CatchingCallback(func_, param.server_context, controller->request(),
@ -468,18 +484,41 @@ class CallbackUnaryHandler : public MethodHandler {
}
}
void* Deserialize(grpc_call* call, grpc_byte_buffer* req,
Status* status) final {
void* Deserialize(grpc_call* call, grpc_byte_buffer* req, Status* status,
void** handler_data) final {
ByteBuffer buf;
buf.set_buffer(req);
auto* request = new (g_core_codegen_interface->grpc_call_arena_alloc(
call, sizeof(RequestType))) RequestType();
RequestType* request = nullptr;
experimental::RpcAllocatorInfo<RequestType, ResponseType>* allocator_info =
new (g_core_codegen_interface->grpc_call_arena_alloc(
call, sizeof(*allocator_info)))
experimental::RpcAllocatorInfo<RequestType, ResponseType>();
if (allocator_ != nullptr) {
allocator_->AllocateMessages(allocator_info);
} else {
allocator_info->request =
new (g_core_codegen_interface->grpc_call_arena_alloc(
call, sizeof(RequestType))) RequestType();
allocator_info->response =
new (g_core_codegen_interface->grpc_call_arena_alloc(
call, sizeof(ResponseType))) ResponseType();
}
*handler_data = allocator_info;
request = allocator_info->request;
*status = SerializationTraits<RequestType>::Deserialize(&buf, request);
buf.Release();
if (status->ok()) {
return request;
}
request->~RequestType();
// Clean up on deserialization failure.
if (allocator_ != nullptr) {
allocator_->DeallocateMessages(allocator_info);
} else {
allocator_info->request->~RequestType();
allocator_info->response->~ResponseType();
allocator_info->request = nullptr;
allocator_info->response = nullptr;
}
return nullptr;
}
@ -487,6 +526,8 @@ class CallbackUnaryHandler : public MethodHandler {
std::function<void(ServerContext*, const RequestType*, ResponseType*,
experimental::ServerCallbackRpcController*)>
func_;
experimental::MessageAllocator<RequestType, ResponseType>* allocator_ =
nullptr;
// The implementation class of ServerCallbackRpcController is a private member
// of CallbackUnaryHandler since it is never exposed anywhere, and this allows
@ -507,8 +548,9 @@ class CallbackUnaryHandler : public MethodHandler {
}
// The response is dropped if the status is not OK.
if (s.ok()) {
finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_,
finish_ops_.SendMessagePtr(&resp_));
finish_ops_.ServerSendStatus(
&ctx_->trailing_metadata_,
finish_ops_.SendMessagePtr(allocator_info_->response));
} else {
finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, s);
}
@ -546,28 +588,50 @@ class CallbackUnaryHandler : public MethodHandler {
void ClearCancelCallback() override { ctx_->ClearCancelCallback(); }
void FreeRequest() override {
if (allocator_ != nullptr) {
allocator_->DeallocateRequest(allocator_info_);
}
}
void* GetAllocatorState() override {
return allocator_info_->allocator_state;
}
private:
friend class CallbackUnaryHandler<RequestType, ResponseType>;
ServerCallbackRpcControllerImpl(ServerContext* ctx, Call* call,
const RequestType* req,
std::function<void()> call_requester)
ServerCallbackRpcControllerImpl(
ServerContext* ctx, Call* call,
experimental::RpcAllocatorInfo<RequestType, ResponseType>*
allocator_info,
experimental::MessageAllocator<RequestType, ResponseType>* allocator,
std::function<void()> call_requester)
: ctx_(ctx),
call_(*call),
req_(req),
allocator_info_(allocator_info),
allocator_(allocator),
call_requester_(std::move(call_requester)) {
ctx_->BeginCompletionOp(call, [this](bool) { MaybeDone(); }, nullptr);
}
~ServerCallbackRpcControllerImpl() { req_->~RequestType(); }
const RequestType* request() { return req_; }
ResponseType* response() { return &resp_; }
const RequestType* request() { return allocator_info_->request; }
ResponseType* response() { return allocator_info_->response; }
void MaybeDone() {
if (--callbacks_outstanding_ == 0) {
grpc_call* call = call_.call();
auto call_requester = std::move(call_requester_);
if (allocator_ != nullptr) {
allocator_->DeallocateMessages(allocator_info_);
} else {
if (allocator_info_->request != nullptr) {
allocator_info_->request->~RequestType();
}
if (allocator_info_->response != nullptr) {
allocator_info_->response->~ResponseType();
}
}
this->~ServerCallbackRpcControllerImpl(); // explicitly call destructor
g_core_codegen_interface->grpc_call_unref(call);
call_requester();
@ -583,8 +647,8 @@ class CallbackUnaryHandler : public MethodHandler {
ServerContext* ctx_;
Call call_;
const RequestType* req_;
ResponseType resp_;
experimental::RpcAllocatorInfo<RequestType, ResponseType>* allocator_info_;
experimental::MessageAllocator<RequestType, ResponseType>* allocator_;
std::function<void()> call_requester_;
std::atomic_int callbacks_outstanding_{
2}; // reserve for Finish and CompletionOp
@ -771,8 +835,8 @@ class CallbackServerStreamingHandler : public MethodHandler {
writer->MaybeDone();
}
void* Deserialize(grpc_call* call, grpc_byte_buffer* req,
Status* status) final {
void* Deserialize(grpc_call* call, grpc_byte_buffer* req, Status* status,
void** handler_data) final {
ByteBuffer buf;
buf.set_buffer(req);
auto* request = new (g_core_codegen_interface->grpc_call_arena_alloc(

@ -32,8 +32,9 @@ namespace grpc_impl {
class CompletionQueue;
class ServerCompletionQueue;
class Channel;
class ServerCredentials;
}
} // namespace grpc_impl
namespace grpc {
class AsyncGenericService;
@ -149,7 +150,7 @@ class ServerInterface : public internal::CallHook {
/// 192.168.1.1:31416, [::1]:27182, etc.).
/// \params creds The credentials associated with the server.
///
/// \return bound port number on sucess, 0 on failure.
/// \return bound port number on success, 0 on failure.
///
/// \warning It's an error to call this method on an already started server.
virtual int AddListeningPort(const grpc::string& addr,

@ -130,6 +130,11 @@ class Service {
internal::RpcServiceMethod::ApiType::RAW_CALL_BACK);
}
internal::MethodHandler* GetHandler(int index) {
size_t idx = static_cast<size_t>(index);
return service_->methods_[idx]->handler();
}
private:
Service* service_;
};

@ -19,8 +19,15 @@
#ifndef GRPCPP_IMPL_CODEGEN_SYNC_H
#define GRPCPP_IMPL_CODEGEN_SYNC_H
#include <grpc/impl/codegen/log.h>
#include <grpc/impl/codegen/port_platform.h>
#ifdef GPR_HAS_PTHREAD_H
#include <pthread.h>
#endif
#include <mutex>
#include <grpc/impl/codegen/log.h>
#include <grpc/impl/codegen/sync.h>
#include <grpcpp/impl/codegen/core_codegen_interface.h>
@ -49,7 +56,13 @@ class Mutex {
const gpr_mu* get() const { return &mu_; }
private:
gpr_mu mu_;
union {
gpr_mu mu_;
std::mutex do_not_use_sth_;
#ifdef GPR_HAS_PTHREAD_H
pthread_mutex_t do_not_use_pth_;
#endif
};
};
// MutexLock is a std::

@ -180,7 +180,7 @@ class ClientReader final : public ClientReaderInterface<R> {
///
// Side effect:
/// Once complete, the initial metadata read from
/// the server will be accessable through the \a ClientContext used to
/// the server will be accessible through the \a ClientContext used to
/// construct this object.
void WaitForInitialMetadata() override {
GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
@ -298,7 +298,7 @@ class ClientWriter : public ClientWriterInterface<W> {
///
// Side effect:
/// Once complete, the initial metadata read from the server will be
/// accessable through the \a ClientContext used to construct this object.
/// accessible through the \a ClientContext used to construct this object.
void WaitForInitialMetadata() {
GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
@ -449,7 +449,7 @@ class ClientReaderWriter final : public ClientReaderWriterInterface<W, R> {
/// with or after the \a Finish method.
///
/// Once complete, the initial metadata read from the server will be
/// accessable through the \a ClientContext used to construct this object.
/// accessible through the \a ClientContext used to construct this object.
void WaitForInitialMetadata() override {
GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);

@ -25,13 +25,12 @@
namespace grpc_impl {
class ChannelArguments;
class ServerBuilder;
class ServerInitializer;
} // namespace grpc_impl
namespace grpc {
class ChannelArguments;
/// This interface is meant for internal usage only. Implementations of this
/// interface should add themselves to a \a ServerBuilder instance through the
/// \a InternalAddPluginFactory method.
@ -58,7 +57,7 @@ class ServerBuilderPlugin {
/// UpdateChannelArguments will be called in ServerBuilder::BuildAndStart(),
/// before the Server instance is created.
virtual void UpdateChannelArguments(ChannelArguments* args) {}
virtual void UpdateChannelArguments(grpc_impl::ChannelArguments* args) {}
virtual bool has_sync_methods() const { return false; }
virtual bool has_async_methods() const { return false; }

@ -19,265 +19,104 @@
#ifndef GRPCPP_SECURITY_CREDENTIALS_H
#define GRPCPP_SECURITY_CREDENTIALS_H
#include <map>
#include <memory>
#include <vector>
#include <grpc/grpc_security_constants.h>
#include <grpcpp/impl/codegen/client_interceptor.h>
#include <grpcpp/impl/codegen/grpc_library.h>
#include <grpcpp/security/auth_context.h>
#include <grpcpp/support/status.h>
#include <grpcpp/support/string_ref.h>
struct grpc_call;
#include <grpcpp/security/credentials_impl.h>
namespace grpc {
class CallCredentials;
class ChannelArguments;
class ChannelCredentials;
} // namespace grpc
namespace grpc_impl {
std::shared_ptr<grpc::Channel> CreateCustomChannel(
const grpc::string& target,
const std::shared_ptr<grpc::ChannelCredentials>& creds,
const grpc::ChannelArguments& args);
namespace experimental {
std::shared_ptr<grpc::Channel> CreateCustomChannelWithInterceptors(
const grpc::string& target,
const std::shared_ptr<grpc::ChannelCredentials>& creds,
const grpc::ChannelArguments& args,
std::vector<
std::unique_ptr<grpc::experimental::ClientInterceptorFactoryInterface>>
interceptor_creators);
} // namespace experimental
} // namespace grpc_impl
namespace grpc {
class Channel;
class SecureChannelCredentials;
class SecureCallCredentials;
/// A channel credentials object encapsulates all the state needed by a client
/// to authenticate with a server for a given channel.
/// It can make various assertions, e.g., about the client’s identity, role
/// for all the calls on that channel.
///
/// \see https://grpc.io/docs/guides/auth.html
class ChannelCredentials : private GrpcLibraryCodegen {
public:
ChannelCredentials();
~ChannelCredentials();
protected:
friend std::shared_ptr<ChannelCredentials> CompositeChannelCredentials(
const std::shared_ptr<ChannelCredentials>& channel_creds,
const std::shared_ptr<CallCredentials>& call_creds);
virtual SecureChannelCredentials* AsSecureCredentials() = 0;
private:
friend std::shared_ptr<Channel> grpc_impl::CreateCustomChannel(
const grpc::string& target,
const std::shared_ptr<ChannelCredentials>& creds,
const grpc::ChannelArguments& args);
friend std::shared_ptr<Channel>
grpc_impl::experimental::CreateCustomChannelWithInterceptors(
const grpc::string& target,
const std::shared_ptr<ChannelCredentials>& creds,
const grpc::ChannelArguments& args,
std::vector<std::unique_ptr<
grpc::experimental::ClientInterceptorFactoryInterface>>
interceptor_creators);
virtual std::shared_ptr<Channel> CreateChannel(
const grpc::string& target, const ChannelArguments& args) = 0;
// This function should have been a pure virtual function, but it is
// implemented as a virtual function so that it does not break API.
virtual std::shared_ptr<Channel> CreateChannelWithInterceptors(
const grpc::string& target, const ChannelArguments& args,
std::vector<
std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
interceptor_creators) {
return nullptr;
}
};
/// A call credentials object encapsulates the state needed by a client to
/// authenticate with a server for a given call on a channel.
///
/// \see https://grpc.io/docs/guides/auth.html
class CallCredentials : private GrpcLibraryCodegen {
public:
CallCredentials();
~CallCredentials();
/// Apply this instance's credentials to \a call.
virtual bool ApplyToCall(grpc_call* call) = 0;
protected:
friend std::shared_ptr<ChannelCredentials> CompositeChannelCredentials(
const std::shared_ptr<ChannelCredentials>& channel_creds,
const std::shared_ptr<CallCredentials>& call_creds);
typedef ::grpc_impl::ChannelCredentials ChannelCredentials;
typedef ::grpc_impl::CallCredentials CallCredentials;
typedef ::grpc_impl::SslCredentialsOptions SslCredentialsOptions;
typedef ::grpc_impl::SecureCallCredentials SecureCallCredentials;
typedef ::grpc_impl::SecureChannelCredentials SecureChannelCredentials;
friend std::shared_ptr<CallCredentials> CompositeCallCredentials(
const std::shared_ptr<CallCredentials>& creds1,
const std::shared_ptr<CallCredentials>& creds2);
static inline std::shared_ptr<grpc_impl::ChannelCredentials>
GoogleDefaultCredentials() {
return ::grpc_impl::GoogleDefaultCredentials();
}
virtual SecureCallCredentials* AsSecureCredentials() = 0;
};
static inline std::shared_ptr<ChannelCredentials> SslCredentials(
const SslCredentialsOptions& options) {
return ::grpc_impl::SslCredentials(options);
}
/// Options used to build SslCredentials.
struct SslCredentialsOptions {
/// The buffer containing the PEM encoding of the server root certificates. If
/// this parameter is empty, the default roots will be used. The default
/// roots can be overridden using the \a GRPC_DEFAULT_SSL_ROOTS_FILE_PATH
/// environment variable pointing to a file on the file system containing the
/// roots.
grpc::string pem_root_certs;
/// The buffer containing the PEM encoding of the client's private key. This
/// parameter can be empty if the client does not have a private key.
grpc::string pem_private_key;
/// The buffer containing the PEM encoding of the client's certificate chain.
/// This parameter can be empty if the client does not have a certificate
/// chain.
grpc::string pem_cert_chain;
};
// Factories for building different types of Credentials The functions may
// return empty shared_ptr when credentials cannot be created. If a
// Credentials pointer is returned, it can still be invalid when used to create
// a channel. A lame channel will be created then and all rpcs will fail on it.
/// Builds credentials with reasonable defaults.
///
/// \warning Only use these credentials when connecting to a Google endpoint.
/// Using these credentials to connect to any other service may result in this
/// service being able to impersonate your client for requests to Google
/// services.
std::shared_ptr<ChannelCredentials> GoogleDefaultCredentials();
/// Builds SSL Credentials given SSL specific options
std::shared_ptr<ChannelCredentials> SslCredentials(
const SslCredentialsOptions& options);
/// Builds credentials for use when running in GCE
///
/// \warning Only use these credentials when connecting to a Google endpoint.
/// Using these credentials to connect to any other service may result in this
/// service being able to impersonate your client for requests to Google
/// services.
std::shared_ptr<CallCredentials> GoogleComputeEngineCredentials();
static inline std::shared_ptr<grpc_impl::CallCredentials>
GoogleComputeEngineCredentials() {
return ::grpc_impl::GoogleComputeEngineCredentials();
}
/// Constant for maximum auth token lifetime.
constexpr long kMaxAuthTokenLifetimeSecs = 3600;
constexpr long kMaxAuthTokenLifetimeSecs =
::grpc_impl::kMaxAuthTokenLifetimeSecs;
/// Builds Service Account JWT Access credentials.
/// json_key is the JSON key string containing the client's private key.
/// token_lifetime_seconds is the lifetime in seconds of each Json Web Token
/// (JWT) created with this credentials. It should not exceed
/// \a kMaxAuthTokenLifetimeSecs or will be cropped to this value.
std::shared_ptr<CallCredentials> ServiceAccountJWTAccessCredentials(
static inline std::shared_ptr<grpc_impl::CallCredentials>
ServiceAccountJWTAccessCredentials(
const grpc::string& json_key,
long token_lifetime_seconds = kMaxAuthTokenLifetimeSecs);
/// Builds refresh token credentials.
/// json_refresh_token is the JSON string containing the refresh token along
/// with a client_id and client_secret.
///
/// \warning Only use these credentials when connecting to a Google endpoint.
/// Using these credentials to connect to any other service may result in this
/// service being able to impersonate your client for requests to Google
/// services.
std::shared_ptr<CallCredentials> GoogleRefreshTokenCredentials(
const grpc::string& json_refresh_token);
/// Builds access token credentials.
/// access_token is an oauth2 access token that was fetched using an out of band
/// mechanism.
///
/// \warning Only use these credentials when connecting to a Google endpoint.
/// Using these credentials to connect to any other service may result in this
/// service being able to impersonate your client for requests to Google
/// services.
std::shared_ptr<CallCredentials> AccessTokenCredentials(
const grpc::string& access_token);
/// Builds IAM credentials.
///
/// \warning Only use these credentials when connecting to a Google endpoint.
/// Using these credentials to connect to any other service may result in this
/// service being able to impersonate your client for requests to Google
/// services.
std::shared_ptr<CallCredentials> GoogleIAMCredentials(
long token_lifetime_seconds = grpc::kMaxAuthTokenLifetimeSecs) {
return ::grpc_impl::ServiceAccountJWTAccessCredentials(
json_key, token_lifetime_seconds);
}
static inline std::shared_ptr<grpc_impl::CallCredentials>
GoogleRefreshTokenCredentials(const grpc::string& json_refresh_token) {
return ::grpc_impl::GoogleRefreshTokenCredentials(json_refresh_token);
}
static inline std::shared_ptr<grpc_impl::CallCredentials>
AccessTokenCredentials(const grpc::string& access_token) {
return ::grpc_impl::AccessTokenCredentials(access_token);
}
static inline std::shared_ptr<grpc_impl::CallCredentials> GoogleIAMCredentials(
const grpc::string& authorization_token,
const grpc::string& authority_selector);
const grpc::string& authority_selector) {
return ::grpc_impl::GoogleIAMCredentials(authorization_token,
authority_selector);
}
/// Combines a channel credentials and a call credentials into a composite
/// channel credentials.
std::shared_ptr<ChannelCredentials> CompositeChannelCredentials(
static inline std::shared_ptr<ChannelCredentials> CompositeChannelCredentials(
const std::shared_ptr<ChannelCredentials>& channel_creds,
const std::shared_ptr<CallCredentials>& call_creds);
/// Combines two call credentials objects into a composite call credentials.
std::shared_ptr<CallCredentials> CompositeCallCredentials(
const std::shared_ptr<CallCredentials>& creds1,
const std::shared_ptr<CallCredentials>& creds2);
/// Credentials for an unencrypted, unauthenticated channel
std::shared_ptr<ChannelCredentials> InsecureChannelCredentials();
/// Credentials for a channel using Cronet.
std::shared_ptr<ChannelCredentials> CronetChannelCredentials(void* engine);
/// User defined metadata credentials.
class MetadataCredentialsPlugin {
public:
virtual ~MetadataCredentialsPlugin() {}
/// If this method returns true, the Process function will be scheduled in
/// a different thread from the one processing the call.
virtual bool IsBlocking() const { return true; }
/// Type of credentials this plugin is implementing.
virtual const char* GetType() const { return ""; }
/// Gets the auth metatada produced by this plugin.
/// The fully qualified method name is:
/// service_url + "/" + method_name.
/// The channel_auth_context contains (among other things), the identity of
/// the server.
virtual Status GetMetadata(
grpc::string_ref service_url, grpc::string_ref method_name,
const AuthContext& channel_auth_context,
std::multimap<grpc::string, grpc::string>* metadata) = 0;
};
std::shared_ptr<CallCredentials> MetadataCredentialsFromPlugin(
std::unique_ptr<MetadataCredentialsPlugin> plugin);
const std::shared_ptr<CallCredentials>& call_creds) {
return ::grpc_impl::CompositeChannelCredentials(channel_creds, call_creds);
}
static inline std::shared_ptr<grpc_impl::CallCredentials>
CompositeCallCredentials(const std::shared_ptr<CallCredentials>& creds1,
const std::shared_ptr<CallCredentials>& creds2) {
return ::grpc_impl::CompositeCallCredentials(creds1, creds2);
}
static inline std::shared_ptr<grpc_impl::ChannelCredentials>
InsecureChannelCredentials() {
return ::grpc_impl::InsecureChannelCredentials();
}
static inline std::shared_ptr<grpc_impl::ChannelCredentials>
CronetChannelCredentials(void* engine) {
return ::grpc_impl::CronetChannelCredentials(engine);
}
typedef ::grpc_impl::MetadataCredentialsPlugin MetadataCredentialsPlugin;
static inline std::shared_ptr<grpc_impl::CallCredentials>
MetadataCredentialsFromPlugin(
std::unique_ptr<MetadataCredentialsPlugin> plugin) {
return ::grpc_impl::MetadataCredentialsFromPlugin(std::move(plugin));
}
namespace experimental {
/// Options used to build AltsCredentials.
struct AltsCredentialsOptions {
/// service accounts of target endpoint that will be acceptable
/// by the client. If service accounts are provided and none of them matches
/// that of the server, authentication will fail.
std::vector<grpc::string> target_service_accounts;
};
typedef ::grpc_impl::experimental::AltsCredentialsOptions
AltsCredentialsOptions;
/// Builds ALTS Credentials given ALTS specific options
std::shared_ptr<ChannelCredentials> AltsCredentials(
const AltsCredentialsOptions& options);
static inline std::shared_ptr<grpc_impl::ChannelCredentials> AltsCredentials(
const AltsCredentialsOptions& options) {
return ::grpc_impl::experimental::AltsCredentials(options);
}
/// Builds Local Credentials.
std::shared_ptr<ChannelCredentials> LocalCredentials(
grpc_local_connect_type type);
static inline std::shared_ptr<grpc_impl::ChannelCredentials> LocalCredentials(
grpc_local_connect_type type) {
return ::grpc_impl::experimental::LocalCredentials(type);
}
} // namespace experimental
} // namespace grpc

@ -0,0 +1,281 @@
/*
*
* 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_SECURITY_CREDENTIALS_IMPL_H
#define GRPCPP_SECURITY_CREDENTIALS_IMPL_H
#include <map>
#include <memory>
#include <vector>
#include <grpc/grpc_security_constants.h>
#include <grpcpp/channel.h>
#include <grpcpp/impl/codegen/client_interceptor.h>
#include <grpcpp/impl/codegen/grpc_library.h>
#include <grpcpp/security/auth_context.h>
#include <grpcpp/support/channel_arguments.h>
#include <grpcpp/support/status.h>
#include <grpcpp/support/string_ref.h>
struct grpc_call;
namespace grpc_impl {
class ChannelCredentials;
class CallCredentials;
class SecureCallCredentials;
class SecureChannelCredentials;
std::shared_ptr<::grpc::Channel> CreateCustomChannelImpl(
const grpc::string& target,
const std::shared_ptr<ChannelCredentials>& creds,
const grpc::ChannelArguments& args);
namespace experimental {
std::shared_ptr<::grpc::Channel> CreateCustomChannelWithInterceptors(
const grpc::string& target,
const std::shared_ptr<ChannelCredentials>& creds,
const grpc::ChannelArguments& args,
std::vector<
std::unique_ptr<grpc::experimental::ClientInterceptorFactoryInterface>>
interceptor_creators);
}
/// A channel credentials object encapsulates all the state needed by a client
/// to authenticate with a server for a given channel.
/// It can make various assertions, e.g., about the client’s identity, role
/// for all the calls on that channel.
///
/// \see https://grpc.io/docs/guides/auth.html
class ChannelCredentials : private grpc::GrpcLibraryCodegen {
public:
ChannelCredentials();
~ChannelCredentials();
protected:
friend std::shared_ptr<ChannelCredentials> CompositeChannelCredentials(
const std::shared_ptr<ChannelCredentials>& channel_creds,
const std::shared_ptr<CallCredentials>& call_creds);
virtual SecureChannelCredentials* AsSecureCredentials() = 0;
private:
friend std::shared_ptr<::grpc::Channel> CreateCustomChannelImpl(
const grpc::string& target,
const std::shared_ptr<ChannelCredentials>& creds,
const grpc::ChannelArguments& args);
friend std::shared_ptr<::grpc::Channel>
grpc_impl::experimental::CreateCustomChannelWithInterceptors(
const grpc::string& target,
const std::shared_ptr<ChannelCredentials>& creds,
const grpc::ChannelArguments& args,
std::vector<std::unique_ptr<
grpc::experimental::ClientInterceptorFactoryInterface>>
interceptor_creators);
virtual std::shared_ptr<::grpc::Channel> CreateChannelImpl(
const grpc::string& target, const grpc::ChannelArguments& args) = 0;
// This function should have been a pure virtual function, but it is
// implemented as a virtual function so that it does not break API.
virtual std::shared_ptr<::grpc::Channel> CreateChannelWithInterceptors(
const grpc::string& target, const grpc::ChannelArguments& args,
std::vector<std::unique_ptr<
grpc::experimental::ClientInterceptorFactoryInterface>>
interceptor_creators) {
return nullptr;
}
};
/// A call credentials object encapsulates the state needed by a client to
/// authenticate with a server for a given call on a channel.
///
/// \see https://grpc.io/docs/guides/auth.html
class CallCredentials : private grpc::GrpcLibraryCodegen {
public:
CallCredentials();
~CallCredentials();
/// Apply this instance's credentials to \a call.
virtual bool ApplyToCall(grpc_call* call) = 0;
protected:
friend std::shared_ptr<ChannelCredentials> CompositeChannelCredentials(
const std::shared_ptr<ChannelCredentials>& channel_creds,
const std::shared_ptr<CallCredentials>& call_creds);
friend std::shared_ptr<CallCredentials> CompositeCallCredentials(
const std::shared_ptr<CallCredentials>& creds1,
const std::shared_ptr<CallCredentials>& creds2);
virtual SecureCallCredentials* AsSecureCredentials() = 0;
};
/// Options used to build SslCredentials.
struct SslCredentialsOptions {
/// The buffer containing the PEM encoding of the server root certificates. If
/// this parameter is empty, the default roots will be used. The default
/// roots can be overridden using the \a GRPC_DEFAULT_SSL_ROOTS_FILE_PATH
/// environment variable pointing to a file on the file system containing the
/// roots.
grpc::string pem_root_certs;
/// The buffer containing the PEM encoding of the client's private key. This
/// parameter can be empty if the client does not have a private key.
grpc::string pem_private_key;
/// The buffer containing the PEM encoding of the client's certificate chain.
/// This parameter can be empty if the client does not have a certificate
/// chain.
grpc::string pem_cert_chain;
};
// Factories for building different types of Credentials The functions may
// return empty shared_ptr when credentials cannot be created. If a
// Credentials pointer is returned, it can still be invalid when used to create
// a channel. A lame channel will be created then and all rpcs will fail on it.
/// Builds credentials with reasonable defaults.
///
/// \warning Only use these credentials when connecting to a Google endpoint.
/// Using these credentials to connect to any other service may result in this
/// service being able to impersonate your client for requests to Google
/// services.
std::shared_ptr<ChannelCredentials> GoogleDefaultCredentials();
/// Builds SSL Credentials given SSL specific options
std::shared_ptr<ChannelCredentials> SslCredentials(
const SslCredentialsOptions& options);
/// Builds credentials for use when running in GCE
///
/// \warning Only use these credentials when connecting to a Google endpoint.
/// Using these credentials to connect to any other service may result in this
/// service being able to impersonate your client for requests to Google
/// services.
std::shared_ptr<CallCredentials> GoogleComputeEngineCredentials();
constexpr long kMaxAuthTokenLifetimeSecs = 3600;
/// Builds Service Account JWT Access credentials.
/// json_key is the JSON key string containing the client's private key.
/// token_lifetime_seconds is the lifetime in seconds of each Json Web Token
/// (JWT) created with this credentials. It should not exceed
/// \a kMaxAuthTokenLifetimeSecs or will be cropped to this value.
std::shared_ptr<CallCredentials> ServiceAccountJWTAccessCredentials(
const grpc::string& json_key,
long token_lifetime_seconds = grpc_impl::kMaxAuthTokenLifetimeSecs);
/// Builds refresh token credentials.
/// json_refresh_token is the JSON string containing the refresh token along
/// with a client_id and client_secret.
///
/// \warning Only use these credentials when connecting to a Google endpoint.
/// Using these credentials to connect to any other service may result in this
/// service being able to impersonate your client for requests to Google
/// services.
std::shared_ptr<CallCredentials> GoogleRefreshTokenCredentials(
const grpc::string& json_refresh_token);
/// Builds access token credentials.
/// access_token is an oauth2 access token that was fetched using an out of band
/// mechanism.
///
/// \warning Only use these credentials when connecting to a Google endpoint.
/// Using these credentials to connect to any other service may result in this
/// service being able to impersonate your client for requests to Google
/// services.
std::shared_ptr<CallCredentials> AccessTokenCredentials(
const grpc::string& access_token);
/// Builds IAM credentials.
///
/// \warning Only use these credentials when connecting to a Google endpoint.
/// Using these credentials to connect to any other service may result in this
/// service being able to impersonate your client for requests to Google
/// services.
std::shared_ptr<CallCredentials> GoogleIAMCredentials(
const grpc::string& authorization_token,
const grpc::string& authority_selector);
/// Combines a channel credentials and a call credentials into a composite
/// channel credentials.
std::shared_ptr<ChannelCredentials> CompositeChannelCredentials(
const std::shared_ptr<ChannelCredentials>& channel_creds,
const std::shared_ptr<CallCredentials>& call_creds);
/// Combines two call credentials objects into a composite call credentials.
std::shared_ptr<CallCredentials> CompositeCallCredentials(
const std::shared_ptr<CallCredentials>& creds1,
const std::shared_ptr<CallCredentials>& creds2);
/// Credentials for an unencrypted, unauthenticated channel
std::shared_ptr<ChannelCredentials> InsecureChannelCredentials();
/// Credentials for a channel using Cronet.
std::shared_ptr<ChannelCredentials> CronetChannelCredentials(void* engine);
/// User defined metadata credentials.
class MetadataCredentialsPlugin {
public:
virtual ~MetadataCredentialsPlugin() {}
/// If this method returns true, the Process function will be scheduled in
/// a different thread from the one processing the call.
virtual bool IsBlocking() const { return true; }
/// Type of credentials this plugin is implementing.
virtual const char* GetType() const { return ""; }
/// Gets the auth metatada produced by this plugin.
/// The fully qualified method name is:
/// service_url + "/" + method_name.
/// The channel_auth_context contains (among other things), the identity of
/// the server.
virtual grpc::Status GetMetadata(
grpc::string_ref service_url, grpc::string_ref method_name,
const grpc::AuthContext& channel_auth_context,
std::multimap<grpc::string, grpc::string>* metadata) = 0;
};
std::shared_ptr<CallCredentials> MetadataCredentialsFromPlugin(
std::unique_ptr<MetadataCredentialsPlugin> plugin);
namespace experimental {
/// Options used to build AltsCredentials.
struct AltsCredentialsOptions {
/// service accounts of target endpoint that will be acceptable
/// by the client. If service accounts are provided and none of them matches
/// that of the server, authentication will fail.
std::vector<grpc::string> target_service_accounts;
};
/// Builds ALTS Credentials given ALTS specific options
std::shared_ptr<ChannelCredentials> AltsCredentials(
const AltsCredentialsOptions& options);
/// Builds Local Credentials.
std::shared_ptr<ChannelCredentials> LocalCredentials(
grpc_local_connect_type type);
} // namespace experimental
} // namespace grpc_impl
#endif // GRPCPP_SECURITY_CREDENTIALS_IMPL_H

@ -27,6 +27,7 @@
#include <grpc/compression.h>
#include <grpc/support/atm.h>
#include <grpcpp/channel.h>
#include <grpcpp/completion_queue.h>
#include <grpcpp/health_check_service_interface.h>
#include <grpcpp/impl/call.h>

@ -19,132 +19,17 @@
#ifndef GRPCPP_SUPPORT_CHANNEL_ARGUMENTS_H
#define GRPCPP_SUPPORT_CHANNEL_ARGUMENTS_H
#include <list>
#include <vector>
#include <grpc/compression.h>
#include <grpc/grpc.h>
#include <grpcpp/support/config.h>
#include <grpcpp/support/channel_arguments_impl.h>
namespace grpc_impl {
class SecureChannelCredentials;
class ResourceQuota;
}
} // namespace grpc_impl
namespace grpc {
namespace testing {
class ChannelArgumentsTest;
} // namespace testing
/// 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.
class ChannelArguments {
public:
ChannelArguments();
~ChannelArguments();
ChannelArguments(const ChannelArguments& other);
ChannelArguments& operator=(ChannelArguments other) {
Swap(other);
return *this;
}
void Swap(ChannelArguments& other);
/// Dump arguments in this instance to \a channel_args. Does not take
/// ownership of \a channel_args.
///
/// Note that the underlying arguments are shared. Changes made to either \a
/// channel_args or this instance would be reflected on both.
void SetChannelArgs(grpc_channel_args* channel_args) const;
// gRPC specific channel argument setters
/// Set target name override for SSL host name checking. This option is for
/// testing only and should never be used in production.
void SetSslTargetNameOverride(const grpc::string& name);
// TODO(yangg) add flow control options
/// Set the compression algorithm for the channel.
void SetCompressionAlgorithm(grpc_compression_algorithm algorithm);
/// Set the grpclb fallback timeout (in ms) for the channel. If this amount
/// of time has passed but we have not gotten any non-empty \a serverlist from
/// the balancer, we will fall back to use the backend address(es) returned by
/// the resolver.
void SetGrpclbFallbackTimeout(int fallback_timeout);
/// For client channel's, the socket mutator operates on
/// "channel" sockets. For server's, the socket mutator operates
/// only on "listen" sockets.
/// TODO(apolcyn): allow socket mutators to also operate
/// on server "channel" sockets, and adjust the socket mutator
/// object to be more speficic about which type of socket
/// it should operate on.
void SetSocketMutator(grpc_socket_mutator* mutator);
/// Set the string to prepend to the user agent.
void SetUserAgentPrefix(const grpc::string& user_agent_prefix);
/// Set the buffer pool to be attached to the constructed channel.
void SetResourceQuota(const ::grpc_impl::ResourceQuota& resource_quota);
/// Set the max receive and send message sizes.
void SetMaxReceiveMessageSize(int size);
void SetMaxSendMessageSize(int size);
/// Set LB policy name.
/// Note that if the name resolver returns only balancer addresses, the
/// grpclb LB policy will be used, regardless of what is specified here.
void SetLoadBalancingPolicyName(const grpc::string& lb_policy_name);
/// Set service config in JSON form.
/// Primarily meant for use in unit tests.
void SetServiceConfigJSON(const grpc::string& service_config_json);
// Generic channel argument setters. Only for advanced use cases.
/// Set an integer argument \a value under \a key.
void SetInt(const grpc::string& key, int value);
// Generic channel argument setter. Only for advanced use cases.
/// Set a pointer argument \a value under \a key. Owership is not transferred.
void SetPointer(const grpc::string& key, void* value);
void SetPointerWithVtable(const grpc::string& key, void* value,
const grpc_arg_pointer_vtable* vtable);
/// Set a textual argument \a value under \a key.
void SetString(const grpc::string& key, const grpc::string& value);
/// Return (by value) a C \a grpc_channel_args structure which points to
/// arguments owned by this \a ChannelArguments instance
grpc_channel_args c_channel_args() const {
grpc_channel_args out;
out.num_args = args_.size();
out.args = args_.empty() ? NULL : const_cast<grpc_arg*>(&args_[0]);
return out;
}
private:
friend class SecureChannelCredentials;
friend class testing::ChannelArgumentsTest;
/// Default pointer argument operations.
struct PointerVtableMembers {
static void* Copy(void* in) { return in; }
static void Destroy(void* in) {}
static int Compare(void* a, void* b) {
if (a < b) return -1;
if (a > b) return 1;
return 0;
}
};
// Returns empty string when it is not set.
grpc::string GetSslTargetNameOverride() const;
std::vector<grpc_arg> args_;
std::list<grpc::string> strings_;
};
typedef ::grpc_impl::ChannelArguments ChannelArguments;
} // namespace grpc

@ -0,0 +1,152 @@
/*
*
* 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_SUPPORT_CHANNEL_ARGUMENTS_IMPL_H
#define GRPCPP_SUPPORT_CHANNEL_ARGUMENTS_IMPL_H
#include <list>
#include <vector>
#include <grpc/compression.h>
#include <grpc/grpc.h>
#include <grpcpp/resource_quota.h>
#include <grpcpp/support/config.h>
namespace grpc {
namespace testing {
class ChannelArgumentsTest;
} // namespace testing
} // namespace grpc
namespace grpc_impl {
class SecureChannelCredentials;
/// 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.
class ChannelArguments {
public:
ChannelArguments();
~ChannelArguments();
ChannelArguments(const ChannelArguments& other);
ChannelArguments& operator=(ChannelArguments other) {
Swap(other);
return *this;
}
void Swap(ChannelArguments& other);
/// Dump arguments in this instance to \a channel_args. Does not take
/// ownership of \a channel_args.
///
/// Note that the underlying arguments are shared. Changes made to either \a
/// channel_args or this instance would be reflected on both.
void SetChannelArgs(grpc_channel_args* channel_args) const;
// gRPC specific channel argument setters
/// Set target name override for SSL host name checking. This option is for
/// testing only and should never be used in production.
void SetSslTargetNameOverride(const grpc::string& name);
// TODO(yangg) add flow control options
/// Set the compression algorithm for the channel.
void SetCompressionAlgorithm(grpc_compression_algorithm algorithm);
/// Set the grpclb fallback timeout (in ms) for the channel. If this amount
/// of time has passed but we have not gotten any non-empty \a serverlist from
/// the balancer, we will fall back to use the backend address(es) returned by
/// the resolver.
void SetGrpclbFallbackTimeout(int fallback_timeout);
/// For client channel's, the socket mutator operates on
/// "channel" sockets. For server's, the socket mutator operates
/// only on "listen" sockets.
/// TODO(apolcyn): allow socket mutators to also operate
/// on server "channel" sockets, and adjust the socket mutator
/// object to be more speficic about which type of socket
/// it should operate on.
void SetSocketMutator(grpc_socket_mutator* mutator);
/// Set the string to prepend to the user agent.
void SetUserAgentPrefix(const grpc::string& user_agent_prefix);
/// Set the buffer pool to be attached to the constructed channel.
void SetResourceQuota(const grpc::ResourceQuota& resource_quota);
/// Set the max receive and send message sizes.
void SetMaxReceiveMessageSize(int size);
void SetMaxSendMessageSize(int size);
/// Set LB policy name.
/// Note that if the name resolver returns only balancer addresses, the
/// grpclb LB policy will be used, regardless of what is specified here.
void SetLoadBalancingPolicyName(const grpc::string& lb_policy_name);
/// Set service config in JSON form.
/// Primarily meant for use in unit tests.
void SetServiceConfigJSON(const grpc::string& service_config_json);
// Generic channel argument setters. Only for advanced use cases.
/// Set an integer argument \a value under \a key.
void SetInt(const grpc::string& key, int value);
// Generic channel argument setter. Only for advanced use cases.
/// Set a pointer argument \a value under \a key. Owership is not transferred.
void SetPointer(const grpc::string& key, void* value);
void SetPointerWithVtable(const grpc::string& key, void* value,
const grpc_arg_pointer_vtable* vtable);
/// Set a textual argument \a value under \a key.
void SetString(const grpc::string& key, const grpc::string& value);
/// Return (by value) a C \a grpc_channel_args structure which points to
/// arguments owned by this \a ChannelArguments instance
grpc_channel_args c_channel_args() const {
grpc_channel_args out;
out.num_args = args_.size();
out.args = args_.empty() ? NULL : const_cast<grpc_arg*>(&args_[0]);
return out;
}
private:
friend class grpc_impl::SecureChannelCredentials;
friend class grpc::testing::ChannelArgumentsTest;
/// Default pointer argument operations.
struct PointerVtableMembers {
static void* Copy(void* in) { return in; }
static void Destroy(void* in) {}
static int Compare(void* a, void* b) {
if (a < b) return -1;
if (a > b) return 1;
return 0;
}
};
// Returns empty string when it is not set.
grpc::string GetSslTargetNameOverride() const;
std::vector<grpc_arg> args_;
std::list<grpc::string> strings_;
};
} // namespace grpc_impl
#endif // GRPCPP_SUPPORT_CHANNEL_ARGUMENTS_IMPL_H

@ -0,0 +1,24 @@
/*
*
* 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_SUPPORT_MESSAGE_ALLOCATOR_H
#define GRPCPP_SUPPORT_MESSAGE_ALLOCATOR_H
#include <grpcpp/impl/codegen/message_allocator.h>
#endif // GRPCPP_SUPPORT_MESSAGE_ALLOCATOR_H

@ -104,6 +104,7 @@
<file baseinstalldir="/" name="src/core/lib/gpr/tmpfile.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/useful.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/abstract.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/arena.h" role="src" />
<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" />
@ -114,7 +115,6 @@
<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" />
<file baseinstalldir="/" name="src/core/lib/gpr/arena.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/atm.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/cpu_iphone.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/cpu_linux.cc" role="src" />
@ -147,6 +147,7 @@
<file baseinstalldir="/" name="src/core/lib/gpr/tmpfile_posix.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/tmpfile_windows.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/wrap_memcpy.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/arena.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/fork.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/thd_posix.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/thd_windows.cc" role="src" />
@ -332,6 +333,7 @@
<file baseinstalldir="/" name="src/core/lib/channel/handshaker_registry.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/channel/status_util.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/compression/algorithm_metadata.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/compression/compression_args.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/compression/compression_internal.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/compression/message_compress.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/compression/stream_compression.h" role="src" />
@ -351,12 +353,15 @@
<file baseinstalldir="/" name="src/core/lib/iomgr/block_annotate.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/buffer_list.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/call_combiner.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/cfstream_handle.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/closure.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/combiner.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/dynamic_annotations.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/endpoint.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/endpoint_cfstream.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/endpoint_pair.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/error.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/error_cfstream.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/error_internal.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/ev_epoll1_linux.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/ev_epollex_linux.h" role="src" />
@ -486,6 +491,7 @@
<file baseinstalldir="/" name="src/core/lib/channel/handshaker_registry.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/channel/status_util.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/compression/compression.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/compression/compression_args.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/compression/compression_internal.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/compression/message_compress.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/compression/stream_compression.cc" role="src" />
@ -498,12 +504,15 @@
<file baseinstalldir="/" name="src/core/lib/http/parser.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/buffer_list.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/call_combiner.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/cfstream_handle.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/combiner.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/endpoint.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/endpoint_cfstream.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/endpoint_pair_posix.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/endpoint_pair_uv.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/endpoint_pair_windows.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/error.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/error_cfstream.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/ev_epoll1_linux.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/ev_epollex_linux.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/ev_poll_posix.cc" role="src" />
@ -524,6 +533,7 @@
<file baseinstalldir="/" name="src/core/lib/iomgr/iomgr_custom.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/iomgr_internal.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/iomgr_posix.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/iomgr_posix_cfstream.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/iomgr_uv.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/iomgr_windows.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/is_epollexclusive_available.cc" role="src" />
@ -552,6 +562,7 @@
<file baseinstalldir="/" name="src/core/lib/iomgr/socket_utils_windows.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/socket_windows.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/tcp_client.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/tcp_client_cfstream.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/tcp_client_custom.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/tcp_client_posix.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/tcp_client_windows.cc" role="src" />

@ -84,7 +84,7 @@ void PrintIncludes(grpc_generator::Printer* printer,
}
grpc::string GetHeaderPrologue(grpc_generator::File* file,
const Parameters& /*params*/) {
const Parameters& params) {
grpc::string output;
{
// Scope the output stream so it closes and finalizes output to the string.
@ -94,7 +94,9 @@ grpc::string GetHeaderPrologue(grpc_generator::File* file,
vars["filename"] = file->filename();
vars["filename_identifier"] = FilenameIdentifier(file->filename());
vars["filename_base"] = file->filename_without_ext();
vars["message_header_ext"] = kCppGeneratorMessageHeaderExt;
vars["message_header_ext"] = params.message_header_extension.empty()
? kCppGeneratorMessageHeaderExt
: params.message_header_extension;
printer->Print(vars, "// Generated by the gRPC C++ plugin.\n");
printer->Print(vars,
@ -115,6 +117,13 @@ grpc::string GetHeaderPrologue(grpc_generator::File* file,
return output;
}
// Convert from "a/b/c.proto" to "#include \"a/b/c$message_header_ext$\"\n"
grpc::string ImportInludeFromProtoName(const grpc::string& proto_name) {
return grpc::string("#include \"") +
proto_name.substr(0, proto_name.size() - 6) +
grpc::string("$message_header_ext$\"\n");
}
grpc::string GetHeaderIncludes(grpc_generator::File* file,
const Parameters& params) {
grpc::string output;
@ -146,14 +155,34 @@ grpc::string GetHeaderIncludes(grpc_generator::File* file,
params.grpc_search_path);
printer->Print(vars, "\n");
printer->Print(vars, "namespace grpc_impl {\n");
printer->Print(vars, "class Channel;\n");
printer->Print(vars, "class CompletionQueue;\n");
printer->Print(vars, "class ServerCompletionQueue;\n");
printer->Print(vars, "} // namespace grpc_impl\n\n");
printer->Print(vars, "namespace grpc {\n");
printer->Print(vars, "class Channel;\n");
printer->Print(vars, "namespace experimental {\n");
printer->Print(vars, "template <typename RequestT, typename ResponseT>\n");
printer->Print(vars, "class MessageAllocator;\n");
printer->Print(vars, "} // namespace experimental\n");
printer->Print(vars, "} // namespace grpc_impl\n\n");
printer->Print(vars, "namespace grpc {\n");
printer->Print(vars, "class ServerContext;\n");
printer->Print(vars, "} // namespace grpc\n\n");
vars["message_header_ext"] = params.message_header_extension.empty()
? kCppGeneratorMessageHeaderExt
: params.message_header_extension;
if (params.include_import_headers) {
const std::vector<grpc::string> import_names = file->GetImportNames();
for (const auto& import_name : import_names) {
const grpc::string include_name =
ImportInludeFromProtoName(import_name);
printer->Print(vars, include_name.c_str());
}
printer->PrintRaw("\n");
}
if (!file->package().empty()) {
std::vector<grpc::string> parts = file->package_parts();
@ -586,6 +615,14 @@ void PrintHeaderClientMethodCallbackInterfaces(
"virtual void $Method$(::grpc::ClientContext* context, "
"const ::grpc::ByteBuffer* request, $Response$* response, "
"std::function<void(::grpc::Status)>) = 0;\n");
printer->Print(*vars,
"virtual void $Method$(::grpc::ClientContext* context, "
"const $Request$* request, $Response$* response, "
"::grpc::experimental::ClientUnaryReactor* reactor) = 0;\n");
printer->Print(*vars,
"virtual void $Method$(::grpc::ClientContext* context, "
"const ::grpc::ByteBuffer* request, $Response$* response, "
"::grpc::experimental::ClientUnaryReactor* reactor) = 0;\n");
} else if (ClientOnlyStreaming(method)) {
printer->Print(*vars,
"virtual void $Method$(::grpc::ClientContext* context, "
@ -652,6 +689,16 @@ void PrintHeaderClientMethodCallback(grpc_generator::Printer* printer,
"void $Method$(::grpc::ClientContext* context, "
"const ::grpc::ByteBuffer* request, $Response$* response, "
"std::function<void(::grpc::Status)>) override;\n");
printer->Print(
*vars,
"void $Method$(::grpc::ClientContext* context, "
"const $Request$* request, $Response$* response, "
"::grpc::experimental::ClientUnaryReactor* reactor) override;\n");
printer->Print(
*vars,
"void $Method$(::grpc::ClientContext* context, "
"const ::grpc::ByteBuffer* request, $Response$* response, "
"::grpc::experimental::ClientUnaryReactor* reactor) override;\n");
} else if (ClientOnlyStreaming(method)) {
printer->Print(*vars,
"void $Method$(::grpc::ClientContext* context, "
@ -972,7 +1019,15 @@ void PrintHeaderServerMethodCallback(
"controller) {\n"
" return this->$"
"Method$(context, request, response, controller);\n"
" }));\n");
" }));\n}\n");
printer->Print(*vars,
"void SetMessageAllocatorFor_$Method$(\n"
" ::grpc::experimental::MessageAllocator< "
"$RealRequest$, $RealResponse$>* allocator) {\n"
" static_cast<::grpc::internal::CallbackUnaryHandler< "
"$RealRequest$, $RealResponse$>*>(\n"
" ::grpc::Service::experimental().GetHandler($Idx$))\n"
" ->SetMessageAllocator(allocator);\n");
} else if (ClientOnlyStreaming(method)) {
printer->Print(
*vars,
@ -1558,7 +1613,7 @@ grpc::string GetHeaderEpilogue(grpc_generator::File* file,
}
grpc::string GetSourcePrologue(grpc_generator::File* file,
const Parameters& /*params*/) {
const Parameters& params) {
grpc::string output;
{
// Scope the output stream so it closes and finalizes output to the string.
@ -1567,7 +1622,9 @@ grpc::string GetSourcePrologue(grpc_generator::File* file,
vars["filename"] = file->filename();
vars["filename_base"] = file->filename_without_ext();
vars["message_header_ext"] = kCppGeneratorMessageHeaderExt;
vars["message_header_ext"] = params.message_header_extension.empty()
? kCppGeneratorMessageHeaderExt
: params.message_header_extension;
vars["service_header_ext"] = kCppGeneratorServiceHeaderExt;
printer->Print(vars, "// Generated by the gRPC C++ plugin.\n");
@ -1589,7 +1646,6 @@ grpc::string GetSourceIncludes(grpc_generator::File* file,
// Scope the output stream so it closes and finalizes output to the string.
auto printer = file->CreatePrinter(&output);
std::map<grpc::string, grpc::string> vars;
static const char* headers_strs[] = {
"functional",
"grpcpp/impl/codegen/async_stream.h",
@ -1649,7 +1705,7 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer,
"const $Request$* request, $Response$* response, "
"std::function<void(::grpc::Status)> f) {\n");
printer->Print(*vars,
" return ::grpc::internal::CallbackUnaryCall"
" ::grpc::internal::CallbackUnaryCall"
"(stub_->channel_.get(), stub_->rpcmethod_$Method$_, "
"context, request, response, std::move(f));\n}\n\n");
@ -1659,10 +1715,30 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer,
"const ::grpc::ByteBuffer* request, $Response$* response, "
"std::function<void(::grpc::Status)> f) {\n");
printer->Print(*vars,
" return ::grpc::internal::CallbackUnaryCall"
" ::grpc::internal::CallbackUnaryCall"
"(stub_->channel_.get(), stub_->rpcmethod_$Method$_, "
"context, request, response, std::move(f));\n}\n\n");
printer->Print(*vars,
"void $ns$$Service$::Stub::experimental_async::$Method$("
"::grpc::ClientContext* context, "
"const $Request$* request, $Response$* response, "
"::grpc::experimental::ClientUnaryReactor* reactor) {\n");
printer->Print(*vars,
" ::grpc::internal::ClientCallbackUnaryFactory::Create"
"(stub_->channel_.get(), stub_->rpcmethod_$Method$_, "
"context, request, response, reactor);\n}\n\n");
printer->Print(*vars,
"void $ns$$Service$::Stub::experimental_async::$Method$("
"::grpc::ClientContext* context, "
"const ::grpc::ByteBuffer* request, $Response$* response, "
"::grpc::experimental::ClientUnaryReactor* reactor) {\n");
printer->Print(*vars,
" ::grpc::internal::ClientCallbackUnaryFactory::Create"
"(stub_->channel_.get(), stub_->rpcmethod_$Method$_, "
"context, request, response, reactor);\n}\n\n");
for (auto async_prefix : async_prefixes) {
(*vars)["AsyncPrefix"] = async_prefix.prefix;
(*vars)["AsyncStart"] = async_prefix.start;
@ -2048,7 +2124,7 @@ grpc::string GetSourceEpilogue(grpc_generator::File* file,
// TODO(mmukhi): Make sure we need parameters or not.
grpc::string GetMockPrologue(grpc_generator::File* file,
const Parameters& /*params*/) {
const Parameters& params) {
grpc::string output;
{
// Scope the output stream so it closes and finalizes output to the string.
@ -2057,7 +2133,9 @@ grpc::string GetMockPrologue(grpc_generator::File* file,
vars["filename"] = file->filename();
vars["filename_base"] = file->filename_without_ext();
vars["message_header_ext"] = kCppGeneratorMessageHeaderExt;
vars["message_header_ext"] = params.message_header_extension.empty()
? kCppGeneratorMessageHeaderExt
: params.message_header_extension;
vars["service_header_ext"] = kCppGeneratorServiceHeaderExt;
printer->Print(vars, "// Generated by the gRPC C++ plugin.\n");
@ -2067,6 +2145,15 @@ grpc::string GetMockPrologue(grpc_generator::File* file,
printer->Print(vars, "#include \"$filename_base$$message_header_ext$\"\n");
printer->Print(vars, "#include \"$filename_base$$service_header_ext$\"\n");
if (params.include_import_headers) {
const std::vector<grpc::string> import_names = file->GetImportNames();
for (const auto& import_name : import_names) {
const grpc::string include_name =
ImportInludeFromProtoName(import_name);
printer->Print(vars, include_name.c_str());
}
printer->PrintRaw("\n");
}
printer->Print(vars, file->additional_headers().c_str());
printer->Print(vars, "\n");
}

@ -56,6 +56,10 @@ struct Parameters {
grpc::string gmock_search_path;
// *EXPERIMENTAL* Additional include files in grpc.pb.h
std::vector<grpc::string> additional_header_includes;
// By default, use "pb.h"
grpc::string message_header_extension;
// Whether to include headers corresponding to imports in source file.
bool include_import_headers;
};
// Return the prologue of the generated header file.

@ -48,6 +48,7 @@ class CppGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
grpc_cpp_generator::Parameters generator_parameters;
generator_parameters.use_system_headers = true;
generator_parameters.generate_mock_code = false;
generator_parameters.include_import_headers = false;
ProtoBufFile pbfile(file);
@ -83,6 +84,15 @@ class CppGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
} else if (param[0] == "additional_header_includes") {
generator_parameters.additional_header_includes =
grpc_generator::tokenize(param[1], ":");
} else if (param[0] == "message_header_extension") {
generator_parameters.message_header_extension = param[1];
} else if (param[0] == "include_import_headers") {
if (param[1] == "true") {
generator_parameters.include_import_headers = true;
} else if (param[1] != "false") {
*error = grpc::string("Invalid parameter: ") + *parameter_string;
return false;
}
} else {
*error = grpc::string("Unknown parameter: ") + *parameter_string;
return false;

@ -50,7 +50,8 @@ void PrintProtoRpcDeclarationAsPragma(
}
template <typename DescriptorType>
static void PrintAllComments(const DescriptorType* desc, Printer* printer) {
static void PrintAllComments(const DescriptorType* desc, Printer* printer,
bool deprecated = false) {
std::vector<grpc::string> comments;
grpc_generator::GetComment(desc, grpc_generator::COMMENTTYPE_LEADING_DETACHED,
&comments);
@ -70,17 +71,20 @@ 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");
if (deprecated) {
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");
}
void PrintMethodSignature(Printer* printer, const MethodDescriptor* method,
const map< ::grpc::string, ::grpc::string>& vars) {
// Print comment
PrintAllComments(method, printer);
PrintAllComments(method, printer, true);
printer->Print(vars, "- ($return_type$)$method_name$With");
if (method->client_streaming()) {

@ -55,22 +55,23 @@ class ProtoBufMethod : public grpc_generator::Method {
return method_->output_type()->file()->name();
}
bool get_module_and_message_path_input(grpc::string* str,
grpc::string generator_file_name,
bool generate_in_pb2_grpc,
grpc::string import_prefix) const {
// TODO(https://github.com/grpc/grpc/issues/18800): Clean this up.
bool get_module_and_message_path_input(
grpc::string* str, grpc::string generator_file_name,
bool generate_in_pb2_grpc, grpc::string import_prefix,
const std::vector<grpc::string>& prefixes_to_filter) const final {
return grpc_python_generator::GetModuleAndMessagePath(
method_->input_type(), str, generator_file_name, generate_in_pb2_grpc,
import_prefix);
import_prefix, prefixes_to_filter);
}
bool get_module_and_message_path_output(grpc::string* str,
grpc::string generator_file_name,
bool generate_in_pb2_grpc,
grpc::string import_prefix) const {
bool get_module_and_message_path_output(
grpc::string* str, grpc::string generator_file_name,
bool generate_in_pb2_grpc, grpc::string import_prefix,
const std::vector<grpc::string>& prefixes_to_filter) const final {
return grpc_python_generator::GetModuleAndMessagePath(
method_->output_type(), str, generator_file_name, generate_in_pb2_grpc,
import_prefix);
import_prefix, prefixes_to_filter);
}
bool NoStreaming() const {
@ -189,6 +190,15 @@ class ProtoBufFile : public grpc_generator::File {
return grpc_python_generator::get_all_comments(file_);
}
vector<grpc::string> GetImportNames() const {
vector<grpc::string> proto_names;
for (int i = 0; i < file_->dependency_count(); ++i) {
const auto& dep = *file_->dependency(i);
proto_names.push_back(dep.name());
}
return proto_names;
}
private:
const grpc::protobuf::FileDescriptor* file_;
};

@ -214,13 +214,15 @@ bool PrivateGenerator::PrintBetaServerFactory(
grpc::string input_message_module_and_class;
if (!method->get_module_and_message_path_input(
&input_message_module_and_class, generator_file_name,
generate_in_pb2_grpc, config.import_prefix)) {
generate_in_pb2_grpc, config.import_prefix,
config.prefixes_to_filter)) {
return false;
}
grpc::string output_message_module_and_class;
if (!method->get_module_and_message_path_output(
&output_message_module_and_class, generator_file_name,
generate_in_pb2_grpc, config.import_prefix)) {
generate_in_pb2_grpc, config.import_prefix,
config.prefixes_to_filter)) {
return false;
}
method_implementation_constructors.insert(
@ -320,13 +322,15 @@ bool PrivateGenerator::PrintBetaStubFactory(
grpc::string input_message_module_and_class;
if (!method->get_module_and_message_path_input(
&input_message_module_and_class, generator_file_name,
generate_in_pb2_grpc, config.import_prefix)) {
generate_in_pb2_grpc, config.import_prefix,
config.prefixes_to_filter)) {
return false;
}
grpc::string output_message_module_and_class;
if (!method->get_module_and_message_path_output(
&output_message_module_and_class, generator_file_name,
generate_in_pb2_grpc, config.import_prefix)) {
generate_in_pb2_grpc, config.import_prefix,
config.prefixes_to_filter)) {
return false;
}
method_cardinalities.insert(
@ -425,13 +429,15 @@ bool PrivateGenerator::PrintStub(
grpc::string request_module_and_class;
if (!method->get_module_and_message_path_input(
&request_module_and_class, generator_file_name,
generate_in_pb2_grpc, config.import_prefix)) {
generate_in_pb2_grpc, config.import_prefix,
config.prefixes_to_filter)) {
return false;
}
grpc::string response_module_and_class;
if (!method->get_module_and_message_path_output(
&response_module_and_class, generator_file_name,
generate_in_pb2_grpc, config.import_prefix)) {
generate_in_pb2_grpc, config.import_prefix,
config.prefixes_to_filter)) {
return false;
}
StringMap method_dict;
@ -516,13 +522,15 @@ bool PrivateGenerator::PrintAddServicerToServer(
grpc::string request_module_and_class;
if (!method->get_module_and_message_path_input(
&request_module_and_class, generator_file_name,
generate_in_pb2_grpc, config.import_prefix)) {
generate_in_pb2_grpc, config.import_prefix,
config.prefixes_to_filter)) {
return false;
}
grpc::string response_module_and_class;
if (!method->get_module_and_message_path_output(
&response_module_and_class, generator_file_name,
generate_in_pb2_grpc, config.import_prefix)) {
generate_in_pb2_grpc, config.import_prefix,
config.prefixes_to_filter)) {
return false;
}
StringMap method_dict;
@ -589,17 +597,21 @@ bool PrivateGenerator::PrintPreamble(grpc_generator::Printer* out) {
grpc::string input_type_file_name = method->get_input_type_name();
grpc::string input_module_name =
ModuleName(input_type_file_name, config.import_prefix);
ModuleName(input_type_file_name, config.import_prefix,
config.prefixes_to_filter);
grpc::string input_module_alias =
ModuleAlias(input_type_file_name, config.import_prefix);
ModuleAlias(input_type_file_name, config.import_prefix,
config.prefixes_to_filter);
imports_set.insert(
std::make_tuple(input_module_name, input_module_alias));
grpc::string output_type_file_name = method->get_output_type_name();
grpc::string output_module_name =
ModuleName(output_type_file_name, config.import_prefix);
ModuleName(output_type_file_name, config.import_prefix,
config.prefixes_to_filter);
grpc::string output_module_alias =
ModuleAlias(output_type_file_name, config.import_prefix);
ModuleAlias(output_type_file_name, config.import_prefix,
config.prefixes_to_filter);
imports_set.insert(
std::make_tuple(output_module_name, output_module_alias));
}

@ -20,6 +20,7 @@
#define GRPC_INTERNAL_COMPILER_PYTHON_GENERATOR_H
#include <utility>
#include <vector>
#include "src/compiler/config.h"
#include "src/compiler/schema_interface.h"
@ -35,6 +36,7 @@ struct GeneratorConfiguration {
grpc::string beta_package_root;
// TODO(https://github.com/google/protobuf/issues/888): Drop this.
grpc::string import_prefix;
std::vector<grpc::string> prefixes_to_filter;
};
class PythonGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {

@ -49,23 +49,39 @@ namespace {
typedef vector<const Descriptor*> DescriptorVector;
typedef vector<grpc::string> StringVector;
static grpc::string StripModulePrefixes(
const grpc::string& raw_module_name,
const std::vector<grpc::string>& prefixes_to_filter) {
for (const auto& prefix : prefixes_to_filter) {
if (raw_module_name.rfind(prefix, 0) == 0) {
return raw_module_name.substr(prefix.size(),
raw_module_name.size() - prefix.size());
}
}
return raw_module_name;
}
// TODO(https://github.com/google/protobuf/issues/888):
// Export `ModuleName` from protobuf's
// `src/google/protobuf/compiler/python/python_generator.cc` file.
grpc::string ModuleName(const grpc::string& filename,
const grpc::string& import_prefix) {
const grpc::string& import_prefix,
const std::vector<grpc::string>& prefixes_to_filter) {
grpc::string basename = StripProto(filename);
basename = StringReplace(basename, "-", "_");
basename = StringReplace(basename, "/", ".");
return import_prefix + basename + "_pb2";
return StripModulePrefixes(import_prefix + basename + "_pb2",
prefixes_to_filter);
}
// TODO(https://github.com/google/protobuf/issues/888):
// Export `ModuleAlias` from protobuf's
// `src/google/protobuf/compiler/python/python_generator.cc` file.
grpc::string ModuleAlias(const grpc::string& filename,
const grpc::string& import_prefix) {
grpc::string module_name = ModuleName(filename, import_prefix);
const grpc::string& import_prefix,
const std::vector<grpc::string>& prefixes_to_filter) {
grpc::string module_name =
ModuleName(filename, import_prefix, prefixes_to_filter);
// We can't have dots in the module name, so we replace each with _dot_.
// But that could lead to a collision between a.b and a_dot_b, so we also
// duplicate each underscore.
@ -74,10 +90,10 @@ grpc::string ModuleAlias(const grpc::string& filename,
return module_name;
}
bool GetModuleAndMessagePath(const Descriptor* type, grpc::string* out,
grpc::string generator_file_name,
bool generate_in_pb2_grpc,
grpc::string& import_prefix) {
bool GetModuleAndMessagePath(
const Descriptor* type, grpc::string* out, grpc::string generator_file_name,
bool generate_in_pb2_grpc, grpc::string& import_prefix,
const std::vector<grpc::string>& prefixes_to_filter) {
const Descriptor* path_elem_type = type;
DescriptorVector message_path;
do {
@ -93,7 +109,7 @@ bool GetModuleAndMessagePath(const Descriptor* type, grpc::string* out,
grpc::string module;
if (generator_file_name != file_name || generate_in_pb2_grpc) {
module = ModuleAlias(file_name, import_prefix) + ".";
module = ModuleAlias(file_name, import_prefix, prefixes_to_filter) + ".";
} else {
module = "";
}

@ -57,10 +57,12 @@ struct Method : public CommentHolder {
virtual bool get_module_and_message_path_input(
grpc::string* str, grpc::string generator_file_name,
bool generate_in_pb2_grpc, grpc::string import_prefix) const = 0;
bool generate_in_pb2_grpc, grpc::string import_prefix,
const std::vector<grpc::string>& prefixes_to_filter) const = 0;
virtual bool get_module_and_message_path_output(
grpc::string* str, grpc::string generator_file_name,
bool generate_in_pb2_grpc, grpc::string import_prefix) const = 0;
bool generate_in_pb2_grpc, grpc::string import_prefix,
const std::vector<grpc::string>& prefixes_to_filter) const = 0;
virtual grpc::string get_input_type_name() const = 0;
virtual grpc::string get_output_type_name() const = 0;
@ -101,6 +103,7 @@ struct File : public CommentHolder {
virtual grpc::string package() const = 0;
virtual std::vector<grpc::string> package_parts() const = 0;
virtual grpc::string additional_headers() const = 0;
virtual std::vector<grpc::string> GetImportNames() const { return {}; }
virtual int service_count() const = 0;
virtual std::unique_ptr<const Service> service(int i) const = 0;

File diff suppressed because it is too large Load Diff

@ -49,8 +49,8 @@ ClientChannelNode::ClientChannelNode(grpc_channel* channel,
: ChannelNode(channel, channel_tracer_max_nodes, is_top_level_channel) {
client_channel_ =
grpc_channel_stack_last_element(grpc_channel_get_channel_stack(channel));
grpc_client_channel_set_channelz_node(client_channel_, this);
GPR_ASSERT(client_channel_->filter == &grpc_client_channel_filter);
grpc_client_channel_set_channelz_node(client_channel_, this);
}
void ClientChannelNode::PopulateConnectivityState(grpc_json* json) {
@ -127,8 +127,7 @@ void SubchannelNode::PopulateConnectivityState(grpc_json* json) {
if (subchannel_ == nullptr) {
state = GRPC_CHANNEL_SHUTDOWN;
} else {
state = subchannel_->CheckConnectivity(nullptr,
true /* inhibit_health_checking */);
state = subchannel_->CheckConnectivity(true /* inhibit_health_checking */);
}
json = grpc_json_create_child(nullptr, json, "state", nullptr,
GRPC_JSON_OBJECT, false);

@ -32,6 +32,7 @@
#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
#include "src/core/ext/filters/client_channel/proxy_mapper_registry.h"
#include "src/core/ext/filters/client_channel/resolver_registry.h"
#include "src/core/ext/filters/client_channel/resolver_result_parsing.h"
#include "src/core/ext/filters/client_channel/retry_throttle.h"
#include "src/core/lib/surface/channel_init.h"
@ -50,6 +51,7 @@ static bool append_filter(grpc_channel_stack_builder* builder, void* arg) {
void grpc_client_channel_init(void) {
grpc_core::ServiceConfig::Init();
grpc_core::internal::ClientChannelServiceConfigParser::Register();
grpc_core::LoadBalancingPolicyRegistry::Builder::InitRegistry();
grpc_core::ResolverRegistry::Builder::InitRegistry();
grpc_core::internal::ServerRetryThrottleMap::Init();

@ -37,11 +37,10 @@
#define HEALTH_CHECK_RECONNECT_MAX_BACKOFF_SECONDS 120
#define HEALTH_CHECK_RECONNECT_JITTER 0.2
grpc_core::TraceFlag grpc_health_check_client_trace(false,
"health_check_client");
namespace grpc_core {
TraceFlag grpc_health_check_client_trace(false, "health_check_client");
//
// HealthCheckClient
//
@ -50,7 +49,7 @@ HealthCheckClient::HealthCheckClient(
const char* service_name,
RefCountedPtr<ConnectedSubchannel> connected_subchannel,
grpc_pollset_set* interested_parties,
grpc_core::RefCountedPtr<grpc_core::channelz::SubchannelNode> channelz_node)
RefCountedPtr<channelz::SubchannelNode> channelz_node)
: InternallyRefCounted<HealthCheckClient>(&grpc_health_check_client_trace),
service_name_(service_name),
connected_subchannel_(std::move(connected_subchannel)),
@ -281,11 +280,9 @@ HealthCheckClient::CallState::CallState(
: InternallyRefCounted<CallState>(&grpc_health_check_client_trace),
health_check_client_(std::move(health_check_client)),
pollent_(grpc_polling_entity_create_from_pollset_set(interested_parties)),
arena_(gpr_arena_create(health_check_client_->connected_subchannel_
->GetInitialCallSizeEstimate(0))),
payload_(context_) {
grpc_call_combiner_init(&call_combiner_);
}
arena_(Arena::Create(health_check_client_->connected_subchannel_
->GetInitialCallSizeEstimate(0))),
payload_(context_) {}
HealthCheckClient::CallState::~CallState() {
if (grpc_health_check_client_trace.enabled()) {
@ -303,14 +300,13 @@ HealthCheckClient::CallState::~CallState() {
// holding to the call stack. Also flush the closures on exec_ctx so that
// filters that schedule cancel notification closures on exec_ctx do not
// need to take a ref of the call stack to guarantee closure liveness.
grpc_call_combiner_set_notify_on_cancel(&call_combiner_, nullptr);
grpc_core::ExecCtx::Get()->Flush();
grpc_call_combiner_destroy(&call_combiner_);
gpr_arena_destroy(arena_);
call_combiner_.SetNotifyOnCancel(nullptr);
ExecCtx::Get()->Flush();
arena_->Destroy();
}
void HealthCheckClient::CallState::Orphan() {
grpc_call_combiner_cancel(&call_combiner_, GRPC_ERROR_CANCELLED);
call_combiner_.Cancel(GRPC_ERROR_CANCELLED);
Cancel();
}

@ -27,7 +27,7 @@
#include "src/core/ext/filters/client_channel/client_channel_channelz.h"
#include "src/core/ext/filters/client_channel/subchannel.h"
#include "src/core/lib/backoff/backoff.h"
#include "src/core/lib/gpr/arena.h"
#include "src/core/lib/gprpp/arena.h"
#include "src/core/lib/gprpp/atomic.h"
#include "src/core/lib/gprpp/orphanable.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
@ -97,8 +97,8 @@ class HealthCheckClient : public InternallyRefCounted<HealthCheckClient> {
RefCountedPtr<HealthCheckClient> health_check_client_;
grpc_polling_entity pollent_;
gpr_arena* arena_;
grpc_call_combiner call_combiner_;
Arena* arena_;
grpc_core::CallCombiner call_combiner_;
grpc_call_context_element context_[GRPC_CONTEXT_COUNT] = {};
// The streaming call to the backend. Always non-NULL.

@ -25,7 +25,7 @@
/// Channel arg indicating HTTP CONNECT headers (string).
/// Multiple headers are separated by newlines. Key/value pairs are
/// seperated by colons.
/// separated by colons.
#define GRPC_ARG_HTTP_CONNECT_HEADERS "grpc.http_connect_headers"
/// Registers handshaker factory.

@ -62,32 +62,6 @@ void LoadBalancingPolicy::ShutdownAndUnrefLocked(void* arg,
policy->Unref();
}
grpc_json* LoadBalancingPolicy::ParseLoadBalancingConfig(
const grpc_json* lb_config_array) {
if (lb_config_array == nullptr || lb_config_array->type != GRPC_JSON_ARRAY) {
return nullptr;
}
// Find the first LB policy that this client supports.
for (const grpc_json* lb_config = lb_config_array->child;
lb_config != nullptr; lb_config = lb_config->next) {
if (lb_config->type != GRPC_JSON_OBJECT) return nullptr;
grpc_json* policy = nullptr;
for (grpc_json* field = lb_config->child; field != nullptr;
field = field->next) {
if (field->key == nullptr || field->type != GRPC_JSON_OBJECT)
return nullptr;
if (policy != nullptr) return nullptr; // Violate "oneof" type.
policy = field;
}
if (policy == nullptr) return nullptr;
// If we support this policy, then select it.
if (LoadBalancingPolicyRegistry::LoadBalancingPolicyExists(policy->key)) {
return policy;
}
}
return nullptr;
}
//
// LoadBalancingPolicy::UpdateArgs
//

@ -36,6 +36,18 @@ extern grpc_core::DebugOnlyTraceFlag grpc_trace_lb_policy_refcount;
namespace grpc_core {
/// Interface for parsed forms of load balancing configs found in a service
/// config.
class ParsedLoadBalancingConfig : public RefCounted<ParsedLoadBalancingConfig> {
public:
virtual ~ParsedLoadBalancingConfig() = default;
// Returns the load balancing policy name
virtual const char* name() const GRPC_ABSTRACT;
GRPC_ABSTRACT_BASE_CLASS;
};
/// Interface for load balancing policies.
///
/// The following concepts are used here:
@ -167,6 +179,9 @@ class LoadBalancingPolicy : public InternallyRefCounted<LoadBalancingPolicy> {
/// A proxy object used by the LB policy to communicate with the client
/// channel.
// TODO(juanlishen): Consider adding a mid-layer subclass that helps handle
// things like swapping in pending policy when it's ready. Currently, we are
// duplicating the logic in many subclasses.
class ChannelControlHelper {
public:
ChannelControlHelper() = default;
@ -185,7 +200,6 @@ class LoadBalancingPolicy : public InternallyRefCounted<LoadBalancingPolicy> {
/// Sets the connectivity state and returns a new picker to be used
/// by the client channel.
virtual void UpdateState(grpc_connectivity_state state,
grpc_error* state_error,
UniquePtr<SubchannelPicker>) GRPC_ABSTRACT;
/// Requests that the resolver re-resolve.
@ -194,30 +208,11 @@ class LoadBalancingPolicy : public InternallyRefCounted<LoadBalancingPolicy> {
GRPC_ABSTRACT_BASE_CLASS
};
/// Configuration for an LB policy instance.
// TODO(roth): Find a better JSON representation for this API.
class Config : public RefCounted<Config> {
public:
Config(const grpc_json* lb_config,
RefCountedPtr<ServiceConfig> service_config)
: json_(lb_config), service_config_(std::move(service_config)) {}
const char* name() const { return json_->key; }
const grpc_json* config() const { return json_->child; }
RefCountedPtr<ServiceConfig> service_config() const {
return service_config_;
}
private:
const grpc_json* json_;
RefCountedPtr<ServiceConfig> service_config_;
};
/// Data passed to the UpdateLocked() method when new addresses and
/// config are available.
struct UpdateArgs {
ServerAddressList addresses;
RefCountedPtr<Config> config;
RefCountedPtr<ParsedLoadBalancingConfig> config;
const grpc_channel_args* args = nullptr;
// TODO(roth): Remove everything below once channel args is
@ -288,10 +283,6 @@ class LoadBalancingPolicy : public InternallyRefCounted<LoadBalancingPolicy> {
void Orphan() override;
/// Returns the JSON node of policy (with both policy name and config content)
/// given the JSON node of a LoadBalancingConfig array.
static grpc_json* ParseLoadBalancingConfig(const grpc_json* lb_config_array);
// A picker that returns PICK_QUEUE for all picks.
// Also calls the parent LB policy's ExitIdleLocked() method when the
// first pick is seen.

@ -118,6 +118,21 @@ namespace {
constexpr char kGrpclb[] = "grpclb";
class ParsedGrpcLbConfig : public ParsedLoadBalancingConfig {
public:
explicit ParsedGrpcLbConfig(
RefCountedPtr<ParsedLoadBalancingConfig> child_policy)
: child_policy_(std::move(child_policy)) {}
const char* name() const override { return kGrpclb; }
RefCountedPtr<ParsedLoadBalancingConfig> child_policy() const {
return child_policy_;
}
private:
RefCountedPtr<ParsedLoadBalancingConfig> child_policy_;
};
class GrpcLb : public LoadBalancingPolicy {
public:
explicit GrpcLb(Args args);
@ -281,7 +296,7 @@ class GrpcLb : public LoadBalancingPolicy {
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,
void UpdateState(grpc_connectivity_state state,
UniquePtr<SubchannelPicker> picker) override;
void RequestReresolution() override;
@ -302,7 +317,6 @@ class GrpcLb : public LoadBalancingPolicy {
// Helper functions used in UpdateLocked().
void ProcessAddressesAndChannelArgsLocked(const ServerAddressList& addresses,
const grpc_channel_args& args);
void ParseLbConfig(Config* grpclb_config);
static void OnBalancerChannelConnectivityChangedLocked(void* arg,
grpc_error* error);
void CancelBalancerChannelConnectivityWatchLocked();
@ -380,7 +394,7 @@ class GrpcLb : public LoadBalancingPolicy {
// until it reports READY, at which point it will be moved to child_policy_.
OrphanablePtr<LoadBalancingPolicy> pending_child_policy_;
// The child policy config.
RefCountedPtr<Config> child_policy_config_;
RefCountedPtr<ParsedLoadBalancingConfig> child_policy_config_;
// Child policy in state READY.
bool child_policy_ready_ = false;
};
@ -621,12 +635,8 @@ grpc_channel* GrpcLb::Helper::CreateChannel(const char* target,
}
void GrpcLb::Helper::UpdateState(grpc_connectivity_state state,
grpc_error* state_error,
UniquePtr<SubchannelPicker> picker) {
if (parent_->shutting_down_) {
GRPC_ERROR_UNREF(state_error);
return;
}
if (parent_->shutting_down_) 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()) {
@ -636,10 +646,7 @@ void GrpcLb::Helper::UpdateState(grpc_connectivity_state state,
parent_.get(), this, parent_->pending_child_policy_.get(),
grpc_connectivity_state_name(state));
}
if (state != GRPC_CHANNEL_READY) {
GRPC_ERROR_UNREF(state_error);
return;
}
if (state != GRPC_CHANNEL_READY) return;
grpc_pollset_set_del_pollset_set(
parent_->child_policy_->interested_parties(),
parent_->interested_parties());
@ -647,7 +654,6 @@ void GrpcLb::Helper::UpdateState(grpc_connectivity_state state,
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;
}
// Record whether child policy reports READY.
@ -682,8 +688,7 @@ void GrpcLb::Helper::UpdateState(grpc_connectivity_state state,
parent_.get(), this, grpc_connectivity_state_name(state),
picker.get());
}
parent_->channel_control_helper()->UpdateState(state, state_error,
std::move(picker));
parent_->channel_control_helper()->UpdateState(state, std::move(picker));
return;
}
// Cases 2 and 3a: wrap picker from the child in our own picker.
@ -698,10 +703,9 @@ void GrpcLb::Helper::UpdateState(grpc_connectivity_state state,
client_stats = parent_->lb_calld_->client_stats()->Ref();
}
parent_->channel_control_helper()->UpdateState(
state, state_error,
UniquePtr<SubchannelPicker>(
New<Picker>(parent_.get(), parent_->serverlist_, std::move(picker),
std::move(client_stats))));
state, UniquePtr<SubchannelPicker>(
New<Picker>(parent_.get(), parent_->serverlist_,
std::move(picker), std::move(client_stats))));
}
void GrpcLb::Helper::RequestReresolution() {
@ -1139,13 +1143,13 @@ void GrpcLb::BalancerCallState::OnBalancerStatusReceivedLocked(
// we want to retry connecting. Otherwise, we have deliberately ended this
// call and no further action is required.
if (lb_calld == grpclb_policy->lb_calld_.get()) {
// If we did not receive a serverlist and the fallback-at-startup checks
// are pending, go into fallback mode immediately. This short-circuits
// the timeout for the fallback-at-startup case.
if (!lb_calld->seen_serverlist_ &&
grpclb_policy->fallback_at_startup_checks_pending_) {
// If the fallback-at-startup checks are pending, go into fallback mode
// immediately. This short-circuits the timeout for the fallback-at-startup
// case.
if (grpclb_policy->fallback_at_startup_checks_pending_) {
GPR_ASSERT(!lb_calld->seen_serverlist_);
gpr_log(GPR_INFO,
"[grpclb %p] balancer call finished without receiving "
"[grpclb %p] Balancer call finished without receiving "
"serverlist; entering fallback mode",
grpclb_policy);
grpclb_policy->fallback_at_startup_checks_pending_ = false;
@ -1383,7 +1387,13 @@ void GrpcLb::FillChildRefsForChannelz(
void GrpcLb::UpdateLocked(UpdateArgs args) {
const bool is_initial_update = lb_channel_ == nullptr;
ParseLbConfig(args.config.get());
auto* grpclb_config =
static_cast<const ParsedGrpcLbConfig*>(args.config.get());
if (grpclb_config != nullptr) {
child_policy_config_ = grpclb_config->child_policy();
} else {
child_policy_config_ = nullptr;
}
ProcessAddressesAndChannelArgsLocked(args.addresses, *args.args);
// Update the existing child policy.
if (child_policy_ != nullptr) CreateOrUpdateChildPolicyLocked();
@ -1472,27 +1482,6 @@ void GrpcLb::ProcessAddressesAndChannelArgsLocked(
response_generator_->SetResponse(std::move(result));
}
void GrpcLb::ParseLbConfig(Config* grpclb_config) {
const grpc_json* child_policy = nullptr;
if (grpclb_config != nullptr) {
const grpc_json* grpclb_config_json = grpclb_config->config();
for (const grpc_json* field = grpclb_config_json; field != nullptr;
field = field->next) {
if (field->key == nullptr) return;
if (strcmp(field->key, "childPolicy") == 0) {
if (child_policy != nullptr) return; // Duplicate.
child_policy = ParseLoadBalancingConfig(field);
}
}
}
if (child_policy != nullptr) {
child_policy_config_ =
MakeRefCounted<Config>(child_policy, grpclb_config->service_config());
} else {
child_policy_config_.reset();
}
}
void GrpcLb::OnBalancerChannelConnectivityChangedLocked(void* arg,
grpc_error* error) {
GrpcLb* self = static_cast<GrpcLb*>(arg);
@ -1638,20 +1627,16 @@ void GrpcLb::OnFallbackTimerLocked(void* arg, grpc_error* error) {
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(
const_cast<char*>(
GRPC_ARG_ADDRESS_IS_BACKEND_FROM_GRPCLB_LOAD_BALANCER),
is_backend_from_grpclb_load_balancer),
};
size_t num_args_to_add = 1;
InlinedVector<grpc_arg, 2> args_to_add;
args_to_add.emplace_back(grpc_channel_arg_integer_create(
const_cast<char*>(GRPC_ARG_ADDRESS_IS_BACKEND_FROM_GRPCLB_LOAD_BALANCER),
is_backend_from_grpclb_load_balancer));
if (is_backend_from_grpclb_load_balancer) {
args_to_add[num_args_to_add++] = grpc_channel_arg_integer_create(
const_cast<char*>(GRPC_ARG_INHIBIT_HEALTH_CHECKING), 1);
args_to_add.emplace_back(grpc_channel_arg_integer_create(
const_cast<char*>(GRPC_ARG_INHIBIT_HEALTH_CHECKING), 1));
}
return grpc_channel_args_copy_and_add(args_, args_to_add, num_args_to_add);
return grpc_channel_args_copy_and_add(args_, args_to_add.data(),
args_to_add.size());
}
OrphanablePtr<LoadBalancingPolicy> GrpcLb::CreateChildPolicyLocked(
@ -1814,6 +1799,40 @@ class GrpcLbFactory : public LoadBalancingPolicyFactory {
}
const char* name() const override { return kGrpclb; }
RefCountedPtr<ParsedLoadBalancingConfig> ParseLoadBalancingConfig(
const grpc_json* json, grpc_error** error) const override {
GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE);
if (json == nullptr) {
return RefCountedPtr<ParsedLoadBalancingConfig>(
New<ParsedGrpcLbConfig>(nullptr));
}
InlinedVector<grpc_error*, 2> error_list;
RefCountedPtr<ParsedLoadBalancingConfig> child_policy;
for (const grpc_json* field = json->child; field != nullptr;
field = field->next) {
if (field->key == nullptr) continue;
if (strcmp(field->key, "childPolicy") == 0) {
if (child_policy != nullptr) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:childPolicy error:Duplicate entry"));
}
grpc_error* parse_error = GRPC_ERROR_NONE;
child_policy = LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(
field, &parse_error);
if (parse_error != GRPC_ERROR_NONE) {
error_list.push_back(parse_error);
}
}
}
if (error_list.empty()) {
return RefCountedPtr<ParsedLoadBalancingConfig>(
New<ParsedGrpcLbConfig>(std::move(child_policy)));
} else {
*error = GRPC_ERROR_CREATE_FROM_VECTOR("GrpcLb Parser", &error_list);
return nullptr;
}
}
};
} // namespace

@ -73,7 +73,7 @@ class PickFirst : public LoadBalancingPolicy {
: SubchannelData(subchannel_list, address, subchannel, combiner) {}
void ProcessConnectivityChangeLocked(
grpc_connectivity_state connectivity_state, grpc_error* error) override;
grpc_connectivity_state connectivity_state) override;
// Processes the connectivity change to READY for an unselected subchannel.
void ProcessUnselectedReadyLocked();
@ -189,10 +189,11 @@ void PickFirst::ExitIdleLocked() {
idle_ = false;
if (subchannel_list_ == nullptr ||
subchannel_list_->num_subchannels() == 0) {
grpc_error* error =
GRPC_ERROR_CREATE_FROM_STATIC_STRING("No addresses to connect to");
grpc_error* error = grpc_error_set_int(
GRPC_ERROR_CREATE_FROM_STATIC_STRING("No addresses to connect to"),
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
channel_control_helper()->UpdateState(
GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error),
GRPC_CHANNEL_TRANSIENT_FAILURE,
UniquePtr<SubchannelPicker>(New<TransientFailurePicker>(error)));
} else {
subchannel_list_->subchannel(0)
@ -266,9 +267,11 @@ void PickFirst::UpdateLocked(UpdateArgs args) {
// 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");
grpc_error* error = grpc_error_set_int(
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"),
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
channel_control_helper()->UpdateState(
GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error),
GRPC_CHANNEL_TRANSIENT_FAILURE,
UniquePtr<SubchannelPicker>(New<TransientFailurePicker>(error)));
}
return;
@ -282,9 +285,7 @@ void PickFirst::UpdateLocked(UpdateArgs args) {
// check and instead do it in ExitIdleLocked().
for (size_t i = 0; i < subchannel_list->num_subchannels(); ++i) {
PickFirstSubchannelData* sd = subchannel_list->subchannel(i);
grpc_error* error = GRPC_ERROR_NONE;
grpc_connectivity_state state = sd->CheckConnectivityStateLocked(&error);
GRPC_ERROR_UNREF(error);
grpc_connectivity_state state = sd->CheckConnectivityStateLocked();
if (state == GRPC_CHANNEL_READY) {
subchannel_list_ = std::move(subchannel_list);
sd->StartConnectivityWatchLocked();
@ -338,7 +339,7 @@ void PickFirst::UpdateLocked(UpdateArgs args) {
}
void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked(
grpc_connectivity_state connectivity_state, grpc_error* error) {
grpc_connectivity_state connectivity_state) {
PickFirst* p = static_cast<PickFirst*>(subchannel_list()->policy());
AutoChildRefsUpdater guard(p);
// The notification must be for a subchannel in either the current or
@ -369,17 +370,16 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked(
p->subchannel_list_ = std::move(p->latest_pending_subchannel_list_);
// Set our state to that of the pending subchannel list.
if (p->subchannel_list_->in_transient_failure()) {
grpc_error* new_error =
GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
"selected subchannel failed; switching to pending update",
&error, 1);
grpc_error* error = grpc_error_set_int(
GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"selected subchannel failed; switching to pending update"),
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
p->channel_control_helper()->UpdateState(
GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(new_error),
UniquePtr<SubchannelPicker>(
New<TransientFailurePicker>(new_error)));
GRPC_CHANNEL_TRANSIENT_FAILURE,
UniquePtr<SubchannelPicker>(New<TransientFailurePicker>(error)));
} else {
p->channel_control_helper()->UpdateState(
GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE,
GRPC_CHANNEL_CONNECTING,
UniquePtr<SubchannelPicker>(New<QueuePicker>(p->Ref())));
}
} else {
@ -393,7 +393,7 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked(
p->selected_ = nullptr;
StopConnectivityWatchLocked();
p->channel_control_helper()->UpdateState(
GRPC_CHANNEL_IDLE, GRPC_ERROR_NONE,
GRPC_CHANNEL_IDLE,
UniquePtr<SubchannelPicker>(New<QueuePicker>(p->Ref())));
} else {
// This is unlikely but can happen when a subchannel has been asked
@ -401,19 +401,17 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked(
// some connectivity state notifications.
if (connectivity_state == GRPC_CHANNEL_READY) {
p->channel_control_helper()->UpdateState(
GRPC_CHANNEL_READY, GRPC_ERROR_NONE,
UniquePtr<SubchannelPicker>(
New<Picker>(connected_subchannel()->Ref())));
GRPC_CHANNEL_READY, UniquePtr<SubchannelPicker>(New<Picker>(
connected_subchannel()->Ref())));
} else { // CONNECTING
p->channel_control_helper()->UpdateState(
connectivity_state, GRPC_ERROR_REF(error),
connectivity_state,
UniquePtr<SubchannelPicker>(New<QueuePicker>(p->Ref())));
}
// Renew notification.
RenewConnectivityWatchLocked();
}
}
GRPC_ERROR_UNREF(error);
return;
}
// If we get here, there are two possible cases:
@ -450,13 +448,13 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked(
subchannel_list()->set_in_transient_failure(true);
// Only report new state in case 1.
if (subchannel_list() == p->subchannel_list_.get()) {
grpc_error* new_error =
GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
"failed to connect to all addresses", &error, 1);
grpc_error* error = grpc_error_set_int(
GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"failed to connect to all addresses"),
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
p->channel_control_helper()->UpdateState(
GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(new_error),
UniquePtr<SubchannelPicker>(
New<TransientFailurePicker>(new_error)));
GRPC_CHANNEL_TRANSIENT_FAILURE,
UniquePtr<SubchannelPicker>(New<TransientFailurePicker>(error)));
}
}
sd->CheckConnectivityStateAndStartWatchingLocked();
@ -467,7 +465,7 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked(
// Only update connectivity state in case 1.
if (subchannel_list() == p->subchannel_list_.get()) {
p->channel_control_helper()->UpdateState(
GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE,
GRPC_CHANNEL_CONNECTING,
UniquePtr<SubchannelPicker>(New<QueuePicker>(p->Ref())));
}
// Renew notification.
@ -477,7 +475,6 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked(
case GRPC_CHANNEL_SHUTDOWN:
GPR_UNREACHABLE_CODE(break);
}
GRPC_ERROR_UNREF(error);
}
void PickFirst::PickFirstSubchannelData::ProcessUnselectedReadyLocked() {
@ -507,7 +504,7 @@ void PickFirst::PickFirstSubchannelData::ProcessUnselectedReadyLocked() {
// Cases 1 and 2.
p->selected_ = this;
p->channel_control_helper()->UpdateState(
GRPC_CHANNEL_READY, GRPC_ERROR_NONE,
GRPC_CHANNEL_READY,
UniquePtr<SubchannelPicker>(New<Picker>(connected_subchannel()->Ref())));
if (grpc_lb_pick_first_trace.enabled()) {
gpr_log(GPR_INFO, "Pick First %p selected subchannel %p", p, subchannel());
@ -518,9 +515,7 @@ void PickFirst::PickFirstSubchannelData::
CheckConnectivityStateAndStartWatchingLocked() {
PickFirst* p = static_cast<PickFirst*>(subchannel_list()->policy());
// Check current state.
grpc_error* error = GRPC_ERROR_NONE;
grpc_connectivity_state current_state = CheckConnectivityStateLocked(&error);
GRPC_ERROR_UNREF(error);
grpc_connectivity_state current_state = CheckConnectivityStateLocked();
// Start watch.
StartConnectivityWatchLocked();
// If current state is READY, select the subchannel now, since we started
@ -531,6 +526,11 @@ void PickFirst::PickFirstSubchannelData::
}
}
class ParsedPickFirstConfig : public ParsedLoadBalancingConfig {
public:
const char* name() const override { return kPickFirst; }
};
//
// factory
//
@ -543,6 +543,15 @@ class PickFirstFactory : public LoadBalancingPolicyFactory {
}
const char* name() const override { return kPickFirst; }
RefCountedPtr<ParsedLoadBalancingConfig> ParseLoadBalancingConfig(
const grpc_json* json, grpc_error** error) const override {
if (json != nullptr) {
GPR_DEBUG_ASSERT(strcmp(json->key, name()) == 0);
}
return RefCountedPtr<ParsedLoadBalancingConfig>(
New<ParsedPickFirstConfig>());
}
};
} // namespace

@ -92,11 +92,11 @@ class RoundRobin : public LoadBalancingPolicy {
}
void UpdateConnectivityStateLocked(
grpc_connectivity_state connectivity_state, grpc_error* error);
grpc_connectivity_state connectivity_state);
private:
void ProcessConnectivityChangeLocked(
grpc_connectivity_state connectivity_state, grpc_error* error) override;
grpc_connectivity_state connectivity_state) override;
grpc_connectivity_state last_connectivity_state_ = GRPC_CHANNEL_IDLE;
};
@ -119,7 +119,6 @@ class RoundRobin : public LoadBalancingPolicy {
}
~RoundRobinSubchannelList() {
GRPC_ERROR_UNREF(last_transient_failure_error_);
RoundRobin* p = static_cast<RoundRobin*>(policy());
p->Unref(DEBUG_LOCATION, "subchannel_list");
}
@ -129,11 +128,8 @@ class RoundRobin : public LoadBalancingPolicy {
// Updates the counters of subchannels in each state when a
// subchannel transitions from old_state to new_state.
// transient_failure_error is the error that is reported when
// new_state is TRANSIENT_FAILURE.
void UpdateStateCountersLocked(grpc_connectivity_state old_state,
grpc_connectivity_state new_state,
grpc_error* transient_failure_error);
grpc_connectivity_state new_state);
// If this subchannel list is the RR policy's current subchannel
// list, updates the RR policy's connectivity state based on the
@ -148,7 +144,6 @@ class RoundRobin : public LoadBalancingPolicy {
size_t num_ready_ = 0;
size_t num_connecting_ = 0;
size_t num_transient_failure_ = 0;
grpc_error* last_transient_failure_error_ = GRPC_ERROR_NONE;
};
class Picker : public SubchannelPicker {
@ -315,11 +310,10 @@ void RoundRobin::RoundRobinSubchannelList::StartWatchingLocked() {
// subchannel already used by some other channel may have a non-IDLE
// state.
for (size_t i = 0; i < num_subchannels(); ++i) {
grpc_error* error = GRPC_ERROR_NONE;
grpc_connectivity_state state =
subchannel(i)->CheckConnectivityStateLocked(&error);
subchannel(i)->CheckConnectivityStateLocked();
if (state != GRPC_CHANNEL_IDLE) {
subchannel(i)->UpdateConnectivityStateLocked(state, error);
subchannel(i)->UpdateConnectivityStateLocked(state);
}
}
// Start connectivity watch for each subchannel.
@ -333,8 +327,7 @@ void RoundRobin::RoundRobinSubchannelList::StartWatchingLocked() {
}
void RoundRobin::RoundRobinSubchannelList::UpdateStateCountersLocked(
grpc_connectivity_state old_state, grpc_connectivity_state new_state,
grpc_error* transient_failure_error) {
grpc_connectivity_state old_state, grpc_connectivity_state new_state) {
GPR_ASSERT(old_state != GRPC_CHANNEL_SHUTDOWN);
GPR_ASSERT(new_state != GRPC_CHANNEL_SHUTDOWN);
if (old_state == GRPC_CHANNEL_READY) {
@ -354,8 +347,6 @@ void RoundRobin::RoundRobinSubchannelList::UpdateStateCountersLocked(
} else if (new_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
++num_transient_failure_;
}
GRPC_ERROR_UNREF(last_transient_failure_error_);
last_transient_failure_error_ = transient_failure_error;
}
// Sets the RR policy's connectivity state and generates a new picker based
@ -382,20 +373,21 @@ void RoundRobin::RoundRobinSubchannelList::
if (num_ready_ > 0) {
/* 1) READY */
p->channel_control_helper()->UpdateState(
GRPC_CHANNEL_READY, GRPC_ERROR_NONE,
UniquePtr<SubchannelPicker>(New<Picker>(p, this)));
GRPC_CHANNEL_READY, UniquePtr<SubchannelPicker>(New<Picker>(p, this)));
} else if (num_connecting_ > 0) {
/* 2) CONNECTING */
p->channel_control_helper()->UpdateState(
GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE,
GRPC_CHANNEL_CONNECTING,
UniquePtr<SubchannelPicker>(New<QueuePicker>(p->Ref())));
} else if (num_transient_failure_ == num_subchannels()) {
/* 3) TRANSIENT_FAILURE */
grpc_error* error =
grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"connections to all backends failing"),
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
p->channel_control_helper()->UpdateState(
GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_ERROR_REF(last_transient_failure_error_),
UniquePtr<SubchannelPicker>(New<TransientFailurePicker>(
GRPC_ERROR_REF(last_transient_failure_error_))));
UniquePtr<SubchannelPicker>(New<TransientFailurePicker>(error)));
}
}
@ -430,7 +422,7 @@ void RoundRobin::RoundRobinSubchannelList::
}
void RoundRobin::RoundRobinSubchannelData::UpdateConnectivityStateLocked(
grpc_connectivity_state connectivity_state, grpc_error* error) {
grpc_connectivity_state connectivity_state) {
RoundRobin* p = static_cast<RoundRobin*>(subchannel_list()->policy());
if (grpc_lb_round_robin_trace.enabled()) {
gpr_log(
@ -443,12 +435,12 @@ void RoundRobin::RoundRobinSubchannelData::UpdateConnectivityStateLocked(
grpc_connectivity_state_name(connectivity_state));
}
subchannel_list()->UpdateStateCountersLocked(last_connectivity_state_,
connectivity_state, error);
connectivity_state);
last_connectivity_state_ = connectivity_state;
}
void RoundRobin::RoundRobinSubchannelData::ProcessConnectivityChangeLocked(
grpc_connectivity_state connectivity_state, grpc_error* error) {
grpc_connectivity_state connectivity_state) {
RoundRobin* p = static_cast<RoundRobin*>(subchannel_list()->policy());
GPR_ASSERT(subchannel() != nullptr);
// If the new state is TRANSIENT_FAILURE, re-resolve.
@ -468,7 +460,7 @@ void RoundRobin::RoundRobinSubchannelData::ProcessConnectivityChangeLocked(
// Renew connectivity watch.
RenewConnectivityWatchLocked();
// Update state counters.
UpdateConnectivityStateLocked(connectivity_state, error);
UpdateConnectivityStateLocked(connectivity_state);
// Update overall state and renew notification.
subchannel_list()->UpdateRoundRobinStateFromSubchannelStateCountsLocked();
}
@ -492,9 +484,11 @@ void RoundRobin::UpdateLocked(UpdateArgs 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.
grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update");
grpc_error* error =
grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"),
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
channel_control_helper()->UpdateState(
GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error),
GRPC_CHANNEL_TRANSIENT_FAILURE,
UniquePtr<SubchannelPicker>(New<TransientFailurePicker>(error)));
subchannel_list_ = std::move(latest_pending_subchannel_list_);
} else if (subchannel_list_ == nullptr) {
@ -509,6 +503,11 @@ void RoundRobin::UpdateLocked(UpdateArgs args) {
}
}
class ParsedRoundRobinConfig : public ParsedLoadBalancingConfig {
public:
const char* name() const override { return kRoundRobin; }
};
//
// factory
//
@ -521,6 +520,15 @@ class RoundRobinFactory : public LoadBalancingPolicyFactory {
}
const char* name() const override { return kRoundRobin; }
RefCountedPtr<ParsedLoadBalancingConfig> ParseLoadBalancingConfig(
const grpc_json* json, grpc_error** error) const override {
if (json != nullptr) {
GPR_DEBUG_ASSERT(strcmp(json->key, name()) == 0);
}
return RefCountedPtr<ParsedLoadBalancingConfig>(
New<ParsedRoundRobinConfig>());
}
};
} // namespace

@ -51,7 +51,7 @@ class MySubchannelData
: public SubchannelData<MySubchannelList, MySubchannelData> {
public:
void ProcessConnectivityChangeLocked(
grpc_connectivity_state connectivity_state, grpc_error* error) override {
grpc_connectivity_state connectivity_state) override {
// ...code to handle connectivity changes...
}
};
@ -101,10 +101,10 @@ class SubchannelData {
// pending (i.e., between calling StartConnectivityWatchLocked() or
// RenewConnectivityWatchLocked() and the resulting invocation of
// ProcessConnectivityChangeLocked()).
grpc_connectivity_state CheckConnectivityStateLocked(grpc_error** error) {
grpc_connectivity_state CheckConnectivityStateLocked() {
GPR_ASSERT(!connectivity_notification_pending_);
pending_connectivity_state_unsafe_ = subchannel()->CheckConnectivity(
error, subchannel_list_->inhibit_health_checking());
subchannel_list_->inhibit_health_checking());
UpdateConnectedSubchannelLocked();
return pending_connectivity_state_unsafe_;
}
@ -153,8 +153,7 @@ class SubchannelData {
// Implementations must invoke either RenewConnectivityWatchLocked() or
// StopConnectivityWatchLocked() before returning.
virtual void ProcessConnectivityChangeLocked(
grpc_connectivity_state connectivity_state,
grpc_error* error) GRPC_ABSTRACT;
grpc_connectivity_state connectivity_state) GRPC_ABSTRACT;
// Unrefs the subchannel.
void UnrefSubchannelLocked(const char* reason);
@ -462,8 +461,7 @@ void SubchannelData<SubchannelListType, SubchannelDataType>::
return;
}
// Call the subclass's ProcessConnectivityChangeLocked() method.
sd->ProcessConnectivityChangeLocked(sd->pending_connectivity_state_unsafe_,
GRPC_ERROR_REF(error));
sd->ProcessConnectivityChangeLocked(sd->pending_connectivity_state_unsafe_);
}
template <typename SubchannelListType, typename SubchannelDataType>

File diff suppressed because it is too large Load Diff

@ -37,9 +37,12 @@ class LoadBalancingPolicyFactory {
/// Caller does NOT take ownership of result.
virtual const char* name() const GRPC_ABSTRACT;
virtual RefCountedPtr<ParsedLoadBalancingConfig> ParseLoadBalancingConfig(
const grpc_json* json, grpc_error** error) const GRPC_ABSTRACT;
virtual ~LoadBalancingPolicyFactory() {}
GRPC_ABSTRACT_BASE_CLASS
GRPC_ABSTRACT_BASE_CLASS;
};
} // namespace grpc_core

@ -94,9 +94,112 @@ LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy(
return factory->CreateLoadBalancingPolicy(std::move(args));
}
bool LoadBalancingPolicyRegistry::LoadBalancingPolicyExists(const char* name) {
bool LoadBalancingPolicyRegistry::LoadBalancingPolicyExists(
const char* name, bool* requires_config) {
GPR_ASSERT(g_state != nullptr);
return g_state->GetLoadBalancingPolicyFactory(name) != nullptr;
auto* factory = g_state->GetLoadBalancingPolicyFactory(name);
if (factory == nullptr) {
return false;
}
if (requires_config != nullptr) {
grpc_error* error = GRPC_ERROR_NONE;
// Check if the load balancing policy allows an empty config
*requires_config =
factory->ParseLoadBalancingConfig(nullptr, &error) == nullptr;
GRPC_ERROR_UNREF(error);
}
return true;
}
namespace {
// Returns the JSON node of policy (with both policy name and config content)
// given the JSON node of a LoadBalancingConfig array.
grpc_json* ParseLoadBalancingConfigHelper(const grpc_json* lb_config_array,
grpc_error** error) {
GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE);
char* error_msg;
if (lb_config_array == nullptr || lb_config_array->type != GRPC_JSON_ARRAY) {
gpr_asprintf(&error_msg, "field:%s error:type should be array",
lb_config_array->key);
*error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg);
gpr_free(error_msg);
return nullptr;
}
const char* field_name = lb_config_array->key;
// Find the first LB policy that this client supports.
for (const grpc_json* lb_config = lb_config_array->child;
lb_config != nullptr; lb_config = lb_config->next) {
if (lb_config->type != GRPC_JSON_OBJECT) {
gpr_asprintf(&error_msg,
"field:%s error:child entry should be of type object",
field_name);
*error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg);
gpr_free(error_msg);
return nullptr;
}
grpc_json* policy = nullptr;
for (grpc_json* field = lb_config->child; field != nullptr;
field = field->next) {
if (field->key == nullptr || field->type != GRPC_JSON_OBJECT) {
gpr_asprintf(&error_msg,
"field:%s error:child entry should be of type object",
field_name);
*error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg);
gpr_free(error_msg);
return nullptr;
}
if (policy != nullptr) {
gpr_asprintf(&error_msg, "field:%s error:oneOf violation", field_name);
*error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg);
gpr_free(error_msg);
return nullptr;
} // Violate "oneof" type.
policy = field;
}
if (policy == nullptr) {
gpr_asprintf(&error_msg, "field:%s error:no policy found in child entry",
field_name);
*error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg);
gpr_free(error_msg);
return nullptr;
}
// If we support this policy, then select it.
if (LoadBalancingPolicyRegistry::LoadBalancingPolicyExists(policy->key,
nullptr)) {
return policy;
}
}
gpr_asprintf(&error_msg, "field:%s error:No known policy", field_name);
*error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg);
gpr_free(error_msg);
return nullptr;
}
} // namespace
RefCountedPtr<ParsedLoadBalancingConfig>
LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(const grpc_json* json,
grpc_error** error) {
GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE);
GPR_ASSERT(g_state != nullptr);
const grpc_json* policy = ParseLoadBalancingConfigHelper(json, error);
if (policy == nullptr) {
return nullptr;
} else {
GPR_DEBUG_ASSERT(*error == GRPC_ERROR_NONE && json != nullptr);
// Find factory.
LoadBalancingPolicyFactory* factory =
g_state->GetLoadBalancingPolicyFactory(policy->key);
if (factory == nullptr) {
char* msg;
gpr_asprintf(&msg, "field:%s error:Factory not found to create policy",
json->key);
*error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
gpr_free(msg);
return nullptr;
}
// Parse load balancing config via factory.
return factory->ParseLoadBalancingConfig(policy, error);
}
}
} // namespace grpc_core

@ -49,8 +49,15 @@ class LoadBalancingPolicyRegistry {
const char* name, LoadBalancingPolicy::Args args);
/// Returns true if the LB policy factory specified by \a name exists in this
/// registry.
static bool LoadBalancingPolicyExists(const char* name);
/// registry. If the load balancing policy requires a config to be specified
/// then sets \a requires_config to true.
static bool LoadBalancingPolicyExists(const char* name,
bool* requires_config);
/// Returns a parsed object of the load balancing policy to be used from a
/// LoadBalancingConfig array \a json.
static RefCountedPtr<ParsedLoadBalancingConfig> ParseLoadBalancingConfig(
const grpc_json* json, grpc_error** error);
};
} // namespace grpc_core

@ -43,6 +43,7 @@
#include "src/core/lib/gprpp/manual_constructor.h"
#include "src/core/lib/iomgr/combiner.h"
#include "src/core/lib/iomgr/gethostname.h"
#include "src/core/lib/iomgr/iomgr_custom.h"
#include "src/core/lib/iomgr/resolve_address.h"
#include "src/core/lib/iomgr/timer.h"
#include "src/core/lib/json/json.h"
@ -430,8 +431,11 @@ static grpc_address_resolver_vtable ares_resolver = {
grpc_resolve_address_ares, blocking_resolve_address_ares};
static bool should_use_ares(const char* resolver_env) {
return resolver_env == nullptr || strlen(resolver_env) == 0 ||
gpr_stricmp(resolver_env, "ares") == 0;
// TODO(lidiz): Remove the "g_custom_iomgr_enabled" flag once c-ares support
// custom IO managers (e.g. gevent).
return !g_custom_iomgr_enabled &&
(resolver_env == nullptr || strlen(resolver_env) == 0 ||
gpr_stricmp(resolver_env, "ares") == 0);
}
void grpc_resolver_dns_ares_init() {

@ -445,7 +445,8 @@ class SockToPolledFdMap {
*/
static ares_socket_t Socket(int af, int type, int protocol, void* user_data) {
SockToPolledFdMap* map = static_cast<SockToPolledFdMap*>(user_data);
SOCKET s = WSASocket(af, type, protocol, nullptr, 0, WSA_FLAG_OVERLAPPED);
SOCKET s = WSASocket(af, type, protocol, nullptr, 0,
grpc_get_default_wsa_socket_flags());
if (s == INVALID_SOCKET) {
return s;
}

@ -35,6 +35,7 @@
#include "src/core/lib/channel/status_util.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/memory.h"
#include "src/core/lib/gprpp/optional.h"
#include "src/core/lib/uri/uri_parser.h"
// As per the retry design, we do not allow more than 5 retry attempts.
@ -43,80 +44,68 @@
namespace grpc_core {
namespace internal {
namespace {
size_t g_client_channel_service_config_parser_index;
}
size_t ClientChannelServiceConfigParser::ParserIndex() {
return g_client_channel_service_config_parser_index;
}
void ClientChannelServiceConfigParser::Register() {
g_client_channel_service_config_parser_index =
ServiceConfig::RegisterParser(UniquePtr<ServiceConfig::Parser>(
New<ClientChannelServiceConfigParser>()));
}
ProcessedResolverResult::ProcessedResolverResult(
Resolver::Result* resolver_result, bool parse_retry)
: service_config_(resolver_result->service_config) {
const Resolver::Result& resolver_result)
: 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));
grpc_channel_args_find(resolver_result.args, GRPC_ARG_SERVICE_CONFIG));
if (service_config_json != nullptr) {
grpc_error* error = GRPC_ERROR_NONE;
service_config_ = ServiceConfig::Create(service_config_json, &error);
// Error is currently unused.
GRPC_ERROR_UNREF(error);
}
} 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);
const ClientChannelGlobalParsedObject* parsed_object = nullptr;
if (service_config_ != nullptr) {
parsed_object = static_cast<const ClientChannelGlobalParsedObject*>(
service_config_->GetParsedGlobalServiceConfigObject(
ClientChannelServiceConfigParser::ParserIndex()));
ProcessServiceConfig(resolver_result, parsed_object);
}
ProcessLbPolicy(resolver_result, parsed_object);
}
void ProcessedResolverResult::ProcessServiceConfig(
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);
const Resolver::Result& resolver_result,
const ClientChannelGlobalParsedObject* parsed_object) {
health_check_service_name_ = parsed_object->health_check_service_name();
service_config_json_ = service_config_->service_config_json();
if (parsed_object != nullptr) {
retry_throttle_data_ = parsed_object->retry_throttling();
}
method_params_table_ = service_config_->CreateMethodConfigTable(
ClientChannelMethodParams::CreateFromJson);
}
void ProcessedResolverResult::ProcessLbPolicyName(
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.
if (service_config_ != nullptr) {
lb_policy_name_.reset(
gpr_strdup(service_config_->GetLoadBalancingPolicyName()));
// Convert to lower-case.
if (lb_policy_name_ != nullptr) {
char* lb_policy_name = lb_policy_name_.get();
for (size_t i = 0; i < strlen(lb_policy_name); ++i) {
lb_policy_name[i] = tolower(lb_policy_name[i]);
}
void ProcessedResolverResult::ProcessLbPolicy(
const Resolver::Result& resolver_result,
const ClientChannelGlobalParsedObject* parsed_object) {
// Prefer the LB policy name found in the service config.
if (parsed_object != nullptr) {
if (parsed_object->parsed_lb_config() != nullptr) {
lb_policy_name_.reset(
gpr_strdup(parsed_object->parsed_lb_config()->name()));
lb_policy_config_ = parsed_object->parsed_lb_config();
} else {
lb_policy_name_.reset(
gpr_strdup(parsed_object->parsed_deprecated_lb_policy()));
}
}
// Otherwise, find the LB policy name set by the client API.
@ -152,97 +141,8 @@ void ProcessedResolverResult::ProcessLbPolicyName(
}
}
void ProcessedResolverResult::ParseServiceConfig(
const grpc_json* field, ProcessedResolverResult* parsing_state) {
parsing_state->ParseLbConfigFromServiceConfig(field);
if (parsing_state->server_name_ != nullptr) {
parsing_state->ParseRetryThrottleParamsFromServiceConfig(field);
}
}
void ProcessedResolverResult::ParseLbConfigFromServiceConfig(
const grpc_json* field) {
if (lb_policy_config_ != nullptr) return; // Already found.
if (field->key == nullptr || strcmp(field->key, "loadBalancingConfig") != 0) {
return; // Not the LB config global parameter.
}
const grpc_json* policy =
LoadBalancingPolicy::ParseLoadBalancingConfig(field);
if (policy != nullptr) {
lb_policy_name_.reset(gpr_strdup(policy->key));
lb_policy_config_ =
MakeRefCounted<LoadBalancingPolicy::Config>(policy, service_config_);
}
}
void ProcessedResolverResult::ParseRetryThrottleParamsFromServiceConfig(
const grpc_json* field) {
if (strcmp(field->key, "retryThrottling") == 0) {
if (retry_throttle_data_ != nullptr) return; // Duplicate.
if (field->type != GRPC_JSON_OBJECT) return;
int max_milli_tokens = 0;
int milli_token_ratio = 0;
for (grpc_json* sub_field = field->child; sub_field != nullptr;
sub_field = sub_field->next) {
if (sub_field->key == nullptr) return;
if (strcmp(sub_field->key, "maxTokens") == 0) {
if (max_milli_tokens != 0) return; // Duplicate.
if (sub_field->type != GRPC_JSON_NUMBER) return;
max_milli_tokens = gpr_parse_nonnegative_int(sub_field->value);
if (max_milli_tokens == -1) return;
max_milli_tokens *= 1000;
} else if (strcmp(sub_field->key, "tokenRatio") == 0) {
if (milli_token_ratio != 0) return; // Duplicate.
if (sub_field->type != GRPC_JSON_NUMBER) return;
// We support up to 3 decimal digits.
size_t whole_len = strlen(sub_field->value);
uint32_t multiplier = 1;
uint32_t decimal_value = 0;
const char* decimal_point = strchr(sub_field->value, '.');
if (decimal_point != nullptr) {
whole_len = static_cast<size_t>(decimal_point - sub_field->value);
multiplier = 1000;
size_t decimal_len = strlen(decimal_point + 1);
if (decimal_len > 3) decimal_len = 3;
if (!gpr_parse_bytes_to_uint32(decimal_point + 1, decimal_len,
&decimal_value)) {
return;
}
uint32_t decimal_multiplier = 1;
for (size_t i = 0; i < (3 - decimal_len); ++i) {
decimal_multiplier *= 10;
}
decimal_value *= decimal_multiplier;
}
uint32_t whole_value;
if (!gpr_parse_bytes_to_uint32(sub_field->value, whole_len,
&whole_value)) {
return;
}
milli_token_ratio =
static_cast<int>((whole_value * multiplier) + decimal_value);
if (milli_token_ratio <= 0) return;
}
}
retry_throttle_data_ =
grpc_core::internal::ServerRetryThrottleMap::GetDataForServer(
server_name_, max_milli_tokens, milli_token_ratio);
}
}
namespace {
bool ParseWaitForReady(
grpc_json* field, ClientChannelMethodParams::WaitForReady* wait_for_ready) {
if (field->type != GRPC_JSON_TRUE && field->type != GRPC_JSON_FALSE) {
return false;
}
*wait_for_ready = field->type == GRPC_JSON_TRUE
? ClientChannelMethodParams::WAIT_FOR_READY_TRUE
: ClientChannelMethodParams::WAIT_FOR_READY_FALSE;
return true;
}
// Parses a JSON field of the form generated for a google.proto.Duration
// proto message, as per:
// https://developers.google.com/protocol-buffers/docs/proto3#json
@ -275,18 +175,36 @@ bool ParseDuration(grpc_json* field, grpc_millis* duration) {
return true;
}
UniquePtr<ClientChannelMethodParams::RetryPolicy> ParseRetryPolicy(
grpc_json* field) {
auto retry_policy = MakeUnique<ClientChannelMethodParams::RetryPolicy>();
if (field->type != GRPC_JSON_OBJECT) return nullptr;
UniquePtr<ClientChannelMethodParsedObject::RetryPolicy> ParseRetryPolicy(
grpc_json* field, grpc_error** error) {
GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE);
auto retry_policy =
MakeUnique<ClientChannelMethodParsedObject::RetryPolicy>();
if (field->type != GRPC_JSON_OBJECT) {
*error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:retryPolicy error:should be of type object");
return nullptr;
}
InlinedVector<grpc_error*, 4> error_list;
for (grpc_json* sub_field = field->child; sub_field != nullptr;
sub_field = sub_field->next) {
if (sub_field->key == nullptr) return nullptr;
if (sub_field->key == nullptr) continue;
if (strcmp(sub_field->key, "maxAttempts") == 0) {
if (retry_policy->max_attempts != 0) return nullptr; // Duplicate.
if (sub_field->type != GRPC_JSON_NUMBER) return nullptr;
if (retry_policy->max_attempts != 0) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:maxAttempts error:Duplicate entry"));
} // Duplicate. Continue Parsing
if (sub_field->type != GRPC_JSON_NUMBER) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:maxAttempts error:should be of type number"));
continue;
}
retry_policy->max_attempts = gpr_parse_nonnegative_int(sub_field->value);
if (retry_policy->max_attempts <= 1) return nullptr;
if (retry_policy->max_attempts <= 1) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:maxAttempts error:should be at least 2"));
continue;
}
if (retry_policy->max_attempts > MAX_MAX_RETRY_ATTEMPTS) {
gpr_log(GPR_ERROR,
"service config: clamped retryPolicy.maxAttempts at %d",
@ -294,78 +212,375 @@ UniquePtr<ClientChannelMethodParams::RetryPolicy> ParseRetryPolicy(
retry_policy->max_attempts = MAX_MAX_RETRY_ATTEMPTS;
}
} else if (strcmp(sub_field->key, "initialBackoff") == 0) {
if (retry_policy->initial_backoff > 0) return nullptr; // Duplicate.
if (retry_policy->initial_backoff > 0) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:initialBackoff error:Duplicate entry"));
} // Duplicate, continue parsing.
if (!ParseDuration(sub_field, &retry_policy->initial_backoff)) {
return nullptr;
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:initialBackoff error:Failed to parse"));
continue;
}
if (retry_policy->initial_backoff == 0) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:initialBackoff error:must be greater than 0"));
}
if (retry_policy->initial_backoff == 0) return nullptr;
} else if (strcmp(sub_field->key, "maxBackoff") == 0) {
if (retry_policy->max_backoff > 0) return nullptr; // Duplicate.
if (retry_policy->max_backoff > 0) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:maxBackoff error:Duplicate entry"));
} // Duplicate, continue parsing.
if (!ParseDuration(sub_field, &retry_policy->max_backoff)) {
return nullptr;
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:maxBackoff error:failed to parse"));
continue;
}
if (retry_policy->max_backoff == 0) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:maxBackoff error:should be greater than 0"));
}
if (retry_policy->max_backoff == 0) return nullptr;
} else if (strcmp(sub_field->key, "backoffMultiplier") == 0) {
if (retry_policy->backoff_multiplier != 0) return nullptr; // Duplicate.
if (sub_field->type != GRPC_JSON_NUMBER) return nullptr;
if (retry_policy->backoff_multiplier != 0) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:backoffMultiplier error:Duplicate entry"));
} // Duplicate, continue parsing.
if (sub_field->type != GRPC_JSON_NUMBER) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:backoffMultiplier error:should be of type number"));
continue;
}
if (sscanf(sub_field->value, "%f", &retry_policy->backoff_multiplier) !=
1) {
return nullptr;
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:backoffMultiplier error:failed to parse"));
continue;
}
if (retry_policy->backoff_multiplier <= 0) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:backoffMultiplier error:should be greater than 0"));
}
if (retry_policy->backoff_multiplier <= 0) return nullptr;
} else if (strcmp(sub_field->key, "retryableStatusCodes") == 0) {
if (!retry_policy->retryable_status_codes.Empty()) {
return nullptr; // Duplicate.
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:retryableStatusCodes error:Duplicate entry"));
} // Duplicate, continue parsing.
if (sub_field->type != GRPC_JSON_ARRAY) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:retryableStatusCodes error:should be of type array"));
continue;
}
if (sub_field->type != GRPC_JSON_ARRAY) return nullptr;
for (grpc_json* element = sub_field->child; element != nullptr;
element = element->next) {
if (element->type != GRPC_JSON_STRING) return nullptr;
if (element->type != GRPC_JSON_STRING) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:retryableStatusCodes error:status codes should be of type "
"string"));
continue;
}
grpc_status_code status;
if (!grpc_status_code_from_string(element->value, &status)) {
return nullptr;
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:retryableStatusCodes error:failed to parse status code"));
continue;
}
retry_policy->retryable_status_codes.Add(status);
}
if (retry_policy->retryable_status_codes.Empty()) return nullptr;
if (retry_policy->retryable_status_codes.Empty()) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:retryableStatusCodes error:should be non-empty"));
};
}
}
// Make sure required fields are set.
if (retry_policy->max_attempts == 0 || retry_policy->initial_backoff == 0 ||
retry_policy->max_backoff == 0 || retry_policy->backoff_multiplier == 0 ||
retry_policy->retryable_status_codes.Empty()) {
if (error_list.empty()) {
if (retry_policy->max_attempts == 0 || retry_policy->initial_backoff == 0 ||
retry_policy->max_backoff == 0 ||
retry_policy->backoff_multiplier == 0 ||
retry_policy->retryable_status_codes.Empty()) {
*error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:retryPolicy error:Missing required field(s)");
return nullptr;
}
}
*error = GRPC_ERROR_CREATE_FROM_VECTOR("retryPolicy", &error_list);
return *error == GRPC_ERROR_NONE ? std::move(retry_policy) : nullptr;
}
const char* ParseHealthCheckConfig(const grpc_json* field, grpc_error** error) {
GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE);
const char* service_name = nullptr;
GPR_DEBUG_ASSERT(strcmp(field->key, "healthCheckConfig") == 0);
if (field->type != GRPC_JSON_OBJECT) {
*error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:healthCheckConfig error:should be of type object");
return nullptr;
}
InlinedVector<grpc_error*, 2> error_list;
for (grpc_json* sub_field = field->child; sub_field != nullptr;
sub_field = sub_field->next) {
if (sub_field->key == nullptr) {
GPR_DEBUG_ASSERT(false);
continue;
}
if (strcmp(sub_field->key, "serviceName") == 0) {
if (service_name != nullptr) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:serviceName error:Duplicate "
"entry"));
} // Duplicate. Continue parsing
if (sub_field->type != GRPC_JSON_STRING) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:serviceName error:should be of type string"));
continue;
}
service_name = sub_field->value;
}
}
if (!error_list.empty()) {
return nullptr;
}
return retry_policy;
*error =
GRPC_ERROR_CREATE_FROM_VECTOR("field:healthCheckConfig", &error_list);
return service_name;
}
} // namespace
RefCountedPtr<ClientChannelMethodParams>
ClientChannelMethodParams::CreateFromJson(const grpc_json* json) {
RefCountedPtr<ClientChannelMethodParams> method_params =
MakeRefCounted<ClientChannelMethodParams>();
UniquePtr<ServiceConfig::ParsedConfig>
ClientChannelServiceConfigParser::ParseGlobalParams(const grpc_json* json,
grpc_error** error) {
GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE);
InlinedVector<grpc_error*, 4> error_list;
RefCountedPtr<ParsedLoadBalancingConfig> parsed_lb_config;
UniquePtr<char> lb_policy_name;
Optional<ClientChannelGlobalParsedObject::RetryThrottling> retry_throttling;
const char* health_check_service_name = nullptr;
for (grpc_json* field = json->child; field != nullptr; field = field->next) {
if (field->key == nullptr) {
continue; // Not the LB config global parameter
}
// Parsed Load balancing config
if (strcmp(field->key, "loadBalancingConfig") == 0) {
if (parsed_lb_config != nullptr) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:loadBalancingConfig error:Duplicate entry"));
} // Duplicate, continue parsing.
grpc_error* parse_error = GRPC_ERROR_NONE;
parsed_lb_config = LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(
field, &parse_error);
if (parsed_lb_config == nullptr) {
error_list.push_back(parse_error);
}
}
// Parse deprecated loadBalancingPolicy
if (strcmp(field->key, "loadBalancingPolicy") == 0) {
if (lb_policy_name != nullptr) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:loadBalancingPolicy error:Duplicate entry"));
} // Duplicate, continue parsing.
if (field->type != GRPC_JSON_STRING) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:loadBalancingPolicy error:type should be string"));
continue;
}
lb_policy_name.reset(gpr_strdup(field->value));
char* lb_policy = lb_policy_name.get();
if (lb_policy != nullptr) {
for (size_t i = 0; i < strlen(lb_policy); ++i) {
lb_policy[i] = tolower(lb_policy[i]);
}
}
bool requires_config = false;
if (!LoadBalancingPolicyRegistry::LoadBalancingPolicyExists(
lb_policy, &requires_config)) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:loadBalancingPolicy error:Unknown lb policy"));
} else if (requires_config) {
char* error_msg;
gpr_asprintf(&error_msg,
"field:loadBalancingPolicy error:%s requires a config. "
"Please use loadBalancingConfig instead.",
lb_policy);
error_list.push_back(GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg));
gpr_free(error_msg);
}
}
// Parse retry throttling
if (strcmp(field->key, "retryThrottling") == 0) {
if (retry_throttling.has_value()) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:retryThrottling error:Duplicate entry"));
} // Duplicate, continue parsing.
if (field->type != GRPC_JSON_OBJECT) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:retryThrottling error:Type should be object"));
continue;
}
Optional<int> max_milli_tokens;
Optional<int> milli_token_ratio;
for (grpc_json* sub_field = field->child; sub_field != nullptr;
sub_field = sub_field->next) {
if (sub_field->key == nullptr) continue;
if (strcmp(sub_field->key, "maxTokens") == 0) {
if (max_milli_tokens.has_value()) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:retryThrottling field:maxTokens error:Duplicate "
"entry"));
} // Duplicate, continue parsing.
if (sub_field->type != GRPC_JSON_NUMBER) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:retryThrottling field:maxTokens error:Type should be "
"number"));
} else {
max_milli_tokens.set(gpr_parse_nonnegative_int(sub_field->value) *
1000);
if (max_milli_tokens.value() <= 0) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:retryThrottling field:maxTokens error:should be "
"greater than zero"));
}
}
} else if (strcmp(sub_field->key, "tokenRatio") == 0) {
if (milli_token_ratio.has_value()) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:retryThrottling field:tokenRatio error:Duplicate "
"entry"));
} // Duplicate, continue parsing.
if (sub_field->type != GRPC_JSON_NUMBER) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:retryThrottling field:tokenRatio error:type should be "
"number"));
} else {
// We support up to 3 decimal digits.
size_t whole_len = strlen(sub_field->value);
uint32_t multiplier = 1;
uint32_t decimal_value = 0;
const char* decimal_point = strchr(sub_field->value, '.');
if (decimal_point != nullptr) {
whole_len = static_cast<size_t>(decimal_point - sub_field->value);
multiplier = 1000;
size_t decimal_len = strlen(decimal_point + 1);
if (decimal_len > 3) decimal_len = 3;
if (!gpr_parse_bytes_to_uint32(decimal_point + 1, decimal_len,
&decimal_value)) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:retryThrottling field:tokenRatio error:Failed "
"parsing"));
continue;
}
uint32_t decimal_multiplier = 1;
for (size_t i = 0; i < (3 - decimal_len); ++i) {
decimal_multiplier *= 10;
}
decimal_value *= decimal_multiplier;
}
uint32_t whole_value;
if (!gpr_parse_bytes_to_uint32(sub_field->value, whole_len,
&whole_value)) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:retryThrottling field:tokenRatio error:Failed "
"parsing"));
continue;
}
milli_token_ratio.set(
static_cast<int>((whole_value * multiplier) + decimal_value));
if (milli_token_ratio.value() <= 0) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:retryThrottling field:tokenRatio error:value should "
"be greater than 0"));
}
}
}
}
ClientChannelGlobalParsedObject::RetryThrottling data;
if (!max_milli_tokens.has_value()) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:retryThrottling field:maxTokens error:Not found"));
} else {
data.max_milli_tokens = max_milli_tokens.value();
}
if (!milli_token_ratio.has_value()) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:retryThrottling field:tokenRatio error:Not found"));
} else {
data.milli_token_ratio = milli_token_ratio.value();
}
retry_throttling.set(data);
}
if (strcmp(field->key, "healthCheckConfig") == 0) {
if (health_check_service_name != nullptr) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:healthCheckConfig error:Duplicate entry"));
} // Duplicate continue parsing
grpc_error* parsing_error = GRPC_ERROR_NONE;
health_check_service_name = ParseHealthCheckConfig(field, &parsing_error);
if (parsing_error != GRPC_ERROR_NONE) {
error_list.push_back(parsing_error);
}
}
}
*error = GRPC_ERROR_CREATE_FROM_VECTOR("Client channel global parser",
&error_list);
if (*error == GRPC_ERROR_NONE) {
return UniquePtr<ServiceConfig::ParsedConfig>(
New<ClientChannelGlobalParsedObject>(
std::move(parsed_lb_config), std::move(lb_policy_name),
retry_throttling, health_check_service_name));
}
return nullptr;
}
UniquePtr<ServiceConfig::ParsedConfig>
ClientChannelServiceConfigParser::ParsePerMethodParams(const grpc_json* json,
grpc_error** error) {
GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE);
InlinedVector<grpc_error*, 4> error_list;
Optional<bool> wait_for_ready;
grpc_millis timeout = 0;
UniquePtr<ClientChannelMethodParsedObject::RetryPolicy> retry_policy;
for (grpc_json* field = json->child; field != nullptr; field = field->next) {
if (field->key == nullptr) continue;
if (strcmp(field->key, "waitForReady") == 0) {
if (method_params->wait_for_ready_ != WAIT_FOR_READY_UNSET) {
return nullptr; // Duplicate.
}
if (!ParseWaitForReady(field, &method_params->wait_for_ready_)) {
return nullptr;
if (wait_for_ready.has_value()) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:waitForReady error:Duplicate entry"));
} // Duplicate, continue parsing.
if (field->type == GRPC_JSON_TRUE) {
wait_for_ready.set(true);
} else if (field->type == GRPC_JSON_FALSE) {
wait_for_ready.set(false);
} else {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:waitForReady error:Type should be true/false"));
}
} else if (strcmp(field->key, "timeout") == 0) {
if (method_params->timeout_ > 0) return nullptr; // Duplicate.
if (!ParseDuration(field, &method_params->timeout_)) return nullptr;
if (timeout > 0) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:timeout error:Duplicate entry"));
} // Duplicate, continue parsing.
if (!ParseDuration(field, &timeout)) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:timeout error:Failed parsing"));
};
} else if (strcmp(field->key, "retryPolicy") == 0) {
if (method_params->retry_policy_ != nullptr) {
return nullptr; // Duplicate.
if (retry_policy != nullptr) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:retryPolicy error:Duplicate entry"));
} // Duplicate, continue parsing.
grpc_error* error = GRPC_ERROR_NONE;
retry_policy = ParseRetryPolicy(field, &error);
if (retry_policy == nullptr) {
error_list.push_back(error);
}
method_params->retry_policy_ = ParseRetryPolicy(field);
if (method_params->retry_policy_ == nullptr) return nullptr;
}
}
return method_params;
*error = GRPC_ERROR_CREATE_FROM_VECTOR("Client channel parser", &error_list);
if (*error == GRPC_ERROR_NONE) {
return UniquePtr<ServiceConfig::ParsedConfig>(
New<ClientChannelMethodParsedObject>(timeout, wait_for_ready,
std::move(retry_policy)));
}
return nullptr;
}
} // namespace internal

@ -22,10 +22,12 @@
#include <grpc/support/port_platform.h>
#include "src/core/ext/filters/client_channel/lb_policy.h"
#include "src/core/ext/filters/client_channel/lb_policy_factory.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/optional.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
@ -35,44 +37,123 @@
namespace grpc_core {
namespace internal {
class ClientChannelMethodParams;
class ClientChannelGlobalParsedObject : public ServiceConfig::ParsedConfig {
public:
struct RetryThrottling {
intptr_t max_milli_tokens = 0;
intptr_t milli_token_ratio = 0;
};
ClientChannelGlobalParsedObject(
RefCountedPtr<ParsedLoadBalancingConfig> parsed_lb_config,
UniquePtr<char> parsed_deprecated_lb_policy,
const Optional<RetryThrottling>& retry_throttling,
const char* health_check_service_name)
: parsed_lb_config_(std::move(parsed_lb_config)),
parsed_deprecated_lb_policy_(std::move(parsed_deprecated_lb_policy)),
retry_throttling_(retry_throttling),
health_check_service_name_(health_check_service_name) {}
Optional<RetryThrottling> retry_throttling() const {
return retry_throttling_;
}
RefCountedPtr<ParsedLoadBalancingConfig> parsed_lb_config() const {
return parsed_lb_config_;
}
const char* parsed_deprecated_lb_policy() const {
return parsed_deprecated_lb_policy_.get();
}
const char* health_check_service_name() const {
return health_check_service_name_;
}
private:
RefCountedPtr<ParsedLoadBalancingConfig> parsed_lb_config_;
UniquePtr<char> parsed_deprecated_lb_policy_;
Optional<RetryThrottling> retry_throttling_;
const char* health_check_service_name_;
};
class ClientChannelMethodParsedObject : public ServiceConfig::ParsedConfig {
public:
struct RetryPolicy {
int max_attempts = 0;
grpc_millis initial_backoff = 0;
grpc_millis max_backoff = 0;
float backoff_multiplier = 0;
StatusCodeSet retryable_status_codes;
};
ClientChannelMethodParsedObject(grpc_millis timeout,
const Optional<bool>& wait_for_ready,
UniquePtr<RetryPolicy> retry_policy)
: timeout_(timeout),
wait_for_ready_(wait_for_ready),
retry_policy_(std::move(retry_policy)) {}
grpc_millis timeout() const { return timeout_; }
Optional<bool> wait_for_ready() const { return wait_for_ready_; }
const RetryPolicy* retry_policy() const { return retry_policy_.get(); }
private:
grpc_millis timeout_ = 0;
Optional<bool> wait_for_ready_;
UniquePtr<RetryPolicy> retry_policy_;
};
class ClientChannelServiceConfigParser : public ServiceConfig::Parser {
public:
UniquePtr<ServiceConfig::ParsedConfig> ParseGlobalParams(
const grpc_json* json, grpc_error** error) override;
UniquePtr<ServiceConfig::ParsedConfig> ParsePerMethodParams(
const grpc_json* json, grpc_error** error) override;
// A table mapping from a method name to its method parameters.
typedef SliceHashTable<RefCountedPtr<ClientChannelMethodParams>>
ClientChannelMethodParamsTable;
static size_t ParserIndex();
static void Register();
};
// A container of processed fields from the resolver result. Simplifies the
// usage of resolver result.
// TODO(yashykt): It would be cleaner to move this logic to the client_channel
// code. A container of processed fields from the resolver result. Simplifies
// the usage of resolver result.
class ProcessedResolverResult {
public:
// Processes the resolver result and populates the relative members
// for later consumption. Tries to parse retry parameters only if parse_retry
// is true.
ProcessedResolverResult(Resolver::Result* resolver_result, bool parse_retry);
// for later consumption.
ProcessedResolverResult(const Resolver::Result& resolver_result);
// Getters. Any managed object's ownership is transferred.
UniquePtr<char> service_config_json() {
return std::move(service_config_json_);
}
RefCountedPtr<ServerRetryThrottleData> retry_throttle_data() {
return std::move(retry_throttle_data_);
}
RefCountedPtr<ClientChannelMethodParamsTable> method_params_table() {
return std::move(method_params_table_);
}
const char* service_config_json() { return service_config_json_; }
RefCountedPtr<ServiceConfig> service_config() { return service_config_; }
UniquePtr<char> lb_policy_name() { return std::move(lb_policy_name_); }
RefCountedPtr<LoadBalancingPolicy::Config> lb_policy_config() {
return std::move(lb_policy_config_);
RefCountedPtr<ParsedLoadBalancingConfig> lb_policy_config() {
return lb_policy_config_;
}
Optional<ClientChannelGlobalParsedObject::RetryThrottling>
retry_throttle_data() {
return retry_throttle_data_;
}
const char* health_check_service_name() { return health_check_service_name_; }
private:
// Finds the service config; extracts LB config and (maybe) retry throttle
// params from it.
void ProcessServiceConfig(const Resolver::Result& resolver_result,
bool parse_retry);
void ProcessServiceConfig(
const Resolver::Result& resolver_result,
const ClientChannelGlobalParsedObject* parsed_object);
// Finds the LB policy name (when no LB config was found).
void ProcessLbPolicyName(const Resolver::Result& resolver_result);
// Extracts the LB policy.
void ProcessLbPolicy(const Resolver::Result& resolver_result,
const ClientChannelGlobalParsedObject* parsed_object);
// Parses the service config. Intended to be used by
// ServiceConfig::ParseGlobalParams.
@ -84,59 +165,15 @@ class ProcessedResolverResult {
void ParseRetryThrottleParamsFromServiceConfig(const grpc_json* field);
// Service config.
UniquePtr<char> service_config_json_;
const char* service_config_json_ = nullptr;
RefCountedPtr<ServiceConfig> service_config_;
// LB policy.
UniquePtr<char> lb_policy_name_;
RefCountedPtr<LoadBalancingPolicy::Config> lb_policy_config_;
RefCountedPtr<ParsedLoadBalancingConfig> lb_policy_config_;
// Retry throttle data.
char* server_name_ = nullptr;
RefCountedPtr<ServerRetryThrottleData> retry_throttle_data_;
// Method params table.
RefCountedPtr<ClientChannelMethodParamsTable> method_params_table_;
};
// The parameters of a method.
class ClientChannelMethodParams : public RefCounted<ClientChannelMethodParams> {
public:
enum WaitForReady {
WAIT_FOR_READY_UNSET = 0,
WAIT_FOR_READY_FALSE,
WAIT_FOR_READY_TRUE
};
struct RetryPolicy {
int max_attempts = 0;
grpc_millis initial_backoff = 0;
grpc_millis max_backoff = 0;
float backoff_multiplier = 0;
StatusCodeSet retryable_status_codes;
};
/// Creates a method_parameters object from \a json.
/// Intended for use with ServiceConfig::CreateMethodConfigTable().
static RefCountedPtr<ClientChannelMethodParams> CreateFromJson(
const grpc_json* json);
grpc_millis timeout() const { return timeout_; }
WaitForReady wait_for_ready() const { return wait_for_ready_; }
const RetryPolicy* retry_policy() const { return retry_policy_.get(); }
private:
// So New() can call our private ctor.
template <typename T, typename... Args>
friend T* grpc_core::New(Args&&... args);
// So Delete() can call our private dtor.
template <typename T>
friend void grpc_core::Delete(T*);
ClientChannelMethodParams() {}
virtual ~ClientChannelMethodParams() {}
grpc_millis timeout_ = 0;
WaitForReady wait_for_ready_ = WAIT_FOR_READY_UNSET;
UniquePtr<RetryPolicy> retry_policy_;
Optional<ClientChannelGlobalParsedObject::RetryThrottling>
retry_throttle_data_;
const char* health_check_service_name_ = nullptr;
};
} // namespace internal

@ -119,13 +119,9 @@ class ResolvingLoadBalancingPolicy::ResolvingControlHelper
return parent_->channel_control_helper()->CreateChannel(target, args);
}
void UpdateState(grpc_connectivity_state state, grpc_error* state_error,
void UpdateState(grpc_connectivity_state state,
UniquePtr<SubchannelPicker> picker) override {
if (parent_->resolver_ == nullptr) {
// shutting down.
GRPC_ERROR_UNREF(state_error);
return;
}
if (parent_->resolver_ == nullptr) return; // Shutting down.
// 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()) {
@ -136,10 +132,7 @@ class ResolvingLoadBalancingPolicy::ResolvingControlHelper
parent_.get(), this, child_,
grpc_connectivity_state_name(state));
}
if (state != GRPC_CHANNEL_READY) {
GRPC_ERROR_UNREF(state_error);
return;
}
if (state != GRPC_CHANNEL_READY) return;
grpc_pollset_set_del_pollset_set(
parent_->lb_policy_->interested_parties(),
parent_->interested_parties());
@ -147,11 +140,9 @@ class ResolvingLoadBalancingPolicy::ResolvingControlHelper
parent_->lb_policy_ = std::move(parent_->pending_lb_policy_);
} else if (!CalledByCurrentChild()) {
// This request is from an outdated child, so ignore it.
GRPC_ERROR_UNREF(state_error);
return;
}
parent_->channel_control_helper()->UpdateState(state, state_error,
std::move(picker));
parent_->channel_control_helper()->UpdateState(state, std::move(picker));
}
void RequestReresolution() override {
@ -192,7 +183,8 @@ class ResolvingLoadBalancingPolicy::ResolvingControlHelper
ResolvingLoadBalancingPolicy::ResolvingLoadBalancingPolicy(
Args args, TraceFlag* tracer, UniquePtr<char> target_uri,
UniquePtr<char> child_policy_name, RefCountedPtr<Config> child_lb_config,
UniquePtr<char> child_policy_name,
RefCountedPtr<ParsedLoadBalancingConfig> child_lb_config,
grpc_error** error)
: LoadBalancingPolicy(std::move(args)),
tracer_(tracer),
@ -234,8 +226,7 @@ grpc_error* ResolvingLoadBalancingPolicy::Init(const grpc_channel_args& args) {
}
// Return our picker to the channel.
channel_control_helper()->UpdateState(
GRPC_CHANNEL_IDLE, GRPC_ERROR_NONE,
UniquePtr<SubchannelPicker>(New<QueuePicker>(Ref())));
GRPC_CHANNEL_IDLE, UniquePtr<SubchannelPicker>(New<QueuePicker>(Ref())));
return GRPC_ERROR_NONE;
}
@ -313,7 +304,7 @@ void ResolvingLoadBalancingPolicy::StartResolvingLocked() {
GPR_ASSERT(!started_resolving_);
started_resolving_ = true;
channel_control_helper()->UpdateState(
GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE,
GRPC_CHANNEL_CONNECTING,
UniquePtr<SubchannelPicker>(New<QueuePicker>(Ref())));
resolver_->StartLocked();
}
@ -334,14 +325,15 @@ void ResolvingLoadBalancingPolicy::OnResolverError(grpc_error* error) {
grpc_error* state_error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
"Resolver transient failure", &error, 1);
channel_control_helper()->UpdateState(
GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(state_error),
GRPC_CHANNEL_TRANSIENT_FAILURE,
UniquePtr<SubchannelPicker>(New<TransientFailurePicker>(state_error)));
}
GRPC_ERROR_UNREF(error);
}
void ResolvingLoadBalancingPolicy::CreateOrUpdateLbPolicyLocked(
const char* lb_policy_name, RefCountedPtr<Config> lb_policy_config,
const char* lb_policy_name,
RefCountedPtr<ParsedLoadBalancingConfig> lb_policy_config,
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
@ -538,11 +530,11 @@ void ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked(
const bool resolution_contains_addresses = result.addresses.size() > 0;
// Process the resolver result.
const char* lb_policy_name = nullptr;
RefCountedPtr<Config> lb_policy_config;
RefCountedPtr<ParsedLoadBalancingConfig> 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();
@ -550,7 +542,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),
CreateOrUpdateLbPolicyLocked(lb_policy_name, lb_policy_config,
std::move(result), &trace_strings);
// Add channel trace event.
if (channelz_node() != nullptr) {

@ -23,6 +23,7 @@
#include "src/core/ext/filters/client_channel/client_channel_channelz.h"
#include "src/core/ext/filters/client_channel/lb_policy.h"
#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
#include "src/core/ext/filters/client_channel/resolver.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/channel_stack.h"
@ -53,11 +54,11 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy {
public:
// If error is set when this returns, then construction failed, and
// the caller may not use the new object.
ResolvingLoadBalancingPolicy(Args args, TraceFlag* tracer,
UniquePtr<char> target_uri,
UniquePtr<char> child_policy_name,
RefCountedPtr<Config> child_lb_config,
grpc_error** error);
ResolvingLoadBalancingPolicy(
Args args, TraceFlag* tracer, UniquePtr<char> target_uri,
UniquePtr<char> child_policy_name,
RefCountedPtr<ParsedLoadBalancingConfig> child_lb_config,
grpc_error** error);
// Private ctor, to be used by client_channel only!
//
@ -65,8 +66,9 @@ 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, Resolver::Result* result, const char** lb_policy_name,
RefCountedPtr<Config>* lb_policy_config);
void* user_data, const Resolver::Result& result,
const char** lb_policy_name,
RefCountedPtr<ParsedLoadBalancingConfig>* lb_policy_config);
// If error is set when this returns, then construction failed, and
// the caller may not use the new object.
ResolvingLoadBalancingPolicy(
@ -102,10 +104,10 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy {
void StartResolvingLocked();
void OnResolverError(grpc_error* error);
void CreateOrUpdateLbPolicyLocked(const char* lb_policy_name,
RefCountedPtr<Config> lb_policy_config,
Resolver::Result result,
TraceStringVector* trace_strings);
void CreateOrUpdateLbPolicyLocked(
const char* lb_policy_name,
RefCountedPtr<ParsedLoadBalancingConfig> lb_policy_config,
Resolver::Result result, TraceStringVector* trace_strings);
OrphanablePtr<LoadBalancingPolicy> CreateLbPolicyLocked(
const char* lb_policy_name, const grpc_channel_args& args,
TraceStringVector* trace_strings);
@ -121,7 +123,7 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy {
ProcessResolverResultCallback process_resolver_result_ = nullptr;
void* process_resolver_result_user_data_ = nullptr;
UniquePtr<char> child_policy_name_;
RefCountedPtr<Config> child_lb_config_;
RefCountedPtr<ParsedLoadBalancingConfig> child_lb_config_;
// Resolver and associated state.
OrphanablePtr<Resolver> resolver_;

@ -34,28 +34,10 @@
namespace grpc_core {
namespace {
typedef InlinedVector<UniquePtr<ServiceConfigParser>,
typedef InlinedVector<UniquePtr<ServiceConfig::Parser>,
ServiceConfig::kNumPreallocatedParsers>
ServiceConfigParserList;
ServiceConfigParserList* registered_parsers;
// Consumes all the errors in the vector and forms a referencing error from
// them. If the vector is empty, return GRPC_ERROR_NONE.
template <size_t N>
grpc_error* CreateErrorFromVector(const char* desc,
InlinedVector<grpc_error*, N>* error_list) {
grpc_error* error = GRPC_ERROR_NONE;
if (error_list->size() != 0) {
error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
desc, error_list->data(), error_list->size());
// Remove refs to all errors in error_list.
for (size_t i = 0; i < error_list->size(); i++) {
GRPC_ERROR_UNREF((*error_list)[i]);
}
error_list->clear();
}
return error;
}
ServiceConfigParserList* g_registered_parsers;
} // namespace
RefCountedPtr<ServiceConfig> ServiceConfig::Create(const char* json,
@ -107,16 +89,16 @@ grpc_error* ServiceConfig::ParseGlobalParams(const grpc_json* json_tree) {
GPR_DEBUG_ASSERT(json_tree_->type == GRPC_JSON_OBJECT);
GPR_DEBUG_ASSERT(json_tree_->key == nullptr);
InlinedVector<grpc_error*, 4> error_list;
for (size_t i = 0; i < registered_parsers->size(); i++) {
for (size_t i = 0; i < g_registered_parsers->size(); i++) {
grpc_error* parser_error = GRPC_ERROR_NONE;
auto parsed_obj =
(*registered_parsers)[i]->ParseGlobalParams(json_tree, &parser_error);
(*g_registered_parsers)[i]->ParseGlobalParams(json_tree, &parser_error);
if (parser_error != GRPC_ERROR_NONE) {
error_list.push_back(parser_error);
}
parsed_global_service_config_objects_.push_back(std::move(parsed_obj));
}
return CreateErrorFromVector("Global Params", &error_list);
return GRPC_ERROR_CREATE_FROM_VECTOR("Global Params", &error_list);
}
grpc_error* ServiceConfig::ParseJsonMethodConfigToServiceConfigObjectsTable(
@ -125,17 +107,20 @@ grpc_error* ServiceConfig::ParseJsonMethodConfigToServiceConfigObjectsTable(
size_t* idx) {
auto objs_vector = MakeUnique<ServiceConfigObjectsVector>();
InlinedVector<grpc_error*, 4> error_list;
for (size_t i = 0; i < registered_parsers->size(); i++) {
for (size_t i = 0; i < g_registered_parsers->size(); i++) {
grpc_error* parser_error = GRPC_ERROR_NONE;
auto parsed_obj =
(*registered_parsers)[i]->ParsePerMethodParams(json, &parser_error);
(*g_registered_parsers)[i]->ParsePerMethodParams(json, &parser_error);
if (parser_error != GRPC_ERROR_NONE) {
error_list.push_back(parser_error);
}
objs_vector->push_back(std::move(parsed_obj));
}
const auto* vector_ptr = objs_vector.get();
service_config_objects_vectors_storage_.push_back(std::move(objs_vector));
const auto* vector_ptr =
service_config_objects_vectors_storage_
[service_config_objects_vectors_storage_.size() - 1]
.get();
// Construct list of paths.
InlinedVector<UniquePtr<char>, 10> paths;
for (grpc_json* child = json->child; child != nullptr; child = child->next) {
@ -169,7 +154,7 @@ grpc_error* ServiceConfig::ParseJsonMethodConfigToServiceConfigObjectsTable(
++*idx;
}
wrap_error:
return CreateErrorFromVector("methodConfig", &error_list);
return GRPC_ERROR_CREATE_FROM_VECTOR("methodConfig", &error_list);
}
grpc_error* ServiceConfig::ParsePerMethodParams(const grpc_json* json_tree) {
@ -226,28 +211,11 @@ grpc_error* ServiceConfig::ParsePerMethodParams(const grpc_json* json_tree) {
num_entries, entries, nullptr);
gpr_free(entries);
}
return CreateErrorFromVector("Method Params", &error_list);
return GRPC_ERROR_CREATE_FROM_VECTOR("Method Params", &error_list);
}
ServiceConfig::~ServiceConfig() { grpc_json_destroy(json_tree_); }
const char* ServiceConfig::GetLoadBalancingPolicyName() const {
if (json_tree_->type != GRPC_JSON_OBJECT || json_tree_->key != nullptr) {
return nullptr;
}
const char* lb_policy_name = nullptr;
for (grpc_json* field = json_tree_->child; field != nullptr;
field = field->next) {
if (field->key == nullptr) return nullptr;
if (strcmp(field->key, "loadBalancingPolicy") == 0) {
if (lb_policy_name != nullptr) return nullptr; // Duplicate.
if (field->type != GRPC_JSON_STRING) return nullptr;
lb_policy_name = field->value;
}
}
return lb_policy_name;
}
int ServiceConfig::CountNamesInMethodConfig(grpc_json* json) {
int num_names = 0;
for (grpc_json* field = json->child; field != nullptr; field = field->next) {
@ -319,8 +287,11 @@ UniquePtr<char> ServiceConfig::ParseJsonMethodName(grpc_json* json,
return UniquePtr<char>(path);
}
const ServiceConfig::ServiceConfigObjectsVector* const*
const ServiceConfig::ServiceConfigObjectsVector*
ServiceConfig::GetMethodServiceConfigObjectsVector(const grpc_slice& path) {
if (parsed_method_service_config_objects_table_.get() == nullptr) {
return nullptr;
}
const auto* value = parsed_method_service_config_objects_table_->Get(path);
// If we didn't find a match for the path, try looking for a wildcard
// entry (i.e., change "/service/method" to "/service/*").
@ -339,22 +310,22 @@ ServiceConfig::GetMethodServiceConfigObjectsVector(const grpc_slice& path) {
gpr_free(path_str);
if (value == nullptr) return nullptr;
}
return value;
return *value;
}
size_t ServiceConfig::RegisterParser(UniquePtr<ServiceConfigParser> parser) {
registered_parsers->push_back(std::move(parser));
return registered_parsers->size() - 1;
size_t ServiceConfig::RegisterParser(UniquePtr<Parser> parser) {
g_registered_parsers->push_back(std::move(parser));
return g_registered_parsers->size() - 1;
}
void ServiceConfig::Init() {
GPR_ASSERT(registered_parsers == nullptr);
registered_parsers = New<ServiceConfigParserList>();
GPR_ASSERT(g_registered_parsers == nullptr);
g_registered_parsers = New<ServiceConfigParserList>();
}
void ServiceConfig::Shutdown() {
Delete(registered_parsers);
registered_parsers = nullptr;
Delete(g_registered_parsers);
g_registered_parsers = nullptr;
}
} // namespace grpc_core

@ -55,41 +55,73 @@
namespace grpc_core {
/// This is the base class that all service config parsers MUST use to store
/// parsed service config data.
class ServiceConfigParsedObject {
class ServiceConfig : public RefCounted<ServiceConfig> {
public:
virtual ~ServiceConfigParsedObject() = default;
/// This is the base class that all service config parsers MUST use to store
/// parsed service config data.
class ParsedConfig {
public:
virtual ~ParsedConfig() = default;
GRPC_ABSTRACT_BASE_CLASS;
};
/// This is the base class that all service config parsers should derive from.
class Parser {
public:
virtual ~Parser() = default;
virtual UniquePtr<ParsedConfig> ParseGlobalParams(const grpc_json* json,
grpc_error** error) {
GPR_DEBUG_ASSERT(error != nullptr);
return nullptr;
}
GRPC_ABSTRACT_BASE_CLASS;
};
virtual UniquePtr<ParsedConfig> ParsePerMethodParams(const grpc_json* json,
grpc_error** error) {
GPR_DEBUG_ASSERT(error != nullptr);
return nullptr;
}
/// This is the base class that all service config parsers should derive from.
class ServiceConfigParser {
public:
virtual ~ServiceConfigParser() = default;
GRPC_ABSTRACT_BASE_CLASS;
};
virtual UniquePtr<ServiceConfigParsedObject> ParseGlobalParams(
const grpc_json* json, grpc_error** error) {
GPR_DEBUG_ASSERT(error != nullptr);
return nullptr;
}
static constexpr int kNumPreallocatedParsers = 4;
typedef InlinedVector<UniquePtr<ParsedConfig>, kNumPreallocatedParsers>
ServiceConfigObjectsVector;
virtual UniquePtr<ServiceConfigParsedObject> ParsePerMethodParams(
const grpc_json* json, grpc_error** error) {
GPR_DEBUG_ASSERT(error != nullptr);
return nullptr;
}
/// When a service config is applied to a call in the client_channel_filter,
/// we create an instance of this object and store it in the call_data for
/// client_channel. A pointer to this object is also stored in the
/// call_context, so that future filters can easily access method and global
/// parameters for the call.
class CallData {
public:
CallData() = default;
CallData(RefCountedPtr<ServiceConfig> svc_cfg, const grpc_slice& path)
: service_config_(std::move(svc_cfg)) {
if (service_config_ != nullptr) {
method_params_vector_ =
service_config_->GetMethodServiceConfigObjectsVector(path);
}
}
GRPC_ABSTRACT_BASE_CLASS;
};
ServiceConfig* service_config() { return service_config_.get(); }
class ServiceConfig : public RefCounted<ServiceConfig> {
public:
static constexpr int kNumPreallocatedParsers = 4;
typedef InlinedVector<UniquePtr<ServiceConfigParsedObject>,
kNumPreallocatedParsers>
ServiceConfigObjectsVector;
ParsedConfig* GetMethodParsedObject(size_t index) const {
return method_params_vector_ != nullptr
? (*method_params_vector_)[index].get()
: nullptr;
}
ParsedConfig* GetGlobalParsedObject(size_t index) const {
return service_config_->GetParsedGlobalServiceConfigObject(index);
}
private:
RefCountedPtr<ServiceConfig> service_config_;
const ServiceConfigObjectsVector* method_params_vector_ = nullptr;
};
/// Creates a new service config from parsing \a json_string.
/// Returns null on parse error.
@ -100,48 +132,18 @@ class ServiceConfig : public RefCounted<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>
using ProcessJson = void (*)(const grpc_json*, T*);
template <typename T>
void ParseGlobalParams(ProcessJson<T> process_json, T* arg) const;
/// Gets the LB policy name from \a service_config.
/// Returns NULL if no LB policy name was specified.
/// Caller does NOT take ownership.
const char* GetLoadBalancingPolicyName() const;
/// Creates a method config table based on the data in \a json.
/// The table's keys are request paths. The table's value type is
/// returned by \a create_value(), based on data parsed from the JSON tree.
/// Returns null on error.
template <typename T>
using CreateValue = RefCountedPtr<T> (*)(const grpc_json* method_config_json);
template <typename T>
RefCountedPtr<SliceHashTable<RefCountedPtr<T>>> CreateMethodConfigTable(
CreateValue<T> create_value) const;
/// A helper function for looking up values in the table returned by
/// \a CreateMethodConfigTable().
/// Gets the method config for the specified \a path, which should be of
/// the form "/service/method".
/// Returns null if the method has no config.
/// Caller does NOT own a reference to the result.
template <typename T>
static RefCountedPtr<T> MethodConfigTableLookup(
const SliceHashTable<RefCountedPtr<T>>& table, const grpc_slice& path);
/// Retrieves the parsed global service config object at index \a index.
ServiceConfigParsedObject* GetParsedGlobalServiceConfigObject(int index) {
GPR_DEBUG_ASSERT(
index < static_cast<int>(parsed_global_service_config_objects_.size()));
/// Retrieves the parsed global service config object at index \a index. The
/// lifetime of the returned object is tied to the lifetime of the
/// ServiceConfig object.
ParsedConfig* GetParsedGlobalServiceConfigObject(size_t index) {
GPR_DEBUG_ASSERT(index < parsed_global_service_config_objects_.size());
return parsed_global_service_config_objects_[index].get();
}
/// Retrieves the vector of method service config objects for a given path \a
/// path.
const ServiceConfigObjectsVector* const* GetMethodServiceConfigObjectsVector(
/// path. The lifetime of the returned vector and contained objects is tied to
/// the lifetime of the ServiceConfig object.
const ServiceConfigObjectsVector* GetMethodServiceConfigObjectsVector(
const grpc_slice& path);
/// Globally register a service config parser. On successful registration, it
@ -150,7 +152,7 @@ class ServiceConfig : public RefCounted<ServiceConfig> {
/// registered parser. Each parser is responsible for reading the service
/// config json and returning a parsed object. This parsed object can later be
/// retrieved using the same index that was returned at registration time.
static size_t RegisterParser(UniquePtr<ServiceConfigParser> parser);
static size_t RegisterParser(UniquePtr<Parser> parser);
static void Init();
@ -178,14 +180,6 @@ class ServiceConfig : public RefCounted<ServiceConfig> {
static UniquePtr<char> ParseJsonMethodName(grpc_json* json,
grpc_error** error);
// Parses the method config from \a json. Adds an entry to \a entries for
// each name found, incrementing \a idx for each entry added.
// Returns false on error.
template <typename T>
static bool ParseJsonMethodConfig(
grpc_json* json, CreateValue<T> create_value,
typename SliceHashTable<RefCountedPtr<T>>::Entry* entries, size_t* idx);
grpc_error* ParseJsonMethodConfigToServiceConfigObjectsTable(
const grpc_json* json,
SliceHashTable<const ServiceConfigObjectsVector*>::Entry* entries,
@ -195,7 +189,7 @@ class ServiceConfig : public RefCounted<ServiceConfig> {
UniquePtr<char> json_string_; // Underlying storage for json_tree.
grpc_json* json_tree_;
InlinedVector<UniquePtr<ServiceConfigParsedObject>, kNumPreallocatedParsers>
InlinedVector<UniquePtr<ParsedConfig>, kNumPreallocatedParsers>
parsed_global_service_config_objects_;
// A map from the method name to the service config objects vector. Note that
// we are using a raw pointer and not a unique pointer so that we can use the
@ -208,133 +202,6 @@ class ServiceConfig : public RefCounted<ServiceConfig> {
service_config_objects_vectors_storage_;
};
//
// implementation -- no user-serviceable parts below
//
template <typename T>
void ServiceConfig::ParseGlobalParams(ProcessJson<T> process_json,
T* arg) const {
if (json_tree_->type != GRPC_JSON_OBJECT || json_tree_->key != nullptr) {
return;
}
for (grpc_json* field = json_tree_->child; field != nullptr;
field = field->next) {
if (field->key == nullptr) return;
if (strcmp(field->key, "methodConfig") == 0) continue;
process_json(field, arg);
}
}
template <typename T>
bool ServiceConfig::ParseJsonMethodConfig(
grpc_json* json, CreateValue<T> create_value,
typename SliceHashTable<RefCountedPtr<T>>::Entry* entries, size_t* idx) {
// Construct value.
RefCountedPtr<T> method_config = create_value(json);
if (method_config == nullptr) return false;
// Construct list of paths.
InlinedVector<UniquePtr<char>, 10> paths;
for (grpc_json* child = json->child; child != nullptr; child = child->next) {
if (child->key == nullptr) continue;
if (strcmp(child->key, "name") == 0) {
if (child->type != GRPC_JSON_ARRAY) return false;
for (grpc_json* name = child->child; name != nullptr; name = name->next) {
grpc_error* error = GRPC_ERROR_NONE;
UniquePtr<char> path = ParseJsonMethodName(name, &error);
// We are not reporting the error here.
GRPC_ERROR_UNREF(error);
if (path == nullptr) return false;
paths.push_back(std::move(path));
}
}
}
if (paths.size() == 0) return false; // No names specified.
// Add entry for each path.
for (size_t i = 0; i < paths.size(); ++i) {
entries[*idx].key = grpc_slice_from_copied_string(paths[i].get());
entries[*idx].value = method_config; // Takes a new ref.
++*idx;
}
// Success.
return true;
}
template <typename T>
RefCountedPtr<SliceHashTable<RefCountedPtr<T>>>
ServiceConfig::CreateMethodConfigTable(CreateValue<T> create_value) const {
// Traverse parsed JSON tree.
if (json_tree_->type != GRPC_JSON_OBJECT || json_tree_->key != nullptr) {
return nullptr;
}
size_t num_entries = 0;
typename SliceHashTable<RefCountedPtr<T>>::Entry* entries = nullptr;
for (grpc_json* field = json_tree_->child; field != nullptr;
field = field->next) {
if (field->key == nullptr) return nullptr;
if (strcmp(field->key, "methodConfig") == 0) {
if (entries != nullptr) return nullptr; // Duplicate.
if (field->type != GRPC_JSON_ARRAY) return nullptr;
// Find number of entries.
for (grpc_json* method = field->child; method != nullptr;
method = method->next) {
int count = CountNamesInMethodConfig(method);
if (count <= 0) return nullptr;
num_entries += static_cast<size_t>(count);
}
// Populate method config table entries.
entries = static_cast<typename SliceHashTable<RefCountedPtr<T>>::Entry*>(
gpr_zalloc(num_entries *
sizeof(typename SliceHashTable<RefCountedPtr<T>>::Entry)));
size_t idx = 0;
for (grpc_json* method = field->child; method != nullptr;
method = method->next) {
if (!ParseJsonMethodConfig(method, create_value, entries, &idx)) {
for (size_t i = 0; i < idx; ++i) {
grpc_slice_unref_internal(entries[i].key);
entries[i].value.reset();
}
gpr_free(entries);
return nullptr;
}
}
GPR_ASSERT(idx == num_entries);
}
}
// Instantiate method config table.
RefCountedPtr<SliceHashTable<RefCountedPtr<T>>> method_config_table;
if (entries != nullptr) {
method_config_table =
SliceHashTable<RefCountedPtr<T>>::Create(num_entries, entries, nullptr);
gpr_free(entries);
}
return method_config_table;
}
template <typename T>
RefCountedPtr<T> ServiceConfig::MethodConfigTableLookup(
const SliceHashTable<RefCountedPtr<T>>& table, const grpc_slice& path) {
const RefCountedPtr<T>* value = table.Get(path);
// If we didn't find a match for the path, try looking for a wildcard
// entry (i.e., change "/service/method" to "/service/*").
if (value == nullptr) {
char* path_str = grpc_slice_to_c_string(path);
const char* sep = strrchr(path_str, '/') + 1;
const size_t len = (size_t)(sep - path_str);
char* buf = (char*)gpr_malloc(len + 2); // '*' and NUL
memcpy(buf, path_str, len);
buf[len] = '*';
buf[len + 1] = '\0';
grpc_slice wildcard_path = grpc_slice_from_copied_string(buf);
gpr_free(buf);
value = table.Get(wildcard_path);
grpc_slice_unref_internal(wildcard_path);
gpr_free(path_str);
if (value == nullptr) return nullptr;
}
return RefCountedPtr<T>(*value);
}
} // namespace grpc_core
#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SERVICE_CONFIG_H */

@ -121,7 +121,7 @@ RefCountedPtr<SubchannelCall> ConnectedSubchannel::CreateCall(
const size_t allocation_size =
GetInitialCallSizeEstimate(args.parent_data_size);
RefCountedPtr<SubchannelCall> call(
new (gpr_arena_alloc(args.arena, allocation_size))
new (args.arena->Alloc(allocation_size))
SubchannelCall(Ref(DEBUG_LOCATION, "subchannel_call"), args));
grpc_call_stack* callstk = SUBCHANNEL_CALL_TO_CALL_STACK(call.get());
const grpc_call_element_args call_args = {
@ -332,10 +332,9 @@ class Subchannel::ConnectedSubchannelStateWatcher
health_state = GRPC_CHANNEL_CONNECTING;
}
// Report initial state.
c->SetConnectivityStateLocked(GRPC_CHANNEL_READY, GRPC_ERROR_NONE,
"subchannel_connected");
c->SetConnectivityStateLocked(GRPC_CHANNEL_READY, "subchannel_connected");
grpc_connectivity_state_set(&c->state_and_health_tracker_, health_state,
GRPC_ERROR_NONE, "subchannel_connected");
"subchannel_connected");
}
~ConnectedSubchannelStateWatcher() {
@ -367,11 +366,10 @@ class Subchannel::ConnectedSubchannelStateWatcher
c->connected_subchannel_watcher_.reset();
self->last_connectivity_state_ = GRPC_CHANNEL_TRANSIENT_FAILURE;
c->SetConnectivityStateLocked(GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_ERROR_REF(error),
"reflect_child");
grpc_connectivity_state_set(&c->state_and_health_tracker_,
GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_ERROR_REF(error), "reflect_child");
"reflect_child");
c->backoff_begun_ = false;
c->backoff_.Reset();
c->MaybeStartConnectingLocked();
@ -388,11 +386,11 @@ class Subchannel::ConnectedSubchannelStateWatcher
// from READY to CONNECTING or IDLE.
self->last_connectivity_state_ = self->pending_connectivity_state_;
c->SetConnectivityStateLocked(self->pending_connectivity_state_,
GRPC_ERROR_REF(error), "reflect_child");
"reflect_child");
if (self->pending_connectivity_state_ != GRPC_CHANNEL_READY) {
grpc_connectivity_state_set(&c->state_and_health_tracker_,
self->pending_connectivity_state_,
GRPC_ERROR_REF(error), "reflect_child");
"reflect_child");
}
c->connected_subchannel_->NotifyOnStateChange(
nullptr, &self->pending_connectivity_state_,
@ -415,8 +413,7 @@ class Subchannel::ConnectedSubchannelStateWatcher
self->health_check_client_ != nullptr) {
if (self->last_connectivity_state_ == GRPC_CHANNEL_READY) {
grpc_connectivity_state_set(&c->state_and_health_tracker_,
self->health_state_,
GRPC_ERROR_REF(error), "health_changed");
self->health_state_, "health_changed");
}
self->health_check_client_->NotifyOnHealthChange(
&self->health_state_, &self->on_health_changed_);
@ -532,25 +529,6 @@ BackOff::Options ParseArgsForBackoffValues(
.set_max_backoff(max_backoff_ms);
}
struct HealthCheckParams {
UniquePtr<char> service_name;
static void Parse(const grpc_json* field, HealthCheckParams* params) {
if (strcmp(field->key, "healthCheckConfig") == 0) {
if (field->type != GRPC_JSON_OBJECT) return;
for (grpc_json* sub_field = field->child; sub_field != nullptr;
sub_field = sub_field->next) {
if (sub_field->key == nullptr) return;
if (strcmp(sub_field->key, "serviceName") == 0) {
if (params->service_name != nullptr) return; // Duplicate.
if (sub_field->type != GRPC_JSON_STRING) return;
params->service_name.reset(gpr_strdup(sub_field->value));
}
}
}
}
};
} // namespace
Subchannel::Subchannel(SubchannelKey* key, grpc_connector* connector,
@ -586,21 +564,9 @@ Subchannel::Subchannel(SubchannelKey* key, grpc_connector* connector,
"subchannel");
grpc_connectivity_state_init(&state_and_health_tracker_, GRPC_CHANNEL_IDLE,
"subchannel");
// Check whether we should enable health checking.
const char* service_config_json = grpc_channel_arg_get_string(
grpc_channel_args_find(args_, GRPC_ARG_SERVICE_CONFIG));
if (service_config_json != nullptr) {
grpc_error* service_config_error = GRPC_ERROR_NONE;
RefCountedPtr<ServiceConfig> service_config =
ServiceConfig::Create(service_config_json, &service_config_error);
// service_config_error is currently unused.
GRPC_ERROR_UNREF(service_config_error);
if (service_config != nullptr) {
HealthCheckParams params;
service_config->ParseGlobalParams(HealthCheckParams::Parse, &params);
health_check_service_name_ = std::move(params.service_name);
}
}
health_check_service_name_ =
UniquePtr<char>(gpr_strdup(grpc_channel_arg_get_string(
grpc_channel_args_find(args_, "grpc.temp.health_check"))));
const grpc_arg* arg = grpc_channel_args_find(args_, GRPC_ARG_ENABLE_CHANNELZ);
const bool channelz_enabled =
grpc_channel_arg_get_bool(arg, GRPC_ENABLE_CHANNELZ_DEFAULT);
@ -742,11 +708,10 @@ channelz::SubchannelNode* Subchannel::channelz_node() {
}
grpc_connectivity_state Subchannel::CheckConnectivity(
grpc_error** error, bool inhibit_health_checking) {
MutexLock lock(&mu_);
bool inhibit_health_checking) {
grpc_connectivity_state_tracker* tracker =
inhibit_health_checking ? &state_tracker_ : &state_and_health_tracker_;
grpc_connectivity_state state = grpc_connectivity_state_get(tracker, error);
grpc_connectivity_state state = grpc_connectivity_state_check(tracker);
return state;
}
@ -854,7 +819,6 @@ const char* SubchannelConnectivityStateChangeString(
} // namespace
void Subchannel::SetConnectivityStateLocked(grpc_connectivity_state state,
grpc_error* error,
const char* reason) {
if (channelz_node_ != nullptr) {
channelz_node_->AddTraceEvent(
@ -862,7 +826,7 @@ void Subchannel::SetConnectivityStateLocked(grpc_connectivity_state state,
grpc_slice_from_static_string(
SubchannelConnectivityStateChangeString(state)));
}
grpc_connectivity_state_set(&state_tracker_, state, error, reason);
grpc_connectivity_state_set(&state_tracker_, state, reason);
}
void Subchannel::MaybeStartConnectingLocked() {
@ -939,11 +903,9 @@ void Subchannel::ContinueConnectingLocked() {
next_attempt_deadline_ = backoff_.NextAttemptTime();
args.deadline = std::max(next_attempt_deadline_, min_deadline);
args.channel_args = args_;
SetConnectivityStateLocked(GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE,
"connecting");
SetConnectivityStateLocked(GRPC_CHANNEL_CONNECTING, "connecting");
grpc_connectivity_state_set(&state_and_health_tracker_,
GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE,
"connecting");
GRPC_CHANNEL_CONNECTING, "connecting");
grpc_connector_connect(connector_, &args, &connecting_result_,
&on_connecting_finished_);
}
@ -961,16 +923,11 @@ void Subchannel::OnConnectingFinished(void* arg, grpc_error* error) {
} else if (c->disconnected_) {
GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting");
} else {
const char* errmsg = grpc_error_string(error);
gpr_log(GPR_INFO, "Connect failed: %s", errmsg);
error = grpc_error_set_int(
GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING("Connect Failed",
&error, 1),
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
gpr_log(GPR_INFO, "Connect failed: %s", grpc_error_string(error));
c->SetConnectivityStateLocked(GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_ERROR_REF(error), "connect_failed");
"connect_failed");
grpc_connectivity_state_set(&c->state_and_health_tracker_,
GRPC_CHANNEL_TRANSIENT_FAILURE, error,
GRPC_CHANNEL_TRANSIENT_FAILURE,
"connect_failed");
c->MaybeStartConnectingLocked();
GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting");

@ -26,7 +26,7 @@
#include "src/core/ext/filters/client_channel/subchannel_pool_interface.h"
#include "src/core/lib/backoff/backoff.h"
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/gpr/arena.h"
#include "src/core/lib/gprpp/arena.h"
#include "src/core/lib/gprpp/ref_counted.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/gprpp/sync.h"
@ -75,9 +75,9 @@ class ConnectedSubchannel : public RefCounted<ConnectedSubchannel> {
grpc_slice path;
gpr_timespec start_time;
grpc_millis deadline;
gpr_arena* arena;
Arena* arena;
grpc_call_context_element* context;
grpc_call_combiner* call_combiner;
grpc_core::CallCombiner* call_combiner;
size_t parent_data_size;
};
@ -208,8 +208,7 @@ class Subchannel {
channelz::SubchannelNode* channelz_node();
// Polls the current connectivity state of the subchannel.
grpc_connectivity_state CheckConnectivity(grpc_error** error,
bool inhibit_health_checking);
grpc_connectivity_state CheckConnectivity(bool inhibit_health_checking);
// When the connectivity state of the subchannel changes from \a *state,
// invokes \a notify and updates \a *state with the new state.
@ -242,7 +241,7 @@ class Subchannel {
// Sets the subchannel's connectivity state to \a state.
void SetConnectivityStateLocked(grpc_connectivity_state state,
grpc_error* error, const char* reason);
const char* reason);
// Methods for connection.
void MaybeStartConnectingLocked();

@ -68,8 +68,7 @@ static void timer_callback(void* arg, grpc_error* error) {
error = grpc_error_set_int(
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Deadline Exceeded"),
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_DEADLINE_EXCEEDED);
grpc_call_combiner_cancel(deadline_state->call_combiner,
GRPC_ERROR_REF(error));
deadline_state->call_combiner->Cancel(GRPC_ERROR_REF(error));
GRPC_CLOSURE_INIT(&deadline_state->timer_callback,
send_cancel_op_in_call_combiner, elem,
grpc_schedule_on_exec_ctx);
@ -124,7 +123,7 @@ static void cancel_timer_if_needed(grpc_deadline_state* deadline_state) {
deadline_state->timer_state = GRPC_DEADLINE_STATE_FINISHED;
grpc_timer_cancel(&deadline_state->timer);
} else {
// timer was either in STATE_INITAL (nothing to cancel)
// timer was either in STATE_INITIAL (nothing to cancel)
// OR in STATE_FINISHED (again nothing to cancel)
}
}
@ -183,7 +182,7 @@ static void start_timer_after_init(void* arg, grpc_error* error) {
grpc_deadline_state::grpc_deadline_state(grpc_call_element* elem,
grpc_call_stack* call_stack,
grpc_call_combiner* call_combiner,
grpc_core::CallCombiner* call_combiner,
grpc_millis deadline)
: call_stack(call_stack), call_combiner(call_combiner) {
// Deadline will always be infinite on servers, so the timer will only be

@ -32,12 +32,13 @@ enum grpc_deadline_timer_state {
// Must be the first field in the filter's call_data.
struct grpc_deadline_state {
grpc_deadline_state(grpc_call_element* elem, grpc_call_stack* call_stack,
grpc_call_combiner* call_combiner, grpc_millis deadline);
grpc_core::CallCombiner* call_combiner,
grpc_millis deadline);
~grpc_deadline_state();
// We take a reference to the call stack for the timer callback.
grpc_call_stack* call_stack;
grpc_call_combiner* call_combiner;
grpc_core::CallCombiner* call_combiner;
grpc_deadline_timer_state timer_state = GRPC_DEADLINE_STATE_INITIAL;
grpc_timer timer;
grpc_closure timer_callback;

@ -36,7 +36,7 @@
#define EXPECTED_CONTENT_TYPE "application/grpc"
#define EXPECTED_CONTENT_TYPE_LENGTH sizeof(EXPECTED_CONTENT_TYPE) - 1
/* default maximum size of payload eligable for GET request */
/* default maximum size of payload eligible for GET request */
static constexpr size_t kMaxPayloadSizeForGet = 2048;
static void recv_initial_metadata_ready(void* user_data, grpc_error* error);
@ -62,7 +62,7 @@ struct call_data {
~call_data() { GRPC_ERROR_UNREF(recv_initial_metadata_error); }
grpc_call_combiner* call_combiner;
grpc_core::CallCombiner* call_combiner;
// State for handling send_initial_metadata ops.
grpc_linked_mdelem method;
grpc_linked_mdelem scheme;
@ -107,7 +107,8 @@ static grpc_error* client_filter_incoming_metadata(grpc_call_element* elem,
* https://github.com/grpc/grpc/blob/master/doc/http-grpc-status-mapping.md.
*/
if (b->idx.named.grpc_status != nullptr ||
grpc_mdelem_eq(b->idx.named.status->md, GRPC_MDELEM_STATUS_200)) {
grpc_mdelem_static_value_eq(b->idx.named.status->md,
GRPC_MDELEM_STATUS_200)) {
grpc_metadata_batch_remove(b, b->idx.named.status);
} else {
char* val = grpc_dump_slice(GRPC_MDVALUE(b->idx.named.status->md),
@ -140,8 +141,9 @@ static grpc_error* client_filter_incoming_metadata(grpc_call_element* elem,
}
if (b->idx.named.content_type != nullptr) {
if (!grpc_mdelem_eq(b->idx.named.content_type->md,
GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC)) {
if (!grpc_mdelem_static_value_eq(
b->idx.named.content_type->md,
GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC)) {
if (grpc_slice_buf_start_eq(GRPC_MDVALUE(b->idx.named.content_type->md),
EXPECTED_CONTENT_TYPE,
EXPECTED_CONTENT_TYPE_LENGTH) &&

@ -25,7 +25,7 @@
/* Processes metadata on the client side for HTTP2 transports */
extern const grpc_channel_filter grpc_http_client_filter;
/* Channel arg to determine maximum size of payload eligable for GET request */
/* Channel arg to determine maximum size of payload eligible for GET request */
#define GRPC_ARG_MAX_PAYLOAD_SIZE_FOR_GET "grpc.max_payload_size_for_get"
#endif /* GRPC_CORE_EXT_FILTERS_HTTP_CLIENT_HTTP_CLIENT_FILTER_H */

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

Loading…
Cancel
Save