aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--BUILD10
-rw-r--r--CMakeLists.txt14
-rw-r--r--Makefile17
-rw-r--r--PYTHON-MANIFEST.in1
-rw-r--r--build.yaml8
-rw-r--r--cmake/cares.cmake4
-rw-r--r--config.m42
-rw-r--r--config.w322
-rw-r--r--examples/csharp/.gitignore2
-rw-r--r--examples/csharp/Helloworld/Greeter.sln2
-rw-r--r--examples/csharp/Helloworld/Greeter/Greeter.csproj17
-rw-r--r--examples/csharp/Helloworld/Greeter/Helloworld.cs312
-rw-r--r--examples/csharp/Helloworld/Greeter/HelloworldGrpc.cs149
-rw-r--r--examples/csharp/Helloworld/GreeterClient/GreeterClient.csproj8
-rw-r--r--examples/csharp/Helloworld/GreeterServer/GreeterServer.csproj8
-rw-r--r--examples/csharp/Helloworld/README.md32
-rw-r--r--examples/csharp/Helloworld/generate_protos.bat28
-rw-r--r--examples/csharp/HelloworldLegacyCsproj/Greeter.sln2
-rw-r--r--examples/csharp/HelloworldLegacyCsproj/Greeter/Greeter.csproj23
-rw-r--r--examples/csharp/HelloworldLegacyCsproj/Greeter/Helloworld.cs312
-rw-r--r--examples/csharp/HelloworldLegacyCsproj/Greeter/HelloworldGrpc.cs149
-rw-r--r--examples/csharp/HelloworldLegacyCsproj/Greeter/packages.config10
-rw-r--r--examples/csharp/HelloworldLegacyCsproj/GreeterClient/GreeterClient.csproj8
-rw-r--r--examples/csharp/HelloworldLegacyCsproj/GreeterClient/packages.config6
-rw-r--r--examples/csharp/HelloworldLegacyCsproj/GreeterServer/GreeterServer.csproj8
-rw-r--r--examples/csharp/HelloworldLegacyCsproj/GreeterServer/packages.config6
-rw-r--r--examples/csharp/HelloworldLegacyCsproj/README.md27
-rw-r--r--examples/csharp/HelloworldLegacyCsproj/generate_protos.bat26
-rw-r--r--examples/csharp/RouteGuide/RouteGuide.sln2
-rw-r--r--examples/csharp/RouteGuide/RouteGuide/RouteGuide.cs981
-rw-r--r--examples/csharp/RouteGuide/RouteGuide/RouteGuide.csproj21
-rw-r--r--examples/csharp/RouteGuide/RouteGuide/RouteGuideGrpc.cs331
-rw-r--r--examples/csharp/RouteGuide/RouteGuide/RouteGuideUtil.cs2
-rw-r--r--examples/csharp/RouteGuide/RouteGuideClient/RouteGuideClient.csproj8
-rw-r--r--examples/csharp/RouteGuide/RouteGuideServer/RouteGuideServer.csproj8
-rw-r--r--examples/csharp/RouteGuide/generate_protos.bat28
-rw-r--r--examples/objective-c/helloworld/HelloWorld.xcodeproj/project.pbxproj8
-rw-r--r--gRPC-C++.podspec5
-rw-r--r--gRPC-Core.podspec6
-rw-r--r--grpc.gemspec4
-rw-r--r--grpc.gyp10
-rw-r--r--include/grpc/grpc.h3
-rw-r--r--include/grpc/impl/codegen/port_platform.h9
-rw-r--r--include/grpcpp/health_check_service_interface.h4
-rw-r--r--include/grpcpp/impl/codegen/channel_interface.h1
-rw-r--r--include/grpcpp/impl/codegen/client_callback.h32
-rw-r--r--include/grpcpp/impl/codegen/client_context.h6
-rw-r--r--include/grpcpp/impl/codegen/client_interceptor.h48
-rw-r--r--include/grpcpp/impl/codegen/server_context.h4
-rw-r--r--include/grpcpp/impl/codegen/server_interceptor.h25
-rw-r--r--include/grpcpp/impl/codegen/server_interface.h18
-rw-r--r--package.xml4
-rw-r--r--setup.cfg3
-rw-r--r--src/core/ext/filters/client_channel/client_channel.cc28
-rw-r--r--src/core/ext/filters/client_channel/lb_policy.h9
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc242
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h2
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc33
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h2
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc93
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc40
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/subchannel_list.h53
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/xds/xds.cc247
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h2
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc33
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h2
-rw-r--r--src/core/ext/filters/client_channel/lb_policy_factory.cc163
-rw-r--r--src/core/ext/filters/client_channel/lb_policy_factory.h86
-rw-r--r--src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc12
-rw-r--r--src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc1
-rw-r--r--src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc149
-rw-r--r--src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h13
-rw-r--r--src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc9
-rw-r--r--src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc3
-rw-r--r--src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc26
-rw-r--r--src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc14
-rw-r--r--src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc3
-rw-r--r--src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h3
-rw-r--r--src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc34
-rw-r--r--src/core/ext/filters/client_channel/resolver_result_parsing.cc85
-rw-r--r--src/core/ext/filters/client_channel/server_address.cc103
-rw-r--r--src/core/ext/filters/client_channel/server_address.h108
-rw-r--r--src/core/ext/filters/client_channel/subchannel.cc16
-rw-r--r--src/core/ext/filters/client_channel/subchannel.h13
-rw-r--r--src/core/ext/filters/client_channel/subchannel_index.cc47
-rw-r--r--src/core/ext/transport/chttp2/client/chttp2_connector.cc5
-rw-r--r--src/core/ext/transport/chttp2/server/chttp2_server.cc2
-rw-r--r--src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc2
-rw-r--r--src/core/ext/transport/chttp2/transport/chttp2_transport.cc9
-rw-r--r--src/core/ext/transport/chttp2/transport/chttp2_transport.h4
-rw-r--r--src/core/ext/transport/inproc/inproc_transport.cc2
-rw-r--r--src/core/lib/channel/channelz.cc37
-rw-r--r--src/core/lib/channel/channelz.h8
-rw-r--r--src/core/lib/channel/channelz_registry.cc5
-rw-r--r--src/core/lib/debug/trace.cc3
-rw-r--r--src/core/lib/debug/trace.h3
-rw-r--r--src/core/lib/gpr/sync_posix.cc100
-rw-r--r--src/core/lib/iomgr/call_combiner.cc52
-rw-r--r--src/core/lib/iomgr/call_combiner.h31
-rw-r--r--src/core/lib/iomgr/dynamic_annotations.h67
-rw-r--r--src/core/lib/iomgr/exec_ctx.cc13
-rw-r--r--src/core/lib/iomgr/sockaddr_utils.cc1
-rw-r--r--src/core/lib/iomgr/tcp_windows.cc94
-rw-r--r--src/core/lib/iomgr/timer_manager.cc6
-rw-r--r--src/core/lib/security/credentials/google_default/google_default_credentials.cc138
-rw-r--r--src/core/lib/surface/server.cc128
-rw-r--r--src/core/lib/surface/server.h12
-rw-r--r--src/cpp/client/channel_cc.cc5
-rw-r--r--src/cpp/server/channelz/channelz_service.cc4
-rw-r--r--src/cpp/server/health/default_health_check_service.cc19
-rw-r--r--src/cpp/server/health/default_health_check_service.h3
-rw-r--r--src/cpp/server/server_cc.cc17
-rw-r--r--src/proto/grpc/channelz/channelz.proto36
-rw-r--r--src/python/grpcio/grpc/_channel.py1
-rw-r--r--src/python/grpcio/grpc/_cython/BUILD.bazel47
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/_hooks.pyx.pxi15
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi27
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/channelz.pyx.pxi8
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi3
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/propagation_bits.pxd.pxi20
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/propagation_bits.pyx.pxi20
-rw-r--r--src/python/grpcio/grpc/_cython/cygrpc.pxd1
-rw-r--r--src/python/grpcio/grpc/_cython/cygrpc.pyx1
-rw-r--r--src/python/grpcio/grpc/_interceptor.py5
-rw-r--r--src/python/grpcio/grpc/_server.py72
-rw-r--r--src/python/grpcio/grpc_core_dependencies.py2
-rw-r--r--src/python/grpcio_channelz/MANIFEST.in1
-rw-r--r--src/python/grpcio_channelz/channelz_commands.py8
-rw-r--r--src/python/grpcio_channelz/grpc_channelz/v1/channelz.py3
-rw-r--r--src/python/grpcio_channelz/setup.py2
-rw-r--r--src/python/grpcio_health_checking/MANIFEST.in1
-rw-r--r--src/python/grpcio_health_checking/health_commands.py8
-rw-r--r--src/python/grpcio_health_checking/setup.py2
-rw-r--r--src/python/grpcio_reflection/MANIFEST.in1
-rw-r--r--src/python/grpcio_reflection/reflection_commands.py8
-rw-r--r--src/python/grpcio_reflection/setup.py2
-rw-r--r--src/python/grpcio_testing/MANIFEST.in1
-rw-r--r--src/python/grpcio_testing/setup.py33
-rw-r--r--src/python/grpcio_testing/testing_commands.py39
-rw-r--r--src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py46
-rw-r--r--src/python/grpcio_tests/tests/qps/worker_server.py4
-rw-r--r--src/python/grpcio_tests/tests/unit/_exit_scenarios.py2
-rw-r--r--src/ruby/ext/grpc/rb_grpc_imports.generated.h2
-rw-r--r--templates/gRPC-C++.podspec.template10
-rw-r--r--test/core/bad_client/bad_client.cc2
-rw-r--r--test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc12
-rw-r--r--test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc15
-rw-r--r--test/core/client_channel/resolvers/fake_resolver_test.cc42
-rw-r--r--test/core/end2end/fixtures/h2_sockpair+trace.cc2
-rw-r--r--test/core/end2end/fixtures/h2_sockpair.cc2
-rw-r--r--test/core/end2end/fixtures/h2_sockpair_1byte.cc2
-rw-r--r--test/core/end2end/fuzzers/api_fuzzer.cc30
-rw-r--r--test/core/end2end/fuzzers/server_fuzzer.cc2
-rw-r--r--test/core/end2end/goaway_server_test.cc29
-rw-r--r--test/core/end2end/no_server_test.cc1
-rw-r--r--test/core/end2end/tests/channelz.cc4
-rw-r--r--test/core/security/credentials_test.cc76
-rw-r--r--test/core/util/ubsan_suppressions.txt3
-rw-r--r--test/cpp/client/client_channel_stress_test.cc28
-rw-r--r--test/cpp/end2end/BUILD13
-rw-r--r--test/cpp/end2end/channelz_service_test.cc82
-rw-r--r--test/cpp/end2end/client_callback_end2end_test.cc47
-rw-r--r--test/cpp/end2end/client_interceptors_end2end_test.cc6
-rw-r--r--test/cpp/end2end/client_lb_end2end_test.cc111
-rw-r--r--test/cpp/end2end/grpclb_end2end_test.cc37
-rw-r--r--test/cpp/end2end/health_service_end2end_test.cc149
-rw-r--r--test/cpp/end2end/interceptors_util.cc1
-rw-r--r--test/cpp/end2end/server_interceptors_end2end_test.cc29
-rw-r--r--test/cpp/end2end/test_health_check_service_impl.cc97
-rw-r--r--test/cpp/end2end/test_health_check_service_impl.h58
-rw-r--r--test/cpp/microbenchmarks/BUILD53
-rw-r--r--test/cpp/microbenchmarks/bm_call_create.cc2
-rw-r--r--test/cpp/microbenchmarks/fullstack_fixtures.h2
-rw-r--r--test/cpp/naming/address_sorting_test.cc127
-rw-r--r--test/cpp/naming/resolver_component_test.cc21
-rw-r--r--test/cpp/performance/writes_per_rpc_test.cc2
-rw-r--r--tools/doxygen/Doxyfile.c++.internal1
-rw-r--r--tools/doxygen/Doxyfile.core.internal4
-rwxr-xr-xtools/internal_ci/linux/grpc_bazel_on_foundry_base.sh13
-rw-r--r--tools/remote_build/kokoro.bazelrc1
-rwxr-xr-xtools/run_tests/artifacts/build_artifact_python.sh3
-rwxr-xr-xtools/run_tests/artifacts/build_package_python.sh14
-rw-r--r--tools/run_tests/generated/sources_and_headers.json12
183 files changed, 2731 insertions, 4043 deletions
diff --git a/BUILD b/BUILD
index 0d789ae7c0..034e47d1a9 100644
--- a/BUILD
+++ b/BUILD
@@ -856,6 +856,7 @@ grpc_cc_library(
"src/core/lib/iomgr/call_combiner.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_pair.h",
"src/core/lib/iomgr/error.h",
@@ -1047,7 +1048,6 @@ grpc_cc_library(
"src/core/ext/filters/client_channel/http_connect_handshaker.cc",
"src/core/ext/filters/client_channel/http_proxy.cc",
"src/core/ext/filters/client_channel/lb_policy.cc",
- "src/core/ext/filters/client_channel/lb_policy_factory.cc",
"src/core/ext/filters/client_channel/lb_policy_registry.cc",
"src/core/ext/filters/client_channel/parse_address.cc",
"src/core/ext/filters/client_channel/proxy_mapper.cc",
@@ -1056,6 +1056,7 @@ grpc_cc_library(
"src/core/ext/filters/client_channel/resolver_registry.cc",
"src/core/ext/filters/client_channel/resolver_result_parsing.cc",
"src/core/ext/filters/client_channel/retry_throttle.cc",
+ "src/core/ext/filters/client_channel/server_address.cc",
"src/core/ext/filters/client_channel/subchannel.cc",
"src/core/ext/filters/client_channel/subchannel_index.cc",
],
@@ -1079,6 +1080,7 @@ grpc_cc_library(
"src/core/ext/filters/client_channel/resolver_registry.h",
"src/core/ext/filters/client_channel/resolver_result_parsing.h",
"src/core/ext/filters/client_channel/retry_throttle.h",
+ "src/core/ext/filters/client_channel/server_address.h",
"src/core/ext/filters/client_channel/subchannel.h",
"src/core/ext/filters/client_channel/subchannel_index.h",
],
@@ -1088,11 +1090,11 @@ grpc_cc_library(
"grpc_base",
"grpc_client_authority_filter",
"grpc_deadline_filter",
+ "health_proto",
"inlined_vector",
"orphanable",
"ref_counted",
"ref_counted_ptr",
- "health_proto",
],
)
@@ -1590,8 +1592,8 @@ grpc_cc_library(
"src/core/lib/security/security_connector/load_system_roots_linux.cc",
"src/core/lib/security/security_connector/local/local_security_connector.cc",
"src/core/lib/security/security_connector/security_connector.cc",
- "src/core/lib/security/security_connector/ssl_utils.cc",
"src/core/lib/security/security_connector/ssl/ssl_security_connector.cc",
+ "src/core/lib/security/security_connector/ssl_utils.cc",
"src/core/lib/security/transport/client_auth_filter.cc",
"src/core/lib/security/transport/secure_endpoint.cc",
"src/core/lib/security/transport/security_handshaker.cc",
@@ -1624,8 +1626,8 @@ grpc_cc_library(
"src/core/lib/security/security_connector/load_system_roots_linux.h",
"src/core/lib/security/security_connector/local/local_security_connector.h",
"src/core/lib/security/security_connector/security_connector.h",
- "src/core/lib/security/security_connector/ssl_utils.h",
"src/core/lib/security/security_connector/ssl/ssl_security_connector.h",
+ "src/core/lib/security/security_connector/ssl_utils.h",
"src/core/lib/security/transport/auth_filters.h",
"src/core/lib/security/transport/secure_endpoint.h",
"src/core/lib/security/transport/security_handshaker.h",
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a956296092..08240fe82b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1240,7 +1240,6 @@ add_library(grpc
src/core/ext/filters/client_channel/http_connect_handshaker.cc
src/core/ext/filters/client_channel/http_proxy.cc
src/core/ext/filters/client_channel/lb_policy.cc
- src/core/ext/filters/client_channel/lb_policy_factory.cc
src/core/ext/filters/client_channel/lb_policy_registry.cc
src/core/ext/filters/client_channel/parse_address.cc
src/core/ext/filters/client_channel/proxy_mapper.cc
@@ -1249,6 +1248,7 @@ add_library(grpc
src/core/ext/filters/client_channel/resolver_registry.cc
src/core/ext/filters/client_channel/resolver_result_parsing.cc
src/core/ext/filters/client_channel/retry_throttle.cc
+ src/core/ext/filters/client_channel/server_address.cc
src/core/ext/filters/client_channel/subchannel.cc
src/core/ext/filters/client_channel/subchannel_index.cc
src/core/ext/filters/deadline/deadline_filter.cc
@@ -1592,7 +1592,6 @@ add_library(grpc_cronet
src/core/ext/filters/client_channel/http_connect_handshaker.cc
src/core/ext/filters/client_channel/http_proxy.cc
src/core/ext/filters/client_channel/lb_policy.cc
- src/core/ext/filters/client_channel/lb_policy_factory.cc
src/core/ext/filters/client_channel/lb_policy_registry.cc
src/core/ext/filters/client_channel/parse_address.cc
src/core/ext/filters/client_channel/proxy_mapper.cc
@@ -1601,6 +1600,7 @@ add_library(grpc_cronet
src/core/ext/filters/client_channel/resolver_registry.cc
src/core/ext/filters/client_channel/resolver_result_parsing.cc
src/core/ext/filters/client_channel/retry_throttle.cc
+ src/core/ext/filters/client_channel/server_address.cc
src/core/ext/filters/client_channel/subchannel.cc
src/core/ext/filters/client_channel/subchannel_index.cc
src/core/ext/filters/deadline/deadline_filter.cc
@@ -1963,7 +1963,6 @@ add_library(grpc_test_util
src/core/ext/filters/client_channel/http_connect_handshaker.cc
src/core/ext/filters/client_channel/http_proxy.cc
src/core/ext/filters/client_channel/lb_policy.cc
- src/core/ext/filters/client_channel/lb_policy_factory.cc
src/core/ext/filters/client_channel/lb_policy_registry.cc
src/core/ext/filters/client_channel/parse_address.cc
src/core/ext/filters/client_channel/proxy_mapper.cc
@@ -1972,6 +1971,7 @@ add_library(grpc_test_util
src/core/ext/filters/client_channel/resolver_registry.cc
src/core/ext/filters/client_channel/resolver_result_parsing.cc
src/core/ext/filters/client_channel/retry_throttle.cc
+ src/core/ext/filters/client_channel/server_address.cc
src/core/ext/filters/client_channel/subchannel.cc
src/core/ext/filters/client_channel/subchannel_index.cc
src/core/ext/filters/deadline/deadline_filter.cc
@@ -2283,7 +2283,6 @@ add_library(grpc_test_util_unsecure
src/core/ext/filters/client_channel/http_connect_handshaker.cc
src/core/ext/filters/client_channel/http_proxy.cc
src/core/ext/filters/client_channel/lb_policy.cc
- src/core/ext/filters/client_channel/lb_policy_factory.cc
src/core/ext/filters/client_channel/lb_policy_registry.cc
src/core/ext/filters/client_channel/parse_address.cc
src/core/ext/filters/client_channel/proxy_mapper.cc
@@ -2292,6 +2291,7 @@ add_library(grpc_test_util_unsecure
src/core/ext/filters/client_channel/resolver_registry.cc
src/core/ext/filters/client_channel/resolver_result_parsing.cc
src/core/ext/filters/client_channel/retry_throttle.cc
+ src/core/ext/filters/client_channel/server_address.cc
src/core/ext/filters/client_channel/subchannel.cc
src/core/ext/filters/client_channel/subchannel_index.cc
src/core/ext/filters/deadline/deadline_filter.cc
@@ -2617,7 +2617,6 @@ add_library(grpc_unsecure
src/core/ext/filters/client_channel/http_connect_handshaker.cc
src/core/ext/filters/client_channel/http_proxy.cc
src/core/ext/filters/client_channel/lb_policy.cc
- src/core/ext/filters/client_channel/lb_policy_factory.cc
src/core/ext/filters/client_channel/lb_policy_registry.cc
src/core/ext/filters/client_channel/parse_address.cc
src/core/ext/filters/client_channel/proxy_mapper.cc
@@ -2626,6 +2625,7 @@ add_library(grpc_unsecure
src/core/ext/filters/client_channel/resolver_registry.cc
src/core/ext/filters/client_channel/resolver_result_parsing.cc
src/core/ext/filters/client_channel/retry_throttle.cc
+ src/core/ext/filters/client_channel/server_address.cc
src/core/ext/filters/client_channel/subchannel.cc
src/core/ext/filters/client_channel/subchannel_index.cc
src/core/ext/filters/deadline/deadline_filter.cc
@@ -3469,7 +3469,6 @@ add_library(grpc++_cronet
src/core/ext/filters/client_channel/http_connect_handshaker.cc
src/core/ext/filters/client_channel/http_proxy.cc
src/core/ext/filters/client_channel/lb_policy.cc
- src/core/ext/filters/client_channel/lb_policy_factory.cc
src/core/ext/filters/client_channel/lb_policy_registry.cc
src/core/ext/filters/client_channel/parse_address.cc
src/core/ext/filters/client_channel/proxy_mapper.cc
@@ -3478,6 +3477,7 @@ add_library(grpc++_cronet
src/core/ext/filters/client_channel/resolver_registry.cc
src/core/ext/filters/client_channel/resolver_result_parsing.cc
src/core/ext/filters/client_channel/retry_throttle.cc
+ src/core/ext/filters/client_channel/server_address.cc
src/core/ext/filters/client_channel/subchannel.cc
src/core/ext/filters/client_channel/subchannel_index.cc
src/core/ext/filters/deadline/deadline_filter.cc
@@ -4024,6 +4024,7 @@ add_library(grpc++_test_util
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h
+ test/cpp/end2end/test_health_check_service_impl.cc
test/cpp/end2end/test_service_impl.cc
test/cpp/util/byte_buffer_proto_helper.cc
test/cpp/util/channel_trace_proto_helper.cc
@@ -4224,6 +4225,7 @@ add_library(grpc++_test_util_unsecure
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h
+ test/cpp/end2end/test_health_check_service_impl.cc
test/cpp/end2end/test_service_impl.cc
test/cpp/util/byte_buffer_proto_helper.cc
test/cpp/util/string_ref_helper.cc
diff --git a/Makefile b/Makefile
index e1ae7e7ad6..950ac75695 100644
--- a/Makefile
+++ b/Makefile
@@ -3735,7 +3735,6 @@ LIBGRPC_SRC = \
src/core/ext/filters/client_channel/http_connect_handshaker.cc \
src/core/ext/filters/client_channel/http_proxy.cc \
src/core/ext/filters/client_channel/lb_policy.cc \
- src/core/ext/filters/client_channel/lb_policy_factory.cc \
src/core/ext/filters/client_channel/lb_policy_registry.cc \
src/core/ext/filters/client_channel/parse_address.cc \
src/core/ext/filters/client_channel/proxy_mapper.cc \
@@ -3744,6 +3743,7 @@ LIBGRPC_SRC = \
src/core/ext/filters/client_channel/resolver_registry.cc \
src/core/ext/filters/client_channel/resolver_result_parsing.cc \
src/core/ext/filters/client_channel/retry_throttle.cc \
+ src/core/ext/filters/client_channel/server_address.cc \
src/core/ext/filters/client_channel/subchannel.cc \
src/core/ext/filters/client_channel/subchannel_index.cc \
src/core/ext/filters/deadline/deadline_filter.cc \
@@ -4081,7 +4081,6 @@ LIBGRPC_CRONET_SRC = \
src/core/ext/filters/client_channel/http_connect_handshaker.cc \
src/core/ext/filters/client_channel/http_proxy.cc \
src/core/ext/filters/client_channel/lb_policy.cc \
- src/core/ext/filters/client_channel/lb_policy_factory.cc \
src/core/ext/filters/client_channel/lb_policy_registry.cc \
src/core/ext/filters/client_channel/parse_address.cc \
src/core/ext/filters/client_channel/proxy_mapper.cc \
@@ -4090,6 +4089,7 @@ LIBGRPC_CRONET_SRC = \
src/core/ext/filters/client_channel/resolver_registry.cc \
src/core/ext/filters/client_channel/resolver_result_parsing.cc \
src/core/ext/filters/client_channel/retry_throttle.cc \
+ src/core/ext/filters/client_channel/server_address.cc \
src/core/ext/filters/client_channel/subchannel.cc \
src/core/ext/filters/client_channel/subchannel_index.cc \
src/core/ext/filters/deadline/deadline_filter.cc \
@@ -4445,7 +4445,6 @@ LIBGRPC_TEST_UTIL_SRC = \
src/core/ext/filters/client_channel/http_connect_handshaker.cc \
src/core/ext/filters/client_channel/http_proxy.cc \
src/core/ext/filters/client_channel/lb_policy.cc \
- src/core/ext/filters/client_channel/lb_policy_factory.cc \
src/core/ext/filters/client_channel/lb_policy_registry.cc \
src/core/ext/filters/client_channel/parse_address.cc \
src/core/ext/filters/client_channel/proxy_mapper.cc \
@@ -4454,6 +4453,7 @@ LIBGRPC_TEST_UTIL_SRC = \
src/core/ext/filters/client_channel/resolver_registry.cc \
src/core/ext/filters/client_channel/resolver_result_parsing.cc \
src/core/ext/filters/client_channel/retry_throttle.cc \
+ src/core/ext/filters/client_channel/server_address.cc \
src/core/ext/filters/client_channel/subchannel.cc \
src/core/ext/filters/client_channel/subchannel_index.cc \
src/core/ext/filters/deadline/deadline_filter.cc \
@@ -4751,7 +4751,6 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \
src/core/ext/filters/client_channel/http_connect_handshaker.cc \
src/core/ext/filters/client_channel/http_proxy.cc \
src/core/ext/filters/client_channel/lb_policy.cc \
- src/core/ext/filters/client_channel/lb_policy_factory.cc \
src/core/ext/filters/client_channel/lb_policy_registry.cc \
src/core/ext/filters/client_channel/parse_address.cc \
src/core/ext/filters/client_channel/proxy_mapper.cc \
@@ -4760,6 +4759,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \
src/core/ext/filters/client_channel/resolver_registry.cc \
src/core/ext/filters/client_channel/resolver_result_parsing.cc \
src/core/ext/filters/client_channel/retry_throttle.cc \
+ src/core/ext/filters/client_channel/server_address.cc \
src/core/ext/filters/client_channel/subchannel.cc \
src/core/ext/filters/client_channel/subchannel_index.cc \
src/core/ext/filters/deadline/deadline_filter.cc \
@@ -5058,7 +5058,6 @@ LIBGRPC_UNSECURE_SRC = \
src/core/ext/filters/client_channel/http_connect_handshaker.cc \
src/core/ext/filters/client_channel/http_proxy.cc \
src/core/ext/filters/client_channel/lb_policy.cc \
- src/core/ext/filters/client_channel/lb_policy_factory.cc \
src/core/ext/filters/client_channel/lb_policy_registry.cc \
src/core/ext/filters/client_channel/parse_address.cc \
src/core/ext/filters/client_channel/proxy_mapper.cc \
@@ -5067,6 +5066,7 @@ LIBGRPC_UNSECURE_SRC = \
src/core/ext/filters/client_channel/resolver_registry.cc \
src/core/ext/filters/client_channel/resolver_result_parsing.cc \
src/core/ext/filters/client_channel/retry_throttle.cc \
+ src/core/ext/filters/client_channel/server_address.cc \
src/core/ext/filters/client_channel/subchannel.cc \
src/core/ext/filters/client_channel/subchannel_index.cc \
src/core/ext/filters/deadline/deadline_filter.cc \
@@ -5885,7 +5885,6 @@ LIBGRPC++_CRONET_SRC = \
src/core/ext/filters/client_channel/http_connect_handshaker.cc \
src/core/ext/filters/client_channel/http_proxy.cc \
src/core/ext/filters/client_channel/lb_policy.cc \
- src/core/ext/filters/client_channel/lb_policy_factory.cc \
src/core/ext/filters/client_channel/lb_policy_registry.cc \
src/core/ext/filters/client_channel/parse_address.cc \
src/core/ext/filters/client_channel/proxy_mapper.cc \
@@ -5894,6 +5893,7 @@ LIBGRPC++_CRONET_SRC = \
src/core/ext/filters/client_channel/resolver_registry.cc \
src/core/ext/filters/client_channel/resolver_result_parsing.cc \
src/core/ext/filters/client_channel/retry_throttle.cc \
+ src/core/ext/filters/client_channel/server_address.cc \
src/core/ext/filters/client_channel/subchannel.cc \
src/core/ext/filters/client_channel/subchannel_index.cc \
src/core/ext/filters/deadline/deadline_filter.cc \
@@ -6439,6 +6439,7 @@ LIBGRPC++_TEST_UTIL_SRC = \
$(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc \
$(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc \
$(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc \
+ test/cpp/end2end/test_health_check_service_impl.cc \
test/cpp/end2end/test_service_impl.cc \
test/cpp/util/byte_buffer_proto_helper.cc \
test/cpp/util/channel_trace_proto_helper.cc \
@@ -6591,6 +6592,7 @@ ifneq ($(NO_DEPS),true)
-include $(LIBGRPC++_TEST_UTIL_OBJS:.o=.dep)
endif
endif
+$(OBJDIR)/$(CONFIG)/test/cpp/end2end/test_health_check_service_impl.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/end2end/test_service_impl.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/util/byte_buffer_proto_helper.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/util/channel_trace_proto_helper.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc
@@ -6607,6 +6609,7 @@ LIBGRPC++_TEST_UTIL_UNSECURE_SRC = \
$(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc \
$(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc \
$(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc \
+ test/cpp/end2end/test_health_check_service_impl.cc \
test/cpp/end2end/test_service_impl.cc \
test/cpp/util/byte_buffer_proto_helper.cc \
test/cpp/util/string_ref_helper.cc \
@@ -6756,6 +6759,7 @@ ifneq ($(NO_DEPS),true)
-include $(LIBGRPC++_TEST_UTIL_UNSECURE_OBJS:.o=.dep)
endif
endif
+$(OBJDIR)/$(CONFIG)/test/cpp/end2end/test_health_check_service_impl.o: $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/end2end/test_service_impl.o: $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/util/byte_buffer_proto_helper.o: $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/util/string_ref_helper.o: $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc
@@ -25178,6 +25182,7 @@ test/core/tsi/alts/crypt/gsec_test_util.cc: $(OPENSSL_DEP)
test/core/tsi/alts/handshaker/alts_handshaker_service_api_test_lib.cc: $(OPENSSL_DEP)
test/core/util/reconnect_server.cc: $(OPENSSL_DEP)
test/core/util/test_tcp_server.cc: $(OPENSSL_DEP)
+test/cpp/end2end/test_health_check_service_impl.cc: $(OPENSSL_DEP)
test/cpp/end2end/test_service_impl.cc: $(OPENSSL_DEP)
test/cpp/interop/client.cc: $(OPENSSL_DEP)
test/cpp/interop/client_helper.cc: $(OPENSSL_DEP)
diff --git a/PYTHON-MANIFEST.in b/PYTHON-MANIFEST.in
index c0de5289ee..544fefbc48 100644
--- a/PYTHON-MANIFEST.in
+++ b/PYTHON-MANIFEST.in
@@ -20,3 +20,4 @@ include src/python/grpcio/README.rst
include requirements.txt
include etc/roots.pem
include Makefile
+include LICENSE
diff --git a/build.yaml b/build.yaml
index fa8d65b760..b8c2fa6b02 100644
--- a/build.yaml
+++ b/build.yaml
@@ -440,6 +440,7 @@ filegroups:
- src/core/lib/iomgr/call_combiner.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_pair.h
- src/core/lib/iomgr/error.h
@@ -588,6 +589,7 @@ filegroups:
- src/core/ext/filters/client_channel/resolver_registry.h
- src/core/ext/filters/client_channel/resolver_result_parsing.h
- src/core/ext/filters/client_channel/retry_throttle.h
+ - src/core/ext/filters/client_channel/server_address.h
- src/core/ext/filters/client_channel/subchannel.h
- src/core/ext/filters/client_channel/subchannel_index.h
src:
@@ -602,7 +604,6 @@ filegroups:
- src/core/ext/filters/client_channel/http_connect_handshaker.cc
- src/core/ext/filters/client_channel/http_proxy.cc
- src/core/ext/filters/client_channel/lb_policy.cc
- - src/core/ext/filters/client_channel/lb_policy_factory.cc
- src/core/ext/filters/client_channel/lb_policy_registry.cc
- src/core/ext/filters/client_channel/parse_address.cc
- src/core/ext/filters/client_channel/proxy_mapper.cc
@@ -611,6 +612,7 @@ filegroups:
- src/core/ext/filters/client_channel/resolver_registry.cc
- src/core/ext/filters/client_channel/resolver_result_parsing.cc
- src/core/ext/filters/client_channel/retry_throttle.cc
+ - src/core/ext/filters/client_channel/server_address.cc
- src/core/ext/filters/client_channel/subchannel.cc
- src/core/ext/filters/client_channel/subchannel_index.cc
plugin: grpc_client_channel
@@ -1754,6 +1756,7 @@ libs:
build: private
language: c++
headers:
+ - test/cpp/end2end/test_health_check_service_impl.h
- test/cpp/end2end/test_service_impl.h
- test/cpp/util/byte_buffer_proto_helper.h
- test/cpp/util/channel_trace_proto_helper.h
@@ -1768,6 +1771,7 @@ libs:
- src/proto/grpc/testing/echo.proto
- src/proto/grpc/testing/duplicate/echo_duplicate.proto
- src/proto/grpc/testing/simple_messages.proto
+ - test/cpp/end2end/test_health_check_service_impl.cc
- test/cpp/end2end/test_service_impl.cc
- test/cpp/util/byte_buffer_proto_helper.cc
- test/cpp/util/channel_trace_proto_helper.cc
@@ -1788,6 +1792,7 @@ libs:
build: private
language: c++
headers:
+ - test/cpp/end2end/test_health_check_service_impl.h
- test/cpp/end2end/test_service_impl.h
- test/cpp/util/byte_buffer_proto_helper.h
- test/cpp/util/string_ref_helper.h
@@ -1798,6 +1803,7 @@ libs:
- src/proto/grpc/testing/echo.proto
- src/proto/grpc/testing/duplicate/echo_duplicate.proto
- src/proto/grpc/testing/simple_messages.proto
+ - test/cpp/end2end/test_health_check_service_impl.cc
- test/cpp/end2end/test_service_impl.cc
- test/cpp/util/byte_buffer_proto_helper.cc
- test/cpp/util/string_ref_helper.cc
diff --git a/cmake/cares.cmake b/cmake/cares.cmake
index 3d4a0cae76..4ea0d8725d 100644
--- a/cmake/cares.cmake
+++ b/cmake/cares.cmake
@@ -18,6 +18,10 @@ if("${gRPC_CARES_PROVIDER}" STREQUAL "module")
endif()
set(CARES_SHARED OFF CACHE BOOL "disable shared library")
set(CARES_STATIC ON CACHE BOOL "link cares statically")
+ if(gRPC_BACKWARDS_COMPATIBILITY_MODE)
+ # See https://github.com/grpc/grpc/issues/17255
+ set(HAVE_LIBNSL OFF CACHE BOOL "avoid cares dependency on libnsl")
+ endif()
add_subdirectory(third_party/cares/cares)
if(TARGET c-ares)
diff --git a/config.m4 b/config.m4
index 3db660acee..16de5204bb 100644
--- a/config.m4
+++ b/config.m4
@@ -348,7 +348,6 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/filters/client_channel/http_connect_handshaker.cc \
src/core/ext/filters/client_channel/http_proxy.cc \
src/core/ext/filters/client_channel/lb_policy.cc \
- src/core/ext/filters/client_channel/lb_policy_factory.cc \
src/core/ext/filters/client_channel/lb_policy_registry.cc \
src/core/ext/filters/client_channel/parse_address.cc \
src/core/ext/filters/client_channel/proxy_mapper.cc \
@@ -357,6 +356,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/filters/client_channel/resolver_registry.cc \
src/core/ext/filters/client_channel/resolver_result_parsing.cc \
src/core/ext/filters/client_channel/retry_throttle.cc \
+ src/core/ext/filters/client_channel/server_address.cc \
src/core/ext/filters/client_channel/subchannel.cc \
src/core/ext/filters/client_channel/subchannel_index.cc \
src/core/ext/filters/deadline/deadline_filter.cc \
diff --git a/config.w32 b/config.w32
index 7f8b6eee5f..be10faab9c 100644
--- a/config.w32
+++ b/config.w32
@@ -323,7 +323,6 @@ if (PHP_GRPC != "no") {
"src\\core\\ext\\filters\\client_channel\\http_connect_handshaker.cc " +
"src\\core\\ext\\filters\\client_channel\\http_proxy.cc " +
"src\\core\\ext\\filters\\client_channel\\lb_policy.cc " +
- "src\\core\\ext\\filters\\client_channel\\lb_policy_factory.cc " +
"src\\core\\ext\\filters\\client_channel\\lb_policy_registry.cc " +
"src\\core\\ext\\filters\\client_channel\\parse_address.cc " +
"src\\core\\ext\\filters\\client_channel\\proxy_mapper.cc " +
@@ -332,6 +331,7 @@ if (PHP_GRPC != "no") {
"src\\core\\ext\\filters\\client_channel\\resolver_registry.cc " +
"src\\core\\ext\\filters\\client_channel\\resolver_result_parsing.cc " +
"src\\core\\ext\\filters\\client_channel\\retry_throttle.cc " +
+ "src\\core\\ext\\filters\\client_channel\\server_address.cc " +
"src\\core\\ext\\filters\\client_channel\\subchannel.cc " +
"src\\core\\ext\\filters\\client_channel\\subchannel_index.cc " +
"src\\core\\ext\\filters\\deadline\\deadline_filter.cc " +
diff --git a/examples/csharp/.gitignore b/examples/csharp/.gitignore
index 585000ea2d..11f758f5c8 100644
--- a/examples/csharp/.gitignore
+++ b/examples/csharp/.gitignore
@@ -1,5 +1,7 @@
+.vs/
bin/
obj/
packages/
*.suo
+*.user
*.userprefs
diff --git a/examples/csharp/Helloworld/Greeter.sln b/examples/csharp/Helloworld/Greeter.sln
index ca50470e66..a5ba98d0be 100644
--- a/examples/csharp/Helloworld/Greeter.sln
+++ b/examples/csharp/Helloworld/Greeter.sln
@@ -1,4 +1,4 @@
-
+
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26228.4
diff --git a/examples/csharp/Helloworld/Greeter/Greeter.csproj b/examples/csharp/Helloworld/Greeter/Greeter.csproj
index eba262565d..7989f79541 100644
--- a/examples/csharp/Helloworld/Greeter/Greeter.csproj
+++ b/examples/csharp/Helloworld/Greeter/Greeter.csproj
@@ -1,18 +1,17 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
- <AssemblyTitle>Greeter</AssemblyTitle>
- <TargetFrameworks>netcoreapp2.1</TargetFrameworks>
- <DebugType>portable</DebugType>
- <AssemblyName>Greeter</AssemblyName>
- <PackageId>Greeter</PackageId>
+ <TargetFramework>netstandard1.5</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Google.Protobuf" Version="3.6.1" />
- <PackageReference Include="Google.Protobuf.Tools" Version="3.6.1" />
- <PackageReference Include="Grpc" Version="1.14.1" />
- <PackageReference Include="Grpc.Tools" Version="1.14.1" />
+ <PackageReference Include="Grpc" Version="1.17.0" />
+ <PackageReference Include="Grpc.Tools" Version="1.17.0" PrivateAssets="All" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Protobuf Include="../../../protos/helloworld.proto" Link="helloworld.proto" />
</ItemGroup>
</Project>
diff --git a/examples/csharp/Helloworld/Greeter/Helloworld.cs b/examples/csharp/Helloworld/Greeter/Helloworld.cs
deleted file mode 100644
index e008ec27e5..0000000000
--- a/examples/csharp/Helloworld/Greeter/Helloworld.cs
+++ /dev/null
@@ -1,312 +0,0 @@
-// <auto-generated>
-// Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: helloworld.proto
-// </auto-generated>
-#pragma warning disable 1591, 0612, 3021
-#region Designer generated code
-
-using pb = global::Google.Protobuf;
-using pbc = global::Google.Protobuf.Collections;
-using pbr = global::Google.Protobuf.Reflection;
-using scg = global::System.Collections.Generic;
-namespace Helloworld {
-
- /// <summary>Holder for reflection information generated from helloworld.proto</summary>
- public static partial class HelloworldReflection {
-
- #region Descriptor
- /// <summary>File descriptor for helloworld.proto</summary>
- public static pbr::FileDescriptor Descriptor {
- get { return descriptor; }
- }
- private static pbr::FileDescriptor descriptor;
-
- static HelloworldReflection() {
- byte[] descriptorData = global::System.Convert.FromBase64String(
- string.Concat(
- "ChBoZWxsb3dvcmxkLnByb3RvEgpoZWxsb3dvcmxkIhwKDEhlbGxvUmVxdWVz",
- "dBIMCgRuYW1lGAEgASgJIh0KCkhlbGxvUmVwbHkSDwoHbWVzc2FnZRgBIAEo",
- "CTJJCgdHcmVldGVyEj4KCFNheUhlbGxvEhguaGVsbG93b3JsZC5IZWxsb1Jl",
- "cXVlc3QaFi5oZWxsb3dvcmxkLkhlbGxvUmVwbHkiAEI2Chtpby5ncnBjLmV4",
- "YW1wbGVzLmhlbGxvd29ybGRCD0hlbGxvV29ybGRQcm90b1ABogIDSExXYgZw",
- "cm90bzM="));
- descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
- new pbr::FileDescriptor[] { },
- new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
- new pbr::GeneratedClrTypeInfo(typeof(global::Helloworld.HelloRequest), global::Helloworld.HelloRequest.Parser, new[]{ "Name" }, null, null, null),
- new pbr::GeneratedClrTypeInfo(typeof(global::Helloworld.HelloReply), global::Helloworld.HelloReply.Parser, new[]{ "Message" }, null, null, null)
- }));
- }
- #endregion
-
- }
- #region Messages
- /// <summary>
- /// The request message containing the user's name.
- /// </summary>
- public sealed partial class HelloRequest : pb::IMessage<HelloRequest> {
- private static readonly pb::MessageParser<HelloRequest> _parser = new pb::MessageParser<HelloRequest>(() => new HelloRequest());
- private pb::UnknownFieldSet _unknownFields;
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public static pb::MessageParser<HelloRequest> Parser { get { return _parser; } }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public static pbr::MessageDescriptor Descriptor {
- get { return global::Helloworld.HelloworldReflection.Descriptor.MessageTypes[0]; }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- pbr::MessageDescriptor pb::IMessage.Descriptor {
- get { return Descriptor; }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public HelloRequest() {
- OnConstruction();
- }
-
- partial void OnConstruction();
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public HelloRequest(HelloRequest other) : this() {
- name_ = other.name_;
- _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public HelloRequest Clone() {
- return new HelloRequest(this);
- }
-
- /// <summary>Field number for the "name" field.</summary>
- public const int NameFieldNumber = 1;
- private string name_ = "";
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public string Name {
- get { return name_; }
- set {
- name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
- }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override bool Equals(object other) {
- return Equals(other as HelloRequest);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public bool Equals(HelloRequest other) {
- if (ReferenceEquals(other, null)) {
- return false;
- }
- if (ReferenceEquals(other, this)) {
- return true;
- }
- if (Name != other.Name) return false;
- return Equals(_unknownFields, other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override int GetHashCode() {
- int hash = 1;
- if (Name.Length != 0) hash ^= Name.GetHashCode();
- if (_unknownFields != null) {
- hash ^= _unknownFields.GetHashCode();
- }
- return hash;
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override string ToString() {
- return pb::JsonFormatter.ToDiagnosticString(this);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void WriteTo(pb::CodedOutputStream output) {
- if (Name.Length != 0) {
- output.WriteRawTag(10);
- output.WriteString(Name);
- }
- if (_unknownFields != null) {
- _unknownFields.WriteTo(output);
- }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public int CalculateSize() {
- int size = 0;
- if (Name.Length != 0) {
- size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
- }
- if (_unknownFields != null) {
- size += _unknownFields.CalculateSize();
- }
- return size;
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void MergeFrom(HelloRequest other) {
- if (other == null) {
- return;
- }
- if (other.Name.Length != 0) {
- Name = other.Name;
- }
- _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void MergeFrom(pb::CodedInputStream input) {
- uint tag;
- while ((tag = input.ReadTag()) != 0) {
- switch(tag) {
- default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
- break;
- case 10: {
- Name = input.ReadString();
- break;
- }
- }
- }
- }
-
- }
-
- /// <summary>
- /// The response message containing the greetings
- /// </summary>
- public sealed partial class HelloReply : pb::IMessage<HelloReply> {
- private static readonly pb::MessageParser<HelloReply> _parser = new pb::MessageParser<HelloReply>(() => new HelloReply());
- private pb::UnknownFieldSet _unknownFields;
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public static pb::MessageParser<HelloReply> Parser { get { return _parser; } }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public static pbr::MessageDescriptor Descriptor {
- get { return global::Helloworld.HelloworldReflection.Descriptor.MessageTypes[1]; }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- pbr::MessageDescriptor pb::IMessage.Descriptor {
- get { return Descriptor; }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public HelloReply() {
- OnConstruction();
- }
-
- partial void OnConstruction();
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public HelloReply(HelloReply other) : this() {
- message_ = other.message_;
- _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public HelloReply Clone() {
- return new HelloReply(this);
- }
-
- /// <summary>Field number for the "message" field.</summary>
- public const int MessageFieldNumber = 1;
- private string message_ = "";
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public string Message {
- get { return message_; }
- set {
- message_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
- }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override bool Equals(object other) {
- return Equals(other as HelloReply);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public bool Equals(HelloReply other) {
- if (ReferenceEquals(other, null)) {
- return false;
- }
- if (ReferenceEquals(other, this)) {
- return true;
- }
- if (Message != other.Message) return false;
- return Equals(_unknownFields, other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override int GetHashCode() {
- int hash = 1;
- if (Message.Length != 0) hash ^= Message.GetHashCode();
- if (_unknownFields != null) {
- hash ^= _unknownFields.GetHashCode();
- }
- return hash;
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override string ToString() {
- return pb::JsonFormatter.ToDiagnosticString(this);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void WriteTo(pb::CodedOutputStream output) {
- if (Message.Length != 0) {
- output.WriteRawTag(10);
- output.WriteString(Message);
- }
- if (_unknownFields != null) {
- _unknownFields.WriteTo(output);
- }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public int CalculateSize() {
- int size = 0;
- if (Message.Length != 0) {
- size += 1 + pb::CodedOutputStream.ComputeStringSize(Message);
- }
- if (_unknownFields != null) {
- size += _unknownFields.CalculateSize();
- }
- return size;
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void MergeFrom(HelloReply other) {
- if (other == null) {
- return;
- }
- if (other.Message.Length != 0) {
- Message = other.Message;
- }
- _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void MergeFrom(pb::CodedInputStream input) {
- uint tag;
- while ((tag = input.ReadTag()) != 0) {
- switch(tag) {
- default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
- break;
- case 10: {
- Message = input.ReadString();
- break;
- }
- }
- }
- }
-
- }
-
- #endregion
-
-}
-
-#endregion Designer generated code
diff --git a/examples/csharp/Helloworld/Greeter/HelloworldGrpc.cs b/examples/csharp/Helloworld/Greeter/HelloworldGrpc.cs
deleted file mode 100644
index d6b959adc6..0000000000
--- a/examples/csharp/Helloworld/Greeter/HelloworldGrpc.cs
+++ /dev/null
@@ -1,149 +0,0 @@
-// <auto-generated>
-// Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: helloworld.proto
-// </auto-generated>
-// Original file comments:
-// 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.
-//
-#pragma warning disable 0414, 1591
-#region Designer generated code
-
-using grpc = global::Grpc.Core;
-
-namespace Helloworld {
- /// <summary>
- /// The greeting service definition.
- /// </summary>
- public static partial class Greeter
- {
- static readonly string __ServiceName = "helloworld.Greeter";
-
- static readonly grpc::Marshaller<global::Helloworld.HelloRequest> __Marshaller_helloworld_HelloRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloRequest.Parser.ParseFrom);
- static readonly grpc::Marshaller<global::Helloworld.HelloReply> __Marshaller_helloworld_HelloReply = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloReply.Parser.ParseFrom);
-
- static readonly grpc::Method<global::Helloworld.HelloRequest, global::Helloworld.HelloReply> __Method_SayHello = new grpc::Method<global::Helloworld.HelloRequest, global::Helloworld.HelloReply>(
- grpc::MethodType.Unary,
- __ServiceName,
- "SayHello",
- __Marshaller_helloworld_HelloRequest,
- __Marshaller_helloworld_HelloReply);
-
- /// <summary>Service descriptor</summary>
- public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
- {
- get { return global::Helloworld.HelloworldReflection.Descriptor.Services[0]; }
- }
-
- /// <summary>Base class for server-side implementations of Greeter</summary>
- public abstract partial class GreeterBase
- {
- /// <summary>
- /// Sends a greeting
- /// </summary>
- /// <param name="request">The request received from the client.</param>
- /// <param name="context">The context of the server-side call handler being invoked.</param>
- /// <returns>The response to send back to the client (wrapped by a task).</returns>
- public virtual global::System.Threading.Tasks.Task<global::Helloworld.HelloReply> SayHello(global::Helloworld.HelloRequest request, grpc::ServerCallContext context)
- {
- throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
- }
-
- }
-
- /// <summary>Client for Greeter</summary>
- public partial class GreeterClient : grpc::ClientBase<GreeterClient>
- {
- /// <summary>Creates a new client for Greeter</summary>
- /// <param name="channel">The channel to use to make remote calls.</param>
- public GreeterClient(grpc::Channel channel) : base(channel)
- {
- }
- /// <summary>Creates a new client for Greeter that uses a custom <c>CallInvoker</c>.</summary>
- /// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
- public GreeterClient(grpc::CallInvoker callInvoker) : base(callInvoker)
- {
- }
- /// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
- protected GreeterClient() : base()
- {
- }
- /// <summary>Protected constructor to allow creation of configured clients.</summary>
- /// <param name="configuration">The client configuration.</param>
- protected GreeterClient(ClientBaseConfiguration configuration) : base(configuration)
- {
- }
-
- /// <summary>
- /// Sends a greeting
- /// </summary>
- /// <param name="request">The request to send to the server.</param>
- /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
- /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
- /// <param name="cancellationToken">An optional token for canceling the call.</param>
- /// <returns>The response received from the server.</returns>
- public virtual global::Helloworld.HelloReply SayHello(global::Helloworld.HelloRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
- {
- return SayHello(request, new grpc::CallOptions(headers, deadline, cancellationToken));
- }
- /// <summary>
- /// Sends a greeting
- /// </summary>
- /// <param name="request">The request to send to the server.</param>
- /// <param name="options">The options for the call.</param>
- /// <returns>The response received from the server.</returns>
- public virtual global::Helloworld.HelloReply SayHello(global::Helloworld.HelloRequest request, grpc::CallOptions options)
- {
- return CallInvoker.BlockingUnaryCall(__Method_SayHello, null, options, request);
- }
- /// <summary>
- /// Sends a greeting
- /// </summary>
- /// <param name="request">The request to send to the server.</param>
- /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
- /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
- /// <param name="cancellationToken">An optional token for canceling the call.</param>
- /// <returns>The call object.</returns>
- public virtual grpc::AsyncUnaryCall<global::Helloworld.HelloReply> SayHelloAsync(global::Helloworld.HelloRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
- {
- return SayHelloAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
- }
- /// <summary>
- /// Sends a greeting
- /// </summary>
- /// <param name="request">The request to send to the server.</param>
- /// <param name="options">The options for the call.</param>
- /// <returns>The call object.</returns>
- public virtual grpc::AsyncUnaryCall<global::Helloworld.HelloReply> SayHelloAsync(global::Helloworld.HelloRequest request, grpc::CallOptions options)
- {
- return CallInvoker.AsyncUnaryCall(__Method_SayHello, null, options, request);
- }
- /// <summary>Creates a new instance of client from given <c>ClientBaseConfiguration</c>.</summary>
- protected override GreeterClient NewInstance(ClientBaseConfiguration configuration)
- {
- return new GreeterClient(configuration);
- }
- }
-
- /// <summary>Creates service definition that can be registered with a server</summary>
- /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
- public static grpc::ServerServiceDefinition BindService(GreeterBase serviceImpl)
- {
- return grpc::ServerServiceDefinition.CreateBuilder()
- .AddMethod(__Method_SayHello, serviceImpl.SayHello).Build();
- }
-
- }
-}
-#endregion
diff --git a/examples/csharp/Helloworld/GreeterClient/GreeterClient.csproj b/examples/csharp/Helloworld/GreeterClient/GreeterClient.csproj
index 24a89d58c5..ac10d85497 100644
--- a/examples/csharp/Helloworld/GreeterClient/GreeterClient.csproj
+++ b/examples/csharp/Helloworld/GreeterClient/GreeterClient.csproj
@@ -1,12 +1,8 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
- <AssemblyTitle>GreeterClient</AssemblyTitle>
- <TargetFrameworks>netcoreapp2.1</TargetFrameworks>
- <DebugType>portable</DebugType>
- <AssemblyName>GreeterClient</AssemblyName>
+ <TargetFramework>netcoreapp2.1</TargetFramework>
<OutputType>Exe</OutputType>
- <PackageId>GreeterClient</PackageId>
</PropertyGroup>
<ItemGroup>
diff --git a/examples/csharp/Helloworld/GreeterServer/GreeterServer.csproj b/examples/csharp/Helloworld/GreeterServer/GreeterServer.csproj
index 9ea1fa3817..ac10d85497 100644
--- a/examples/csharp/Helloworld/GreeterServer/GreeterServer.csproj
+++ b/examples/csharp/Helloworld/GreeterServer/GreeterServer.csproj
@@ -1,12 +1,8 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
- <AssemblyTitle>GreeterServer</AssemblyTitle>
- <TargetFrameworks>netcoreapp2.1</TargetFrameworks>
- <DebugType>portable</DebugType>
- <AssemblyName>GreeterServer</AssemblyName>
+ <TargetFramework>netcoreapp2.1</TargetFramework>
<OutputType>Exe</OutputType>
- <PackageId>GreeterServer</PackageId>
</PropertyGroup>
<ItemGroup>
diff --git a/examples/csharp/Helloworld/README.md b/examples/csharp/Helloworld/README.md
index 4871132426..e4771ee91a 100644
--- a/examples/csharp/Helloworld/README.md
+++ b/examples/csharp/Helloworld/README.md
@@ -3,41 +3,31 @@ gRPC in 3 minutes (C#)
BACKGROUND
-------------
-For this sample, we've already generated the server and client stubs from [helloworld.proto][].
-
-Example projects in this directory depend on the [Grpc](https://www.nuget.org/packages/Grpc/)
-and [Google.Protobuf](https://www.nuget.org/packages/Google.Protobuf/) NuGet packages
-which have been already added to the project for you.
+This is a version of the helloworld example using the dotnet SDK
+tools to compile [helloworld.proto][] in a common library, build the server
+and the client, and run them.
PREREQUISITES
-------------
- The [.NET Core SDK 2.1+](https://www.microsoft.com/net/core)
-You can also build the example directly using Visual Studio 2017, but it's not a requirement.
-
-BUILD
--------
-
-From the `examples/csharp/Helloworld` directory:
+You can also build the solution `Greeter.sln` using Visual Studio 2017,
+but it's not a requirement.
-- `dotnet build Greeter.sln`
-
-Try it!
--------
+BUILD AND RUN
+-------------
-- Run the server
+- Build and run the server
```
- > cd GreeterServer
- > dotnet run -f netcoreapp2.1
+ > dotnet run -p GreeterServer
```
-- Run the client
+- Build and run the client
```
- > cd GreeterClient
- > dotnet run -f netcoreapp2.1
+ > dotnet run -p GreeterClient
```
Tutorial
diff --git a/examples/csharp/Helloworld/generate_protos.bat b/examples/csharp/Helloworld/generate_protos.bat
deleted file mode 100644
index ab0c0eb46a..0000000000
--- a/examples/csharp/Helloworld/generate_protos.bat
+++ /dev/null
@@ -1,28 +0,0 @@
-@rem Copyright 2016 gRPC authors.
-@rem
-@rem Licensed under the Apache License, Version 2.0 (the "License");
-@rem you may not use this file except in compliance with the License.
-@rem You may obtain a copy of the License at
-@rem
-@rem http://www.apache.org/licenses/LICENSE-2.0
-@rem
-@rem Unless required by applicable law or agreed to in writing, software
-@rem distributed under the License is distributed on an "AS IS" BASIS,
-@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-@rem See the License for the specific language governing permissions and
-@rem limitations under the License.
-
-@rem Generate the C# code for .proto files
-
-setlocal
-
-@rem enter this directory
-cd /d %~dp0
-
-@rem packages will be available in nuget cache directory once the project is built or after "dotnet restore"
-set PROTOC=%UserProfile%\.nuget\packages\Google.Protobuf.Tools\3.6.1\tools\windows_x64\protoc.exe
-set PLUGIN=%UserProfile%\.nuget\packages\Grpc.Tools\1.14.1\tools\windows_x64\grpc_csharp_plugin.exe
-
-%PROTOC% -I../../protos --csharp_out Greeter ../../protos/helloworld.proto --grpc_out Greeter --plugin=protoc-gen-grpc=%PLUGIN%
-
-endlocal
diff --git a/examples/csharp/HelloworldLegacyCsproj/Greeter.sln b/examples/csharp/HelloworldLegacyCsproj/Greeter.sln
index 49e364d91c..26cae7a727 100644
--- a/examples/csharp/HelloworldLegacyCsproj/Greeter.sln
+++ b/examples/csharp/HelloworldLegacyCsproj/Greeter.sln
@@ -1,4 +1,4 @@
-
+
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.31101.0
diff --git a/examples/csharp/HelloworldLegacyCsproj/Greeter/Greeter.csproj b/examples/csharp/HelloworldLegacyCsproj/Greeter/Greeter.csproj
index 197a9fb625..da15ba3954 100644
--- a/examples/csharp/HelloworldLegacyCsproj/Greeter/Greeter.csproj
+++ b/examples/csharp/HelloworldLegacyCsproj/Greeter/Greeter.csproj
@@ -1,5 +1,6 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="..\packages\Grpc.Tools.1.17.0\build\Grpc.Tools.props" Condition="Exists('..\packages\Grpc.Tools.1.17.0\build\Grpc.Tools.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
@@ -36,7 +37,7 @@
<HintPath>..\packages\Google.Protobuf.3.6.1\lib\net45\Google.Protobuf.dll</HintPath>
</Reference>
<Reference Include="Grpc.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
- <HintPath>..\packages\Grpc.Core.1.14.1\lib\net45\Grpc.Core.dll</HintPath>
+ <HintPath>..\packages\Grpc.Core.1.17.0\lib\net45\Grpc.Core.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Interactive.Async, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
@@ -47,25 +48,23 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
- <Compile Include="Helloworld.cs" />
- <Compile Include="HelloworldGrpc.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
- <None Include="..\..\..\protos\helloworld.proto">
+ <Protobuf Include="..\..\..\protos\helloworld.proto">
<Link>protos\helloworld.proto</Link>
- </None>
- <None Include="..\generate_protos.bat">
- <Link>generate_protos.bat</Link>
- </None>
+ </Protobuf>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup />
- <Import Project="..\packages\Grpc.Core.1.14.1\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.14.1\build\net45\Grpc.Core.targets')" />
+ <Import Project="..\packages\Grpc.Core.1.17.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.17.0\build\net45\Grpc.Core.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
- <Error Condition="!Exists('..\packages\Grpc.Core.1.14.1\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.14.1\build\net45\Grpc.Core.targets'))" />
+ <Error Condition="!Exists('..\packages\Grpc.Core.1.17.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.17.0\build\net45\Grpc.Core.targets'))" />
+ <Error Condition="!Exists('..\packages\Grpc.Tools.1.17.0\build\Grpc.Tools.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Tools.1.17.0\build\Grpc.Tools.props'))" />
+ <Error Condition="!Exists('..\packages\Grpc.Tools.1.17.0\build\Grpc.Tools.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Tools.1.17.0\build\Grpc.Tools.targets'))" />
</Target>
-</Project> \ No newline at end of file
+ <Import Project="..\packages\Grpc.Tools.1.17.0\build\Grpc.Tools.targets" Condition="Exists('..\packages\Grpc.Tools.1.17.0\build\Grpc.Tools.targets')" />
+</Project>
diff --git a/examples/csharp/HelloworldLegacyCsproj/Greeter/Helloworld.cs b/examples/csharp/HelloworldLegacyCsproj/Greeter/Helloworld.cs
deleted file mode 100644
index e008ec27e5..0000000000
--- a/examples/csharp/HelloworldLegacyCsproj/Greeter/Helloworld.cs
+++ /dev/null
@@ -1,312 +0,0 @@
-// <auto-generated>
-// Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: helloworld.proto
-// </auto-generated>
-#pragma warning disable 1591, 0612, 3021
-#region Designer generated code
-
-using pb = global::Google.Protobuf;
-using pbc = global::Google.Protobuf.Collections;
-using pbr = global::Google.Protobuf.Reflection;
-using scg = global::System.Collections.Generic;
-namespace Helloworld {
-
- /// <summary>Holder for reflection information generated from helloworld.proto</summary>
- public static partial class HelloworldReflection {
-
- #region Descriptor
- /// <summary>File descriptor for helloworld.proto</summary>
- public static pbr::FileDescriptor Descriptor {
- get { return descriptor; }
- }
- private static pbr::FileDescriptor descriptor;
-
- static HelloworldReflection() {
- byte[] descriptorData = global::System.Convert.FromBase64String(
- string.Concat(
- "ChBoZWxsb3dvcmxkLnByb3RvEgpoZWxsb3dvcmxkIhwKDEhlbGxvUmVxdWVz",
- "dBIMCgRuYW1lGAEgASgJIh0KCkhlbGxvUmVwbHkSDwoHbWVzc2FnZRgBIAEo",
- "CTJJCgdHcmVldGVyEj4KCFNheUhlbGxvEhguaGVsbG93b3JsZC5IZWxsb1Jl",
- "cXVlc3QaFi5oZWxsb3dvcmxkLkhlbGxvUmVwbHkiAEI2Chtpby5ncnBjLmV4",
- "YW1wbGVzLmhlbGxvd29ybGRCD0hlbGxvV29ybGRQcm90b1ABogIDSExXYgZw",
- "cm90bzM="));
- descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
- new pbr::FileDescriptor[] { },
- new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
- new pbr::GeneratedClrTypeInfo(typeof(global::Helloworld.HelloRequest), global::Helloworld.HelloRequest.Parser, new[]{ "Name" }, null, null, null),
- new pbr::GeneratedClrTypeInfo(typeof(global::Helloworld.HelloReply), global::Helloworld.HelloReply.Parser, new[]{ "Message" }, null, null, null)
- }));
- }
- #endregion
-
- }
- #region Messages
- /// <summary>
- /// The request message containing the user's name.
- /// </summary>
- public sealed partial class HelloRequest : pb::IMessage<HelloRequest> {
- private static readonly pb::MessageParser<HelloRequest> _parser = new pb::MessageParser<HelloRequest>(() => new HelloRequest());
- private pb::UnknownFieldSet _unknownFields;
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public static pb::MessageParser<HelloRequest> Parser { get { return _parser; } }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public static pbr::MessageDescriptor Descriptor {
- get { return global::Helloworld.HelloworldReflection.Descriptor.MessageTypes[0]; }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- pbr::MessageDescriptor pb::IMessage.Descriptor {
- get { return Descriptor; }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public HelloRequest() {
- OnConstruction();
- }
-
- partial void OnConstruction();
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public HelloRequest(HelloRequest other) : this() {
- name_ = other.name_;
- _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public HelloRequest Clone() {
- return new HelloRequest(this);
- }
-
- /// <summary>Field number for the "name" field.</summary>
- public const int NameFieldNumber = 1;
- private string name_ = "";
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public string Name {
- get { return name_; }
- set {
- name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
- }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override bool Equals(object other) {
- return Equals(other as HelloRequest);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public bool Equals(HelloRequest other) {
- if (ReferenceEquals(other, null)) {
- return false;
- }
- if (ReferenceEquals(other, this)) {
- return true;
- }
- if (Name != other.Name) return false;
- return Equals(_unknownFields, other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override int GetHashCode() {
- int hash = 1;
- if (Name.Length != 0) hash ^= Name.GetHashCode();
- if (_unknownFields != null) {
- hash ^= _unknownFields.GetHashCode();
- }
- return hash;
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override string ToString() {
- return pb::JsonFormatter.ToDiagnosticString(this);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void WriteTo(pb::CodedOutputStream output) {
- if (Name.Length != 0) {
- output.WriteRawTag(10);
- output.WriteString(Name);
- }
- if (_unknownFields != null) {
- _unknownFields.WriteTo(output);
- }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public int CalculateSize() {
- int size = 0;
- if (Name.Length != 0) {
- size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
- }
- if (_unknownFields != null) {
- size += _unknownFields.CalculateSize();
- }
- return size;
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void MergeFrom(HelloRequest other) {
- if (other == null) {
- return;
- }
- if (other.Name.Length != 0) {
- Name = other.Name;
- }
- _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void MergeFrom(pb::CodedInputStream input) {
- uint tag;
- while ((tag = input.ReadTag()) != 0) {
- switch(tag) {
- default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
- break;
- case 10: {
- Name = input.ReadString();
- break;
- }
- }
- }
- }
-
- }
-
- /// <summary>
- /// The response message containing the greetings
- /// </summary>
- public sealed partial class HelloReply : pb::IMessage<HelloReply> {
- private static readonly pb::MessageParser<HelloReply> _parser = new pb::MessageParser<HelloReply>(() => new HelloReply());
- private pb::UnknownFieldSet _unknownFields;
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public static pb::MessageParser<HelloReply> Parser { get { return _parser; } }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public static pbr::MessageDescriptor Descriptor {
- get { return global::Helloworld.HelloworldReflection.Descriptor.MessageTypes[1]; }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- pbr::MessageDescriptor pb::IMessage.Descriptor {
- get { return Descriptor; }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public HelloReply() {
- OnConstruction();
- }
-
- partial void OnConstruction();
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public HelloReply(HelloReply other) : this() {
- message_ = other.message_;
- _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public HelloReply Clone() {
- return new HelloReply(this);
- }
-
- /// <summary>Field number for the "message" field.</summary>
- public const int MessageFieldNumber = 1;
- private string message_ = "";
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public string Message {
- get { return message_; }
- set {
- message_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
- }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override bool Equals(object other) {
- return Equals(other as HelloReply);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public bool Equals(HelloReply other) {
- if (ReferenceEquals(other, null)) {
- return false;
- }
- if (ReferenceEquals(other, this)) {
- return true;
- }
- if (Message != other.Message) return false;
- return Equals(_unknownFields, other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override int GetHashCode() {
- int hash = 1;
- if (Message.Length != 0) hash ^= Message.GetHashCode();
- if (_unknownFields != null) {
- hash ^= _unknownFields.GetHashCode();
- }
- return hash;
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override string ToString() {
- return pb::JsonFormatter.ToDiagnosticString(this);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void WriteTo(pb::CodedOutputStream output) {
- if (Message.Length != 0) {
- output.WriteRawTag(10);
- output.WriteString(Message);
- }
- if (_unknownFields != null) {
- _unknownFields.WriteTo(output);
- }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public int CalculateSize() {
- int size = 0;
- if (Message.Length != 0) {
- size += 1 + pb::CodedOutputStream.ComputeStringSize(Message);
- }
- if (_unknownFields != null) {
- size += _unknownFields.CalculateSize();
- }
- return size;
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void MergeFrom(HelloReply other) {
- if (other == null) {
- return;
- }
- if (other.Message.Length != 0) {
- Message = other.Message;
- }
- _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void MergeFrom(pb::CodedInputStream input) {
- uint tag;
- while ((tag = input.ReadTag()) != 0) {
- switch(tag) {
- default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
- break;
- case 10: {
- Message = input.ReadString();
- break;
- }
- }
- }
- }
-
- }
-
- #endregion
-
-}
-
-#endregion Designer generated code
diff --git a/examples/csharp/HelloworldLegacyCsproj/Greeter/HelloworldGrpc.cs b/examples/csharp/HelloworldLegacyCsproj/Greeter/HelloworldGrpc.cs
deleted file mode 100644
index d6b959adc6..0000000000
--- a/examples/csharp/HelloworldLegacyCsproj/Greeter/HelloworldGrpc.cs
+++ /dev/null
@@ -1,149 +0,0 @@
-// <auto-generated>
-// Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: helloworld.proto
-// </auto-generated>
-// Original file comments:
-// 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.
-//
-#pragma warning disable 0414, 1591
-#region Designer generated code
-
-using grpc = global::Grpc.Core;
-
-namespace Helloworld {
- /// <summary>
- /// The greeting service definition.
- /// </summary>
- public static partial class Greeter
- {
- static readonly string __ServiceName = "helloworld.Greeter";
-
- static readonly grpc::Marshaller<global::Helloworld.HelloRequest> __Marshaller_helloworld_HelloRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloRequest.Parser.ParseFrom);
- static readonly grpc::Marshaller<global::Helloworld.HelloReply> __Marshaller_helloworld_HelloReply = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloReply.Parser.ParseFrom);
-
- static readonly grpc::Method<global::Helloworld.HelloRequest, global::Helloworld.HelloReply> __Method_SayHello = new grpc::Method<global::Helloworld.HelloRequest, global::Helloworld.HelloReply>(
- grpc::MethodType.Unary,
- __ServiceName,
- "SayHello",
- __Marshaller_helloworld_HelloRequest,
- __Marshaller_helloworld_HelloReply);
-
- /// <summary>Service descriptor</summary>
- public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
- {
- get { return global::Helloworld.HelloworldReflection.Descriptor.Services[0]; }
- }
-
- /// <summary>Base class for server-side implementations of Greeter</summary>
- public abstract partial class GreeterBase
- {
- /// <summary>
- /// Sends a greeting
- /// </summary>
- /// <param name="request">The request received from the client.</param>
- /// <param name="context">The context of the server-side call handler being invoked.</param>
- /// <returns>The response to send back to the client (wrapped by a task).</returns>
- public virtual global::System.Threading.Tasks.Task<global::Helloworld.HelloReply> SayHello(global::Helloworld.HelloRequest request, grpc::ServerCallContext context)
- {
- throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
- }
-
- }
-
- /// <summary>Client for Greeter</summary>
- public partial class GreeterClient : grpc::ClientBase<GreeterClient>
- {
- /// <summary>Creates a new client for Greeter</summary>
- /// <param name="channel">The channel to use to make remote calls.</param>
- public GreeterClient(grpc::Channel channel) : base(channel)
- {
- }
- /// <summary>Creates a new client for Greeter that uses a custom <c>CallInvoker</c>.</summary>
- /// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
- public GreeterClient(grpc::CallInvoker callInvoker) : base(callInvoker)
- {
- }
- /// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
- protected GreeterClient() : base()
- {
- }
- /// <summary>Protected constructor to allow creation of configured clients.</summary>
- /// <param name="configuration">The client configuration.</param>
- protected GreeterClient(ClientBaseConfiguration configuration) : base(configuration)
- {
- }
-
- /// <summary>
- /// Sends a greeting
- /// </summary>
- /// <param name="request">The request to send to the server.</param>
- /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
- /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
- /// <param name="cancellationToken">An optional token for canceling the call.</param>
- /// <returns>The response received from the server.</returns>
- public virtual global::Helloworld.HelloReply SayHello(global::Helloworld.HelloRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
- {
- return SayHello(request, new grpc::CallOptions(headers, deadline, cancellationToken));
- }
- /// <summary>
- /// Sends a greeting
- /// </summary>
- /// <param name="request">The request to send to the server.</param>
- /// <param name="options">The options for the call.</param>
- /// <returns>The response received from the server.</returns>
- public virtual global::Helloworld.HelloReply SayHello(global::Helloworld.HelloRequest request, grpc::CallOptions options)
- {
- return CallInvoker.BlockingUnaryCall(__Method_SayHello, null, options, request);
- }
- /// <summary>
- /// Sends a greeting
- /// </summary>
- /// <param name="request">The request to send to the server.</param>
- /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
- /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
- /// <param name="cancellationToken">An optional token for canceling the call.</param>
- /// <returns>The call object.</returns>
- public virtual grpc::AsyncUnaryCall<global::Helloworld.HelloReply> SayHelloAsync(global::Helloworld.HelloRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
- {
- return SayHelloAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
- }
- /// <summary>
- /// Sends a greeting
- /// </summary>
- /// <param name="request">The request to send to the server.</param>
- /// <param name="options">The options for the call.</param>
- /// <returns>The call object.</returns>
- public virtual grpc::AsyncUnaryCall<global::Helloworld.HelloReply> SayHelloAsync(global::Helloworld.HelloRequest request, grpc::CallOptions options)
- {
- return CallInvoker.AsyncUnaryCall(__Method_SayHello, null, options, request);
- }
- /// <summary>Creates a new instance of client from given <c>ClientBaseConfiguration</c>.</summary>
- protected override GreeterClient NewInstance(ClientBaseConfiguration configuration)
- {
- return new GreeterClient(configuration);
- }
- }
-
- /// <summary>Creates service definition that can be registered with a server</summary>
- /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
- public static grpc::ServerServiceDefinition BindService(GreeterBase serviceImpl)
- {
- return grpc::ServerServiceDefinition.CreateBuilder()
- .AddMethod(__Method_SayHello, serviceImpl.SayHello).Build();
- }
-
- }
-}
-#endregion
diff --git a/examples/csharp/HelloworldLegacyCsproj/Greeter/packages.config b/examples/csharp/HelloworldLegacyCsproj/Greeter/packages.config
index 23857be22f..154b599321 100644
--- a/examples/csharp/HelloworldLegacyCsproj/Greeter/packages.config
+++ b/examples/csharp/HelloworldLegacyCsproj/Greeter/packages.config
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Google.Protobuf" version="3.6.1" targetFramework="net45" />
- <package id="Grpc" version="1.14.1" targetFramework="net45" />
- <package id="Grpc.Core" version="1.14.1" targetFramework="net45" />
- <package id="Grpc.Tools" version="1.14.1" targetFramework="net45" />
+ <package id="Grpc" version="1.17.0" targetFramework="net45" />
+ <package id="Grpc.Core" version="1.17.0" targetFramework="net45" />
+ <package id="Grpc.Tools" version="1.17.0" targetFramework="net45" developmentDependency="true" />
<package id="System.Interactive.Async" version="3.1.1" targetFramework="net45" />
-</packages> \ No newline at end of file
+</packages>
diff --git a/examples/csharp/HelloworldLegacyCsproj/GreeterClient/GreeterClient.csproj b/examples/csharp/HelloworldLegacyCsproj/GreeterClient/GreeterClient.csproj
index 3bb7ff1ee1..31a3a90345 100644
--- a/examples/csharp/HelloworldLegacyCsproj/GreeterClient/GreeterClient.csproj
+++ b/examples/csharp/HelloworldLegacyCsproj/GreeterClient/GreeterClient.csproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -36,7 +36,7 @@
<HintPath>..\packages\Google.Protobuf.3.6.1\lib\net45\Google.Protobuf.dll</HintPath>
</Reference>
<Reference Include="Grpc.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
- <HintPath>..\packages\Grpc.Core.1.14.1\lib\net45\Grpc.Core.dll</HintPath>
+ <HintPath>..\packages\Grpc.Core.1.17.0\lib\net45\Grpc.Core.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Interactive.Async, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
@@ -59,11 +59,11 @@
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
- <Import Project="..\packages\Grpc.Core.1.14.1\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.14.1\build\net45\Grpc.Core.targets')" />
+ <Import Project="..\packages\Grpc.Core.1.17.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.17.0\build\net45\Grpc.Core.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
- <Error Condition="!Exists('..\packages\Grpc.Core.1.14.1\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.14.1\build\net45\Grpc.Core.targets'))" />
+ <Error Condition="!Exists('..\packages\Grpc.Core.1.17.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.17.0\build\net45\Grpc.Core.targets'))" />
</Target>
</Project> \ No newline at end of file
diff --git a/examples/csharp/HelloworldLegacyCsproj/GreeterClient/packages.config b/examples/csharp/HelloworldLegacyCsproj/GreeterClient/packages.config
index df4df8282c..2fd8228689 100644
--- a/examples/csharp/HelloworldLegacyCsproj/GreeterClient/packages.config
+++ b/examples/csharp/HelloworldLegacyCsproj/GreeterClient/packages.config
@@ -1,7 +1,7 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Google.Protobuf" version="3.6.1" targetFramework="net45" />
- <package id="Grpc" version="1.14.1" targetFramework="net45" />
- <package id="Grpc.Core" version="1.14.1" targetFramework="net45" />
+ <package id="Grpc" version="1.17.0" targetFramework="net45" />
+ <package id="Grpc.Core" version="1.17.0" targetFramework="net45" />
<package id="System.Interactive.Async" version="3.1.1" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/examples/csharp/HelloworldLegacyCsproj/GreeterServer/GreeterServer.csproj b/examples/csharp/HelloworldLegacyCsproj/GreeterServer/GreeterServer.csproj
index 4396b04efe..27ca963040 100644
--- a/examples/csharp/HelloworldLegacyCsproj/GreeterServer/GreeterServer.csproj
+++ b/examples/csharp/HelloworldLegacyCsproj/GreeterServer/GreeterServer.csproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -36,7 +36,7 @@
<HintPath>..\packages\Google.Protobuf.3.6.1\lib\net45\Google.Protobuf.dll</HintPath>
</Reference>
<Reference Include="Grpc.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
- <HintPath>..\packages\Grpc.Core.1.14.1\lib\net45\Grpc.Core.dll</HintPath>
+ <HintPath>..\packages\Grpc.Core.1.17.0\lib\net45\Grpc.Core.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Interactive.Async, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
@@ -59,11 +59,11 @@
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
- <Import Project="..\packages\Grpc.Core.1.14.1\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.14.1\build\net45\Grpc.Core.targets')" />
+ <Import Project="..\packages\Grpc.Core.1.17.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.17.0\build\net45\Grpc.Core.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
- <Error Condition="!Exists('..\packages\Grpc.Core.1.14.1\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.14.1\build\net45\Grpc.Core.targets'))" />
+ <Error Condition="!Exists('..\packages\Grpc.Core.1.17.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.17.0\build\net45\Grpc.Core.targets'))" />
</Target>
</Project> \ No newline at end of file
diff --git a/examples/csharp/HelloworldLegacyCsproj/GreeterServer/packages.config b/examples/csharp/HelloworldLegacyCsproj/GreeterServer/packages.config
index df4df8282c..2fd8228689 100644
--- a/examples/csharp/HelloworldLegacyCsproj/GreeterServer/packages.config
+++ b/examples/csharp/HelloworldLegacyCsproj/GreeterServer/packages.config
@@ -1,7 +1,7 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Google.Protobuf" version="3.6.1" targetFramework="net45" />
- <package id="Grpc" version="1.14.1" targetFramework="net45" />
- <package id="Grpc.Core" version="1.14.1" targetFramework="net45" />
+ <package id="Grpc" version="1.17.0" targetFramework="net45" />
+ <package id="Grpc.Core" version="1.17.0" targetFramework="net45" />
<package id="System.Interactive.Async" version="3.1.1" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/examples/csharp/HelloworldLegacyCsproj/README.md b/examples/csharp/HelloworldLegacyCsproj/README.md
index 6d42c5ef25..60b09e0925 100644
--- a/examples/csharp/HelloworldLegacyCsproj/README.md
+++ b/examples/csharp/HelloworldLegacyCsproj/README.md
@@ -3,21 +3,21 @@ gRPC in 3 minutes (C#)
BACKGROUND
-------------
-This is a different version of the helloworld example, using the old-style .csproj
-files supported by VS2013 and VS2015 (and older versions of mono).
-You can still use gRPC with the old-style .csproj files, but [using the new-style
-.csproj projects](../helloworld/README.md) (supported by VS2017 and dotnet SDK) is recommended.
-
-For this sample, we've already generated the server and client stubs from [helloworld.proto][].
-
-Example projects depend on the [Grpc](https://www.nuget.org/packages/Grpc/), [Grpc.Tools](https://www.nuget.org/packages/Grpc.Tools/)
+This is a different version of the helloworld example, using the "classic" .csproj
+files, the only format supported by VS2013 (and older versions of mono).
+You can still use gRPC with the classic .csproj files, but [using the new-style
+.csproj projects](../helloworld/README.md) (supported by VS2015 Update3 and above,
+and dotnet SDK) is recommended.
+
+Example projects depend on the [Grpc](https://www.nuget.org/packages/Grpc/),
+[Grpc.Tools](https://www.nuget.org/packages/Grpc.Tools/)
and [Google.Protobuf](https://www.nuget.org/packages/Google.Protobuf/) NuGet packages
which have been already added to the project for you.
PREREQUISITES
-------------
-- Windows: .NET Framework 4.5+, Visual Studio 2013 or 2015
+- Windows: .NET Framework 4.5+, Visual Studio 2013 or higher
- Linux: Mono 4+, MonoDevelop 5.9+
- Mac OS X: Xamarin Studio 5.9+
@@ -28,12 +28,15 @@ BUILD
# Using Visual Studio
-* Build the solution (this will automatically download NuGet dependencies)
+* Select "Restore NuGet Packages" from the solution context menu. It is recommended
+ to close and re-open the solution after the packages have been restored from
+ Visual Studio.
+* Build the solution.
# Using Monodevelop or Xamarin Studio
-The nuget add-in available for Xamarin Studio and Monodevelop IDEs is too old to
-download all of the nuget dependencies of gRPC.
+The NuGet add-in available for Xamarin Studio and Monodevelop IDEs is too old to
+download all of the NuGet dependencies of gRPC.
Using these IDEs, a workaround is as follows:
* Obtain a nuget executable for your platform and update it with
diff --git a/examples/csharp/HelloworldLegacyCsproj/generate_protos.bat b/examples/csharp/HelloworldLegacyCsproj/generate_protos.bat
deleted file mode 100644
index d1e7160f91..0000000000
--- a/examples/csharp/HelloworldLegacyCsproj/generate_protos.bat
+++ /dev/null
@@ -1,26 +0,0 @@
-@rem Copyright 2016 gRPC authors.
-@rem
-@rem Licensed under the Apache License, Version 2.0 (the "License");
-@rem you may not use this file except in compliance with the License.
-@rem You may obtain a copy of the License at
-@rem
-@rem http://www.apache.org/licenses/LICENSE-2.0
-@rem
-@rem Unless required by applicable law or agreed to in writing, software
-@rem distributed under the License is distributed on an "AS IS" BASIS,
-@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-@rem See the License for the specific language governing permissions and
-@rem limitations under the License.
-
-@rem Generate the C# code for .proto files
-
-setlocal
-
-@rem enter this directory
-cd /d %~dp0
-
-set TOOLS_PATH=packages\Grpc.Tools.1.14.1\tools\windows_x86
-
-%TOOLS_PATH%\protoc.exe -I../../protos --csharp_out Greeter ../../protos/helloworld.proto --grpc_out Greeter --plugin=protoc-gen-grpc=%TOOLS_PATH%\grpc_csharp_plugin.exe
-
-endlocal
diff --git a/examples/csharp/RouteGuide/RouteGuide.sln b/examples/csharp/RouteGuide/RouteGuide.sln
index 73e6e306b1..5e103294a5 100644
--- a/examples/csharp/RouteGuide/RouteGuide.sln
+++ b/examples/csharp/RouteGuide/RouteGuide.sln
@@ -1,4 +1,4 @@
-
+
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26228.4
diff --git a/examples/csharp/RouteGuide/RouteGuide/RouteGuide.cs b/examples/csharp/RouteGuide/RouteGuide/RouteGuide.cs
deleted file mode 100644
index 10c9aec5f8..0000000000
--- a/examples/csharp/RouteGuide/RouteGuide/RouteGuide.cs
+++ /dev/null
@@ -1,981 +0,0 @@
-// <auto-generated>
-// Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: route_guide.proto
-// </auto-generated>
-#pragma warning disable 1591, 0612, 3021
-#region Designer generated code
-
-using pb = global::Google.Protobuf;
-using pbc = global::Google.Protobuf.Collections;
-using pbr = global::Google.Protobuf.Reflection;
-using scg = global::System.Collections.Generic;
-namespace Routeguide {
-
- /// <summary>Holder for reflection information generated from route_guide.proto</summary>
- public static partial class RouteGuideReflection {
-
- #region Descriptor
- /// <summary>File descriptor for route_guide.proto</summary>
- public static pbr::FileDescriptor Descriptor {
- get { return descriptor; }
- }
- private static pbr::FileDescriptor descriptor;
-
- static RouteGuideReflection() {
- byte[] descriptorData = global::System.Convert.FromBase64String(
- string.Concat(
- "ChFyb3V0ZV9ndWlkZS5wcm90bxIKcm91dGVndWlkZSIsCgVQb2ludBIQCghs",
- "YXRpdHVkZRgBIAEoBRIRCglsb25naXR1ZGUYAiABKAUiSQoJUmVjdGFuZ2xl",
- "Eh0KAmxvGAEgASgLMhEucm91dGVndWlkZS5Qb2ludBIdCgJoaRgCIAEoCzIR",
- "LnJvdXRlZ3VpZGUuUG9pbnQiPAoHRmVhdHVyZRIMCgRuYW1lGAEgASgJEiMK",
- "CGxvY2F0aW9uGAIgASgLMhEucm91dGVndWlkZS5Qb2ludCJBCglSb3V0ZU5v",
- "dGUSIwoIbG9jYXRpb24YASABKAsyES5yb3V0ZWd1aWRlLlBvaW50Eg8KB21l",
- "c3NhZ2UYAiABKAkiYgoMUm91dGVTdW1tYXJ5EhMKC3BvaW50X2NvdW50GAEg",
- "ASgFEhUKDWZlYXR1cmVfY291bnQYAiABKAUSEAoIZGlzdGFuY2UYAyABKAUS",
- "FAoMZWxhcHNlZF90aW1lGAQgASgFMoUCCgpSb3V0ZUd1aWRlEjYKCkdldEZl",
- "YXR1cmUSES5yb3V0ZWd1aWRlLlBvaW50GhMucm91dGVndWlkZS5GZWF0dXJl",
- "IgASPgoMTGlzdEZlYXR1cmVzEhUucm91dGVndWlkZS5SZWN0YW5nbGUaEy5y",
- "b3V0ZWd1aWRlLkZlYXR1cmUiADABEj4KC1JlY29yZFJvdXRlEhEucm91dGVn",
- "dWlkZS5Qb2ludBoYLnJvdXRlZ3VpZGUuUm91dGVTdW1tYXJ5IgAoARI/CglS",
- "b3V0ZUNoYXQSFS5yb3V0ZWd1aWRlLlJvdXRlTm90ZRoVLnJvdXRlZ3VpZGUu",
- "Um91dGVOb3RlIgAoATABQjYKG2lvLmdycGMuZXhhbXBsZXMucm91dGVndWlk",
- "ZUIPUm91dGVHdWlkZVByb3RvUAGiAgNSVEdiBnByb3RvMw=="));
- descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
- new pbr::FileDescriptor[] { },
- new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
- new pbr::GeneratedClrTypeInfo(typeof(global::Routeguide.Point), global::Routeguide.Point.Parser, new[]{ "Latitude", "Longitude" }, null, null, null),
- new pbr::GeneratedClrTypeInfo(typeof(global::Routeguide.Rectangle), global::Routeguide.Rectangle.Parser, new[]{ "Lo", "Hi" }, null, null, null),
- new pbr::GeneratedClrTypeInfo(typeof(global::Routeguide.Feature), global::Routeguide.Feature.Parser, new[]{ "Name", "Location" }, null, null, null),
- new pbr::GeneratedClrTypeInfo(typeof(global::Routeguide.RouteNote), global::Routeguide.RouteNote.Parser, new[]{ "Location", "Message" }, null, null, null),
- new pbr::GeneratedClrTypeInfo(typeof(global::Routeguide.RouteSummary), global::Routeguide.RouteSummary.Parser, new[]{ "PointCount", "FeatureCount", "Distance", "ElapsedTime" }, null, null, null)
- }));
- }
- #endregion
-
- }
- #region Messages
- /// <summary>
- /// Points are represented as latitude-longitude pairs in the E7 representation
- /// (degrees multiplied by 10**7 and rounded to the nearest integer).
- /// Latitudes should be in the range +/- 90 degrees and longitude should be in
- /// the range +/- 180 degrees (inclusive).
- /// </summary>
- public sealed partial class Point : pb::IMessage<Point> {
- private static readonly pb::MessageParser<Point> _parser = new pb::MessageParser<Point>(() => new Point());
- private pb::UnknownFieldSet _unknownFields;
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public static pb::MessageParser<Point> Parser { get { return _parser; } }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public static pbr::MessageDescriptor Descriptor {
- get { return global::Routeguide.RouteGuideReflection.Descriptor.MessageTypes[0]; }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- pbr::MessageDescriptor pb::IMessage.Descriptor {
- get { return Descriptor; }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public Point() {
- OnConstruction();
- }
-
- partial void OnConstruction();
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public Point(Point other) : this() {
- latitude_ = other.latitude_;
- longitude_ = other.longitude_;
- _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public Point Clone() {
- return new Point(this);
- }
-
- /// <summary>Field number for the "latitude" field.</summary>
- public const int LatitudeFieldNumber = 1;
- private int latitude_;
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public int Latitude {
- get { return latitude_; }
- set {
- latitude_ = value;
- }
- }
-
- /// <summary>Field number for the "longitude" field.</summary>
- public const int LongitudeFieldNumber = 2;
- private int longitude_;
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public int Longitude {
- get { return longitude_; }
- set {
- longitude_ = value;
- }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override bool Equals(object other) {
- return Equals(other as Point);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public bool Equals(Point other) {
- if (ReferenceEquals(other, null)) {
- return false;
- }
- if (ReferenceEquals(other, this)) {
- return true;
- }
- if (Latitude != other.Latitude) return false;
- if (Longitude != other.Longitude) return false;
- return Equals(_unknownFields, other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override int GetHashCode() {
- int hash = 1;
- if (Latitude != 0) hash ^= Latitude.GetHashCode();
- if (Longitude != 0) hash ^= Longitude.GetHashCode();
- if (_unknownFields != null) {
- hash ^= _unknownFields.GetHashCode();
- }
- return hash;
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override string ToString() {
- return pb::JsonFormatter.ToDiagnosticString(this);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void WriteTo(pb::CodedOutputStream output) {
- if (Latitude != 0) {
- output.WriteRawTag(8);
- output.WriteInt32(Latitude);
- }
- if (Longitude != 0) {
- output.WriteRawTag(16);
- output.WriteInt32(Longitude);
- }
- if (_unknownFields != null) {
- _unknownFields.WriteTo(output);
- }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public int CalculateSize() {
- int size = 0;
- if (Latitude != 0) {
- size += 1 + pb::CodedOutputStream.ComputeInt32Size(Latitude);
- }
- if (Longitude != 0) {
- size += 1 + pb::CodedOutputStream.ComputeInt32Size(Longitude);
- }
- if (_unknownFields != null) {
- size += _unknownFields.CalculateSize();
- }
- return size;
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void MergeFrom(Point other) {
- if (other == null) {
- return;
- }
- if (other.Latitude != 0) {
- Latitude = other.Latitude;
- }
- if (other.Longitude != 0) {
- Longitude = other.Longitude;
- }
- _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void MergeFrom(pb::CodedInputStream input) {
- uint tag;
- while ((tag = input.ReadTag()) != 0) {
- switch(tag) {
- default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
- break;
- case 8: {
- Latitude = input.ReadInt32();
- break;
- }
- case 16: {
- Longitude = input.ReadInt32();
- break;
- }
- }
- }
- }
-
- }
-
- /// <summary>
- /// A latitude-longitude rectangle, represented as two diagonally opposite
- /// points "lo" and "hi".
- /// </summary>
- public sealed partial class Rectangle : pb::IMessage<Rectangle> {
- private static readonly pb::MessageParser<Rectangle> _parser = new pb::MessageParser<Rectangle>(() => new Rectangle());
- private pb::UnknownFieldSet _unknownFields;
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public static pb::MessageParser<Rectangle> Parser { get { return _parser; } }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public static pbr::MessageDescriptor Descriptor {
- get { return global::Routeguide.RouteGuideReflection.Descriptor.MessageTypes[1]; }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- pbr::MessageDescriptor pb::IMessage.Descriptor {
- get { return Descriptor; }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public Rectangle() {
- OnConstruction();
- }
-
- partial void OnConstruction();
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public Rectangle(Rectangle other) : this() {
- lo_ = other.lo_ != null ? other.lo_.Clone() : null;
- hi_ = other.hi_ != null ? other.hi_.Clone() : null;
- _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public Rectangle Clone() {
- return new Rectangle(this);
- }
-
- /// <summary>Field number for the "lo" field.</summary>
- public const int LoFieldNumber = 1;
- private global::Routeguide.Point lo_;
- /// <summary>
- /// One corner of the rectangle.
- /// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public global::Routeguide.Point Lo {
- get { return lo_; }
- set {
- lo_ = value;
- }
- }
-
- /// <summary>Field number for the "hi" field.</summary>
- public const int HiFieldNumber = 2;
- private global::Routeguide.Point hi_;
- /// <summary>
- /// The other corner of the rectangle.
- /// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public global::Routeguide.Point Hi {
- get { return hi_; }
- set {
- hi_ = value;
- }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override bool Equals(object other) {
- return Equals(other as Rectangle);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public bool Equals(Rectangle other) {
- if (ReferenceEquals(other, null)) {
- return false;
- }
- if (ReferenceEquals(other, this)) {
- return true;
- }
- if (!object.Equals(Lo, other.Lo)) return false;
- if (!object.Equals(Hi, other.Hi)) return false;
- return Equals(_unknownFields, other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override int GetHashCode() {
- int hash = 1;
- if (lo_ != null) hash ^= Lo.GetHashCode();
- if (hi_ != null) hash ^= Hi.GetHashCode();
- if (_unknownFields != null) {
- hash ^= _unknownFields.GetHashCode();
- }
- return hash;
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override string ToString() {
- return pb::JsonFormatter.ToDiagnosticString(this);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void WriteTo(pb::CodedOutputStream output) {
- if (lo_ != null) {
- output.WriteRawTag(10);
- output.WriteMessage(Lo);
- }
- if (hi_ != null) {
- output.WriteRawTag(18);
- output.WriteMessage(Hi);
- }
- if (_unknownFields != null) {
- _unknownFields.WriteTo(output);
- }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public int CalculateSize() {
- int size = 0;
- if (lo_ != null) {
- size += 1 + pb::CodedOutputStream.ComputeMessageSize(Lo);
- }
- if (hi_ != null) {
- size += 1 + pb::CodedOutputStream.ComputeMessageSize(Hi);
- }
- if (_unknownFields != null) {
- size += _unknownFields.CalculateSize();
- }
- return size;
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void MergeFrom(Rectangle other) {
- if (other == null) {
- return;
- }
- if (other.lo_ != null) {
- if (lo_ == null) {
- lo_ = new global::Routeguide.Point();
- }
- Lo.MergeFrom(other.Lo);
- }
- if (other.hi_ != null) {
- if (hi_ == null) {
- hi_ = new global::Routeguide.Point();
- }
- Hi.MergeFrom(other.Hi);
- }
- _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void MergeFrom(pb::CodedInputStream input) {
- uint tag;
- while ((tag = input.ReadTag()) != 0) {
- switch(tag) {
- default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
- break;
- case 10: {
- if (lo_ == null) {
- lo_ = new global::Routeguide.Point();
- }
- input.ReadMessage(lo_);
- break;
- }
- case 18: {
- if (hi_ == null) {
- hi_ = new global::Routeguide.Point();
- }
- input.ReadMessage(hi_);
- break;
- }
- }
- }
- }
-
- }
-
- /// <summary>
- /// A feature names something at a given point.
- ///
- /// If a feature could not be named, the name is empty.
- /// </summary>
- public sealed partial class Feature : pb::IMessage<Feature> {
- private static readonly pb::MessageParser<Feature> _parser = new pb::MessageParser<Feature>(() => new Feature());
- private pb::UnknownFieldSet _unknownFields;
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public static pb::MessageParser<Feature> Parser { get { return _parser; } }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public static pbr::MessageDescriptor Descriptor {
- get { return global::Routeguide.RouteGuideReflection.Descriptor.MessageTypes[2]; }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- pbr::MessageDescriptor pb::IMessage.Descriptor {
- get { return Descriptor; }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public Feature() {
- OnConstruction();
- }
-
- partial void OnConstruction();
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public Feature(Feature other) : this() {
- name_ = other.name_;
- location_ = other.location_ != null ? other.location_.Clone() : null;
- _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public Feature Clone() {
- return new Feature(this);
- }
-
- /// <summary>Field number for the "name" field.</summary>
- public const int NameFieldNumber = 1;
- private string name_ = "";
- /// <summary>
- /// The name of the feature.
- /// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public string Name {
- get { return name_; }
- set {
- name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
- }
- }
-
- /// <summary>Field number for the "location" field.</summary>
- public const int LocationFieldNumber = 2;
- private global::Routeguide.Point location_;
- /// <summary>
- /// The point where the feature is detected.
- /// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public global::Routeguide.Point Location {
- get { return location_; }
- set {
- location_ = value;
- }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override bool Equals(object other) {
- return Equals(other as Feature);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public bool Equals(Feature other) {
- if (ReferenceEquals(other, null)) {
- return false;
- }
- if (ReferenceEquals(other, this)) {
- return true;
- }
- if (Name != other.Name) return false;
- if (!object.Equals(Location, other.Location)) return false;
- return Equals(_unknownFields, other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override int GetHashCode() {
- int hash = 1;
- if (Name.Length != 0) hash ^= Name.GetHashCode();
- if (location_ != null) hash ^= Location.GetHashCode();
- if (_unknownFields != null) {
- hash ^= _unknownFields.GetHashCode();
- }
- return hash;
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override string ToString() {
- return pb::JsonFormatter.ToDiagnosticString(this);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void WriteTo(pb::CodedOutputStream output) {
- if (Name.Length != 0) {
- output.WriteRawTag(10);
- output.WriteString(Name);
- }
- if (location_ != null) {
- output.WriteRawTag(18);
- output.WriteMessage(Location);
- }
- if (_unknownFields != null) {
- _unknownFields.WriteTo(output);
- }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public int CalculateSize() {
- int size = 0;
- if (Name.Length != 0) {
- size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
- }
- if (location_ != null) {
- size += 1 + pb::CodedOutputStream.ComputeMessageSize(Location);
- }
- if (_unknownFields != null) {
- size += _unknownFields.CalculateSize();
- }
- return size;
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void MergeFrom(Feature other) {
- if (other == null) {
- return;
- }
- if (other.Name.Length != 0) {
- Name = other.Name;
- }
- if (other.location_ != null) {
- if (location_ == null) {
- location_ = new global::Routeguide.Point();
- }
- Location.MergeFrom(other.Location);
- }
- _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void MergeFrom(pb::CodedInputStream input) {
- uint tag;
- while ((tag = input.ReadTag()) != 0) {
- switch(tag) {
- default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
- break;
- case 10: {
- Name = input.ReadString();
- break;
- }
- case 18: {
- if (location_ == null) {
- location_ = new global::Routeguide.Point();
- }
- input.ReadMessage(location_);
- break;
- }
- }
- }
- }
-
- }
-
- /// <summary>
- /// A RouteNote is a message sent while at a given point.
- /// </summary>
- public sealed partial class RouteNote : pb::IMessage<RouteNote> {
- private static readonly pb::MessageParser<RouteNote> _parser = new pb::MessageParser<RouteNote>(() => new RouteNote());
- private pb::UnknownFieldSet _unknownFields;
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public static pb::MessageParser<RouteNote> Parser { get { return _parser; } }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public static pbr::MessageDescriptor Descriptor {
- get { return global::Routeguide.RouteGuideReflection.Descriptor.MessageTypes[3]; }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- pbr::MessageDescriptor pb::IMessage.Descriptor {
- get { return Descriptor; }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public RouteNote() {
- OnConstruction();
- }
-
- partial void OnConstruction();
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public RouteNote(RouteNote other) : this() {
- location_ = other.location_ != null ? other.location_.Clone() : null;
- message_ = other.message_;
- _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public RouteNote Clone() {
- return new RouteNote(this);
- }
-
- /// <summary>Field number for the "location" field.</summary>
- public const int LocationFieldNumber = 1;
- private global::Routeguide.Point location_;
- /// <summary>
- /// The location from which the message is sent.
- /// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public global::Routeguide.Point Location {
- get { return location_; }
- set {
- location_ = value;
- }
- }
-
- /// <summary>Field number for the "message" field.</summary>
- public const int MessageFieldNumber = 2;
- private string message_ = "";
- /// <summary>
- /// The message to be sent.
- /// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public string Message {
- get { return message_; }
- set {
- message_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
- }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override bool Equals(object other) {
- return Equals(other as RouteNote);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public bool Equals(RouteNote other) {
- if (ReferenceEquals(other, null)) {
- return false;
- }
- if (ReferenceEquals(other, this)) {
- return true;
- }
- if (!object.Equals(Location, other.Location)) return false;
- if (Message != other.Message) return false;
- return Equals(_unknownFields, other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override int GetHashCode() {
- int hash = 1;
- if (location_ != null) hash ^= Location.GetHashCode();
- if (Message.Length != 0) hash ^= Message.GetHashCode();
- if (_unknownFields != null) {
- hash ^= _unknownFields.GetHashCode();
- }
- return hash;
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override string ToString() {
- return pb::JsonFormatter.ToDiagnosticString(this);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void WriteTo(pb::CodedOutputStream output) {
- if (location_ != null) {
- output.WriteRawTag(10);
- output.WriteMessage(Location);
- }
- if (Message.Length != 0) {
- output.WriteRawTag(18);
- output.WriteString(Message);
- }
- if (_unknownFields != null) {
- _unknownFields.WriteTo(output);
- }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public int CalculateSize() {
- int size = 0;
- if (location_ != null) {
- size += 1 + pb::CodedOutputStream.ComputeMessageSize(Location);
- }
- if (Message.Length != 0) {
- size += 1 + pb::CodedOutputStream.ComputeStringSize(Message);
- }
- if (_unknownFields != null) {
- size += _unknownFields.CalculateSize();
- }
- return size;
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void MergeFrom(RouteNote other) {
- if (other == null) {
- return;
- }
- if (other.location_ != null) {
- if (location_ == null) {
- location_ = new global::Routeguide.Point();
- }
- Location.MergeFrom(other.Location);
- }
- if (other.Message.Length != 0) {
- Message = other.Message;
- }
- _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void MergeFrom(pb::CodedInputStream input) {
- uint tag;
- while ((tag = input.ReadTag()) != 0) {
- switch(tag) {
- default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
- break;
- case 10: {
- if (location_ == null) {
- location_ = new global::Routeguide.Point();
- }
- input.ReadMessage(location_);
- break;
- }
- case 18: {
- Message = input.ReadString();
- break;
- }
- }
- }
- }
-
- }
-
- /// <summary>
- /// A RouteSummary is received in response to a RecordRoute rpc.
- ///
- /// It contains the number of individual points received, the number of
- /// detected features, and the total distance covered as the cumulative sum of
- /// the distance between each point.
- /// </summary>
- public sealed partial class RouteSummary : pb::IMessage<RouteSummary> {
- private static readonly pb::MessageParser<RouteSummary> _parser = new pb::MessageParser<RouteSummary>(() => new RouteSummary());
- private pb::UnknownFieldSet _unknownFields;
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public static pb::MessageParser<RouteSummary> Parser { get { return _parser; } }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public static pbr::MessageDescriptor Descriptor {
- get { return global::Routeguide.RouteGuideReflection.Descriptor.MessageTypes[4]; }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- pbr::MessageDescriptor pb::IMessage.Descriptor {
- get { return Descriptor; }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public RouteSummary() {
- OnConstruction();
- }
-
- partial void OnConstruction();
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public RouteSummary(RouteSummary other) : this() {
- pointCount_ = other.pointCount_;
- featureCount_ = other.featureCount_;
- distance_ = other.distance_;
- elapsedTime_ = other.elapsedTime_;
- _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public RouteSummary Clone() {
- return new RouteSummary(this);
- }
-
- /// <summary>Field number for the "point_count" field.</summary>
- public const int PointCountFieldNumber = 1;
- private int pointCount_;
- /// <summary>
- /// The number of points received.
- /// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public int PointCount {
- get { return pointCount_; }
- set {
- pointCount_ = value;
- }
- }
-
- /// <summary>Field number for the "feature_count" field.</summary>
- public const int FeatureCountFieldNumber = 2;
- private int featureCount_;
- /// <summary>
- /// The number of known features passed while traversing the route.
- /// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public int FeatureCount {
- get { return featureCount_; }
- set {
- featureCount_ = value;
- }
- }
-
- /// <summary>Field number for the "distance" field.</summary>
- public const int DistanceFieldNumber = 3;
- private int distance_;
- /// <summary>
- /// The distance covered in metres.
- /// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public int Distance {
- get { return distance_; }
- set {
- distance_ = value;
- }
- }
-
- /// <summary>Field number for the "elapsed_time" field.</summary>
- public const int ElapsedTimeFieldNumber = 4;
- private int elapsedTime_;
- /// <summary>
- /// The duration of the traversal in seconds.
- /// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public int ElapsedTime {
- get { return elapsedTime_; }
- set {
- elapsedTime_ = value;
- }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override bool Equals(object other) {
- return Equals(other as RouteSummary);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public bool Equals(RouteSummary other) {
- if (ReferenceEquals(other, null)) {
- return false;
- }
- if (ReferenceEquals(other, this)) {
- return true;
- }
- if (PointCount != other.PointCount) return false;
- if (FeatureCount != other.FeatureCount) return false;
- if (Distance != other.Distance) return false;
- if (ElapsedTime != other.ElapsedTime) return false;
- return Equals(_unknownFields, other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override int GetHashCode() {
- int hash = 1;
- if (PointCount != 0) hash ^= PointCount.GetHashCode();
- if (FeatureCount != 0) hash ^= FeatureCount.GetHashCode();
- if (Distance != 0) hash ^= Distance.GetHashCode();
- if (ElapsedTime != 0) hash ^= ElapsedTime.GetHashCode();
- if (_unknownFields != null) {
- hash ^= _unknownFields.GetHashCode();
- }
- return hash;
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override string ToString() {
- return pb::JsonFormatter.ToDiagnosticString(this);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void WriteTo(pb::CodedOutputStream output) {
- if (PointCount != 0) {
- output.WriteRawTag(8);
- output.WriteInt32(PointCount);
- }
- if (FeatureCount != 0) {
- output.WriteRawTag(16);
- output.WriteInt32(FeatureCount);
- }
- if (Distance != 0) {
- output.WriteRawTag(24);
- output.WriteInt32(Distance);
- }
- if (ElapsedTime != 0) {
- output.WriteRawTag(32);
- output.WriteInt32(ElapsedTime);
- }
- if (_unknownFields != null) {
- _unknownFields.WriteTo(output);
- }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public int CalculateSize() {
- int size = 0;
- if (PointCount != 0) {
- size += 1 + pb::CodedOutputStream.ComputeInt32Size(PointCount);
- }
- if (FeatureCount != 0) {
- size += 1 + pb::CodedOutputStream.ComputeInt32Size(FeatureCount);
- }
- if (Distance != 0) {
- size += 1 + pb::CodedOutputStream.ComputeInt32Size(Distance);
- }
- if (ElapsedTime != 0) {
- size += 1 + pb::CodedOutputStream.ComputeInt32Size(ElapsedTime);
- }
- if (_unknownFields != null) {
- size += _unknownFields.CalculateSize();
- }
- return size;
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void MergeFrom(RouteSummary other) {
- if (other == null) {
- return;
- }
- if (other.PointCount != 0) {
- PointCount = other.PointCount;
- }
- if (other.FeatureCount != 0) {
- FeatureCount = other.FeatureCount;
- }
- if (other.Distance != 0) {
- Distance = other.Distance;
- }
- if (other.ElapsedTime != 0) {
- ElapsedTime = other.ElapsedTime;
- }
- _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void MergeFrom(pb::CodedInputStream input) {
- uint tag;
- while ((tag = input.ReadTag()) != 0) {
- switch(tag) {
- default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
- break;
- case 8: {
- PointCount = input.ReadInt32();
- break;
- }
- case 16: {
- FeatureCount = input.ReadInt32();
- break;
- }
- case 24: {
- Distance = input.ReadInt32();
- break;
- }
- case 32: {
- ElapsedTime = input.ReadInt32();
- break;
- }
- }
- }
- }
-
- }
-
- #endregion
-
-}
-
-#endregion Designer generated code
diff --git a/examples/csharp/RouteGuide/RouteGuide/RouteGuide.csproj b/examples/csharp/RouteGuide/RouteGuide/RouteGuide.csproj
index 86346d1e14..4c6949488c 100644
--- a/examples/csharp/RouteGuide/RouteGuide/RouteGuide.csproj
+++ b/examples/csharp/RouteGuide/RouteGuide/RouteGuide.csproj
@@ -1,25 +1,22 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
- <AssemblyTitle>RouteGuide</AssemblyTitle>
- <TargetFrameworks>netcoreapp2.1</TargetFrameworks>
- <DebugType>portable</DebugType>
- <AssemblyName>RouteGuide</AssemblyName>
- <PackageId>RouteGuide</PackageId>
+ <TargetFramework>netstandard1.5</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Google.Protobuf" Version="3.6.1" />
- <PackageReference Include="Google.Protobuf.Tools" Version="3.6.1" />
- <PackageReference Include="Grpc" Version="1.14.1" />
- <PackageReference Include="Grpc.Tools" Version="1.14.1" />
+ <PackageReference Include="Grpc" Version="1.17.0" />
+ <PackageReference Include="Grpc.Tools" Version="1.17.0" PrivateAssets="All" />
<PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
</ItemGroup>
<ItemGroup>
- <None Include="route_guide_db.json">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </None>
+ <Protobuf Include="..\..\..\protos\route_guide.proto" Link="protos\route_guide.proto" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <None Include="route_guide_db.json" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>
</Project>
diff --git a/examples/csharp/RouteGuide/RouteGuide/RouteGuideGrpc.cs b/examples/csharp/RouteGuide/RouteGuide/RouteGuideGrpc.cs
deleted file mode 100644
index 445708e446..0000000000
--- a/examples/csharp/RouteGuide/RouteGuide/RouteGuideGrpc.cs
+++ /dev/null
@@ -1,331 +0,0 @@
-// <auto-generated>
-// Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: route_guide.proto
-// </auto-generated>
-// Original file comments:
-// 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.
-//
-#pragma warning disable 0414, 1591
-#region Designer generated code
-
-using grpc = global::Grpc.Core;
-
-namespace Routeguide {
- /// <summary>
- /// Interface exported by the server.
- /// </summary>
- public static partial class RouteGuide
- {
- static readonly string __ServiceName = "routeguide.RouteGuide";
-
- static readonly grpc::Marshaller<global::Routeguide.Point> __Marshaller_routeguide_Point = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.Point.Parser.ParseFrom);
- static readonly grpc::Marshaller<global::Routeguide.Feature> __Marshaller_routeguide_Feature = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.Feature.Parser.ParseFrom);
- static readonly grpc::Marshaller<global::Routeguide.Rectangle> __Marshaller_routeguide_Rectangle = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.Rectangle.Parser.ParseFrom);
- static readonly grpc::Marshaller<global::Routeguide.RouteSummary> __Marshaller_routeguide_RouteSummary = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.RouteSummary.Parser.ParseFrom);
- static readonly grpc::Marshaller<global::Routeguide.RouteNote> __Marshaller_routeguide_RouteNote = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.RouteNote.Parser.ParseFrom);
-
- static readonly grpc::Method<global::Routeguide.Point, global::Routeguide.Feature> __Method_GetFeature = new grpc::Method<global::Routeguide.Point, global::Routeguide.Feature>(
- grpc::MethodType.Unary,
- __ServiceName,
- "GetFeature",
- __Marshaller_routeguide_Point,
- __Marshaller_routeguide_Feature);
-
- static readonly grpc::Method<global::Routeguide.Rectangle, global::Routeguide.Feature> __Method_ListFeatures = new grpc::Method<global::Routeguide.Rectangle, global::Routeguide.Feature>(
- grpc::MethodType.ServerStreaming,
- __ServiceName,
- "ListFeatures",
- __Marshaller_routeguide_Rectangle,
- __Marshaller_routeguide_Feature);
-
- static readonly grpc::Method<global::Routeguide.Point, global::Routeguide.RouteSummary> __Method_RecordRoute = new grpc::Method<global::Routeguide.Point, global::Routeguide.RouteSummary>(
- grpc::MethodType.ClientStreaming,
- __ServiceName,
- "RecordRoute",
- __Marshaller_routeguide_Point,
- __Marshaller_routeguide_RouteSummary);
-
- static readonly grpc::Method<global::Routeguide.RouteNote, global::Routeguide.RouteNote> __Method_RouteChat = new grpc::Method<global::Routeguide.RouteNote, global::Routeguide.RouteNote>(
- grpc::MethodType.DuplexStreaming,
- __ServiceName,
- "RouteChat",
- __Marshaller_routeguide_RouteNote,
- __Marshaller_routeguide_RouteNote);
-
- /// <summary>Service descriptor</summary>
- public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
- {
- get { return global::Routeguide.RouteGuideReflection.Descriptor.Services[0]; }
- }
-
- /// <summary>Base class for server-side implementations of RouteGuide</summary>
- public abstract partial class RouteGuideBase
- {
- /// <summary>
- /// A simple RPC.
- ///
- /// Obtains the feature at a given position.
- ///
- /// A feature with an empty name is returned if there's no feature at the given
- /// position.
- /// </summary>
- /// <param name="request">The request received from the client.</param>
- /// <param name="context">The context of the server-side call handler being invoked.</param>
- /// <returns>The response to send back to the client (wrapped by a task).</returns>
- public virtual global::System.Threading.Tasks.Task<global::Routeguide.Feature> GetFeature(global::Routeguide.Point request, grpc::ServerCallContext context)
- {
- throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
- }
-
- /// <summary>
- /// A server-to-client streaming RPC.
- ///
- /// Obtains the Features available within the given Rectangle. Results are
- /// streamed rather than returned at once (e.g. in a response message with a
- /// repeated field), as the rectangle may cover a large area and contain a
- /// huge number of features.
- /// </summary>
- /// <param name="request">The request received from the client.</param>
- /// <param name="responseStream">Used for sending responses back to the client.</param>
- /// <param name="context">The context of the server-side call handler being invoked.</param>
- /// <returns>A task indicating completion of the handler.</returns>
- public virtual global::System.Threading.Tasks.Task ListFeatures(global::Routeguide.Rectangle request, grpc::IServerStreamWriter<global::Routeguide.Feature> responseStream, grpc::ServerCallContext context)
- {
- throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
- }
-
- /// <summary>
- /// A client-to-server streaming RPC.
- ///
- /// Accepts a stream of Points on a route being traversed, returning a
- /// RouteSummary when traversal is completed.
- /// </summary>
- /// <param name="requestStream">Used for reading requests from the client.</param>
- /// <param name="context">The context of the server-side call handler being invoked.</param>
- /// <returns>The response to send back to the client (wrapped by a task).</returns>
- public virtual global::System.Threading.Tasks.Task<global::Routeguide.RouteSummary> RecordRoute(grpc::IAsyncStreamReader<global::Routeguide.Point> requestStream, grpc::ServerCallContext context)
- {
- throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
- }
-
- /// <summary>
- /// A Bidirectional streaming RPC.
- ///
- /// Accepts a stream of RouteNotes sent while a route is being traversed,
- /// while receiving other RouteNotes (e.g. from other users).
- /// </summary>
- /// <param name="requestStream">Used for reading requests from the client.</param>
- /// <param name="responseStream">Used for sending responses back to the client.</param>
- /// <param name="context">The context of the server-side call handler being invoked.</param>
- /// <returns>A task indicating completion of the handler.</returns>
- public virtual global::System.Threading.Tasks.Task RouteChat(grpc::IAsyncStreamReader<global::Routeguide.RouteNote> requestStream, grpc::IServerStreamWriter<global::Routeguide.RouteNote> responseStream, grpc::ServerCallContext context)
- {
- throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
- }
-
- }
-
- /// <summary>Client for RouteGuide</summary>
- public partial class RouteGuideClient : grpc::ClientBase<RouteGuideClient>
- {
- /// <summary>Creates a new client for RouteGuide</summary>
- /// <param name="channel">The channel to use to make remote calls.</param>
- public RouteGuideClient(grpc::Channel channel) : base(channel)
- {
- }
- /// <summary>Creates a new client for RouteGuide that uses a custom <c>CallInvoker</c>.</summary>
- /// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
- public RouteGuideClient(grpc::CallInvoker callInvoker) : base(callInvoker)
- {
- }
- /// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
- protected RouteGuideClient() : base()
- {
- }
- /// <summary>Protected constructor to allow creation of configured clients.</summary>
- /// <param name="configuration">The client configuration.</param>
- protected RouteGuideClient(ClientBaseConfiguration configuration) : base(configuration)
- {
- }
-
- /// <summary>
- /// A simple RPC.
- ///
- /// Obtains the feature at a given position.
- ///
- /// A feature with an empty name is returned if there's no feature at the given
- /// position.
- /// </summary>
- /// <param name="request">The request to send to the server.</param>
- /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
- /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
- /// <param name="cancellationToken">An optional token for canceling the call.</param>
- /// <returns>The response received from the server.</returns>
- public virtual global::Routeguide.Feature GetFeature(global::Routeguide.Point request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
- {
- return GetFeature(request, new grpc::CallOptions(headers, deadline, cancellationToken));
- }
- /// <summary>
- /// A simple RPC.
- ///
- /// Obtains the feature at a given position.
- ///
- /// A feature with an empty name is returned if there's no feature at the given
- /// position.
- /// </summary>
- /// <param name="request">The request to send to the server.</param>
- /// <param name="options">The options for the call.</param>
- /// <returns>The response received from the server.</returns>
- public virtual global::Routeguide.Feature GetFeature(global::Routeguide.Point request, grpc::CallOptions options)
- {
- return CallInvoker.BlockingUnaryCall(__Method_GetFeature, null, options, request);
- }
- /// <summary>
- /// A simple RPC.
- ///
- /// Obtains the feature at a given position.
- ///
- /// A feature with an empty name is returned if there's no feature at the given
- /// position.
- /// </summary>
- /// <param name="request">The request to send to the server.</param>
- /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
- /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
- /// <param name="cancellationToken">An optional token for canceling the call.</param>
- /// <returns>The call object.</returns>
- public virtual grpc::AsyncUnaryCall<global::Routeguide.Feature> GetFeatureAsync(global::Routeguide.Point request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
- {
- return GetFeatureAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
- }
- /// <summary>
- /// A simple RPC.
- ///
- /// Obtains the feature at a given position.
- ///
- /// A feature with an empty name is returned if there's no feature at the given
- /// position.
- /// </summary>
- /// <param name="request">The request to send to the server.</param>
- /// <param name="options">The options for the call.</param>
- /// <returns>The call object.</returns>
- public virtual grpc::AsyncUnaryCall<global::Routeguide.Feature> GetFeatureAsync(global::Routeguide.Point request, grpc::CallOptions options)
- {
- return CallInvoker.AsyncUnaryCall(__Method_GetFeature, null, options, request);
- }
- /// <summary>
- /// A server-to-client streaming RPC.
- ///
- /// Obtains the Features available within the given Rectangle. Results are
- /// streamed rather than returned at once (e.g. in a response message with a
- /// repeated field), as the rectangle may cover a large area and contain a
- /// huge number of features.
- /// </summary>
- /// <param name="request">The request to send to the server.</param>
- /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
- /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
- /// <param name="cancellationToken">An optional token for canceling the call.</param>
- /// <returns>The call object.</returns>
- public virtual grpc::AsyncServerStreamingCall<global::Routeguide.Feature> ListFeatures(global::Routeguide.Rectangle request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
- {
- return ListFeatures(request, new grpc::CallOptions(headers, deadline, cancellationToken));
- }
- /// <summary>
- /// A server-to-client streaming RPC.
- ///
- /// Obtains the Features available within the given Rectangle. Results are
- /// streamed rather than returned at once (e.g. in a response message with a
- /// repeated field), as the rectangle may cover a large area and contain a
- /// huge number of features.
- /// </summary>
- /// <param name="request">The request to send to the server.</param>
- /// <param name="options">The options for the call.</param>
- /// <returns>The call object.</returns>
- public virtual grpc::AsyncServerStreamingCall<global::Routeguide.Feature> ListFeatures(global::Routeguide.Rectangle request, grpc::CallOptions options)
- {
- return CallInvoker.AsyncServerStreamingCall(__Method_ListFeatures, null, options, request);
- }
- /// <summary>
- /// A client-to-server streaming RPC.
- ///
- /// Accepts a stream of Points on a route being traversed, returning a
- /// RouteSummary when traversal is completed.
- /// </summary>
- /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
- /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
- /// <param name="cancellationToken">An optional token for canceling the call.</param>
- /// <returns>The call object.</returns>
- public virtual grpc::AsyncClientStreamingCall<global::Routeguide.Point, global::Routeguide.RouteSummary> RecordRoute(grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
- {
- return RecordRoute(new grpc::CallOptions(headers, deadline, cancellationToken));
- }
- /// <summary>
- /// A client-to-server streaming RPC.
- ///
- /// Accepts a stream of Points on a route being traversed, returning a
- /// RouteSummary when traversal is completed.
- /// </summary>
- /// <param name="options">The options for the call.</param>
- /// <returns>The call object.</returns>
- public virtual grpc::AsyncClientStreamingCall<global::Routeguide.Point, global::Routeguide.RouteSummary> RecordRoute(grpc::CallOptions options)
- {
- return CallInvoker.AsyncClientStreamingCall(__Method_RecordRoute, null, options);
- }
- /// <summary>
- /// A Bidirectional streaming RPC.
- ///
- /// Accepts a stream of RouteNotes sent while a route is being traversed,
- /// while receiving other RouteNotes (e.g. from other users).
- /// </summary>
- /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
- /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
- /// <param name="cancellationToken">An optional token for canceling the call.</param>
- /// <returns>The call object.</returns>
- public virtual grpc::AsyncDuplexStreamingCall<global::Routeguide.RouteNote, global::Routeguide.RouteNote> RouteChat(grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
- {
- return RouteChat(new grpc::CallOptions(headers, deadline, cancellationToken));
- }
- /// <summary>
- /// A Bidirectional streaming RPC.
- ///
- /// Accepts a stream of RouteNotes sent while a route is being traversed,
- /// while receiving other RouteNotes (e.g. from other users).
- /// </summary>
- /// <param name="options">The options for the call.</param>
- /// <returns>The call object.</returns>
- public virtual grpc::AsyncDuplexStreamingCall<global::Routeguide.RouteNote, global::Routeguide.RouteNote> RouteChat(grpc::CallOptions options)
- {
- return CallInvoker.AsyncDuplexStreamingCall(__Method_RouteChat, null, options);
- }
- /// <summary>Creates a new instance of client from given <c>ClientBaseConfiguration</c>.</summary>
- protected override RouteGuideClient NewInstance(ClientBaseConfiguration configuration)
- {
- return new RouteGuideClient(configuration);
- }
- }
-
- /// <summary>Creates service definition that can be registered with a server</summary>
- /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
- public static grpc::ServerServiceDefinition BindService(RouteGuideBase serviceImpl)
- {
- return grpc::ServerServiceDefinition.CreateBuilder()
- .AddMethod(__Method_GetFeature, serviceImpl.GetFeature)
- .AddMethod(__Method_ListFeatures, serviceImpl.ListFeatures)
- .AddMethod(__Method_RecordRoute, serviceImpl.RecordRoute)
- .AddMethod(__Method_RouteChat, serviceImpl.RouteChat).Build();
- }
-
- }
-}
-#endregion
diff --git a/examples/csharp/RouteGuide/RouteGuide/RouteGuideUtil.cs b/examples/csharp/RouteGuide/RouteGuide/RouteGuideUtil.cs
index f9af190888..96bd8ca09b 100644
--- a/examples/csharp/RouteGuide/RouteGuide/RouteGuideUtil.cs
+++ b/examples/csharp/RouteGuide/RouteGuide/RouteGuideUtil.cs
@@ -108,6 +108,7 @@ namespace Routeguide
return features;
}
+#pragma warning disable 0649 // Suppresses "Field 'x' is never assigned to".
private class JsonFeature
{
public string name;
@@ -119,5 +120,6 @@ namespace Routeguide
public int longitude;
public int latitude;
}
+#pragma warning restore 0649
}
}
diff --git a/examples/csharp/RouteGuide/RouteGuideClient/RouteGuideClient.csproj b/examples/csharp/RouteGuide/RouteGuideClient/RouteGuideClient.csproj
index c6dadf082b..b773dd0923 100644
--- a/examples/csharp/RouteGuide/RouteGuideClient/RouteGuideClient.csproj
+++ b/examples/csharp/RouteGuide/RouteGuideClient/RouteGuideClient.csproj
@@ -1,12 +1,8 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
- <AssemblyTitle>RouteGuideClient</AssemblyTitle>
- <TargetFrameworks>netcoreapp2.1</TargetFrameworks>
- <DebugType>portable</DebugType>
- <AssemblyName>RouteGuideClient</AssemblyName>
+ <TargetFramework>netcoreapp2.1</TargetFramework>
<OutputType>Exe</OutputType>
- <PackageId>RouteGuideClient</PackageId>
</PropertyGroup>
<ItemGroup>
diff --git a/examples/csharp/RouteGuide/RouteGuideServer/RouteGuideServer.csproj b/examples/csharp/RouteGuide/RouteGuideServer/RouteGuideServer.csproj
index 005c87ca0c..b773dd0923 100644
--- a/examples/csharp/RouteGuide/RouteGuideServer/RouteGuideServer.csproj
+++ b/examples/csharp/RouteGuide/RouteGuideServer/RouteGuideServer.csproj
@@ -1,12 +1,8 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
- <AssemblyTitle>RouteGuideServer</AssemblyTitle>
- <TargetFrameworks>netcoreapp2.1</TargetFrameworks>
- <DebugType>portable</DebugType>
- <AssemblyName>RouteGuideServer</AssemblyName>
+ <TargetFramework>netcoreapp2.1</TargetFramework>
<OutputType>Exe</OutputType>
- <PackageId>RouteGuideServer</PackageId>
</PropertyGroup>
<ItemGroup>
diff --git a/examples/csharp/RouteGuide/generate_protos.bat b/examples/csharp/RouteGuide/generate_protos.bat
deleted file mode 100644
index f3a4382cf1..0000000000
--- a/examples/csharp/RouteGuide/generate_protos.bat
+++ /dev/null
@@ -1,28 +0,0 @@
-@rem Copyright 2016 gRPC authors.
-@rem
-@rem Licensed under the Apache License, Version 2.0 (the "License");
-@rem you may not use this file except in compliance with the License.
-@rem You may obtain a copy of the License at
-@rem
-@rem http://www.apache.org/licenses/LICENSE-2.0
-@rem
-@rem Unless required by applicable law or agreed to in writing, software
-@rem distributed under the License is distributed on an "AS IS" BASIS,
-@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-@rem See the License for the specific language governing permissions and
-@rem limitations under the License.
-
-@rem Generate the C# code for .proto files
-
-setlocal
-
-@rem enter this directory
-cd /d %~dp0
-
-@rem packages will be available in nuget cache directory once the project is built or after "dotnet restore"
-set PROTOC=%UserProfile%\.nuget\packages\Google.Protobuf.Tools\3.6.1\tools\windows_x64\protoc.exe
-set PLUGIN=%UserProfile%\.nuget\packages\Grpc.Tools\1.14.1\tools\windows_x64\grpc_csharp_plugin.exe
-
-%PROTOC% -I../../protos --csharp_out RouteGuide ../../protos/route_guide.proto --grpc_out RouteGuide --plugin=protoc-gen-grpc=%PLUGIN%
-
-endlocal
diff --git a/examples/objective-c/helloworld/HelloWorld.xcodeproj/project.pbxproj b/examples/objective-c/helloworld/HelloWorld.xcodeproj/project.pbxproj
index df5c40cda2..e067e82b3d 100644
--- a/examples/objective-c/helloworld/HelloWorld.xcodeproj/project.pbxproj
+++ b/examples/objective-c/helloworld/HelloWorld.xcodeproj/project.pbxproj
@@ -132,6 +132,8 @@
TargetAttributes = {
5E36905F1B2A23800040F884 = {
CreatedOnToolsVersion = 6.2;
+ DevelopmentTeam = EQHXZ8M8AV;
+ ProvisioningStyle = Manual;
};
};
};
@@ -321,9 +323,12 @@
baseConfigurationReference = DBDE3E48389499064CD664B8 /* Pods-HelloWorld.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CODE_SIGN_STYLE = Manual;
+ DEVELOPMENT_TEAM = EQHXZ8M8AV;
INFOPLIST_FILE = HelloWorld/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
+ PROVISIONING_PROFILE_SPECIFIER = "Google Development";
};
name = Debug;
};
@@ -332,9 +337,12 @@
baseConfigurationReference = 0C432EF610DB15C0F47A66BB /* Pods-HelloWorld.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CODE_SIGN_STYLE = Manual;
+ DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = HelloWorld/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
+ PROVISIONING_PROFILE_SPECIFIER = "";
};
name = Release;
};
diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec
index 6647201714..30fcb51ee1 100644
--- a/gRPC-C++.podspec
+++ b/gRPC-C++.podspec
@@ -24,7 +24,7 @@ Pod::Spec.new do |s|
s.name = 'gRPC-C++'
# TODO (mxyan): use version that match gRPC version when pod is stabilized
# version = '1.18.0-dev'
- version = '0.0.4'
+ version = '0.0.6-dev'
s.version = version
s.summary = 'gRPC C++ library'
s.homepage = 'https://grpc.io'
@@ -356,6 +356,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/resolver_registry.h',
'src/core/ext/filters/client_channel/resolver_result_parsing.h',
'src/core/ext/filters/client_channel/retry_throttle.h',
+ 'src/core/ext/filters/client_channel/server_address.h',
'src/core/ext/filters/client_channel/subchannel.h',
'src/core/ext/filters/client_channel/subchannel_index.h',
'src/core/ext/filters/deadline/deadline_filter.h',
@@ -405,6 +406,7 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/call_combiner.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_pair.h',
'src/core/lib/iomgr/error.h',
@@ -597,6 +599,7 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/call_combiner.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_pair.h',
'src/core/lib/iomgr/error.h',
diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec
index 3ec0852ad3..5ab7a49cd2 100644
--- a/gRPC-Core.podspec
+++ b/gRPC-Core.podspec
@@ -354,6 +354,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/resolver_registry.h',
'src/core/ext/filters/client_channel/resolver_result_parsing.h',
'src/core/ext/filters/client_channel/retry_throttle.h',
+ 'src/core/ext/filters/client_channel/server_address.h',
'src/core/ext/filters/client_channel/subchannel.h',
'src/core/ext/filters/client_channel/subchannel_index.h',
'src/core/ext/filters/deadline/deadline_filter.h',
@@ -403,6 +404,7 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/call_combiner.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_pair.h',
'src/core/lib/iomgr/error.h',
@@ -785,7 +787,6 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/http_connect_handshaker.cc',
'src/core/ext/filters/client_channel/http_proxy.cc',
'src/core/ext/filters/client_channel/lb_policy.cc',
- 'src/core/ext/filters/client_channel/lb_policy_factory.cc',
'src/core/ext/filters/client_channel/lb_policy_registry.cc',
'src/core/ext/filters/client_channel/parse_address.cc',
'src/core/ext/filters/client_channel/proxy_mapper.cc',
@@ -794,6 +795,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/resolver_registry.cc',
'src/core/ext/filters/client_channel/resolver_result_parsing.cc',
'src/core/ext/filters/client_channel/retry_throttle.cc',
+ 'src/core/ext/filters/client_channel/server_address.cc',
'src/core/ext/filters/client_channel/subchannel.cc',
'src/core/ext/filters/client_channel/subchannel_index.cc',
'src/core/ext/filters/deadline/deadline_filter.cc',
@@ -973,6 +975,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/resolver_registry.h',
'src/core/ext/filters/client_channel/resolver_result_parsing.h',
'src/core/ext/filters/client_channel/retry_throttle.h',
+ 'src/core/ext/filters/client_channel/server_address.h',
'src/core/ext/filters/client_channel/subchannel.h',
'src/core/ext/filters/client_channel/subchannel_index.h',
'src/core/ext/filters/deadline/deadline_filter.h',
@@ -1022,6 +1025,7 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/call_combiner.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_pair.h',
'src/core/lib/iomgr/error.h',
diff --git a/grpc.gemspec b/grpc.gemspec
index b5a1ef43fd..1ee7bec8e7 100644
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -290,6 +290,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/filters/client_channel/resolver_registry.h )
s.files += %w( src/core/ext/filters/client_channel/resolver_result_parsing.h )
s.files += %w( src/core/ext/filters/client_channel/retry_throttle.h )
+ s.files += %w( src/core/ext/filters/client_channel/server_address.h )
s.files += %w( src/core/ext/filters/client_channel/subchannel.h )
s.files += %w( src/core/ext/filters/client_channel/subchannel_index.h )
s.files += %w( src/core/ext/filters/deadline/deadline_filter.h )
@@ -339,6 +340,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/iomgr/call_combiner.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_pair.h )
s.files += %w( src/core/lib/iomgr/error.h )
@@ -724,7 +726,6 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/filters/client_channel/http_connect_handshaker.cc )
s.files += %w( src/core/ext/filters/client_channel/http_proxy.cc )
s.files += %w( src/core/ext/filters/client_channel/lb_policy.cc )
- s.files += %w( src/core/ext/filters/client_channel/lb_policy_factory.cc )
s.files += %w( src/core/ext/filters/client_channel/lb_policy_registry.cc )
s.files += %w( src/core/ext/filters/client_channel/parse_address.cc )
s.files += %w( src/core/ext/filters/client_channel/proxy_mapper.cc )
@@ -733,6 +734,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/filters/client_channel/resolver_registry.cc )
s.files += %w( src/core/ext/filters/client_channel/resolver_result_parsing.cc )
s.files += %w( src/core/ext/filters/client_channel/retry_throttle.cc )
+ s.files += %w( src/core/ext/filters/client_channel/server_address.cc )
s.files += %w( src/core/ext/filters/client_channel/subchannel.cc )
s.files += %w( src/core/ext/filters/client_channel/subchannel_index.cc )
s.files += %w( src/core/ext/filters/deadline/deadline_filter.cc )
diff --git a/grpc.gyp b/grpc.gyp
index 10277110dd..d03c74d8dc 100644
--- a/grpc.gyp
+++ b/grpc.gyp
@@ -540,7 +540,6 @@
'src/core/ext/filters/client_channel/http_connect_handshaker.cc',
'src/core/ext/filters/client_channel/http_proxy.cc',
'src/core/ext/filters/client_channel/lb_policy.cc',
- 'src/core/ext/filters/client_channel/lb_policy_factory.cc',
'src/core/ext/filters/client_channel/lb_policy_registry.cc',
'src/core/ext/filters/client_channel/parse_address.cc',
'src/core/ext/filters/client_channel/proxy_mapper.cc',
@@ -549,6 +548,7 @@
'src/core/ext/filters/client_channel/resolver_registry.cc',
'src/core/ext/filters/client_channel/resolver_result_parsing.cc',
'src/core/ext/filters/client_channel/retry_throttle.cc',
+ 'src/core/ext/filters/client_channel/server_address.cc',
'src/core/ext/filters/client_channel/subchannel.cc',
'src/core/ext/filters/client_channel/subchannel_index.cc',
'src/core/ext/filters/deadline/deadline_filter.cc',
@@ -799,7 +799,6 @@
'src/core/ext/filters/client_channel/http_connect_handshaker.cc',
'src/core/ext/filters/client_channel/http_proxy.cc',
'src/core/ext/filters/client_channel/lb_policy.cc',
- 'src/core/ext/filters/client_channel/lb_policy_factory.cc',
'src/core/ext/filters/client_channel/lb_policy_registry.cc',
'src/core/ext/filters/client_channel/parse_address.cc',
'src/core/ext/filters/client_channel/proxy_mapper.cc',
@@ -808,6 +807,7 @@
'src/core/ext/filters/client_channel/resolver_registry.cc',
'src/core/ext/filters/client_channel/resolver_result_parsing.cc',
'src/core/ext/filters/client_channel/retry_throttle.cc',
+ 'src/core/ext/filters/client_channel/server_address.cc',
'src/core/ext/filters/client_channel/subchannel.cc',
'src/core/ext/filters/client_channel/subchannel_index.cc',
'src/core/ext/filters/deadline/deadline_filter.cc',
@@ -1039,7 +1039,6 @@
'src/core/ext/filters/client_channel/http_connect_handshaker.cc',
'src/core/ext/filters/client_channel/http_proxy.cc',
'src/core/ext/filters/client_channel/lb_policy.cc',
- 'src/core/ext/filters/client_channel/lb_policy_factory.cc',
'src/core/ext/filters/client_channel/lb_policy_registry.cc',
'src/core/ext/filters/client_channel/parse_address.cc',
'src/core/ext/filters/client_channel/proxy_mapper.cc',
@@ -1048,6 +1047,7 @@
'src/core/ext/filters/client_channel/resolver_registry.cc',
'src/core/ext/filters/client_channel/resolver_result_parsing.cc',
'src/core/ext/filters/client_channel/retry_throttle.cc',
+ 'src/core/ext/filters/client_channel/server_address.cc',
'src/core/ext/filters/client_channel/subchannel.cc',
'src/core/ext/filters/client_channel/subchannel_index.cc',
'src/core/ext/filters/deadline/deadline_filter.cc',
@@ -1292,7 +1292,6 @@
'src/core/ext/filters/client_channel/http_connect_handshaker.cc',
'src/core/ext/filters/client_channel/http_proxy.cc',
'src/core/ext/filters/client_channel/lb_policy.cc',
- 'src/core/ext/filters/client_channel/lb_policy_factory.cc',
'src/core/ext/filters/client_channel/lb_policy_registry.cc',
'src/core/ext/filters/client_channel/parse_address.cc',
'src/core/ext/filters/client_channel/proxy_mapper.cc',
@@ -1301,6 +1300,7 @@
'src/core/ext/filters/client_channel/resolver_registry.cc',
'src/core/ext/filters/client_channel/resolver_result_parsing.cc',
'src/core/ext/filters/client_channel/retry_throttle.cc',
+ 'src/core/ext/filters/client_channel/server_address.cc',
'src/core/ext/filters/client_channel/subchannel.cc',
'src/core/ext/filters/client_channel/subchannel_index.cc',
'src/core/ext/filters/deadline/deadline_filter.cc',
@@ -1498,6 +1498,7 @@
'src/proto/grpc/testing/echo.proto',
'src/proto/grpc/testing/duplicate/echo_duplicate.proto',
'src/proto/grpc/testing/simple_messages.proto',
+ 'test/cpp/end2end/test_health_check_service_impl.cc',
'test/cpp/end2end/test_service_impl.cc',
'test/cpp/util/byte_buffer_proto_helper.cc',
'test/cpp/util/channel_trace_proto_helper.cc',
@@ -1522,6 +1523,7 @@
'src/proto/grpc/testing/echo.proto',
'src/proto/grpc/testing/duplicate/echo_duplicate.proto',
'src/proto/grpc/testing/simple_messages.proto',
+ 'test/cpp/end2end/test_health_check_service_impl.cc',
'test/cpp/end2end/test_service_impl.cc',
'test/cpp/util/byte_buffer_proto_helper.cc',
'test/cpp/util/string_ref_helper.cc',
diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h
index d3b74cabab..fec7f5269e 100644
--- a/include/grpc/grpc.h
+++ b/include/grpc/grpc.h
@@ -511,7 +511,8 @@ GRPCAPI char* grpc_channelz_get_server(intptr_t server_id);
/* Gets all server sockets that exist in the server. */
GRPCAPI char* grpc_channelz_get_server_sockets(intptr_t server_id,
- intptr_t start_socket_id);
+ intptr_t start_socket_id,
+ intptr_t max_results);
/* Returns a single Channel, or else a NOT_FOUND code. The returned string
is allocated and must be freed by the application. */
diff --git a/include/grpc/impl/codegen/port_platform.h b/include/grpc/impl/codegen/port_platform.h
index b2028a6305..031c0c36ae 100644
--- a/include/grpc/impl/codegen/port_platform.h
+++ b/include/grpc/impl/codegen/port_platform.h
@@ -526,6 +526,15 @@ typedef unsigned __int64 uint64_t;
#endif /* GPR_ATTRIBUTE_NO_TSAN (2) */
#endif /* GPR_ATTRIBUTE_NO_TSAN (1) */
+/* GRPC_TSAN_ENABLED will be defined, when compiled with thread sanitizer. */
+#if defined(__SANITIZE_THREAD__)
+#define GRPC_TSAN_ENABLED
+#elif defined(__has_feature)
+#if __has_feature(thread_sanitizer)
+#define GRPC_TSAN_ENABLED
+#endif
+#endif
+
/* GRPC_ALLOW_EXCEPTIONS should be 0 or 1 if exceptions are allowed or not */
#ifndef GRPC_ALLOW_EXCEPTIONS
/* If not already set, set to 1 on Windows (style guide standard) but to
diff --git a/include/grpcpp/health_check_service_interface.h b/include/grpcpp/health_check_service_interface.h
index b45a699bda..dfd4c3983a 100644
--- a/include/grpcpp/health_check_service_interface.h
+++ b/include/grpcpp/health_check_service_interface.h
@@ -37,6 +37,10 @@ class HealthCheckServiceInterface {
bool serving) = 0;
/// Apply to all registered service names.
virtual void SetServingStatus(bool serving) = 0;
+
+ /// Set all registered service names to not serving and prevent future
+ /// state changes.
+ virtual void Shutdown() {}
};
/// Enable/disable the default health checking service. This applies to all C++
diff --git a/include/grpcpp/impl/codegen/channel_interface.h b/include/grpcpp/impl/codegen/channel_interface.h
index 728a7b9049..5353f5feaa 100644
--- a/include/grpcpp/impl/codegen/channel_interface.h
+++ b/include/grpcpp/impl/codegen/channel_interface.h
@@ -21,7 +21,6 @@
#include <grpc/impl/codegen/connectivity_state.h>
#include <grpcpp/impl/codegen/call.h>
-#include <grpcpp/impl/codegen/client_context.h>
#include <grpcpp/impl/codegen/status.h>
#include <grpcpp/impl/codegen/time.h>
diff --git a/include/grpcpp/impl/codegen/client_callback.h b/include/grpcpp/impl/codegen/client_callback.h
index 4d9579fd6a..66cf9b7754 100644
--- a/include/grpcpp/impl/codegen/client_callback.h
+++ b/include/grpcpp/impl/codegen/client_callback.h
@@ -255,10 +255,12 @@ class ClientCallbackReaderWriterImpl
void MaybeFinish() {
if (--callbacks_outstanding_ == 0) {
- reactor_->OnDone(finish_status_);
+ Status s = std::move(finish_status_);
+ auto* reactor = reactor_;
auto* call = call_.call();
this->~ClientCallbackReaderWriterImpl();
g_core_codegen_interface->grpc_call_unref(call);
+ reactor->OnDone(s);
}
}
@@ -268,6 +270,7 @@ class ClientCallbackReaderWriterImpl
// 2. Any read backlog
// 3. Recv trailing metadata, on_completion callback
// 4. Any write backlog
+ // 5. See if the call can finish (if other callbacks were triggered already)
started_ = true;
start_tag_.Set(call_.call(),
@@ -318,6 +321,7 @@ class ClientCallbackReaderWriterImpl
if (writes_done_ops_at_start_) {
call_.PerformOps(&writes_done_ops_);
}
+ MaybeFinish();
}
void Read(Response* msg) override {
@@ -410,8 +414,8 @@ class ClientCallbackReaderWriterImpl
CallbackWithSuccessTag read_tag_;
bool read_ops_at_start_{false};
- // Minimum of 2 outstanding callbacks to pre-register for start and finish
- std::atomic_int callbacks_outstanding_{2};
+ // Minimum of 3 callbacks to pre-register for StartCall, start, and finish
+ std::atomic_int callbacks_outstanding_{3};
bool started_{false};
};
@@ -450,10 +454,12 @@ class ClientCallbackReaderImpl
void MaybeFinish() {
if (--callbacks_outstanding_ == 0) {
- reactor_->OnDone(finish_status_);
+ Status s = std::move(finish_status_);
+ auto* reactor = reactor_;
auto* call = call_.call();
this->~ClientCallbackReaderImpl();
g_core_codegen_interface->grpc_call_unref(call);
+ reactor->OnDone(s);
}
}
@@ -462,6 +468,7 @@ class ClientCallbackReaderImpl
// 1. Send initial metadata (unless corked) + recv initial metadata
// 2. Any backlog
// 3. Recv trailing metadata, on_completion callback
+ // 4. See if the call can finish (if other callbacks were triggered already)
started_ = true;
start_tag_.Set(call_.call(),
@@ -493,6 +500,8 @@ class ClientCallbackReaderImpl
finish_ops_.ClientRecvStatus(context_, &finish_status_);
finish_ops_.set_core_cq_tag(&finish_tag_);
call_.PerformOps(&finish_ops_);
+
+ MaybeFinish();
}
void Read(Response* msg) override {
@@ -536,8 +545,8 @@ class ClientCallbackReaderImpl
CallbackWithSuccessTag read_tag_;
bool read_ops_at_start_{false};
- // Minimum of 2 outstanding callbacks to pre-register for start and finish
- std::atomic_int callbacks_outstanding_{2};
+ // Minimum of 3 callbacks to pre-register for StartCall, start, and finish
+ std::atomic_int callbacks_outstanding_{3};
bool started_{false};
};
@@ -576,10 +585,12 @@ class ClientCallbackWriterImpl
void MaybeFinish() {
if (--callbacks_outstanding_ == 0) {
- reactor_->OnDone(finish_status_);
+ Status s = std::move(finish_status_);
+ auto* reactor = reactor_;
auto* call = call_.call();
this->~ClientCallbackWriterImpl();
g_core_codegen_interface->grpc_call_unref(call);
+ reactor->OnDone(s);
}
}
@@ -588,6 +599,7 @@ class ClientCallbackWriterImpl
// 1. Send initial metadata (unless corked) + recv initial metadata
// 2. Recv trailing metadata, on_completion callback
// 3. Any backlog
+ // 4. See if the call can finish (if other callbacks were triggered already)
started_ = true;
start_tag_.Set(call_.call(),
@@ -627,6 +639,8 @@ class ClientCallbackWriterImpl
if (writes_done_ops_at_start_) {
call_.PerformOps(&writes_done_ops_);
}
+
+ MaybeFinish();
}
void Write(const Request* msg, WriteOptions options) override {
@@ -708,8 +722,8 @@ class ClientCallbackWriterImpl
CallbackWithSuccessTag writes_done_tag_;
bool writes_done_ops_at_start_{false};
- // Minimum of 2 outstanding callbacks to pre-register for start and finish
- std::atomic_int callbacks_outstanding_{2};
+ // Minimum of 3 callbacks to pre-register for StartCall, start, and finish
+ std::atomic_int callbacks_outstanding_{3};
bool started_{false};
};
diff --git a/include/grpcpp/impl/codegen/client_context.h b/include/grpcpp/impl/codegen/client_context.h
index 142cfa35dd..0a71f3d9b6 100644
--- a/include/grpcpp/impl/codegen/client_context.h
+++ b/include/grpcpp/impl/codegen/client_context.h
@@ -46,6 +46,7 @@
#include <grpcpp/impl/codegen/core_codegen_interface.h>
#include <grpcpp/impl/codegen/create_auth_context.h>
#include <grpcpp/impl/codegen/metadata_map.h>
+#include <grpcpp/impl/codegen/rpc_method.h>
#include <grpcpp/impl/codegen/security/auth_context.h>
#include <grpcpp/impl/codegen/slice.h>
#include <grpcpp/impl/codegen/status.h>
@@ -418,12 +419,13 @@ class ClientContext {
void set_call(grpc_call* call, const std::shared_ptr<Channel>& channel);
experimental::ClientRpcInfo* set_client_rpc_info(
- const char* method, grpc::ChannelInterface* channel,
+ const char* method, internal::RpcMethod::RpcType type,
+ grpc::ChannelInterface* channel,
const std::vector<
std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>&
creators,
size_t interceptor_pos) {
- rpc_info_ = experimental::ClientRpcInfo(this, method, channel);
+ rpc_info_ = experimental::ClientRpcInfo(this, type, method, channel);
rpc_info_.RegisterInterceptors(creators, interceptor_pos);
return &rpc_info_;
}
diff --git a/include/grpcpp/impl/codegen/client_interceptor.h b/include/grpcpp/impl/codegen/client_interceptor.h
index f69c99ab22..2bae11a251 100644
--- a/include/grpcpp/impl/codegen/client_interceptor.h
+++ b/include/grpcpp/impl/codegen/client_interceptor.h
@@ -23,6 +23,7 @@
#include <vector>
#include <grpcpp/impl/codegen/interceptor.h>
+#include <grpcpp/impl/codegen/rpc_method.h>
#include <grpcpp/impl/codegen/string_ref.h>
namespace grpc {
@@ -52,23 +53,56 @@ extern experimental::ClientInterceptorFactoryInterface*
namespace experimental {
class ClientRpcInfo {
public:
- ClientRpcInfo() {}
+ // TODO(yashykt): Stop default-constructing ClientRpcInfo and remove UNKNOWN
+ // from the list of possible Types.
+ enum class Type {
+ UNARY,
+ CLIENT_STREAMING,
+ SERVER_STREAMING,
+ BIDI_STREAMING,
+ UNKNOWN // UNKNOWN is not API and will be removed later
+ };
~ClientRpcInfo(){};
ClientRpcInfo(const ClientRpcInfo&) = delete;
ClientRpcInfo(ClientRpcInfo&&) = default;
- ClientRpcInfo& operator=(ClientRpcInfo&&) = default;
// Getter methods
- const char* method() { return method_; }
+ const char* method() const { return method_; }
ChannelInterface* channel() { return channel_; }
grpc::ClientContext* client_context() { return ctx_; }
+ Type type() const { return type_; }
private:
- ClientRpcInfo(grpc::ClientContext* ctx, const char* method,
- grpc::ChannelInterface* channel)
- : ctx_(ctx), method_(method), channel_(channel) {}
+ static_assert(Type::UNARY ==
+ static_cast<Type>(internal::RpcMethod::NORMAL_RPC),
+ "violated expectation about Type enum");
+ static_assert(Type::CLIENT_STREAMING ==
+ static_cast<Type>(internal::RpcMethod::CLIENT_STREAMING),
+ "violated expectation about Type enum");
+ static_assert(Type::SERVER_STREAMING ==
+ static_cast<Type>(internal::RpcMethod::SERVER_STREAMING),
+ "violated expectation about Type enum");
+ static_assert(Type::BIDI_STREAMING ==
+ static_cast<Type>(internal::RpcMethod::BIDI_STREAMING),
+ "violated expectation about Type enum");
+
+ // Default constructor should only be used by ClientContext
+ ClientRpcInfo() = default;
+
+ // Constructor will only be called from ClientContext
+ ClientRpcInfo(grpc::ClientContext* ctx, internal::RpcMethod::RpcType type,
+ const char* method, grpc::ChannelInterface* channel)
+ : ctx_(ctx),
+ type_(static_cast<Type>(type)),
+ method_(method),
+ channel_(channel) {}
+
+ // Move assignment should only be used by ClientContext
+ // TODO(yashykt): Delete move assignment
+ ClientRpcInfo& operator=(ClientRpcInfo&&) = default;
+
// Runs interceptor at pos \a pos.
void RunInterceptor(
experimental::InterceptorBatchMethods* interceptor_methods, size_t pos) {
@@ -97,6 +131,8 @@ class ClientRpcInfo {
}
grpc::ClientContext* ctx_ = nullptr;
+ // TODO(yashykt): make type_ const once move-assignment is deleted
+ Type type_{Type::UNKNOWN};
const char* method_ = nullptr;
grpc::ChannelInterface* channel_ = nullptr;
std::vector<std::unique_ptr<experimental::Interceptor>> interceptors_;
diff --git a/include/grpcpp/impl/codegen/server_context.h b/include/grpcpp/impl/codegen/server_context.h
index 4a5f9e2dd9..ccb5925e7d 100644
--- a/include/grpcpp/impl/codegen/server_context.h
+++ b/include/grpcpp/impl/codegen/server_context.h
@@ -314,12 +314,12 @@ class ServerContext {
uint32_t initial_metadata_flags() const { return 0; }
experimental::ServerRpcInfo* set_server_rpc_info(
- const char* method,
+ const char* method, internal::RpcMethod::RpcType type,
const std::vector<
std::unique_ptr<experimental::ServerInterceptorFactoryInterface>>&
creators) {
if (creators.size() != 0) {
- rpc_info_ = new experimental::ServerRpcInfo(this, method);
+ rpc_info_ = new experimental::ServerRpcInfo(this, method, type);
rpc_info_->RegisterInterceptors(creators);
}
return rpc_info_;
diff --git a/include/grpcpp/impl/codegen/server_interceptor.h b/include/grpcpp/impl/codegen/server_interceptor.h
index 5fb5df28b7..cd7c0600b6 100644
--- a/include/grpcpp/impl/codegen/server_interceptor.h
+++ b/include/grpcpp/impl/codegen/server_interceptor.h
@@ -23,6 +23,7 @@
#include <vector>
#include <grpcpp/impl/codegen/interceptor.h>
+#include <grpcpp/impl/codegen/rpc_method.h>
#include <grpcpp/impl/codegen/string_ref.h>
namespace grpc {
@@ -44,6 +45,8 @@ class ServerInterceptorFactoryInterface {
class ServerRpcInfo {
public:
+ enum class Type { UNARY, CLIENT_STREAMING, SERVER_STREAMING, BIDI_STREAMING };
+
~ServerRpcInfo(){};
ServerRpcInfo(const ServerRpcInfo&) = delete;
@@ -51,12 +54,27 @@ class ServerRpcInfo {
ServerRpcInfo& operator=(ServerRpcInfo&&) = default;
// Getter methods
- const char* method() { return method_; }
+ const char* method() const { return method_; }
+ Type type() const { return type_; }
grpc::ServerContext* server_context() { return ctx_; }
private:
- ServerRpcInfo(grpc::ServerContext* ctx, const char* method)
- : ctx_(ctx), method_(method) {
+ static_assert(Type::UNARY ==
+ static_cast<Type>(internal::RpcMethod::NORMAL_RPC),
+ "violated expectation about Type enum");
+ static_assert(Type::CLIENT_STREAMING ==
+ static_cast<Type>(internal::RpcMethod::CLIENT_STREAMING),
+ "violated expectation about Type enum");
+ static_assert(Type::SERVER_STREAMING ==
+ static_cast<Type>(internal::RpcMethod::SERVER_STREAMING),
+ "violated expectation about Type enum");
+ static_assert(Type::BIDI_STREAMING ==
+ static_cast<Type>(internal::RpcMethod::BIDI_STREAMING),
+ "violated expectation about Type enum");
+
+ ServerRpcInfo(grpc::ServerContext* ctx, const char* method,
+ internal::RpcMethod::RpcType type)
+ : ctx_(ctx), method_(method), type_(static_cast<Type>(type)) {
ref_.store(1);
}
@@ -86,6 +104,7 @@ class ServerRpcInfo {
grpc::ServerContext* ctx_ = nullptr;
const char* method_ = nullptr;
+ const Type type_;
std::atomic_int ref_;
std::vector<std::unique_ptr<experimental::Interceptor>> interceptors_;
diff --git a/include/grpcpp/impl/codegen/server_interface.h b/include/grpcpp/impl/codegen/server_interface.h
index 55c94f4d2f..e0e2629827 100644
--- a/include/grpcpp/impl/codegen/server_interface.h
+++ b/include/grpcpp/impl/codegen/server_interface.h
@@ -174,13 +174,14 @@ class ServerInterface : public internal::CallHook {
bool done_intercepting_;
};
+ /// RegisteredAsyncRequest is not part of the C++ API
class RegisteredAsyncRequest : public BaseAsyncRequest {
public:
RegisteredAsyncRequest(ServerInterface* server, ServerContext* context,
internal::ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag,
- const char* name);
+ const char* name, internal::RpcMethod::RpcType type);
virtual bool FinalizeResult(void** tag, bool* status) override {
/* If we are done intercepting, then there is nothing more for us to do */
@@ -189,7 +190,7 @@ class ServerInterface : public internal::CallHook {
}
call_wrapper_ = internal::Call(
call_, server_, call_cq_, server_->max_receive_message_size(),
- context_->set_server_rpc_info(name_,
+ context_->set_server_rpc_info(name_, type_,
*server_->interceptor_creators()));
return BaseAsyncRequest::FinalizeResult(tag, status);
}
@@ -198,6 +199,7 @@ class ServerInterface : public internal::CallHook {
void IssueRequest(void* registered_method, grpc_byte_buffer** payload,
ServerCompletionQueue* notification_cq);
const char* name_;
+ const internal::RpcMethod::RpcType type_;
};
class NoPayloadAsyncRequest final : public RegisteredAsyncRequest {
@@ -207,9 +209,9 @@ class ServerInterface : public internal::CallHook {
internal::ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag)
- : RegisteredAsyncRequest(server, context, stream, call_cq,
- notification_cq, tag,
- registered_method->name()) {
+ : RegisteredAsyncRequest(
+ server, context, stream, call_cq, notification_cq, tag,
+ registered_method->name(), registered_method->method_type()) {
IssueRequest(registered_method->server_tag(), nullptr, notification_cq);
}
@@ -225,9 +227,9 @@ class ServerInterface : public internal::CallHook {
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag,
Message* request)
- : RegisteredAsyncRequest(server, context, stream, call_cq,
- notification_cq, tag,
- registered_method->name()),
+ : RegisteredAsyncRequest(
+ server, context, stream, call_cq, notification_cq, tag,
+ registered_method->name(), registered_method->method_type()),
registered_method_(registered_method),
server_(server),
context_(context),
diff --git a/package.xml b/package.xml
index a354ad5fa7..68fc7433cb 100644
--- a/package.xml
+++ b/package.xml
@@ -295,6 +295,7 @@
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver_registry.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver_result_parsing.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/retry_throttle.h" role="src" />
+ <file baseinstalldir="/" name="src/core/ext/filters/client_channel/server_address.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/subchannel.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/subchannel_index.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/deadline/deadline_filter.h" role="src" />
@@ -344,6 +345,7 @@
<file baseinstalldir="/" name="src/core/lib/iomgr/call_combiner.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_pair.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/error.h" role="src" />
@@ -729,7 +731,6 @@
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/http_connect_handshaker.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/http_proxy.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy.cc" role="src" />
- <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy_factory.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy_registry.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/parse_address.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/proxy_mapper.cc" role="src" />
@@ -738,6 +739,7 @@
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver_registry.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver_result_parsing.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/retry_throttle.cc" role="src" />
+ <file baseinstalldir="/" name="src/core/ext/filters/client_channel/server_address.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/subchannel.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/subchannel_index.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/deadline/deadline_filter.cc" role="src" />
diff --git a/setup.cfg b/setup.cfg
index 218792e674..125ec93491 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -15,3 +15,6 @@ exclude=.*protoc_plugin/protoc_plugin_test\.proto$
# Style settings
[yapf]
based_on_style = google
+
+[metadata]
+license_files = LICENSE
diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc
index be7962261b..70aac47231 100644
--- a/src/core/ext/filters/client_channel/client_channel.cc
+++ b/src/core/ext/filters/client_channel/client_channel.cc
@@ -38,6 +38,7 @@
#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/ext/filters/client_channel/server_address.h"
#include "src/core/ext/filters/client_channel/subchannel.h"
#include "src/core/ext/filters/deadline/deadline_filter.h"
#include "src/core/lib/backoff/backoff.h"
@@ -62,6 +63,7 @@
#include "src/core/lib/transport/static_metadata.h"
#include "src/core/lib/transport/status_metadata.h"
+using grpc_core::ServerAddressList;
using grpc_core::internal::ClientChannelMethodParams;
using grpc_core::internal::ClientChannelMethodParamsTable;
using grpc_core::internal::ProcessedResolverResult;
@@ -383,16 +385,10 @@ static void create_new_lb_policy_locked(
static void maybe_add_trace_message_for_address_changes_locked(
channel_data* chand, TraceStringVector* trace_strings) {
- int resolution_contains_addresses = false;
- const grpc_arg* channel_arg =
- grpc_channel_args_find(chand->resolver_result, GRPC_ARG_LB_ADDRESSES);
- if (channel_arg != nullptr && channel_arg->type == GRPC_ARG_POINTER) {
- grpc_lb_addresses* addresses =
- static_cast<grpc_lb_addresses*>(channel_arg->value.pointer.p);
- if (addresses->num_addresses > 0) {
- resolution_contains_addresses = true;
- }
- }
+ const ServerAddressList* addresses =
+ grpc_core::FindServerAddressListChannelArg(chand->resolver_result);
+ const bool resolution_contains_addresses =
+ addresses != nullptr && addresses->size() > 0;
if (!resolution_contains_addresses &&
chand->previous_resolution_contained_addresses) {
trace_strings->push_back(gpr_strdup("Address list became empty"));
@@ -489,9 +485,9 @@ static void on_resolver_result_changed_locked(void* arg, grpc_error* error) {
// taking a lock on chand->info_mu, because this function is the
// only thing that modifies its value, and it can only be invoked
// once at any given time.
- bool lb_policy_name_changed = chand->info_lb_policy_name == nullptr ||
- gpr_stricmp(chand->info_lb_policy_name.get(),
- lb_policy_name.get()) != 0;
+ bool lb_policy_name_changed =
+ chand->info_lb_policy_name == nullptr ||
+ strcmp(chand->info_lb_policy_name.get(), lb_policy_name.get()) != 0;
if (chand->lb_policy != nullptr && !lb_policy_name_changed) {
// Continue using the same LB policy. Update with new addresses.
if (grpc_client_channel_trace.enabled()) {
@@ -570,12 +566,6 @@ static void start_transport_op_locked(void* arg, grpc_error* error_ignored) {
} else {
grpc_error* error = GRPC_ERROR_NONE;
grpc_core::LoadBalancingPolicy::PickState pick_state;
- pick_state.initial_metadata = nullptr;
- pick_state.initial_metadata_flags = 0;
- pick_state.on_complete = nullptr;
- memset(&pick_state.subchannel_call_context, 0,
- sizeof(pick_state.subchannel_call_context));
- pick_state.user_data = nullptr;
// Pick must return synchronously, because pick_state.on_complete is null.
GPR_ASSERT(chand->lb_policy->PickLocked(&pick_state, &error));
if (pick_state.connected_subchannel != nullptr) {
diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h
index 7034da6249..6b76fe5d5d 100644
--- a/src/core/ext/filters/client_channel/lb_policy.h
+++ b/src/core/ext/filters/client_channel/lb_policy.h
@@ -55,7 +55,7 @@ class LoadBalancingPolicy : public InternallyRefCounted<LoadBalancingPolicy> {
grpc_client_channel_factory* client_channel_factory = nullptr;
/// Channel args from the resolver.
/// Note that the LB policy gets the set of addresses from the
- /// GRPC_ARG_LB_ADDRESSES channel arg.
+ /// GRPC_ARG_SERVER_ADDRESS_LIST channel arg.
grpc_channel_args* args = nullptr;
/// Load balancing config from the resolver.
grpc_json* lb_config = nullptr;
@@ -80,11 +80,6 @@ class LoadBalancingPolicy : public InternallyRefCounted<LoadBalancingPolicy> {
/// Will be populated with context to pass to the subchannel call, if
/// needed.
grpc_call_context_element subchannel_call_context[GRPC_CONTEXT_COUNT] = {};
- /// Upon success, \a *user_data will be set to whatever opaque information
- /// may need to be propagated from the LB policy, or nullptr if not needed.
- // TODO(roth): As part of revamping our metadata APIs, try to find a
- // way to clean this up and C++-ify it.
- void** user_data = nullptr;
/// Next pointer. For internal use by LB policy.
PickState* next = nullptr;
};
@@ -95,7 +90,7 @@ class LoadBalancingPolicy : public InternallyRefCounted<LoadBalancingPolicy> {
/// Updates the policy with a new set of \a args and a new \a lb_config from
/// the resolver. Note that the LB policy gets the set of addresses from the
- /// GRPC_ARG_LB_ADDRESSES channel arg.
+ /// GRPC_ARG_SERVER_ADDRESS_LIST channel arg.
virtual void UpdateLocked(const grpc_channel_args& args,
grpc_json* lb_config) GRPC_ABSTRACT;
diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc
index a46579c7f7..a9a5965ed1 100644
--- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc
+++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc
@@ -84,6 +84,7 @@
#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
#include "src/core/ext/filters/client_channel/parse_address.h"
#include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h"
+#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/ext/filters/client_channel/subchannel_index.h"
#include "src/core/lib/backoff/backoff.h"
#include "src/core/lib/channel/channel_args.h"
@@ -113,6 +114,8 @@
#define GRPC_GRPCLB_RECONNECT_JITTER 0.2
#define GRPC_GRPCLB_DEFAULT_FALLBACK_TIMEOUT_MS 10000
+#define GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN "grpc.grpclb_address_lb_token"
+
namespace grpc_core {
TraceFlag grpc_lb_glb_trace(false, "glb");
@@ -121,7 +124,7 @@ namespace {
class GrpcLb : public LoadBalancingPolicy {
public:
- GrpcLb(const grpc_lb_addresses* addresses, const Args& args);
+ explicit GrpcLb(const Args& args);
void UpdateLocked(const grpc_channel_args& args,
grpc_json* lb_config) override;
@@ -161,9 +164,6 @@ class GrpcLb : public LoadBalancingPolicy {
// Our on_complete closure and the original one.
grpc_closure on_complete;
grpc_closure* original_on_complete;
- // The LB token associated with the pick. This is set via user_data in
- // the pick.
- grpc_mdelem lb_token;
// Stats for client-side load reporting.
RefCountedPtr<GrpcLbClientStats> client_stats;
// Next pending pick.
@@ -329,7 +329,7 @@ class GrpcLb : public LoadBalancingPolicy {
// 0 means not using fallback.
int lb_fallback_timeout_ms_ = 0;
// The backend addresses from the resolver.
- grpc_lb_addresses* fallback_backend_addresses_ = nullptr;
+ UniquePtr<ServerAddressList> fallback_backend_addresses_;
// Fallback timer.
bool fallback_timer_callback_pending_ = false;
grpc_timer lb_fallback_timer_;
@@ -349,7 +349,7 @@ class GrpcLb : public LoadBalancingPolicy {
// serverlist parsing code
//
-// vtable for LB tokens in grpc_lb_addresses
+// vtable for LB token channel arg.
void* lb_token_copy(void* token) {
return token == nullptr
? nullptr
@@ -361,38 +361,11 @@ void lb_token_destroy(void* token) {
}
}
int lb_token_cmp(void* token1, void* token2) {
- if (token1 > token2) return 1;
- if (token1 < token2) return -1;
- return 0;
+ return GPR_ICMP(token1, token2);
}
-const grpc_lb_user_data_vtable lb_token_vtable = {
+const grpc_arg_pointer_vtable lb_token_arg_vtable = {
lb_token_copy, lb_token_destroy, lb_token_cmp};
-// Returns the backend addresses extracted from the given addresses.
-grpc_lb_addresses* ExtractBackendAddresses(const grpc_lb_addresses* addresses) {
- // First pass: count the number of backend addresses.
- size_t num_backends = 0;
- for (size_t i = 0; i < addresses->num_addresses; ++i) {
- if (!addresses->addresses[i].is_balancer) {
- ++num_backends;
- }
- }
- // Second pass: actually populate the addresses and (empty) LB tokens.
- grpc_lb_addresses* backend_addresses =
- grpc_lb_addresses_create(num_backends, &lb_token_vtable);
- size_t num_copied = 0;
- for (size_t i = 0; i < addresses->num_addresses; ++i) {
- if (addresses->addresses[i].is_balancer) continue;
- const grpc_resolved_address* addr = &addresses->addresses[i].address;
- grpc_lb_addresses_set_address(backend_addresses, num_copied, &addr->addr,
- addr->len, false /* is_balancer */,
- nullptr /* balancer_name */,
- (void*)GRPC_MDELEM_LB_TOKEN_EMPTY.payload);
- ++num_copied;
- }
- return backend_addresses;
-}
-
bool IsServerValid(const grpc_grpclb_server* server, size_t idx, bool log) {
if (server->drop) return false;
const grpc_grpclb_ip_address* ip = &server->ip_address;
@@ -440,30 +413,16 @@ void ParseServer(const grpc_grpclb_server* server,
}
// Returns addresses extracted from \a serverlist.
-grpc_lb_addresses* ProcessServerlist(const grpc_grpclb_serverlist* serverlist) {
- size_t num_valid = 0;
- /* first pass: count how many are valid in order to allocate the necessary
- * memory in a single block */
+ServerAddressList ProcessServerlist(const grpc_grpclb_serverlist* serverlist) {
+ ServerAddressList addresses;
for (size_t i = 0; i < serverlist->num_servers; ++i) {
- if (IsServerValid(serverlist->servers[i], i, true)) ++num_valid;
- }
- grpc_lb_addresses* lb_addresses =
- grpc_lb_addresses_create(num_valid, &lb_token_vtable);
- /* second pass: actually populate the addresses and LB tokens (aka user data
- * to the outside world) to be read by the RR policy during its creation.
- * Given that the validity tests are very cheap, they are performed again
- * instead of marking the valid ones during the first pass, as this would
- * incurr in an allocation due to the arbitrary number of server */
- size_t addr_idx = 0;
- for (size_t sl_idx = 0; sl_idx < serverlist->num_servers; ++sl_idx) {
- const grpc_grpclb_server* server = serverlist->servers[sl_idx];
- if (!IsServerValid(serverlist->servers[sl_idx], sl_idx, false)) continue;
- GPR_ASSERT(addr_idx < num_valid);
- /* address processing */
+ const grpc_grpclb_server* server = serverlist->servers[i];
+ if (!IsServerValid(serverlist->servers[i], i, false)) continue;
+ // Address processing.
grpc_resolved_address addr;
ParseServer(server, &addr);
- /* lb token processing */
- void* user_data;
+ // LB token processing.
+ void* lb_token;
if (server->has_load_balance_token) {
const size_t lb_token_max_length =
GPR_ARRAY_SIZE(server->load_balance_token);
@@ -471,7 +430,7 @@ grpc_lb_addresses* ProcessServerlist(const grpc_grpclb_serverlist* serverlist) {
strnlen(server->load_balance_token, lb_token_max_length);
grpc_slice lb_token_mdstr = grpc_slice_from_copied_buffer(
server->load_balance_token, lb_token_length);
- user_data =
+ lb_token =
(void*)grpc_mdelem_from_slices(GRPC_MDSTR_LB_TOKEN, lb_token_mdstr)
.payload;
} else {
@@ -481,15 +440,16 @@ grpc_lb_addresses* ProcessServerlist(const grpc_grpclb_serverlist* serverlist) {
"be used instead",
uri);
gpr_free(uri);
- user_data = (void*)GRPC_MDELEM_LB_TOKEN_EMPTY.payload;
+ lb_token = (void*)GRPC_MDELEM_LB_TOKEN_EMPTY.payload;
}
- grpc_lb_addresses_set_address(lb_addresses, addr_idx, &addr.addr, addr.len,
- false /* is_balancer */,
- nullptr /* balancer_name */, user_data);
- ++addr_idx;
- }
- GPR_ASSERT(addr_idx == num_valid);
- return lb_addresses;
+ // Add address.
+ grpc_arg arg = grpc_channel_arg_pointer_create(
+ const_cast<char*>(GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN), lb_token,
+ &lb_token_arg_vtable);
+ grpc_channel_args* args = grpc_channel_args_copy_and_add(nullptr, &arg, 1);
+ addresses.emplace_back(addr, args);
+ }
+ return addresses;
}
//
@@ -829,8 +789,7 @@ void GrpcLb::BalancerCallState::OnBalancerMessageReceivedLocked(
grpc_grpclb_destroy_serverlist(grpclb_policy->serverlist_);
} else {
// Dispose of the fallback.
- grpc_lb_addresses_destroy(grpclb_policy->fallback_backend_addresses_);
- grpclb_policy->fallback_backend_addresses_ = nullptr;
+ grpclb_policy->fallback_backend_addresses_.reset();
if (grpclb_policy->fallback_timer_callback_pending_) {
grpc_timer_cancel(&grpclb_policy->lb_fallback_timer_);
}
@@ -910,31 +869,25 @@ void GrpcLb::BalancerCallState::OnBalancerStatusReceivedLocked(
// helper code for creating balancer channel
//
-grpc_lb_addresses* ExtractBalancerAddresses(
- const grpc_lb_addresses* addresses) {
- size_t num_grpclb_addrs = 0;
- for (size_t i = 0; i < addresses->num_addresses; ++i) {
- if (addresses->addresses[i].is_balancer) ++num_grpclb_addrs;
- }
- // There must be at least one balancer address, or else the
- // client_channel would not have chosen this LB policy.
- GPR_ASSERT(num_grpclb_addrs > 0);
- grpc_lb_addresses* lb_addresses =
- grpc_lb_addresses_create(num_grpclb_addrs, nullptr);
- size_t lb_addresses_idx = 0;
- for (size_t i = 0; i < addresses->num_addresses; ++i) {
- if (!addresses->addresses[i].is_balancer) continue;
- if (GPR_UNLIKELY(addresses->addresses[i].user_data != nullptr)) {
- gpr_log(GPR_ERROR,
- "This LB policy doesn't support user data. It will be ignored");
+ServerAddressList ExtractBalancerAddresses(const ServerAddressList& addresses) {
+ ServerAddressList balancer_addresses;
+ for (size_t i = 0; i < addresses.size(); ++i) {
+ if (addresses[i].IsBalancer()) {
+ // Strip out the is_balancer channel arg, since we don't want to
+ // recursively use the grpclb policy in the channel used to talk to
+ // the balancers. Note that we do NOT strip out the balancer_name
+ // channel arg, since we need that to set the authority correctly
+ // to talk to the balancers.
+ static const char* args_to_remove[] = {
+ GRPC_ARG_ADDRESS_IS_BALANCER,
+ };
+ balancer_addresses.emplace_back(
+ addresses[i].address(),
+ grpc_channel_args_copy_and_remove(addresses[i].args(), args_to_remove,
+ GPR_ARRAY_SIZE(args_to_remove)));
}
- grpc_lb_addresses_set_address(
- lb_addresses, lb_addresses_idx++, addresses->addresses[i].address.addr,
- addresses->addresses[i].address.len, false /* is balancer */,
- addresses->addresses[i].balancer_name, nullptr /* user data */);
}
- GPR_ASSERT(num_grpclb_addrs == lb_addresses_idx);
- return lb_addresses;
+ return balancer_addresses;
}
/* Returns the channel args for the LB channel, used to create a bidirectional
@@ -946,10 +899,10 @@ grpc_lb_addresses* ExtractBalancerAddresses(
* above the grpclb policy.
* - \a args: other args inherited from the grpclb policy. */
grpc_channel_args* BuildBalancerChannelArgs(
- const grpc_lb_addresses* addresses,
+ const ServerAddressList& addresses,
FakeResolverResponseGenerator* response_generator,
const grpc_channel_args* args) {
- grpc_lb_addresses* lb_addresses = ExtractBalancerAddresses(addresses);
+ ServerAddressList balancer_addresses = ExtractBalancerAddresses(addresses);
// Channel args to remove.
static const char* args_to_remove[] = {
// LB policy name, since we want to use the default (pick_first) in
@@ -967,7 +920,7 @@ grpc_channel_args* BuildBalancerChannelArgs(
// is_balancer=true. We need the LB channel to return addresses with
// is_balancer=false so that it does not wind up recursively using the
// grpclb LB policy, as per the special case logic in client_channel.c.
- GRPC_ARG_LB_ADDRESSES,
+ GRPC_ARG_SERVER_ADDRESS_LIST,
// The fake resolver response generator, because we are replacing it
// with the one from the grpclb policy, used to propagate updates to
// the LB channel.
@@ -983,10 +936,10 @@ grpc_channel_args* BuildBalancerChannelArgs(
};
// Channel args to add.
const grpc_arg args_to_add[] = {
- // New LB addresses.
+ // New address list.
// Note that we pass these in both when creating the LB channel
// and via the fake resolver. The latter is what actually gets used.
- grpc_lb_addresses_create_channel_arg(lb_addresses),
+ CreateServerAddressListChannelArg(&balancer_addresses),
// The fake resolver response generator, which we use to inject
// address updates into the LB channel.
grpc_core::FakeResolverResponseGenerator::MakeChannelArg(
@@ -1004,18 +957,14 @@ grpc_channel_args* BuildBalancerChannelArgs(
args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), args_to_add,
GPR_ARRAY_SIZE(args_to_add));
// Make any necessary modifications for security.
- new_args = grpc_lb_policy_grpclb_modify_lb_channel_args(new_args);
- // Clean up.
- grpc_lb_addresses_destroy(lb_addresses);
- return new_args;
+ return grpc_lb_policy_grpclb_modify_lb_channel_args(new_args);
}
//
// ctor and dtor
//
-GrpcLb::GrpcLb(const grpc_lb_addresses* addresses,
- const LoadBalancingPolicy::Args& args)
+GrpcLb::GrpcLb(const LoadBalancingPolicy::Args& args)
: LoadBalancingPolicy(args),
response_generator_(MakeRefCounted<FakeResolverResponseGenerator>()),
lb_call_backoff_(
@@ -1072,9 +1021,6 @@ GrpcLb::~GrpcLb() {
if (serverlist_ != nullptr) {
grpc_grpclb_destroy_serverlist(serverlist_);
}
- if (fallback_backend_addresses_ != nullptr) {
- grpc_lb_addresses_destroy(fallback_backend_addresses_);
- }
grpc_subchannel_index_unref();
}
@@ -1122,7 +1068,6 @@ void GrpcLb::HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) {
while ((pp = pending_picks_) != nullptr) {
pending_picks_ = pp->next;
pp->pick->on_complete = pp->original_on_complete;
- pp->pick->user_data = nullptr;
grpc_error* error = GRPC_ERROR_NONE;
if (new_policy->PickLocked(pp->pick, &error)) {
// Synchronous return; schedule closure.
@@ -1276,9 +1221,27 @@ void GrpcLb::NotifyOnStateChangeLocked(grpc_connectivity_state* current,
notify);
}
+// Returns the backend addresses extracted from the given addresses.
+UniquePtr<ServerAddressList> ExtractBackendAddresses(
+ const ServerAddressList& addresses) {
+ void* lb_token = (void*)GRPC_MDELEM_LB_TOKEN_EMPTY.payload;
+ grpc_arg arg = grpc_channel_arg_pointer_create(
+ const_cast<char*>(GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN), lb_token,
+ &lb_token_arg_vtable);
+ auto backend_addresses = MakeUnique<ServerAddressList>();
+ for (size_t i = 0; i < addresses.size(); ++i) {
+ if (!addresses[i].IsBalancer()) {
+ backend_addresses->emplace_back(
+ addresses[i].address(),
+ grpc_channel_args_copy_and_add(addresses[i].args(), &arg, 1));
+ }
+ }
+ return backend_addresses;
+}
+
void GrpcLb::ProcessChannelArgsLocked(const grpc_channel_args& args) {
- const grpc_arg* arg = grpc_channel_args_find(&args, GRPC_ARG_LB_ADDRESSES);
- if (GPR_UNLIKELY(arg == nullptr || arg->type != GRPC_ARG_POINTER)) {
+ const ServerAddressList* addresses = FindServerAddressListChannelArg(&args);
+ if (addresses == nullptr) {
// Ignore this update.
gpr_log(
GPR_ERROR,
@@ -1286,13 +1249,8 @@ void GrpcLb::ProcessChannelArgsLocked(const grpc_channel_args& args) {
this);
return;
}
- const grpc_lb_addresses* addresses =
- static_cast<const grpc_lb_addresses*>(arg->value.pointer.p);
// Update fallback address list.
- if (fallback_backend_addresses_ != nullptr) {
- grpc_lb_addresses_destroy(fallback_backend_addresses_);
- }
- fallback_backend_addresses_ = ExtractBackendAddresses(addresses);
+ fallback_backend_addresses_ = ExtractBackendAddresses(*addresses);
// Make sure that GRPC_ARG_LB_POLICY_NAME is set in channel args,
// since we use this to trigger the client_load_reporting filter.
static const char* args_to_remove[] = {GRPC_ARG_LB_POLICY_NAME};
@@ -1303,7 +1261,7 @@ void GrpcLb::ProcessChannelArgsLocked(const grpc_channel_args& args) {
&args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), &new_arg, 1);
// Construct args for balancer channel.
grpc_channel_args* lb_channel_args =
- BuildBalancerChannelArgs(addresses, response_generator_.get(), &args);
+ BuildBalancerChannelArgs(*addresses, response_generator_.get(), &args);
// Create balancer channel if needed.
if (lb_channel_ == nullptr) {
char* uri_str;
@@ -1509,12 +1467,17 @@ void DestroyClientStats(void* arg) {
}
void GrpcLb::PendingPickSetMetadataAndContext(PendingPick* pp) {
- /* if connected_subchannel is nullptr, no pick has been made by the RR
- * policy (e.g., all addresses failed to connect). There won't be any
- * user_data/token available */
+ // If connected_subchannel is nullptr, no pick has been made by the RR
+ // policy (e.g., all addresses failed to connect). There won't be any
+ // LB token available.
if (pp->pick->connected_subchannel != nullptr) {
- if (GPR_LIKELY(!GRPC_MDISNULL(pp->lb_token))) {
- AddLbTokenToInitialMetadata(GRPC_MDELEM_REF(pp->lb_token),
+ const grpc_arg* arg =
+ grpc_channel_args_find(pp->pick->connected_subchannel->args(),
+ GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN);
+ if (arg != nullptr) {
+ grpc_mdelem lb_token = {
+ reinterpret_cast<uintptr_t>(arg->value.pointer.p)};
+ AddLbTokenToInitialMetadata(GRPC_MDELEM_REF(lb_token),
&pp->pick->lb_token_mdelem_storage,
pp->pick->initial_metadata);
} else {
@@ -1598,12 +1561,10 @@ bool GrpcLb::PickFromRoundRobinPolicyLocked(bool force_async, PendingPick* pp,
return true;
}
}
- // Set client_stats and user_data.
+ // Set client_stats.
if (lb_calld_ != nullptr && lb_calld_->client_stats() != nullptr) {
pp->client_stats = lb_calld_->client_stats()->Ref();
}
- GPR_ASSERT(pp->pick->user_data == nullptr);
- pp->pick->user_data = (void**)&pp->lb_token;
// Pick via the RR policy.
bool pick_done = rr_policy_->PickLocked(pp->pick, error);
if (pick_done) {
@@ -1668,10 +1629,11 @@ void GrpcLb::CreateRoundRobinPolicyLocked(const Args& args) {
}
grpc_channel_args* GrpcLb::CreateRoundRobinPolicyArgsLocked() {
- grpc_lb_addresses* addresses;
+ ServerAddressList tmp_addresses;
+ ServerAddressList* addresses = &tmp_addresses;
bool is_backend_from_grpclb_load_balancer = false;
if (serverlist_ != nullptr) {
- addresses = ProcessServerlist(serverlist_);
+ tmp_addresses = ProcessServerlist(serverlist_);
is_backend_from_grpclb_load_balancer = true;
} else {
// If CreateOrUpdateRoundRobinPolicyLocked() is invoked when we haven't
@@ -1680,14 +1642,14 @@ grpc_channel_args* GrpcLb::CreateRoundRobinPolicyArgsLocked() {
// empty, in which case the new round_robin policy will keep the requested
// picks pending.
GPR_ASSERT(fallback_backend_addresses_ != nullptr);
- addresses = grpc_lb_addresses_copy(fallback_backend_addresses_);
+ addresses = fallback_backend_addresses_.get();
}
GPR_ASSERT(addresses != nullptr);
- // Replace the LB addresses in the channel args that we pass down to
+ // Replace the server address list in the channel args that we pass down to
// the subchannel.
- static const char* keys_to_remove[] = {GRPC_ARG_LB_ADDRESSES};
+ static const char* keys_to_remove[] = {GRPC_ARG_SERVER_ADDRESS_LIST};
grpc_arg args_to_add[3] = {
- grpc_lb_addresses_create_channel_arg(addresses),
+ CreateServerAddressListChannelArg(addresses),
// A channel arg indicating if the target is a backend inferred from a
// grpclb load balancer.
grpc_channel_arg_integer_create(
@@ -1704,7 +1666,6 @@ grpc_channel_args* GrpcLb::CreateRoundRobinPolicyArgsLocked() {
grpc_channel_args* args = grpc_channel_args_copy_and_add_and_remove(
args_, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), args_to_add,
num_args_to_add);
- grpc_lb_addresses_destroy(addresses);
return args;
}
@@ -1837,19 +1798,18 @@ class GrpcLbFactory : public LoadBalancingPolicyFactory {
OrphanablePtr<LoadBalancingPolicy> CreateLoadBalancingPolicy(
const LoadBalancingPolicy::Args& args) const override {
/* Count the number of gRPC-LB addresses. There must be at least one. */
- const grpc_arg* arg =
- grpc_channel_args_find(args.args, GRPC_ARG_LB_ADDRESSES);
- if (arg == nullptr || arg->type != GRPC_ARG_POINTER) {
- return nullptr;
- }
- grpc_lb_addresses* addresses =
- static_cast<grpc_lb_addresses*>(arg->value.pointer.p);
- size_t num_grpclb_addrs = 0;
- for (size_t i = 0; i < addresses->num_addresses; ++i) {
- if (addresses->addresses[i].is_balancer) ++num_grpclb_addrs;
+ const ServerAddressList* addresses =
+ FindServerAddressListChannelArg(args.args);
+ if (addresses == nullptr) return nullptr;
+ bool found_balancer = false;
+ for (size_t i = 0; i < addresses->size(); ++i) {
+ if ((*addresses)[i].IsBalancer()) {
+ found_balancer = true;
+ break;
+ }
}
- if (num_grpclb_addrs == 0) return nullptr;
- return OrphanablePtr<LoadBalancingPolicy>(New<GrpcLb>(addresses, args));
+ if (!found_balancer) return nullptr;
+ return OrphanablePtr<LoadBalancingPolicy>(New<GrpcLb>(args));
}
const char* name() const override { return "grpclb"; }
diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h
index 825065a9c3..3b2dc370eb 100644
--- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h
+++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h
@@ -21,7 +21,7 @@
#include <grpc/support/port_platform.h>
-#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
+#include <grpc/impl/codegen/grpc_types.h>
/// Makes any necessary modifications to \a args for use in the grpclb
/// balancer channel.
diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc
index 441efd5e23..6e8fbdcab7 100644
--- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc
+++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc
@@ -26,6 +26,7 @@
#include <grpc/support/string_util.h>
#include "src/core/ext/filters/client_channel/client_channel.h"
+#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
@@ -42,22 +43,23 @@ int BalancerNameCmp(const grpc_core::UniquePtr<char>& a,
}
RefCountedPtr<TargetAuthorityTable> CreateTargetAuthorityTable(
- grpc_lb_addresses* addresses) {
+ const ServerAddressList& addresses) {
TargetAuthorityTable::Entry* target_authority_entries =
- static_cast<TargetAuthorityTable::Entry*>(gpr_zalloc(
- sizeof(*target_authority_entries) * addresses->num_addresses));
- for (size_t i = 0; i < addresses->num_addresses; ++i) {
+ static_cast<TargetAuthorityTable::Entry*>(
+ gpr_zalloc(sizeof(*target_authority_entries) * addresses.size()));
+ for (size_t i = 0; i < addresses.size(); ++i) {
char* addr_str;
- GPR_ASSERT(grpc_sockaddr_to_string(
- &addr_str, &addresses->addresses[i].address, true) > 0);
+ GPR_ASSERT(
+ grpc_sockaddr_to_string(&addr_str, &addresses[i].address(), true) > 0);
target_authority_entries[i].key = grpc_slice_from_copied_string(addr_str);
- target_authority_entries[i].value.reset(
- gpr_strdup(addresses->addresses[i].balancer_name));
gpr_free(addr_str);
+ char* balancer_name = grpc_channel_arg_get_string(grpc_channel_args_find(
+ addresses[i].args(), GRPC_ARG_ADDRESS_BALANCER_NAME));
+ target_authority_entries[i].value.reset(gpr_strdup(balancer_name));
}
RefCountedPtr<TargetAuthorityTable> target_authority_table =
- TargetAuthorityTable::Create(addresses->num_addresses,
- target_authority_entries, BalancerNameCmp);
+ TargetAuthorityTable::Create(addresses.size(), target_authority_entries,
+ BalancerNameCmp);
gpr_free(target_authority_entries);
return target_authority_table;
}
@@ -72,13 +74,12 @@ grpc_channel_args* grpc_lb_policy_grpclb_modify_lb_channel_args(
grpc_arg args_to_add[2];
size_t num_args_to_add = 0;
// Add arg for targets info table.
- const grpc_arg* arg = grpc_channel_args_find(args, GRPC_ARG_LB_ADDRESSES);
- GPR_ASSERT(arg != nullptr);
- GPR_ASSERT(arg->type == GRPC_ARG_POINTER);
- grpc_lb_addresses* addresses =
- static_cast<grpc_lb_addresses*>(arg->value.pointer.p);
+ grpc_core::ServerAddressList* addresses =
+ grpc_core::FindServerAddressListChannelArg(args);
+ GPR_ASSERT(addresses != nullptr);
grpc_core::RefCountedPtr<grpc_core::TargetAuthorityTable>
- target_authority_table = grpc_core::CreateTargetAuthorityTable(addresses);
+ target_authority_table =
+ grpc_core::CreateTargetAuthorityTable(*addresses);
args_to_add[num_args_to_add++] =
grpc_core::CreateTargetAuthorityTableChannelArg(
target_authority_table.get());
diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h b/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h
index 9ca7b28d8e..71d371c880 100644
--- a/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h
+++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h
@@ -25,7 +25,7 @@
#include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h"
#include "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h"
-#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
#define GRPC_GRPCLB_SERVICE_NAME_MAX_LENGTH 128
diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
index d454401a66..74c17612a2 100644
--- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
+++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
@@ -24,6 +24,7 @@
#include "src/core/ext/filters/client_channel/lb_policy/subchannel_list.h"
#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
+#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/ext/filters/client_channel/subchannel.h"
#include "src/core/ext/filters/client_channel/subchannel_index.h"
#include "src/core/lib/channel/channel_args.h"
@@ -75,11 +76,9 @@ class PickFirst : public LoadBalancingPolicy {
PickFirstSubchannelData(
SubchannelList<PickFirstSubchannelList, PickFirstSubchannelData>*
subchannel_list,
- const grpc_lb_user_data_vtable* user_data_vtable,
- const grpc_lb_address& address, grpc_subchannel* subchannel,
+ const ServerAddress& address, grpc_subchannel* subchannel,
grpc_combiner* combiner)
- : SubchannelData(subchannel_list, user_data_vtable, address, subchannel,
- combiner) {}
+ : SubchannelData(subchannel_list, address, subchannel, combiner) {}
void ProcessConnectivityChangeLocked(
grpc_connectivity_state connectivity_state, grpc_error* error) override;
@@ -95,7 +94,7 @@ class PickFirst : public LoadBalancingPolicy {
PickFirstSubchannelData> {
public:
PickFirstSubchannelList(PickFirst* policy, TraceFlag* tracer,
- const grpc_lb_addresses* addresses,
+ const ServerAddressList& addresses,
grpc_combiner* combiner,
grpc_client_channel_factory* client_channel_factory,
const grpc_channel_args& args)
@@ -337,8 +336,8 @@ void PickFirst::UpdateChildRefsLocked() {
void PickFirst::UpdateLocked(const grpc_channel_args& args,
grpc_json* lb_config) {
AutoChildRefsUpdater guard(this);
- const grpc_arg* arg = grpc_channel_args_find(&args, GRPC_ARG_LB_ADDRESSES);
- if (arg == nullptr || arg->type != GRPC_ARG_POINTER) {
+ const ServerAddressList* addresses = FindServerAddressListChannelArg(&args);
+ if (addresses == nullptr) {
if (subchannel_list_ == nullptr) {
// If we don't have a current subchannel list, go into TRANSIENT FAILURE.
grpc_connectivity_state_set(
@@ -354,19 +353,17 @@ void PickFirst::UpdateLocked(const grpc_channel_args& args,
}
return;
}
- const grpc_lb_addresses* addresses =
- static_cast<const grpc_lb_addresses*>(arg->value.pointer.p);
if (grpc_lb_pick_first_trace.enabled()) {
gpr_log(GPR_INFO,
"Pick First %p received update with %" PRIuPTR " addresses", this,
- addresses->num_addresses);
+ addresses->size());
}
grpc_arg new_arg = grpc_channel_arg_integer_create(
const_cast<char*>(GRPC_ARG_INHIBIT_HEALTH_CHECKING), 1);
grpc_channel_args* new_args =
grpc_channel_args_copy_and_add(&args, &new_arg, 1);
auto subchannel_list = MakeOrphanable<PickFirstSubchannelList>(
- this, &grpc_lb_pick_first_trace, addresses, combiner(),
+ this, &grpc_lb_pick_first_trace, *addresses, combiner(),
client_channel_factory(), *new_args);
grpc_channel_args_destroy(new_args);
if (subchannel_list->num_subchannels() == 0) {
@@ -380,6 +377,31 @@ void PickFirst::UpdateLocked(const grpc_channel_args& args,
selected_ = nullptr;
return;
}
+ // If one of the subchannels in the new list is already in state
+ // READY, then select it immediately. This can happen when the
+ // currently selected subchannel is also present in the update. It
+ // can also happen if one of the subchannels in the update is already
+ // in the subchannel index because it's in use by another channel.
+ 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);
+ if (state == GRPC_CHANNEL_READY) {
+ subchannel_list_ = std::move(subchannel_list);
+ sd->ProcessUnselectedReadyLocked();
+ sd->StartConnectivityWatchLocked();
+ // If there was a previously pending update (which may or may
+ // not have contained the currently selected subchannel), drop
+ // it, so that it doesn't override what we've done here.
+ latest_pending_subchannel_list_.reset();
+ // Make sure that subsequent calls to ExitIdleLocked() don't cause
+ // us to start watching a subchannel other than the one we've
+ // selected.
+ started_picking_ = true;
+ return;
+ }
+ }
if (selected_ == nullptr) {
// We don't yet have a selected subchannel, so replace the current
// subchannel list immediately.
@@ -387,46 +409,14 @@ void PickFirst::UpdateLocked(const grpc_channel_args& args,
// If we've started picking, start trying to connect to the first
// subchannel in the new list.
if (started_picking_) {
- subchannel_list_->subchannel(0)
- ->CheckConnectivityStateAndStartWatchingLocked();
+ // Note: No need to use CheckConnectivityStateAndStartWatchingLocked()
+ // here, since we've already checked the initial connectivity
+ // state of all subchannels above.
+ subchannel_list_->subchannel(0)->StartConnectivityWatchLocked();
}
} else {
- // We do have a selected subchannel.
- // Check if it's present in the new list. If so, we're done.
- for (size_t i = 0; i < subchannel_list->num_subchannels(); ++i) {
- PickFirstSubchannelData* sd = subchannel_list->subchannel(i);
- if (sd->subchannel() == selected_->subchannel()) {
- // The currently selected subchannel is in the update: we are done.
- if (grpc_lb_pick_first_trace.enabled()) {
- gpr_log(GPR_INFO,
- "Pick First %p found already selected subchannel %p "
- "at update index %" PRIuPTR " of %" PRIuPTR "; update done",
- this, selected_->subchannel(), i,
- subchannel_list->num_subchannels());
- }
- // Make sure it's in state READY. It might not be if we grabbed
- // the combiner while a connectivity state notification
- // informing us otherwise is pending.
- // Note that CheckConnectivityStateLocked() also takes a ref to
- // the connected subchannel.
- grpc_error* error = GRPC_ERROR_NONE;
- if (sd->CheckConnectivityStateLocked(&error) == GRPC_CHANNEL_READY) {
- selected_ = sd;
- subchannel_list_ = std::move(subchannel_list);
- sd->StartConnectivityWatchLocked();
- // If there was a previously pending update (which may or may
- // not have contained the currently selected subchannel), drop
- // it, so that it doesn't override what we've done here.
- latest_pending_subchannel_list_.reset();
- return;
- }
- GRPC_ERROR_UNREF(error);
- }
- }
- // Not keeping the previous selected subchannel, so set the latest
- // pending subchannel list to the new subchannel list. We will wait
- // for it to report READY before swapping it into the current
- // subchannel list.
+ // We do have a selected subchannel, so keep using it until one of
+ // the subchannels in the new list reports READY.
if (latest_pending_subchannel_list_ != nullptr) {
if (grpc_lb_pick_first_trace.enabled()) {
gpr_log(GPR_INFO,
@@ -440,8 +430,11 @@ void PickFirst::UpdateLocked(const grpc_channel_args& args,
// If we've started picking, start trying to connect to the first
// subchannel in the new list.
if (started_picking_) {
+ // Note: No need to use CheckConnectivityStateAndStartWatchingLocked()
+ // here, since we've already checked the initial connectivity
+ // state of all subchannels above.
latest_pending_subchannel_list_->subchannel(0)
- ->CheckConnectivityStateAndStartWatchingLocked();
+ ->StartConnectivityWatchLocked();
}
}
}
diff --git a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc
index 2a16975131..63089afbd7 100644
--- a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc
+++ b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc
@@ -82,8 +82,6 @@ class RoundRobin : public LoadBalancingPolicy {
// Data for a particular subchannel in a subchannel list.
// This subclass adds the following functionality:
- // - Tracks user_data associated with each address, which will be
- // returned along with picks that select the subchannel.
// - Tracks the previous connectivity state of the subchannel, so that
// we know how many subchannels are in each state.
class RoundRobinSubchannelData
@@ -93,26 +91,9 @@ class RoundRobin : public LoadBalancingPolicy {
RoundRobinSubchannelData(
SubchannelList<RoundRobinSubchannelList, RoundRobinSubchannelData>*
subchannel_list,
- const grpc_lb_user_data_vtable* user_data_vtable,
- const grpc_lb_address& address, grpc_subchannel* subchannel,
+ const ServerAddress& address, grpc_subchannel* subchannel,
grpc_combiner* combiner)
- : SubchannelData(subchannel_list, user_data_vtable, address, subchannel,
- combiner),
- user_data_vtable_(user_data_vtable),
- user_data_(user_data_vtable_ != nullptr
- ? user_data_vtable_->copy(address.user_data)
- : nullptr) {}
-
- void UnrefSubchannelLocked(const char* reason) override {
- SubchannelData::UnrefSubchannelLocked(reason);
- if (user_data_ != nullptr) {
- GPR_ASSERT(user_data_vtable_ != nullptr);
- user_data_vtable_->destroy(user_data_);
- user_data_ = nullptr;
- }
- }
-
- void* user_data() const { return user_data_; }
+ : SubchannelData(subchannel_list, address, subchannel, combiner) {}
grpc_connectivity_state connectivity_state() const {
return last_connectivity_state_;
@@ -125,8 +106,6 @@ class RoundRobin : public LoadBalancingPolicy {
void ProcessConnectivityChangeLocked(
grpc_connectivity_state connectivity_state, grpc_error* error) override;
- const grpc_lb_user_data_vtable* user_data_vtable_;
- void* user_data_ = nullptr;
grpc_connectivity_state last_connectivity_state_ = GRPC_CHANNEL_IDLE;
};
@@ -137,7 +116,7 @@ class RoundRobin : public LoadBalancingPolicy {
public:
RoundRobinSubchannelList(
RoundRobin* policy, TraceFlag* tracer,
- const grpc_lb_addresses* addresses, grpc_combiner* combiner,
+ const ServerAddressList& addresses, grpc_combiner* combiner,
grpc_client_channel_factory* client_channel_factory,
const grpc_channel_args& args)
: SubchannelList(policy, tracer, addresses, combiner,
@@ -354,9 +333,6 @@ bool RoundRobin::DoPickLocked(PickState* pick) {
subchannel_list_->subchannel(next_ready_index);
GPR_ASSERT(sd->connected_subchannel() != nullptr);
pick->connected_subchannel = sd->connected_subchannel()->Ref();
- if (pick->user_data != nullptr) {
- *pick->user_data = sd->user_data();
- }
if (grpc_lb_round_robin_trace.enabled()) {
gpr_log(GPR_INFO,
"[RR %p] Picked target <-- Subchannel %p (connected %p) (sl %p, "
@@ -667,9 +643,9 @@ void RoundRobin::NotifyOnStateChangeLocked(grpc_connectivity_state* current,
void RoundRobin::UpdateLocked(const grpc_channel_args& args,
grpc_json* lb_config) {
- const grpc_arg* arg = grpc_channel_args_find(&args, GRPC_ARG_LB_ADDRESSES);
AutoChildRefsUpdater guard(this);
- if (GPR_UNLIKELY(arg == nullptr || arg->type != GRPC_ARG_POINTER)) {
+ const ServerAddressList* addresses = FindServerAddressListChannelArg(&args);
+ if (addresses == nullptr) {
gpr_log(GPR_ERROR, "[RR %p] update provided no addresses; ignoring", this);
// If we don't have a current subchannel list, go into TRANSIENT_FAILURE.
// Otherwise, keep using the current subchannel list (ignore this update).
@@ -681,11 +657,9 @@ void RoundRobin::UpdateLocked(const grpc_channel_args& args,
}
return;
}
- grpc_lb_addresses* addresses =
- static_cast<grpc_lb_addresses*>(arg->value.pointer.p);
if (grpc_lb_round_robin_trace.enabled()) {
gpr_log(GPR_INFO, "[RR %p] received update with %" PRIuPTR " addresses",
- this, addresses->num_addresses);
+ this, addresses->size());
}
// Replace latest_pending_subchannel_list_.
if (latest_pending_subchannel_list_ != nullptr) {
@@ -696,7 +670,7 @@ void RoundRobin::UpdateLocked(const grpc_channel_args& args,
}
}
latest_pending_subchannel_list_ = MakeOrphanable<RoundRobinSubchannelList>(
- this, &grpc_lb_round_robin_trace, addresses, combiner(),
+ this, &grpc_lb_round_robin_trace, *addresses, combiner(),
client_channel_factory(), args);
// If we haven't started picking yet or the new list is empty,
// immediately promote the new list to the current list.
diff --git a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h
index f31401502c..6f31a643c1 100644
--- a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h
+++ b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h
@@ -26,6 +26,7 @@
#include <grpc/support/alloc.h>
#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
+#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/ext/filters/client_channel/subchannel.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/debug/trace.h"
@@ -141,8 +142,7 @@ class SubchannelData {
protected:
SubchannelData(
SubchannelList<SubchannelListType, SubchannelDataType>* subchannel_list,
- const grpc_lb_user_data_vtable* user_data_vtable,
- const grpc_lb_address& address, grpc_subchannel* subchannel,
+ const ServerAddress& address, grpc_subchannel* subchannel,
grpc_combiner* combiner);
virtual ~SubchannelData();
@@ -156,9 +156,8 @@ class SubchannelData {
grpc_connectivity_state connectivity_state,
grpc_error* error) GRPC_ABSTRACT;
- // Unrefs the subchannel. May be overridden by subclasses that need
- // to perform extra cleanup when unreffing the subchannel.
- virtual void UnrefSubchannelLocked(const char* reason);
+ // Unrefs the subchannel.
+ void UnrefSubchannelLocked(const char* reason);
private:
// Updates connected_subchannel_ based on pending_connectivity_state_unsafe_.
@@ -232,7 +231,7 @@ class SubchannelList : public InternallyRefCounted<SubchannelListType> {
protected:
SubchannelList(LoadBalancingPolicy* policy, TraceFlag* tracer,
- const grpc_lb_addresses* addresses, grpc_combiner* combiner,
+ const ServerAddressList& addresses, grpc_combiner* combiner,
grpc_client_channel_factory* client_channel_factory,
const grpc_channel_args& args);
@@ -277,8 +276,7 @@ class SubchannelList : public InternallyRefCounted<SubchannelListType> {
template <typename SubchannelListType, typename SubchannelDataType>
SubchannelData<SubchannelListType, SubchannelDataType>::SubchannelData(
SubchannelList<SubchannelListType, SubchannelDataType>* subchannel_list,
- const grpc_lb_user_data_vtable* user_data_vtable,
- const grpc_lb_address& address, grpc_subchannel* subchannel,
+ const ServerAddress& address, grpc_subchannel* subchannel,
grpc_combiner* combiner)
: subchannel_list_(subchannel_list),
subchannel_(subchannel),
@@ -488,7 +486,7 @@ void SubchannelData<SubchannelListType, SubchannelDataType>::ShutdownLocked() {
template <typename SubchannelListType, typename SubchannelDataType>
SubchannelList<SubchannelListType, SubchannelDataType>::SubchannelList(
LoadBalancingPolicy* policy, TraceFlag* tracer,
- const grpc_lb_addresses* addresses, grpc_combiner* combiner,
+ const ServerAddressList& addresses, grpc_combiner* combiner,
grpc_client_channel_factory* client_channel_factory,
const grpc_channel_args& args)
: InternallyRefCounted<SubchannelListType>(tracer),
@@ -498,9 +496,9 @@ SubchannelList<SubchannelListType, SubchannelDataType>::SubchannelList(
if (tracer_->enabled()) {
gpr_log(GPR_INFO,
"[%s %p] Creating subchannel list %p for %" PRIuPTR " subchannels",
- tracer_->name(), policy, this, addresses->num_addresses);
+ tracer_->name(), policy, this, addresses.size());
}
- subchannels_.reserve(addresses->num_addresses);
+ subchannels_.reserve(addresses.size());
// We need to remove the LB addresses in order to be able to compare the
// subchannel keys of subchannels from a different batch of addresses.
// We also remove the inhibit-health-checking arg, since we are
@@ -508,19 +506,27 @@ SubchannelList<SubchannelListType, SubchannelDataType>::SubchannelList(
inhibit_health_checking_ = grpc_channel_arg_get_bool(
grpc_channel_args_find(&args, GRPC_ARG_INHIBIT_HEALTH_CHECKING), false);
static const char* keys_to_remove[] = {GRPC_ARG_SUBCHANNEL_ADDRESS,
- GRPC_ARG_LB_ADDRESSES,
+ GRPC_ARG_SERVER_ADDRESS_LIST,
GRPC_ARG_INHIBIT_HEALTH_CHECKING};
// Create a subchannel for each address.
grpc_subchannel_args sc_args;
- for (size_t i = 0; i < addresses->num_addresses; i++) {
- // If there were any balancer, we would have chosen grpclb policy instead.
- GPR_ASSERT(!addresses->addresses[i].is_balancer);
+ for (size_t i = 0; i < addresses.size(); i++) {
+ // If there were any balancer addresses, we would have chosen grpclb
+ // policy, which does not use a SubchannelList.
+ GPR_ASSERT(!addresses[i].IsBalancer());
memset(&sc_args, 0, sizeof(grpc_subchannel_args));
- grpc_arg addr_arg =
- grpc_create_subchannel_address_arg(&addresses->addresses[i].address);
+ InlinedVector<grpc_arg, 4> args_to_add;
+ args_to_add.emplace_back(
+ grpc_create_subchannel_address_arg(&addresses[i].address()));
+ if (addresses[i].args() != nullptr) {
+ for (size_t j = 0; j < addresses[i].args()->num_args; ++j) {
+ args_to_add.emplace_back(addresses[i].args()->args[j]);
+ }
+ }
grpc_channel_args* new_args = grpc_channel_args_copy_and_add_and_remove(
- &args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), &addr_arg, 1);
- gpr_free(addr_arg.value.string);
+ &args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove),
+ args_to_add.data(), args_to_add.size());
+ gpr_free(args_to_add[0].value.string);
sc_args.args = new_args;
grpc_subchannel* subchannel = grpc_client_channel_factory_create_subchannel(
client_channel_factory, &sc_args);
@@ -528,8 +534,7 @@ SubchannelList<SubchannelListType, SubchannelDataType>::SubchannelList(
if (subchannel == nullptr) {
// Subchannel could not be created.
if (tracer_->enabled()) {
- char* address_uri =
- grpc_sockaddr_to_uri(&addresses->addresses[i].address);
+ char* address_uri = grpc_sockaddr_to_uri(&addresses[i].address());
gpr_log(GPR_INFO,
"[%s %p] could not create subchannel for address uri %s, "
"ignoring",
@@ -539,8 +544,7 @@ SubchannelList<SubchannelListType, SubchannelDataType>::SubchannelList(
continue;
}
if (tracer_->enabled()) {
- char* address_uri =
- grpc_sockaddr_to_uri(&addresses->addresses[i].address);
+ char* address_uri = grpc_sockaddr_to_uri(&addresses[i].address());
gpr_log(GPR_INFO,
"[%s %p] subchannel list %p index %" PRIuPTR
": Created subchannel %p for address uri %s",
@@ -548,8 +552,7 @@ SubchannelList<SubchannelListType, SubchannelDataType>::SubchannelList(
address_uri);
gpr_free(address_uri);
}
- subchannels_.emplace_back(this, addresses->user_data_vtable,
- addresses->addresses[i], subchannel, combiner);
+ subchannels_.emplace_back(this, addresses[i], subchannel, combiner);
}
}
diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc
index faedc0a919..3c25de2386 100644
--- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc
+++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc
@@ -79,6 +79,7 @@
#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
#include "src/core/ext/filters/client_channel/parse_address.h"
#include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h"
+#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/ext/filters/client_channel/subchannel_index.h"
#include "src/core/lib/backoff/backoff.h"
#include "src/core/lib/channel/channel_args.h"
@@ -116,7 +117,7 @@ namespace {
class XdsLb : public LoadBalancingPolicy {
public:
- XdsLb(const grpc_lb_addresses* addresses, const Args& args);
+ explicit XdsLb(const Args& args);
void UpdateLocked(const grpc_channel_args& args,
grpc_json* lb_config) override;
@@ -156,9 +157,6 @@ class XdsLb : public LoadBalancingPolicy {
// Our on_complete closure and the original one.
grpc_closure on_complete;
grpc_closure* original_on_complete;
- // The LB token associated with the pick. This is set via user_data in
- // the pick.
- grpc_mdelem lb_token;
// Stats for client-side load reporting.
RefCountedPtr<XdsLbClientStats> client_stats;
// Next pending pick.
@@ -256,7 +254,7 @@ class XdsLb : public LoadBalancingPolicy {
grpc_error* error);
// Pending pick methods.
- static void PendingPickSetMetadataAndContext(PendingPick* pp);
+ static void PendingPickCleanup(PendingPick* pp);
PendingPick* PendingPickCreate(PickState* pick);
void AddPendingPick(PendingPick* pp);
static void OnPendingPickComplete(void* arg, grpc_error* error);
@@ -319,7 +317,7 @@ class XdsLb : public LoadBalancingPolicy {
// 0 means not using fallback.
int lb_fallback_timeout_ms_ = 0;
// The backend addresses from the resolver.
- grpc_lb_addresses* fallback_backend_addresses_ = nullptr;
+ UniquePtr<ServerAddressList> fallback_backend_addresses_;
// Fallback timer.
bool fallback_timer_callback_pending_ = false;
grpc_timer lb_fallback_timer_;
@@ -339,47 +337,15 @@ class XdsLb : public LoadBalancingPolicy {
// serverlist parsing code
//
-// vtable for LB tokens in grpc_lb_addresses
-void* lb_token_copy(void* token) {
- return token == nullptr
- ? nullptr
- : (void*)GRPC_MDELEM_REF(grpc_mdelem{(uintptr_t)token}).payload;
-}
-void lb_token_destroy(void* token) {
- if (token != nullptr) {
- GRPC_MDELEM_UNREF(grpc_mdelem{(uintptr_t)token});
- }
-}
-int lb_token_cmp(void* token1, void* token2) {
- if (token1 > token2) return 1;
- if (token1 < token2) return -1;
- return 0;
-}
-const grpc_lb_user_data_vtable lb_token_vtable = {
- lb_token_copy, lb_token_destroy, lb_token_cmp};
-
// Returns the backend addresses extracted from the given addresses.
-grpc_lb_addresses* ExtractBackendAddresses(const grpc_lb_addresses* addresses) {
- // First pass: count the number of backend addresses.
- size_t num_backends = 0;
- for (size_t i = 0; i < addresses->num_addresses; ++i) {
- if (!addresses->addresses[i].is_balancer) {
- ++num_backends;
+UniquePtr<ServerAddressList> ExtractBackendAddresses(
+ const ServerAddressList& addresses) {
+ auto backend_addresses = MakeUnique<ServerAddressList>();
+ for (size_t i = 0; i < addresses.size(); ++i) {
+ if (!addresses[i].IsBalancer()) {
+ backend_addresses->emplace_back(addresses[i]);
}
}
- // Second pass: actually populate the addresses and (empty) LB tokens.
- grpc_lb_addresses* backend_addresses =
- grpc_lb_addresses_create(num_backends, &lb_token_vtable);
- size_t num_copied = 0;
- for (size_t i = 0; i < addresses->num_addresses; ++i) {
- if (addresses->addresses[i].is_balancer) continue;
- const grpc_resolved_address* addr = &addresses->addresses[i].address;
- grpc_lb_addresses_set_address(backend_addresses, num_copied, &addr->addr,
- addr->len, false /* is_balancer */,
- nullptr /* balancer_name */,
- (void*)GRPC_MDELEM_LB_TOKEN_EMPTY.payload);
- ++num_copied;
- }
return backend_addresses;
}
@@ -429,56 +395,17 @@ void ParseServer(const xds_grpclb_server* server, grpc_resolved_address* addr) {
}
// Returns addresses extracted from \a serverlist.
-grpc_lb_addresses* ProcessServerlist(const xds_grpclb_serverlist* serverlist) {
- size_t num_valid = 0;
- /* first pass: count how many are valid in order to allocate the necessary
- * memory in a single block */
+UniquePtr<ServerAddressList> ProcessServerlist(
+ const xds_grpclb_serverlist* serverlist) {
+ auto addresses = MakeUnique<ServerAddressList>();
for (size_t i = 0; i < serverlist->num_servers; ++i) {
- if (IsServerValid(serverlist->servers[i], i, true)) ++num_valid;
- }
- grpc_lb_addresses* lb_addresses =
- grpc_lb_addresses_create(num_valid, &lb_token_vtable);
- /* second pass: actually populate the addresses and LB tokens (aka user data
- * to the outside world) to be read by the child policy during its creation.
- * Given that the validity tests are very cheap, they are performed again
- * instead of marking the valid ones during the first pass, as this would
- * incurr in an allocation due to the arbitrary number of server */
- size_t addr_idx = 0;
- for (size_t sl_idx = 0; sl_idx < serverlist->num_servers; ++sl_idx) {
- const xds_grpclb_server* server = serverlist->servers[sl_idx];
- if (!IsServerValid(serverlist->servers[sl_idx], sl_idx, false)) continue;
- GPR_ASSERT(addr_idx < num_valid);
- /* address processing */
+ const xds_grpclb_server* server = serverlist->servers[i];
+ if (!IsServerValid(serverlist->servers[i], i, false)) continue;
grpc_resolved_address addr;
ParseServer(server, &addr);
- /* lb token processing */
- void* user_data;
- if (server->has_load_balance_token) {
- const size_t lb_token_max_length =
- GPR_ARRAY_SIZE(server->load_balance_token);
- const size_t lb_token_length =
- strnlen(server->load_balance_token, lb_token_max_length);
- grpc_slice lb_token_mdstr = grpc_slice_from_copied_buffer(
- server->load_balance_token, lb_token_length);
- user_data =
- (void*)grpc_mdelem_from_slices(GRPC_MDSTR_LB_TOKEN, lb_token_mdstr)
- .payload;
- } else {
- char* uri = grpc_sockaddr_to_uri(&addr);
- gpr_log(GPR_INFO,
- "Missing LB token for backend address '%s'. The empty token will "
- "be used instead",
- uri);
- gpr_free(uri);
- user_data = (void*)GRPC_MDELEM_LB_TOKEN_EMPTY.payload;
- }
- grpc_lb_addresses_set_address(lb_addresses, addr_idx, &addr.addr, addr.len,
- false /* is_balancer */,
- nullptr /* balancer_name */, user_data);
- ++addr_idx;
+ addresses->emplace_back(addr, nullptr);
}
- GPR_ASSERT(addr_idx == num_valid);
- return lb_addresses;
+ return addresses;
}
//
@@ -789,8 +716,7 @@ void XdsLb::BalancerCallState::OnBalancerMessageReceivedLocked(
xds_grpclb_destroy_serverlist(xdslb_policy->serverlist_);
} else {
/* or dispose of the fallback */
- grpc_lb_addresses_destroy(xdslb_policy->fallback_backend_addresses_);
- xdslb_policy->fallback_backend_addresses_ = nullptr;
+ xdslb_policy->fallback_backend_addresses_.reset();
if (xdslb_policy->fallback_timer_callback_pending_) {
grpc_timer_cancel(&xdslb_policy->lb_fallback_timer_);
}
@@ -876,31 +802,15 @@ void XdsLb::BalancerCallState::OnBalancerStatusReceivedLocked(
// helper code for creating balancer channel
//
-grpc_lb_addresses* ExtractBalancerAddresses(
- const grpc_lb_addresses* addresses) {
- size_t num_grpclb_addrs = 0;
- for (size_t i = 0; i < addresses->num_addresses; ++i) {
- if (addresses->addresses[i].is_balancer) ++num_grpclb_addrs;
- }
- // There must be at least one balancer address, or else the
- // client_channel would not have chosen this LB policy.
- GPR_ASSERT(num_grpclb_addrs > 0);
- grpc_lb_addresses* lb_addresses =
- grpc_lb_addresses_create(num_grpclb_addrs, nullptr);
- size_t lb_addresses_idx = 0;
- for (size_t i = 0; i < addresses->num_addresses; ++i) {
- if (!addresses->addresses[i].is_balancer) continue;
- if (GPR_UNLIKELY(addresses->addresses[i].user_data != nullptr)) {
- gpr_log(GPR_ERROR,
- "This LB policy doesn't support user data. It will be ignored");
+UniquePtr<ServerAddressList> ExtractBalancerAddresses(
+ const ServerAddressList& addresses) {
+ auto balancer_addresses = MakeUnique<ServerAddressList>();
+ for (size_t i = 0; i < addresses.size(); ++i) {
+ if (addresses[i].IsBalancer()) {
+ balancer_addresses->emplace_back(addresses[i]);
}
- grpc_lb_addresses_set_address(
- lb_addresses, lb_addresses_idx++, addresses->addresses[i].address.addr,
- addresses->addresses[i].address.len, false /* is balancer */,
- addresses->addresses[i].balancer_name, nullptr /* user data */);
}
- GPR_ASSERT(num_grpclb_addrs == lb_addresses_idx);
- return lb_addresses;
+ return balancer_addresses;
}
/* Returns the channel args for the LB channel, used to create a bidirectional
@@ -912,10 +822,11 @@ grpc_lb_addresses* ExtractBalancerAddresses(
* above the grpclb policy.
* - \a args: other args inherited from the xds policy. */
grpc_channel_args* BuildBalancerChannelArgs(
- const grpc_lb_addresses* addresses,
+ const ServerAddressList& addresses,
FakeResolverResponseGenerator* response_generator,
const grpc_channel_args* args) {
- grpc_lb_addresses* lb_addresses = ExtractBalancerAddresses(addresses);
+ UniquePtr<ServerAddressList> balancer_addresses =
+ ExtractBalancerAddresses(addresses);
// Channel args to remove.
static const char* args_to_remove[] = {
// LB policy name, since we want to use the default (pick_first) in
@@ -933,7 +844,7 @@ grpc_channel_args* BuildBalancerChannelArgs(
// is_balancer=true. We need the LB channel to return addresses with
// is_balancer=false so that it does not wind up recursively using the
// xds LB policy, as per the special case logic in client_channel.c.
- GRPC_ARG_LB_ADDRESSES,
+ GRPC_ARG_SERVER_ADDRESS_LIST,
// The fake resolver response generator, because we are replacing it
// with the one from the xds policy, used to propagate updates to
// the LB channel.
@@ -949,10 +860,10 @@ grpc_channel_args* BuildBalancerChannelArgs(
};
// Channel args to add.
const grpc_arg args_to_add[] = {
- // New LB addresses.
+ // New server address list.
// Note that we pass these in both when creating the LB channel
// and via the fake resolver. The latter is what actually gets used.
- grpc_lb_addresses_create_channel_arg(lb_addresses),
+ CreateServerAddressListChannelArg(balancer_addresses.get()),
// The fake resolver response generator, which we use to inject
// address updates into the LB channel.
grpc_core::FakeResolverResponseGenerator::MakeChannelArg(
@@ -970,10 +881,7 @@ grpc_channel_args* BuildBalancerChannelArgs(
args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), args_to_add,
GPR_ARRAY_SIZE(args_to_add));
// Make any necessary modifications for security.
- new_args = grpc_lb_policy_xds_modify_lb_channel_args(new_args);
- // Clean up.
- grpc_lb_addresses_destroy(lb_addresses);
- return new_args;
+ return grpc_lb_policy_xds_modify_lb_channel_args(new_args);
}
//
@@ -981,8 +889,7 @@ grpc_channel_args* BuildBalancerChannelArgs(
//
// TODO(vishalpowar): Use lb_config in args to configure LB policy.
-XdsLb::XdsLb(const grpc_lb_addresses* addresses,
- const LoadBalancingPolicy::Args& args)
+XdsLb::XdsLb(const LoadBalancingPolicy::Args& args)
: LoadBalancingPolicy(args),
response_generator_(MakeRefCounted<FakeResolverResponseGenerator>()),
lb_call_backoff_(
@@ -1038,9 +945,6 @@ XdsLb::~XdsLb() {
if (serverlist_ != nullptr) {
xds_grpclb_destroy_serverlist(serverlist_);
}
- if (fallback_backend_addresses_ != nullptr) {
- grpc_lb_addresses_destroy(fallback_backend_addresses_);
- }
grpc_subchannel_index_unref();
}
@@ -1088,7 +992,6 @@ void XdsLb::HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) {
while ((pp = pending_picks_) != nullptr) {
pending_picks_ = pp->next;
pp->pick->on_complete = pp->original_on_complete;
- pp->pick->user_data = nullptr;
grpc_error* error = GRPC_ERROR_NONE;
if (new_policy->PickLocked(pp->pick, &error)) {
// Synchronous return; schedule closure.
@@ -1241,21 +1144,16 @@ void XdsLb::NotifyOnStateChangeLocked(grpc_connectivity_state* current,
}
void XdsLb::ProcessChannelArgsLocked(const grpc_channel_args& args) {
- const grpc_arg* arg = grpc_channel_args_find(&args, GRPC_ARG_LB_ADDRESSES);
- if (GPR_UNLIKELY(arg == nullptr || arg->type != GRPC_ARG_POINTER)) {
+ const ServerAddressList* addresses = FindServerAddressListChannelArg(&args);
+ if (addresses == nullptr) {
// Ignore this update.
gpr_log(GPR_ERROR,
"[xdslb %p] No valid LB addresses channel arg in update, ignoring.",
this);
return;
}
- const grpc_lb_addresses* addresses =
- static_cast<const grpc_lb_addresses*>(arg->value.pointer.p);
// Update fallback address list.
- if (fallback_backend_addresses_ != nullptr) {
- grpc_lb_addresses_destroy(fallback_backend_addresses_);
- }
- fallback_backend_addresses_ = ExtractBackendAddresses(addresses);
+ fallback_backend_addresses_ = ExtractBackendAddresses(*addresses);
// Make sure that GRPC_ARG_LB_POLICY_NAME is set in channel args,
// since we use this to trigger the client_load_reporting filter.
static const char* args_to_remove[] = {GRPC_ARG_LB_POLICY_NAME};
@@ -1266,7 +1164,7 @@ void XdsLb::ProcessChannelArgsLocked(const grpc_channel_args& args) {
&args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), &new_arg, 1);
// Construct args for balancer channel.
grpc_channel_args* lb_channel_args =
- BuildBalancerChannelArgs(addresses, response_generator_.get(), &args);
+ BuildBalancerChannelArgs(*addresses, response_generator_.get(), &args);
// Create balancer channel if needed.
if (lb_channel_ == nullptr) {
char* uri_str;
@@ -1457,37 +1355,15 @@ void XdsLb::OnBalancerChannelConnectivityChangedLocked(void* arg,
// PendingPick
//
-// Adds lb_token of selected subchannel (address) to the call's initial
-// metadata.
-grpc_error* AddLbTokenToInitialMetadata(
- grpc_mdelem lb_token, grpc_linked_mdelem* lb_token_mdelem_storage,
- grpc_metadata_batch* initial_metadata) {
- GPR_ASSERT(lb_token_mdelem_storage != nullptr);
- GPR_ASSERT(!GRPC_MDISNULL(lb_token));
- return grpc_metadata_batch_add_tail(initial_metadata, lb_token_mdelem_storage,
- lb_token);
-}
-
// Destroy function used when embedding client stats in call context.
void DestroyClientStats(void* arg) {
static_cast<XdsLbClientStats*>(arg)->Unref();
}
-void XdsLb::PendingPickSetMetadataAndContext(PendingPick* pp) {
- /* if connected_subchannel is nullptr, no pick has been made by the
- * child policy (e.g., all addresses failed to connect). There won't be any
- * user_data/token available */
+void XdsLb::PendingPickCleanup(PendingPick* pp) {
+ // If connected_subchannel is nullptr, no pick has been made by the
+ // child policy (e.g., all addresses failed to connect).
if (pp->pick->connected_subchannel != nullptr) {
- if (GPR_LIKELY(!GRPC_MDISNULL(pp->lb_token))) {
- AddLbTokenToInitialMetadata(GRPC_MDELEM_REF(pp->lb_token),
- &pp->pick->lb_token_mdelem_storage,
- pp->pick->initial_metadata);
- } else {
- gpr_log(GPR_ERROR,
- "[xdslb %p] No LB token for connected subchannel pick %p",
- pp->xdslb_policy, pp->pick);
- abort();
- }
// Pass on client stats via context. Passes ownership of the reference.
if (pp->client_stats != nullptr) {
pp->pick->subchannel_call_context[GRPC_GRPCLB_CLIENT_STATS].value =
@@ -1505,7 +1381,7 @@ void XdsLb::PendingPickSetMetadataAndContext(PendingPick* pp) {
* order to unref the child policy instance upon its invocation */
void XdsLb::OnPendingPickComplete(void* arg, grpc_error* error) {
PendingPick* pp = static_cast<PendingPick*>(arg);
- PendingPickSetMetadataAndContext(pp);
+ PendingPickCleanup(pp);
GRPC_CLOSURE_SCHED(pp->original_on_complete, GRPC_ERROR_REF(error));
Delete(pp);
}
@@ -1537,16 +1413,14 @@ void XdsLb::AddPendingPick(PendingPick* pp) {
// completion callback even if the pick is available immediately.
bool XdsLb::PickFromChildPolicyLocked(bool force_async, PendingPick* pp,
grpc_error** error) {
- // Set client_stats and user_data.
+ // Set client_stats.
if (lb_calld_ != nullptr && lb_calld_->client_stats() != nullptr) {
pp->client_stats = lb_calld_->client_stats()->Ref();
}
- GPR_ASSERT(pp->pick->user_data == nullptr);
- pp->pick->user_data = (void**)&pp->lb_token;
// Pick via the child policy.
bool pick_done = child_policy_->PickLocked(pp->pick, error);
if (pick_done) {
- PendingPickSetMetadataAndContext(pp);
+ PendingPickCleanup(pp);
if (force_async) {
GRPC_CLOSURE_SCHED(pp->original_on_complete, *error);
*error = GRPC_ERROR_NONE;
@@ -1608,20 +1482,19 @@ void XdsLb::CreateChildPolicyLocked(const Args& args) {
}
grpc_channel_args* XdsLb::CreateChildPolicyArgsLocked() {
- grpc_lb_addresses* addresses;
bool is_backend_from_grpclb_load_balancer = false;
// This should never be invoked if we do not have serverlist_, as fallback
// mode is disabled for xDS plugin.
GPR_ASSERT(serverlist_ != nullptr);
GPR_ASSERT(serverlist_->num_servers > 0);
- addresses = ProcessServerlist(serverlist_);
- is_backend_from_grpclb_load_balancer = true;
+ UniquePtr<ServerAddressList> addresses = ProcessServerlist(serverlist_);
GPR_ASSERT(addresses != nullptr);
- // Replace the LB addresses in the channel args that we pass down to
+ is_backend_from_grpclb_load_balancer = true;
+ // Replace the server address list in the channel args that we pass down to
// the subchannel.
- static const char* keys_to_remove[] = {GRPC_ARG_LB_ADDRESSES};
+ static const char* keys_to_remove[] = {GRPC_ARG_SERVER_ADDRESS_LIST};
const grpc_arg args_to_add[] = {
- grpc_lb_addresses_create_channel_arg(addresses),
+ CreateServerAddressListChannelArg(addresses.get()),
// A channel arg indicating if the target is a backend inferred from a
// grpclb load balancer.
grpc_channel_arg_integer_create(
@@ -1631,7 +1504,6 @@ grpc_channel_args* XdsLb::CreateChildPolicyArgsLocked() {
grpc_channel_args* args = grpc_channel_args_copy_and_add_and_remove(
args_, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), args_to_add,
GPR_ARRAY_SIZE(args_to_add));
- grpc_lb_addresses_destroy(addresses);
return args;
}
@@ -1765,19 +1637,18 @@ class XdsFactory : public LoadBalancingPolicyFactory {
OrphanablePtr<LoadBalancingPolicy> CreateLoadBalancingPolicy(
const LoadBalancingPolicy::Args& args) const override {
/* Count the number of gRPC-LB addresses. There must be at least one. */
- const grpc_arg* arg =
- grpc_channel_args_find(args.args, GRPC_ARG_LB_ADDRESSES);
- if (arg == nullptr || arg->type != GRPC_ARG_POINTER) {
- return nullptr;
- }
- grpc_lb_addresses* addresses =
- static_cast<grpc_lb_addresses*>(arg->value.pointer.p);
- size_t num_grpclb_addrs = 0;
- for (size_t i = 0; i < addresses->num_addresses; ++i) {
- if (addresses->addresses[i].is_balancer) ++num_grpclb_addrs;
+ const ServerAddressList* addresses =
+ FindServerAddressListChannelArg(args.args);
+ if (addresses == nullptr) return nullptr;
+ bool found_balancer_address = false;
+ for (size_t i = 0; i < addresses->size(); ++i) {
+ if ((*addresses)[i].IsBalancer()) {
+ found_balancer_address = true;
+ break;
+ }
}
- if (num_grpclb_addrs == 0) return nullptr;
- return OrphanablePtr<LoadBalancingPolicy>(New<XdsLb>(addresses, args));
+ if (!found_balancer_address) return nullptr;
+ return OrphanablePtr<LoadBalancingPolicy>(New<XdsLb>(args));
}
const char* name() const override { return "xds_experimental"; }
diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h b/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h
index 32c4acc8a3..f713b7f563 100644
--- a/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h
+++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h
@@ -21,7 +21,7 @@
#include <grpc/support/port_platform.h>
-#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
+#include <grpc/impl/codegen/grpc_types.h>
/// Makes any necessary modifications to \a args for use in the xds
/// balancer channel.
diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc
index 5ab72efce4..9a11f8e39f 100644
--- a/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc
+++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc
@@ -25,6 +25,7 @@
#include <string.h>
#include "src/core/ext/filters/client_channel/client_channel.h"
+#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
@@ -41,22 +42,23 @@ int BalancerNameCmp(const grpc_core::UniquePtr<char>& a,
}
RefCountedPtr<TargetAuthorityTable> CreateTargetAuthorityTable(
- grpc_lb_addresses* addresses) {
+ const ServerAddressList& addresses) {
TargetAuthorityTable::Entry* target_authority_entries =
- static_cast<TargetAuthorityTable::Entry*>(gpr_zalloc(
- sizeof(*target_authority_entries) * addresses->num_addresses));
- for (size_t i = 0; i < addresses->num_addresses; ++i) {
+ static_cast<TargetAuthorityTable::Entry*>(
+ gpr_zalloc(sizeof(*target_authority_entries) * addresses.size()));
+ for (size_t i = 0; i < addresses.size(); ++i) {
char* addr_str;
- GPR_ASSERT(grpc_sockaddr_to_string(
- &addr_str, &addresses->addresses[i].address, true) > 0);
+ GPR_ASSERT(
+ grpc_sockaddr_to_string(&addr_str, &addresses[i].address(), true) > 0);
target_authority_entries[i].key = grpc_slice_from_copied_string(addr_str);
- target_authority_entries[i].value.reset(
- gpr_strdup(addresses->addresses[i].balancer_name));
gpr_free(addr_str);
+ char* balancer_name = grpc_channel_arg_get_string(grpc_channel_args_find(
+ addresses[i].args(), GRPC_ARG_ADDRESS_BALANCER_NAME));
+ target_authority_entries[i].value.reset(gpr_strdup(balancer_name));
}
RefCountedPtr<TargetAuthorityTable> target_authority_table =
- TargetAuthorityTable::Create(addresses->num_addresses,
- target_authority_entries, BalancerNameCmp);
+ TargetAuthorityTable::Create(addresses.size(), target_authority_entries,
+ BalancerNameCmp);
gpr_free(target_authority_entries);
return target_authority_table;
}
@@ -71,13 +73,12 @@ grpc_channel_args* grpc_lb_policy_xds_modify_lb_channel_args(
grpc_arg args_to_add[2];
size_t num_args_to_add = 0;
// Add arg for targets info table.
- const grpc_arg* arg = grpc_channel_args_find(args, GRPC_ARG_LB_ADDRESSES);
- GPR_ASSERT(arg != nullptr);
- GPR_ASSERT(arg->type == GRPC_ARG_POINTER);
- grpc_lb_addresses* addresses =
- static_cast<grpc_lb_addresses*>(arg->value.pointer.p);
+ grpc_core::ServerAddressList* addresses =
+ grpc_core::FindServerAddressListChannelArg(args);
+ GPR_ASSERT(addresses != nullptr);
grpc_core::RefCountedPtr<grpc_core::TargetAuthorityTable>
- target_authority_table = grpc_core::CreateTargetAuthorityTable(addresses);
+ target_authority_table =
+ grpc_core::CreateTargetAuthorityTable(*addresses);
args_to_add[num_args_to_add++] =
grpc_core::CreateTargetAuthorityTableChannelArg(
target_authority_table.get());
diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h b/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h
index 9d08defa7e..6704995641 100644
--- a/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h
+++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h
@@ -25,7 +25,7 @@
#include "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h"
#include "src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h"
-#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
#define XDS_SERVICE_NAME_MAX_LENGTH 128
diff --git a/src/core/ext/filters/client_channel/lb_policy_factory.cc b/src/core/ext/filters/client_channel/lb_policy_factory.cc
deleted file mode 100644
index 5c6363d295..0000000000
--- a/src/core/ext/filters/client_channel/lb_policy_factory.cc
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- *
- * 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.
- *
- */
-
-#include <grpc/support/port_platform.h>
-
-#include <string.h>
-
-#include <grpc/support/alloc.h>
-#include <grpc/support/string_util.h>
-
-#include "src/core/lib/channel/channel_args.h"
-
-#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
-#include "src/core/ext/filters/client_channel/parse_address.h"
-
-grpc_lb_addresses* grpc_lb_addresses_create(
- size_t num_addresses, const grpc_lb_user_data_vtable* user_data_vtable) {
- grpc_lb_addresses* addresses =
- static_cast<grpc_lb_addresses*>(gpr_zalloc(sizeof(grpc_lb_addresses)));
- addresses->num_addresses = num_addresses;
- addresses->user_data_vtable = user_data_vtable;
- const size_t addresses_size = sizeof(grpc_lb_address) * num_addresses;
- addresses->addresses =
- static_cast<grpc_lb_address*>(gpr_zalloc(addresses_size));
- return addresses;
-}
-
-grpc_lb_addresses* grpc_lb_addresses_copy(const grpc_lb_addresses* addresses) {
- grpc_lb_addresses* new_addresses = grpc_lb_addresses_create(
- addresses->num_addresses, addresses->user_data_vtable);
- memcpy(new_addresses->addresses, addresses->addresses,
- sizeof(grpc_lb_address) * addresses->num_addresses);
- for (size_t i = 0; i < addresses->num_addresses; ++i) {
- if (new_addresses->addresses[i].balancer_name != nullptr) {
- new_addresses->addresses[i].balancer_name =
- gpr_strdup(new_addresses->addresses[i].balancer_name);
- }
- if (new_addresses->addresses[i].user_data != nullptr) {
- new_addresses->addresses[i].user_data = addresses->user_data_vtable->copy(
- new_addresses->addresses[i].user_data);
- }
- }
- return new_addresses;
-}
-
-void grpc_lb_addresses_set_address(grpc_lb_addresses* addresses, size_t index,
- const void* address, size_t address_len,
- bool is_balancer, const char* balancer_name,
- void* user_data) {
- GPR_ASSERT(index < addresses->num_addresses);
- if (user_data != nullptr) GPR_ASSERT(addresses->user_data_vtable != nullptr);
- grpc_lb_address* target = &addresses->addresses[index];
- memcpy(target->address.addr, address, address_len);
- target->address.len = static_cast<socklen_t>(address_len);
- target->is_balancer = is_balancer;
- target->balancer_name = gpr_strdup(balancer_name);
- target->user_data = user_data;
-}
-
-bool grpc_lb_addresses_set_address_from_uri(grpc_lb_addresses* addresses,
- size_t index, const grpc_uri* uri,
- bool is_balancer,
- const char* balancer_name,
- void* user_data) {
- grpc_resolved_address address;
- if (!grpc_parse_uri(uri, &address)) return false;
- grpc_lb_addresses_set_address(addresses, index, address.addr, address.len,
- is_balancer, balancer_name, user_data);
- return true;
-}
-
-int grpc_lb_addresses_cmp(const grpc_lb_addresses* addresses1,
- const grpc_lb_addresses* addresses2) {
- if (addresses1->num_addresses > addresses2->num_addresses) return 1;
- if (addresses1->num_addresses < addresses2->num_addresses) return -1;
- if (addresses1->user_data_vtable > addresses2->user_data_vtable) return 1;
- if (addresses1->user_data_vtable < addresses2->user_data_vtable) return -1;
- for (size_t i = 0; i < addresses1->num_addresses; ++i) {
- const grpc_lb_address* target1 = &addresses1->addresses[i];
- const grpc_lb_address* target2 = &addresses2->addresses[i];
- if (target1->address.len > target2->address.len) return 1;
- if (target1->address.len < target2->address.len) return -1;
- int retval = memcmp(target1->address.addr, target2->address.addr,
- target1->address.len);
- if (retval != 0) return retval;
- if (target1->is_balancer > target2->is_balancer) return 1;
- if (target1->is_balancer < target2->is_balancer) return -1;
- const char* balancer_name1 =
- target1->balancer_name != nullptr ? target1->balancer_name : "";
- const char* balancer_name2 =
- target2->balancer_name != nullptr ? target2->balancer_name : "";
- retval = strcmp(balancer_name1, balancer_name2);
- if (retval != 0) return retval;
- if (addresses1->user_data_vtable != nullptr) {
- retval = addresses1->user_data_vtable->cmp(target1->user_data,
- target2->user_data);
- if (retval != 0) return retval;
- }
- }
- return 0;
-}
-
-void grpc_lb_addresses_destroy(grpc_lb_addresses* addresses) {
- for (size_t i = 0; i < addresses->num_addresses; ++i) {
- gpr_free(addresses->addresses[i].balancer_name);
- if (addresses->addresses[i].user_data != nullptr) {
- addresses->user_data_vtable->destroy(addresses->addresses[i].user_data);
- }
- }
- gpr_free(addresses->addresses);
- gpr_free(addresses);
-}
-
-static void* lb_addresses_copy(void* addresses) {
- return grpc_lb_addresses_copy(static_cast<grpc_lb_addresses*>(addresses));
-}
-static void lb_addresses_destroy(void* addresses) {
- grpc_lb_addresses_destroy(static_cast<grpc_lb_addresses*>(addresses));
-}
-static int lb_addresses_cmp(void* addresses1, void* addresses2) {
- return grpc_lb_addresses_cmp(static_cast<grpc_lb_addresses*>(addresses1),
- static_cast<grpc_lb_addresses*>(addresses2));
-}
-static const grpc_arg_pointer_vtable lb_addresses_arg_vtable = {
- lb_addresses_copy, lb_addresses_destroy, lb_addresses_cmp};
-
-grpc_arg grpc_lb_addresses_create_channel_arg(
- const grpc_lb_addresses* addresses) {
- return grpc_channel_arg_pointer_create(
- (char*)GRPC_ARG_LB_ADDRESSES, (void*)addresses, &lb_addresses_arg_vtable);
-}
-
-grpc_lb_addresses* grpc_lb_addresses_find_channel_arg(
- const grpc_channel_args* channel_args) {
- const grpc_arg* lb_addresses_arg =
- grpc_channel_args_find(channel_args, GRPC_ARG_LB_ADDRESSES);
- if (lb_addresses_arg == nullptr || lb_addresses_arg->type != GRPC_ARG_POINTER)
- return nullptr;
- return static_cast<grpc_lb_addresses*>(lb_addresses_arg->value.pointer.p);
-}
-
-bool grpc_lb_addresses_contains_balancer_address(
- const grpc_lb_addresses& addresses) {
- for (size_t i = 0; i < addresses.num_addresses; ++i) {
- if (addresses.addresses[i].is_balancer) return true;
- }
- return false;
-}
diff --git a/src/core/ext/filters/client_channel/lb_policy_factory.h b/src/core/ext/filters/client_channel/lb_policy_factory.h
index a59deadb26..a165ebafab 100644
--- a/src/core/ext/filters/client_channel/lb_policy_factory.h
+++ b/src/core/ext/filters/client_channel/lb_policy_factory.h
@@ -21,91 +21,9 @@
#include <grpc/support/port_platform.h>
-#include "src/core/lib/iomgr/resolve_address.h"
-
-#include "src/core/ext/filters/client_channel/client_channel_factory.h"
#include "src/core/ext/filters/client_channel/lb_policy.h"
-#include "src/core/lib/uri/uri_parser.h"
-
-//
-// representation of an LB address
-//
-
-// Channel arg key for grpc_lb_addresses.
-#define GRPC_ARG_LB_ADDRESSES "grpc.lb_addresses"
-
-/** A resolved address alongside any LB related information associated with it.
- * \a user_data, if not NULL, contains opaque data meant to be consumed by the
- * gRPC LB policy. Note that no all LB policies support \a user_data as input.
- * Those who don't will simply ignore it and will correspondingly return NULL in
- * their namesake pick() output argument. */
-// TODO(roth): Once we figure out a better way of handling user_data in
-// LB policies, convert these structs to C++ classes.
-typedef struct grpc_lb_address {
- grpc_resolved_address address;
- bool is_balancer;
- char* balancer_name; /* For secure naming. */
- void* user_data;
-} grpc_lb_address;
-
-typedef struct grpc_lb_user_data_vtable {
- void* (*copy)(void*);
- void (*destroy)(void*);
- int (*cmp)(void*, void*);
-} grpc_lb_user_data_vtable;
-
-typedef struct grpc_lb_addresses {
- size_t num_addresses;
- grpc_lb_address* addresses;
- const grpc_lb_user_data_vtable* user_data_vtable;
-} grpc_lb_addresses;
-
-/** Returns a grpc_addresses struct with enough space for
- \a num_addresses addresses. The \a user_data_vtable argument may be
- NULL if no user data will be added. */
-grpc_lb_addresses* grpc_lb_addresses_create(
- size_t num_addresses, const grpc_lb_user_data_vtable* user_data_vtable);
-
-/** Creates a copy of \a addresses. */
-grpc_lb_addresses* grpc_lb_addresses_copy(const grpc_lb_addresses* addresses);
-
-/** Sets the value of the address at index \a index of \a addresses.
- * \a address is a socket address of length \a address_len. */
-void grpc_lb_addresses_set_address(grpc_lb_addresses* addresses, size_t index,
- const void* address, size_t address_len,
- bool is_balancer, const char* balancer_name,
- void* user_data);
-
-/** Sets the value of the address at index \a index of \a addresses from \a uri.
- * Returns true upon success, false otherwise. */
-bool grpc_lb_addresses_set_address_from_uri(grpc_lb_addresses* addresses,
- size_t index, const grpc_uri* uri,
- bool is_balancer,
- const char* balancer_name,
- void* user_data);
-
-/** Compares \a addresses1 and \a addresses2. */
-int grpc_lb_addresses_cmp(const grpc_lb_addresses* addresses1,
- const grpc_lb_addresses* addresses2);
-
-/** Destroys \a addresses. */
-void grpc_lb_addresses_destroy(grpc_lb_addresses* addresses);
-
-/** Returns a channel arg containing \a addresses. */
-grpc_arg grpc_lb_addresses_create_channel_arg(
- const grpc_lb_addresses* addresses);
-
-/** Returns the \a grpc_lb_addresses instance in \a channel_args or NULL */
-grpc_lb_addresses* grpc_lb_addresses_find_channel_arg(
- const grpc_channel_args* channel_args);
-
-// Returns true if addresses contains at least one balancer address.
-bool grpc_lb_addresses_contains_balancer_address(
- const grpc_lb_addresses& addresses);
-
-//
-// LB policy factory
-//
+#include "src/core/lib/gprpp/abstract.h"
+#include "src/core/lib/gprpp/orphanable.h"
namespace grpc_core {
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
index 4ebc2c8161..c8425ae336 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
@@ -33,6 +33,7 @@
#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
#include "src/core/ext/filters/client_channel/resolver_registry.h"
+#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/lib/backoff/backoff.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/env.h"
@@ -117,7 +118,7 @@ class AresDnsResolver : public Resolver {
/// retry backoff state
BackOff backoff_;
/// currently resolving addresses
- grpc_lb_addresses* lb_addresses_ = nullptr;
+ UniquePtr<ServerAddressList> addresses_;
/// currently resolving service config
char* service_config_json_ = nullptr;
// has shutdown been initiated
@@ -314,13 +315,13 @@ void AresDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) {
r->resolving_ = false;
gpr_free(r->pending_request_);
r->pending_request_ = nullptr;
- if (r->lb_addresses_ != nullptr) {
+ if (r->addresses_ != nullptr) {
static const char* args_to_remove[1];
size_t num_args_to_remove = 0;
grpc_arg args_to_add[2];
size_t num_args_to_add = 0;
args_to_add[num_args_to_add++] =
- grpc_lb_addresses_create_channel_arg(r->lb_addresses_);
+ CreateServerAddressListChannelArg(r->addresses_.get());
char* service_config_string = nullptr;
if (r->service_config_json_ != nullptr) {
service_config_string = ChooseServiceConfig(r->service_config_json_);
@@ -337,7 +338,7 @@ void AresDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) {
r->channel_args_, args_to_remove, num_args_to_remove, args_to_add,
num_args_to_add);
gpr_free(service_config_string);
- grpc_lb_addresses_destroy(r->lb_addresses_);
+ r->addresses_.reset();
// Reset backoff state so that we start from the beginning when the
// next request gets triggered.
r->backoff_.Reset();
@@ -412,11 +413,10 @@ void AresDnsResolver::StartResolvingLocked() {
self.release();
GPR_ASSERT(!resolving_);
resolving_ = true;
- lb_addresses_ = nullptr;
service_config_json_ = nullptr;
pending_request_ = grpc_dns_lookup_ares_locked(
dns_server_, name_to_resolve_, kDefaultPort, interested_parties_,
- &on_resolved_, &lb_addresses_, true /* check_grpclb */,
+ &on_resolved_, &addresses_, true /* check_grpclb */,
request_service_config_ ? &service_config_json_ : nullptr,
query_timeout_ms_, combiner());
last_resolution_timestamp_ = grpc_core::ExecCtx::Get()->Now();
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc
index f42b1e309d..8abc34c6ed 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc
@@ -31,6 +31,7 @@
#include <grpc/support/time.h>
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/iomgr/combiner.h"
#include "src/core/lib/iomgr/iomgr_internal.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
#include "src/core/lib/iomgr/timer.h"
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc
index 55715869b6..1b1c2303da 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc
@@ -37,12 +37,16 @@
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/iomgr/combiner.h"
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/iomgr/executor.h"
#include "src/core/lib/iomgr/iomgr_internal.h"
#include "src/core/lib/iomgr/nameser.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
+using grpc_core::ServerAddress;
+using grpc_core::ServerAddressList;
+
static gpr_once g_basic_init = GPR_ONCE_INIT;
static gpr_mu g_init_mu;
@@ -58,7 +62,7 @@ struct grpc_ares_request {
/** closure to call when the request completes */
grpc_closure* on_done;
/** the pointer to receive the resolved addresses */
- grpc_lb_addresses** lb_addrs_out;
+ grpc_core::UniquePtr<grpc_core::ServerAddressList>* addresses_out;
/** the pointer to receive the service config in JSON */
char** service_config_json_out;
/** the evernt driver used by this request */
@@ -87,12 +91,11 @@ typedef struct grpc_ares_hostbyname_request {
static void do_basic_init(void) { gpr_mu_init(&g_init_mu); }
-static void log_address_sorting_list(grpc_lb_addresses* lb_addrs,
+static void log_address_sorting_list(const ServerAddressList& addresses,
const char* input_output_str) {
- for (size_t i = 0; i < lb_addrs->num_addresses; i++) {
+ for (size_t i = 0; i < addresses.size(); i++) {
char* addr_str;
- if (grpc_sockaddr_to_string(&addr_str, &lb_addrs->addresses[i].address,
- true)) {
+ if (grpc_sockaddr_to_string(&addr_str, &addresses[i].address(), true)) {
gpr_log(GPR_DEBUG, "c-ares address sorting: %s[%" PRIuPTR "]=%s",
input_output_str, i, addr_str);
gpr_free(addr_str);
@@ -104,29 +107,28 @@ static void log_address_sorting_list(grpc_lb_addresses* lb_addrs,
}
}
-void grpc_cares_wrapper_address_sorting_sort(grpc_lb_addresses* lb_addrs) {
+void grpc_cares_wrapper_address_sorting_sort(ServerAddressList* addresses) {
if (grpc_trace_cares_address_sorting.enabled()) {
- log_address_sorting_list(lb_addrs, "input");
+ log_address_sorting_list(*addresses, "input");
}
address_sorting_sortable* sortables = (address_sorting_sortable*)gpr_zalloc(
- sizeof(address_sorting_sortable) * lb_addrs->num_addresses);
- for (size_t i = 0; i < lb_addrs->num_addresses; i++) {
- sortables[i].user_data = &lb_addrs->addresses[i];
- memcpy(&sortables[i].dest_addr.addr, &lb_addrs->addresses[i].address.addr,
- lb_addrs->addresses[i].address.len);
- sortables[i].dest_addr.len = lb_addrs->addresses[i].address.len;
+ sizeof(address_sorting_sortable) * addresses->size());
+ for (size_t i = 0; i < addresses->size(); ++i) {
+ sortables[i].user_data = &(*addresses)[i];
+ memcpy(&sortables[i].dest_addr.addr, &(*addresses)[i].address().addr,
+ (*addresses)[i].address().len);
+ sortables[i].dest_addr.len = (*addresses)[i].address().len;
}
- address_sorting_rfc_6724_sort(sortables, lb_addrs->num_addresses);
- grpc_lb_address* sorted_lb_addrs = (grpc_lb_address*)gpr_zalloc(
- sizeof(grpc_lb_address) * lb_addrs->num_addresses);
- for (size_t i = 0; i < lb_addrs->num_addresses; i++) {
- sorted_lb_addrs[i] = *(grpc_lb_address*)sortables[i].user_data;
+ address_sorting_rfc_6724_sort(sortables, addresses->size());
+ ServerAddressList sorted;
+ sorted.reserve(addresses->size());
+ for (size_t i = 0; i < addresses->size(); ++i) {
+ sorted.emplace_back(*static_cast<ServerAddress*>(sortables[i].user_data));
}
gpr_free(sortables);
- gpr_free(lb_addrs->addresses);
- lb_addrs->addresses = sorted_lb_addrs;
+ *addresses = std::move(sorted);
if (grpc_trace_cares_address_sorting.enabled()) {
- log_address_sorting_list(lb_addrs, "output");
+ log_address_sorting_list(*addresses, "output");
}
}
@@ -145,9 +147,9 @@ void grpc_ares_complete_request_locked(grpc_ares_request* r) {
/* Invoke on_done callback and destroy the
request */
r->ev_driver = nullptr;
- grpc_lb_addresses* lb_addrs = *(r->lb_addrs_out);
- if (lb_addrs != nullptr) {
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ ServerAddressList* addresses = r->addresses_out->get();
+ if (addresses != nullptr) {
+ grpc_cares_wrapper_address_sorting_sort(addresses);
}
GRPC_CLOSURE_SCHED(r->on_done, r->error);
}
@@ -181,33 +183,30 @@ static void on_hostbyname_done_locked(void* arg, int status, int timeouts,
GRPC_ERROR_UNREF(r->error);
r->error = GRPC_ERROR_NONE;
r->success = true;
- grpc_lb_addresses** lb_addresses = r->lb_addrs_out;
- if (*lb_addresses == nullptr) {
- *lb_addresses = grpc_lb_addresses_create(0, nullptr);
- }
- size_t prev_naddr = (*lb_addresses)->num_addresses;
- size_t i;
- for (i = 0; hostent->h_addr_list[i] != nullptr; i++) {
+ if (*r->addresses_out == nullptr) {
+ *r->addresses_out = grpc_core::MakeUnique<ServerAddressList>();
}
- (*lb_addresses)->num_addresses += i;
- (*lb_addresses)->addresses = static_cast<grpc_lb_address*>(
- gpr_realloc((*lb_addresses)->addresses,
- sizeof(grpc_lb_address) * (*lb_addresses)->num_addresses));
- for (i = prev_naddr; i < (*lb_addresses)->num_addresses; i++) {
+ ServerAddressList& addresses = **r->addresses_out;
+ for (size_t i = 0; hostent->h_addr_list[i] != nullptr; ++i) {
+ grpc_core::InlinedVector<grpc_arg, 2> args_to_add;
+ if (hr->is_balancer) {
+ args_to_add.emplace_back(grpc_channel_arg_integer_create(
+ const_cast<char*>(GRPC_ARG_ADDRESS_IS_BALANCER), 1));
+ args_to_add.emplace_back(grpc_channel_arg_string_create(
+ const_cast<char*>(GRPC_ARG_ADDRESS_BALANCER_NAME), hr->host));
+ }
+ grpc_channel_args* args = grpc_channel_args_copy_and_add(
+ nullptr, args_to_add.data(), args_to_add.size());
switch (hostent->h_addrtype) {
case AF_INET6: {
size_t addr_len = sizeof(struct sockaddr_in6);
struct sockaddr_in6 addr;
memset(&addr, 0, addr_len);
- memcpy(&addr.sin6_addr, hostent->h_addr_list[i - prev_naddr],
+ memcpy(&addr.sin6_addr, hostent->h_addr_list[i],
sizeof(struct in6_addr));
addr.sin6_family = static_cast<unsigned char>(hostent->h_addrtype);
addr.sin6_port = hr->port;
- grpc_lb_addresses_set_address(
- *lb_addresses, i, &addr, addr_len,
- hr->is_balancer /* is_balancer */,
- hr->is_balancer ? hr->host : nullptr /* balancer_name */,
- nullptr /* user_data */);
+ addresses.emplace_back(&addr, addr_len, args);
char output[INET6_ADDRSTRLEN];
ares_inet_ntop(AF_INET6, &addr.sin6_addr, output, INET6_ADDRSTRLEN);
gpr_log(GPR_DEBUG,
@@ -220,15 +219,11 @@ static void on_hostbyname_done_locked(void* arg, int status, int timeouts,
size_t addr_len = sizeof(struct sockaddr_in);
struct sockaddr_in addr;
memset(&addr, 0, addr_len);
- memcpy(&addr.sin_addr, hostent->h_addr_list[i - prev_naddr],
+ memcpy(&addr.sin_addr, hostent->h_addr_list[i],
sizeof(struct in_addr));
addr.sin_family = static_cast<unsigned char>(hostent->h_addrtype);
addr.sin_port = hr->port;
- grpc_lb_addresses_set_address(
- *lb_addresses, i, &addr, addr_len,
- hr->is_balancer /* is_balancer */,
- hr->is_balancer ? hr->host : nullptr /* balancer_name */,
- nullptr /* user_data */);
+ addresses.emplace_back(&addr, addr_len, args);
char output[INET_ADDRSTRLEN];
ares_inet_ntop(AF_INET, &addr.sin_addr, output, INET_ADDRSTRLEN);
gpr_log(GPR_DEBUG,
@@ -467,11 +462,10 @@ error_cleanup:
gpr_free(port);
}
-static bool inner_resolve_as_ip_literal_locked(const char* name,
- const char* default_port,
- grpc_lb_addresses** addrs,
- char** host, char** port,
- char** hostport) {
+static bool inner_resolve_as_ip_literal_locked(
+ const char* name, const char* default_port,
+ grpc_core::UniquePtr<grpc_core::ServerAddressList>* addrs, char** host,
+ char** port, char** hostport) {
gpr_split_host_port(name, host, port);
if (*host == nullptr) {
gpr_log(GPR_ERROR,
@@ -495,18 +489,16 @@ static bool inner_resolve_as_ip_literal_locked(const char* name,
if (grpc_parse_ipv4_hostport(*hostport, &addr, false /* log errors */) ||
grpc_parse_ipv6_hostport(*hostport, &addr, false /* log errors */)) {
GPR_ASSERT(*addrs == nullptr);
- *addrs = grpc_lb_addresses_create(1, nullptr);
- grpc_lb_addresses_set_address(
- *addrs, 0, addr.addr, addr.len, false /* is_balancer */,
- nullptr /* balancer_name */, nullptr /* user_data */);
+ *addrs = grpc_core::MakeUnique<ServerAddressList>();
+ (*addrs)->emplace_back(addr.addr, addr.len, nullptr /* args */);
return true;
}
return false;
}
-static bool resolve_as_ip_literal_locked(const char* name,
- const char* default_port,
- grpc_lb_addresses** addrs) {
+static bool resolve_as_ip_literal_locked(
+ const char* name, const char* default_port,
+ grpc_core::UniquePtr<grpc_core::ServerAddressList>* addrs) {
char* host = nullptr;
char* port = nullptr;
char* hostport = nullptr;
@@ -521,13 +513,14 @@ static bool resolve_as_ip_literal_locked(const char* name,
static grpc_ares_request* grpc_dns_lookup_ares_locked_impl(
const char* dns_server, const char* name, const char* default_port,
grpc_pollset_set* interested_parties, grpc_closure* on_done,
- grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json,
- int query_timeout_ms, grpc_combiner* combiner) {
+ grpc_core::UniquePtr<grpc_core::ServerAddressList>* addrs,
+ bool check_grpclb, char** service_config_json, int query_timeout_ms,
+ grpc_combiner* combiner) {
grpc_ares_request* r =
static_cast<grpc_ares_request*>(gpr_zalloc(sizeof(grpc_ares_request)));
r->ev_driver = nullptr;
r->on_done = on_done;
- r->lb_addrs_out = addrs;
+ r->addresses_out = addrs;
r->service_config_json_out = service_config_json;
r->success = false;
r->error = GRPC_ERROR_NONE;
@@ -553,8 +546,8 @@ static grpc_ares_request* grpc_dns_lookup_ares_locked_impl(
grpc_ares_request* (*grpc_dns_lookup_ares_locked)(
const char* dns_server, const char* name, const char* default_port,
grpc_pollset_set* interested_parties, grpc_closure* on_done,
- grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json,
- int query_timeout_ms,
+ grpc_core::UniquePtr<grpc_core::ServerAddressList>* addrs,
+ bool check_grpclb, char** service_config_json, int query_timeout_ms,
grpc_combiner* combiner) = grpc_dns_lookup_ares_locked_impl;
static void grpc_cancel_ares_request_locked_impl(grpc_ares_request* r) {
@@ -599,8 +592,8 @@ typedef struct grpc_resolve_address_ares_request {
grpc_combiner* combiner;
/** the pointer to receive the resolved addresses */
grpc_resolved_addresses** addrs_out;
- /** currently resolving lb addresses */
- grpc_lb_addresses* lb_addrs;
+ /** currently resolving addresses */
+ grpc_core::UniquePtr<ServerAddressList> addresses;
/** closure to call when the resolve_address_ares request completes */
grpc_closure* on_resolve_address_done;
/** a closure wrapping on_resolve_address_done, which should be invoked when
@@ -613,7 +606,7 @@ typedef struct grpc_resolve_address_ares_request {
/* pollset_set to be driven by */
grpc_pollset_set* interested_parties;
/* underlying ares_request that the query is performed on */
- grpc_ares_request* ares_request;
+ grpc_ares_request* ares_request = nullptr;
} grpc_resolve_address_ares_request;
static void on_dns_lookup_done_locked(void* arg, grpc_error* error) {
@@ -621,25 +614,24 @@ static void on_dns_lookup_done_locked(void* arg, grpc_error* error) {
static_cast<grpc_resolve_address_ares_request*>(arg);
gpr_free(r->ares_request);
grpc_resolved_addresses** resolved_addresses = r->addrs_out;
- if (r->lb_addrs == nullptr || r->lb_addrs->num_addresses == 0) {
+ if (r->addresses == nullptr || r->addresses->empty()) {
*resolved_addresses = nullptr;
} else {
*resolved_addresses = static_cast<grpc_resolved_addresses*>(
gpr_zalloc(sizeof(grpc_resolved_addresses)));
- (*resolved_addresses)->naddrs = r->lb_addrs->num_addresses;
+ (*resolved_addresses)->naddrs = r->addresses->size();
(*resolved_addresses)->addrs =
static_cast<grpc_resolved_address*>(gpr_zalloc(
sizeof(grpc_resolved_address) * (*resolved_addresses)->naddrs));
- for (size_t i = 0; i < (*resolved_addresses)->naddrs; i++) {
- GPR_ASSERT(!r->lb_addrs->addresses[i].is_balancer);
- memcpy(&(*resolved_addresses)->addrs[i],
- &r->lb_addrs->addresses[i].address, sizeof(grpc_resolved_address));
+ for (size_t i = 0; i < (*resolved_addresses)->naddrs; ++i) {
+ GPR_ASSERT(!(*r->addresses)[i].IsBalancer());
+ memcpy(&(*resolved_addresses)->addrs[i], &(*r->addresses)[i].address(),
+ sizeof(grpc_resolved_address));
}
}
GRPC_CLOSURE_SCHED(r->on_resolve_address_done, GRPC_ERROR_REF(error));
- if (r->lb_addrs != nullptr) grpc_lb_addresses_destroy(r->lb_addrs);
GRPC_COMBINER_UNREF(r->combiner, "on_dns_lookup_done_cb");
- gpr_free(r);
+ grpc_core::Delete(r);
}
static void grpc_resolve_address_invoke_dns_lookup_ares_locked(
@@ -648,7 +640,7 @@ static void grpc_resolve_address_invoke_dns_lookup_ares_locked(
static_cast<grpc_resolve_address_ares_request*>(arg);
r->ares_request = grpc_dns_lookup_ares_locked(
nullptr /* dns_server */, r->name, r->default_port, r->interested_parties,
- &r->on_dns_lookup_done_locked, &r->lb_addrs, false /* check_grpclb */,
+ &r->on_dns_lookup_done_locked, &r->addresses, false /* check_grpclb */,
nullptr /* service_config_json */, GRPC_DNS_ARES_DEFAULT_QUERY_TIMEOUT_MS,
r->combiner);
}
@@ -659,8 +651,7 @@ static void grpc_resolve_address_ares_impl(const char* name,
grpc_closure* on_done,
grpc_resolved_addresses** addrs) {
grpc_resolve_address_ares_request* r =
- static_cast<grpc_resolve_address_ares_request*>(
- gpr_zalloc(sizeof(grpc_resolve_address_ares_request)));
+ grpc_core::New<grpc_resolve_address_ares_request>();
r->combiner = grpc_combiner_create();
r->addrs_out = addrs;
r->on_resolve_address_done = on_done;
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h
index 9acef1d0ca..2808250456 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h
@@ -21,7 +21,7 @@
#include <grpc/support/port_platform.h>
-#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
+#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/lib/iomgr/iomgr.h"
#include "src/core/lib/iomgr/polling_entity.h"
#include "src/core/lib/iomgr/resolve_address.h"
@@ -61,8 +61,9 @@ extern void (*grpc_resolve_address_ares)(const char* name,
extern grpc_ares_request* (*grpc_dns_lookup_ares_locked)(
const char* dns_server, const char* name, const char* default_port,
grpc_pollset_set* interested_parties, grpc_closure* on_done,
- grpc_lb_addresses** addresses, bool check_grpclb,
- char** service_config_json, int query_timeout_ms, grpc_combiner* combiner);
+ grpc_core::UniquePtr<grpc_core::ServerAddressList>* addresses,
+ bool check_grpclb, char** service_config_json, int query_timeout_ms,
+ grpc_combiner* combiner);
/* Cancel the pending grpc_ares_request \a request */
extern void (*grpc_cancel_ares_request_locked)(grpc_ares_request* request);
@@ -89,10 +90,12 @@ bool grpc_ares_query_ipv6();
* Returns a bool indicating whether or not such an action was performed.
* See https://github.com/grpc/grpc/issues/15158. */
bool grpc_ares_maybe_resolve_localhost_manually_locked(
- const char* name, const char* default_port, grpc_lb_addresses** addrs);
+ const char* name, const char* default_port,
+ grpc_core::UniquePtr<grpc_core::ServerAddressList>* addrs);
/* Sorts destinations in lb_addrs according to RFC 6724. */
-void grpc_cares_wrapper_address_sorting_sort(grpc_lb_addresses* lb_addrs);
+void grpc_cares_wrapper_address_sorting_sort(
+ grpc_core::ServerAddressList* addresses);
#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_WRAPPER_H \
*/
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc
index fc78b18304..1f4701c999 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc
@@ -29,16 +29,17 @@ struct grpc_ares_request {
static grpc_ares_request* grpc_dns_lookup_ares_locked_impl(
const char* dns_server, const char* name, const char* default_port,
grpc_pollset_set* interested_parties, grpc_closure* on_done,
- grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json,
- int query_timeout_ms, grpc_combiner* combiner) {
+ grpc_core::UniquePtr<grpc_core::ServerAddressList>* addrs,
+ bool check_grpclb, char** service_config_json, int query_timeout_ms,
+ grpc_combiner* combiner) {
return NULL;
}
grpc_ares_request* (*grpc_dns_lookup_ares_locked)(
const char* dns_server, const char* name, const char* default_port,
grpc_pollset_set* interested_parties, grpc_closure* on_done,
- grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json,
- int query_timeout_ms,
+ grpc_core::UniquePtr<grpc_core::ServerAddressList>* addrs,
+ bool check_grpclb, char** service_config_json, int query_timeout_ms,
grpc_combiner* combiner) = grpc_dns_lookup_ares_locked_impl;
static void grpc_cancel_ares_request_locked_impl(grpc_ares_request* r) {}
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc
index 639eec2323..028d844216 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc
@@ -27,7 +27,8 @@
bool grpc_ares_query_ipv6() { return grpc_ipv6_loopback_available(); }
bool grpc_ares_maybe_resolve_localhost_manually_locked(
- const char* name, const char* default_port, grpc_lb_addresses** addrs) {
+ const char* name, const char* default_port,
+ grpc_core::UniquePtr<grpc_core::ServerAddressList>* addrs) {
return false;
}
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc
index 7e34784691..202452f1b2 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc
@@ -23,9 +23,9 @@
#include <grpc/support/string_util.h>
-#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
#include "src/core/ext/filters/client_channel/parse_address.h"
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
+#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/iomgr/socket_windows.h"
@@ -33,8 +33,9 @@
bool grpc_ares_query_ipv6() { return grpc_ipv6_loopback_available(); }
static bool inner_maybe_resolve_localhost_manually_locked(
- const char* name, const char* default_port, grpc_lb_addresses** addrs,
- char** host, char** port) {
+ const char* name, const char* default_port,
+ grpc_core::UniquePtr<grpc_core::ServerAddressList>* addrs, char** host,
+ char** port) {
gpr_split_host_port(name, host, port);
if (*host == nullptr) {
gpr_log(GPR_ERROR,
@@ -55,7 +56,7 @@ static bool inner_maybe_resolve_localhost_manually_locked(
}
if (gpr_stricmp(*host, "localhost") == 0) {
GPR_ASSERT(*addrs == nullptr);
- *addrs = grpc_lb_addresses_create(2, nullptr);
+ *addrs = grpc_core::MakeUnique<grpc_core::ServerAddressList>();
uint16_t numeric_port = grpc_strhtons(*port);
// Append the ipv6 loopback address.
struct sockaddr_in6 ipv6_loopback_addr;
@@ -63,10 +64,8 @@ static bool inner_maybe_resolve_localhost_manually_locked(
((char*)&ipv6_loopback_addr.sin6_addr)[15] = 1;
ipv6_loopback_addr.sin6_family = AF_INET6;
ipv6_loopback_addr.sin6_port = numeric_port;
- grpc_lb_addresses_set_address(
- *addrs, 0, &ipv6_loopback_addr, sizeof(ipv6_loopback_addr),
- false /* is_balancer */, nullptr /* balancer_name */,
- nullptr /* user_data */);
+ (*addrs)->emplace_back(&ipv6_loopback_addr, sizeof(ipv6_loopback_addr),
+ nullptr /* args */);
// Append the ipv4 loopback address.
struct sockaddr_in ipv4_loopback_addr;
memset(&ipv4_loopback_addr, 0, sizeof(ipv4_loopback_addr));
@@ -74,19 +73,18 @@ static bool inner_maybe_resolve_localhost_manually_locked(
((char*)&ipv4_loopback_addr.sin_addr)[3] = 0x01;
ipv4_loopback_addr.sin_family = AF_INET;
ipv4_loopback_addr.sin_port = numeric_port;
- grpc_lb_addresses_set_address(
- *addrs, 1, &ipv4_loopback_addr, sizeof(ipv4_loopback_addr),
- false /* is_balancer */, nullptr /* balancer_name */,
- nullptr /* user_data */);
+ (*addrs)->emplace_back(&ipv4_loopback_addr, sizeof(ipv4_loopback_addr),
+ nullptr /* args */);
// Let the address sorter figure out which one should be tried first.
- grpc_cares_wrapper_address_sorting_sort(*addrs);
+ grpc_cares_wrapper_address_sorting_sort(addrs->get());
return true;
}
return false;
}
bool grpc_ares_maybe_resolve_localhost_manually_locked(
- const char* name, const char* default_port, grpc_lb_addresses** addrs) {
+ const char* name, const char* default_port,
+ grpc_core::UniquePtr<grpc_core::ServerAddressList>* addrs) {
char* host = nullptr;
char* port = nullptr;
bool out = inner_maybe_resolve_localhost_manually_locked(name, default_port,
diff --git a/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc b/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc
index 65ff1ec1a5..c365f1abfd 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc
+++ b/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc
@@ -26,8 +26,8 @@
#include <grpc/support/string_util.h>
#include <grpc/support/time.h>
-#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
#include "src/core/ext/filters/client_channel/resolver_registry.h"
+#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/lib/backoff/backoff.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/env.h"
@@ -198,18 +198,14 @@ void NativeDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) {
grpc_error_set_str(error, GRPC_ERROR_STR_TARGET_ADDRESS,
grpc_slice_from_copied_string(r->name_to_resolve_));
if (r->addresses_ != nullptr) {
- grpc_lb_addresses* addresses = grpc_lb_addresses_create(
- r->addresses_->naddrs, nullptr /* user_data_vtable */);
+ ServerAddressList addresses;
for (size_t i = 0; i < r->addresses_->naddrs; ++i) {
- grpc_lb_addresses_set_address(
- addresses, i, &r->addresses_->addrs[i].addr,
- r->addresses_->addrs[i].len, false /* is_balancer */,
- nullptr /* balancer_name */, nullptr /* user_data */);
+ addresses.emplace_back(&r->addresses_->addrs[i].addr,
+ r->addresses_->addrs[i].len, nullptr /* args */);
}
- grpc_arg new_arg = grpc_lb_addresses_create_channel_arg(addresses);
+ grpc_arg new_arg = CreateServerAddressListChannelArg(&addresses);
result = grpc_channel_args_copy_and_add(r->channel_args_, &new_arg, 1);
grpc_resolved_addresses_destroy(r->addresses_);
- grpc_lb_addresses_destroy(addresses);
// Reset backoff state so that we start from the beginning when the
// next request gets triggered.
r->backoff_.Reset();
diff --git a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc
index 3aa690bea4..258339491c 100644
--- a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc
+++ b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc
@@ -28,12 +28,13 @@
#include <grpc/support/alloc.h>
#include <grpc/support/string_util.h>
-#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
#include "src/core/ext/filters/client_channel/parse_address.h"
#include "src/core/ext/filters/client_channel/resolver_registry.h"
+#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/iomgr/closure.h"
#include "src/core/lib/iomgr/combiner.h"
#include "src/core/lib/iomgr/resolve_address.h"
diff --git a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h
index 7f69059351..d86111c382 100644
--- a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h
+++ b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h
@@ -19,10 +19,9 @@
#include <grpc/support/port_platform.h>
-#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gprpp/ref_counted.h"
-#include "src/core/lib/uri/uri_parser.h"
+#include "src/core/lib/iomgr/error.h"
#define GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR \
"grpc.fake_resolver.response_generator"
diff --git a/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc b/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc
index 801734764b..1654747a79 100644
--- a/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc
+++ b/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc
@@ -26,9 +26,9 @@
#include <grpc/support/alloc.h>
#include <grpc/support/string_util.h>
-#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
#include "src/core/ext/filters/client_channel/parse_address.h"
#include "src/core/ext/filters/client_channel/resolver_registry.h"
+#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
@@ -45,7 +45,8 @@ namespace {
class SockaddrResolver : public Resolver {
public:
/// Takes ownership of \a addresses.
- SockaddrResolver(const ResolverArgs& args, grpc_lb_addresses* addresses);
+ SockaddrResolver(const ResolverArgs& args,
+ UniquePtr<ServerAddressList> addresses);
void NextLocked(grpc_channel_args** result,
grpc_closure* on_complete) override;
@@ -58,7 +59,7 @@ class SockaddrResolver : public Resolver {
void MaybeFinishNextLocked();
/// the addresses that we've "resolved"
- grpc_lb_addresses* addresses_ = nullptr;
+ UniquePtr<ServerAddressList> addresses_;
/// channel args
grpc_channel_args* channel_args_ = nullptr;
/// have we published?
@@ -70,13 +71,12 @@ class SockaddrResolver : public Resolver {
};
SockaddrResolver::SockaddrResolver(const ResolverArgs& args,
- grpc_lb_addresses* addresses)
+ UniquePtr<ServerAddressList> addresses)
: Resolver(args.combiner),
- addresses_(addresses),
+ addresses_(std::move(addresses)),
channel_args_(grpc_channel_args_copy(args.args)) {}
SockaddrResolver::~SockaddrResolver() {
- grpc_lb_addresses_destroy(addresses_);
grpc_channel_args_destroy(channel_args_);
}
@@ -100,7 +100,7 @@ void SockaddrResolver::ShutdownLocked() {
void SockaddrResolver::MaybeFinishNextLocked() {
if (next_completion_ != nullptr && !published_) {
published_ = true;
- grpc_arg arg = grpc_lb_addresses_create_channel_arg(addresses_);
+ grpc_arg arg = CreateServerAddressListChannelArg(addresses_.get());
*target_result_ = grpc_channel_args_copy_and_add(channel_args_, &arg, 1);
GRPC_CLOSURE_SCHED(next_completion_, GRPC_ERROR_NONE);
next_completion_ = nullptr;
@@ -127,27 +127,27 @@ OrphanablePtr<Resolver> CreateSockaddrResolver(
grpc_slice_buffer path_parts;
grpc_slice_buffer_init(&path_parts);
grpc_slice_split(path_slice, ",", &path_parts);
- grpc_lb_addresses* addresses = grpc_lb_addresses_create(
- path_parts.count, nullptr /* user_data_vtable */);
+ auto addresses = MakeUnique<ServerAddressList>();
bool errors_found = false;
- for (size_t i = 0; i < addresses->num_addresses; i++) {
+ for (size_t i = 0; i < path_parts.count; i++) {
grpc_uri ith_uri = *args.uri;
- char* part_str = grpc_slice_to_c_string(path_parts.slices[i]);
- ith_uri.path = part_str;
- if (!parse(&ith_uri, &addresses->addresses[i].address)) {
+ UniquePtr<char> part_str(grpc_slice_to_c_string(path_parts.slices[i]));
+ ith_uri.path = part_str.get();
+ grpc_resolved_address addr;
+ if (!parse(&ith_uri, &addr)) {
errors_found = true; /* GPR_TRUE */
+ break;
}
- gpr_free(part_str);
- if (errors_found) break;
+ addresses->emplace_back(addr, nullptr /* args */);
}
grpc_slice_buffer_destroy_internal(&path_parts);
grpc_slice_unref_internal(path_slice);
if (errors_found) {
- grpc_lb_addresses_destroy(addresses);
return OrphanablePtr<Resolver>(nullptr);
}
// Instantiate resolver.
- return OrphanablePtr<Resolver>(New<SockaddrResolver>(args, addresses));
+ return OrphanablePtr<Resolver>(
+ New<SockaddrResolver>(args, std::move(addresses)));
}
class IPv4ResolverFactory : public ResolverFactory {
diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.cc b/src/core/ext/filters/client_channel/resolver_result_parsing.cc
index 82a26ace63..22b06db45c 100644
--- a/src/core/ext/filters/client_channel/resolver_result_parsing.cc
+++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc
@@ -30,9 +30,11 @@
#include "src/core/ext/filters/client_channel/client_channel.h"
#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
+#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/lib/channel/status_util.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/memory.h"
+#include "src/core/lib/uri/uri_parser.h"
// As per the retry design, we do not allow more than 5 retry attempts.
#define MAX_MAX_RETRY_ATTEMPTS 5
@@ -40,32 +42,11 @@
namespace grpc_core {
namespace internal {
-namespace {
-
-// Converts string format from JSON to proto.
-grpc_core::UniquePtr<char> ConvertCamelToSnake(const char* camel) {
- const size_t size = strlen(camel);
- char* snake = static_cast<char*>(gpr_malloc(size * 2));
- size_t j = 0;
- for (size_t i = 0; i < size; ++i) {
- if (isupper(camel[i])) {
- snake[j++] = '_';
- snake[j++] = tolower(camel[i]);
- } else {
- snake[j++] = camel[i];
- }
- }
- snake[j] = '\0';
- return grpc_core::UniquePtr<char>(snake);
-}
-
-} // namespace
-
ProcessedResolverResult::ProcessedResolverResult(
const grpc_channel_args* resolver_result, bool parse_retry) {
ProcessServiceConfig(resolver_result, parse_retry);
// If no LB config was found above, just find the LB policy name then.
- if (lb_policy_config_ == nullptr) ProcessLbPolicyName(resolver_result);
+ if (lb_policy_name_ == nullptr) ProcessLbPolicyName(resolver_result);
}
void ProcessedResolverResult::ProcessServiceConfig(
@@ -98,41 +79,55 @@ void ProcessedResolverResult::ProcessServiceConfig(
void ProcessedResolverResult::ProcessLbPolicyName(
const grpc_channel_args* resolver_result) {
- const char* lb_policy_name = nullptr;
// 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 = service_config_->GetLoadBalancingPolicyName();
+ 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]);
+ }
+ }
}
// Otherwise, find the LB policy name set by the client API.
- if (lb_policy_name == nullptr) {
+ if (lb_policy_name_ == nullptr) {
const grpc_arg* channel_arg =
grpc_channel_args_find(resolver_result, GRPC_ARG_LB_POLICY_NAME);
- lb_policy_name = grpc_channel_arg_get_string(channel_arg);
+ lb_policy_name_.reset(gpr_strdup(grpc_channel_arg_get_string(channel_arg)));
}
// Special case: If at least one balancer address is present, we use
// the grpclb policy, regardless of what the resolver has returned.
- const grpc_arg* channel_arg =
- grpc_channel_args_find(resolver_result, GRPC_ARG_LB_ADDRESSES);
- if (channel_arg != nullptr && channel_arg->type == GRPC_ARG_POINTER) {
- grpc_lb_addresses* addresses =
- static_cast<grpc_lb_addresses*>(channel_arg->value.pointer.p);
- if (grpc_lb_addresses_contains_balancer_address(*addresses)) {
- if (lb_policy_name != nullptr &&
- gpr_stricmp(lb_policy_name, "grpclb") != 0) {
+ const ServerAddressList* addresses =
+ FindServerAddressListChannelArg(resolver_result);
+ if (addresses != nullptr) {
+ bool found_balancer_address = false;
+ for (size_t i = 0; i < addresses->size(); ++i) {
+ const ServerAddress& address = (*addresses)[i];
+ if (address.IsBalancer()) {
+ found_balancer_address = true;
+ break;
+ }
+ }
+ if (found_balancer_address) {
+ if (lb_policy_name_ != nullptr &&
+ strcmp(lb_policy_name_.get(), "grpclb") != 0) {
gpr_log(GPR_INFO,
"resolver requested LB policy %s but provided at least one "
"balancer address -- forcing use of grpclb LB policy",
- lb_policy_name);
+ lb_policy_name_.get());
}
- lb_policy_name = "grpclb";
+ lb_policy_name_.reset(gpr_strdup("grpclb"));
}
}
// Use pick_first if nothing was specified and we didn't select grpclb
// above.
- if (lb_policy_name == nullptr) lb_policy_name = "pick_first";
- lb_policy_name_.reset(gpr_strdup(lb_policy_name));
+ if (lb_policy_name_ == nullptr) {
+ lb_policy_name_.reset(gpr_strdup("pick_first"));
+ }
}
void ProcessedResolverResult::ParseServiceConfig(
@@ -175,15 +170,13 @@ void ProcessedResolverResult::ParseLbConfigFromServiceConfig(
if (policy_content != nullptr) return; // Violate "oneof" type.
policy_content = field;
}
- grpc_core::UniquePtr<char> lb_policy_name =
- ConvertCamelToSnake(policy_content->key);
- if (!grpc_core::LoadBalancingPolicyRegistry::LoadBalancingPolicyExists(
- lb_policy_name.get())) {
- continue;
+ // If we support this policy, then select it.
+ if (grpc_core::LoadBalancingPolicyRegistry::LoadBalancingPolicyExists(
+ policy_content->key)) {
+ lb_policy_name_.reset(gpr_strdup(policy_content->key));
+ lb_policy_config_ = policy_content->child;
+ return;
}
- lb_policy_name_ = std::move(lb_policy_name);
- lb_policy_config_ = policy_content->child;
- return;
}
}
diff --git a/src/core/ext/filters/client_channel/server_address.cc b/src/core/ext/filters/client_channel/server_address.cc
new file mode 100644
index 0000000000..ec33cbbd95
--- /dev/null
+++ b/src/core/ext/filters/client_channel/server_address.cc
@@ -0,0 +1,103 @@
+/*
+ *
+ * Copyright 2018 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <grpc/support/port_platform.h>
+
+#include "src/core/ext/filters/client_channel/server_address.h"
+
+#include <string.h>
+
+namespace grpc_core {
+
+//
+// ServerAddress
+//
+
+ServerAddress::ServerAddress(const grpc_resolved_address& address,
+ grpc_channel_args* args)
+ : address_(address), args_(args) {}
+
+ServerAddress::ServerAddress(const void* address, size_t address_len,
+ grpc_channel_args* args)
+ : args_(args) {
+ memcpy(address_.addr, address, address_len);
+ address_.len = static_cast<socklen_t>(address_len);
+}
+
+int ServerAddress::Cmp(const ServerAddress& other) const {
+ if (address_.len > other.address_.len) return 1;
+ if (address_.len < other.address_.len) return -1;
+ int retval = memcmp(address_.addr, other.address_.addr, address_.len);
+ if (retval != 0) return retval;
+ return grpc_channel_args_compare(args_, other.args_);
+}
+
+bool ServerAddress::IsBalancer() const {
+ return grpc_channel_arg_get_bool(
+ grpc_channel_args_find(args_, GRPC_ARG_ADDRESS_IS_BALANCER), false);
+}
+
+//
+// ServerAddressList
+//
+
+namespace {
+
+void* ServerAddressListCopy(void* addresses) {
+ ServerAddressList* a = static_cast<ServerAddressList*>(addresses);
+ return New<ServerAddressList>(*a);
+}
+
+void ServerAddressListDestroy(void* addresses) {
+ ServerAddressList* a = static_cast<ServerAddressList*>(addresses);
+ Delete(a);
+}
+
+int ServerAddressListCompare(void* addresses1, void* addresses2) {
+ ServerAddressList* a1 = static_cast<ServerAddressList*>(addresses1);
+ ServerAddressList* a2 = static_cast<ServerAddressList*>(addresses2);
+ if (a1->size() > a2->size()) return 1;
+ if (a1->size() < a2->size()) return -1;
+ for (size_t i = 0; i < a1->size(); ++i) {
+ int retval = (*a1)[i].Cmp((*a2)[i]);
+ if (retval != 0) return retval;
+ }
+ return 0;
+}
+
+const grpc_arg_pointer_vtable server_addresses_arg_vtable = {
+ ServerAddressListCopy, ServerAddressListDestroy, ServerAddressListCompare};
+
+} // namespace
+
+grpc_arg CreateServerAddressListChannelArg(const ServerAddressList* addresses) {
+ return grpc_channel_arg_pointer_create(
+ const_cast<char*>(GRPC_ARG_SERVER_ADDRESS_LIST),
+ const_cast<ServerAddressList*>(addresses), &server_addresses_arg_vtable);
+}
+
+ServerAddressList* FindServerAddressListChannelArg(
+ const grpc_channel_args* channel_args) {
+ const grpc_arg* lb_addresses_arg =
+ grpc_channel_args_find(channel_args, GRPC_ARG_SERVER_ADDRESS_LIST);
+ if (lb_addresses_arg == nullptr || lb_addresses_arg->type != GRPC_ARG_POINTER)
+ return nullptr;
+ return static_cast<ServerAddressList*>(lb_addresses_arg->value.pointer.p);
+}
+
+} // namespace grpc_core
diff --git a/src/core/ext/filters/client_channel/server_address.h b/src/core/ext/filters/client_channel/server_address.h
new file mode 100644
index 0000000000..3a1bf1df67
--- /dev/null
+++ b/src/core/ext/filters/client_channel/server_address.h
@@ -0,0 +1,108 @@
+/*
+ *
+ * Copyright 2018 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SERVER_ADDRESS_H
+#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SERVER_ADDRESS_H
+
+#include <grpc/support/port_platform.h>
+
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/gprpp/inlined_vector.h"
+#include "src/core/lib/iomgr/resolve_address.h"
+#include "src/core/lib/uri/uri_parser.h"
+
+// Channel arg key for ServerAddressList.
+#define GRPC_ARG_SERVER_ADDRESS_LIST "grpc.server_address_list"
+
+// Channel arg key for a bool indicating whether an address is a grpclb
+// load balancer (as opposed to a backend).
+#define GRPC_ARG_ADDRESS_IS_BALANCER "grpc.address_is_balancer"
+
+// Channel arg key for a string indicating an address's balancer name.
+#define GRPC_ARG_ADDRESS_BALANCER_NAME "grpc.address_balancer_name"
+
+namespace grpc_core {
+
+//
+// ServerAddress
+//
+
+// A server address is a grpc_resolved_address with an associated set of
+// channel args. Any args present here will be merged into the channel
+// args when a subchannel is created for this address.
+class ServerAddress {
+ public:
+ // Takes ownership of args.
+ ServerAddress(const grpc_resolved_address& address, grpc_channel_args* args);
+ ServerAddress(const void* address, size_t address_len,
+ grpc_channel_args* args);
+
+ ~ServerAddress() { grpc_channel_args_destroy(args_); }
+
+ // Copyable.
+ ServerAddress(const ServerAddress& other)
+ : address_(other.address_), args_(grpc_channel_args_copy(other.args_)) {}
+ ServerAddress& operator=(const ServerAddress& other) {
+ address_ = other.address_;
+ grpc_channel_args_destroy(args_);
+ args_ = grpc_channel_args_copy(other.args_);
+ return *this;
+ }
+
+ // Movable.
+ ServerAddress(ServerAddress&& other)
+ : address_(other.address_), args_(other.args_) {
+ other.args_ = nullptr;
+ }
+ ServerAddress& operator=(ServerAddress&& other) {
+ address_ = other.address_;
+ args_ = other.args_;
+ other.args_ = nullptr;
+ return *this;
+ }
+
+ bool operator==(const ServerAddress& other) const { return Cmp(other) == 0; }
+
+ int Cmp(const ServerAddress& other) const;
+
+ const grpc_resolved_address& address() const { return address_; }
+ const grpc_channel_args* args() const { return args_; }
+
+ bool IsBalancer() const;
+
+ private:
+ grpc_resolved_address address_;
+ grpc_channel_args* args_;
+};
+
+//
+// ServerAddressList
+//
+
+typedef InlinedVector<ServerAddress, 1> ServerAddressList;
+
+// Returns a channel arg containing \a addresses.
+grpc_arg CreateServerAddressListChannelArg(const ServerAddressList* addresses);
+
+// Returns the ServerListAddress instance in channel_args or NULL.
+ServerAddressList* FindServerAddressListChannelArg(
+ const grpc_channel_args* channel_args);
+
+} // namespace grpc_core
+
+#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SERVER_ADDRESS_H */
diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc
index 0817b1dd39..9077aa9753 100644
--- a/src/core/ext/filters/client_channel/subchannel.cc
+++ b/src/core/ext/filters/client_channel/subchannel.cc
@@ -153,7 +153,7 @@ struct grpc_subchannel {
/** have we started the backoff loop */
bool backoff_begun;
// reset_backoff() was called while alarm was pending
- bool deferred_reset_backoff;
+ bool retry_immediately;
/** our alarm */
grpc_timer alarm;
@@ -709,8 +709,8 @@ static void on_alarm(void* arg, grpc_error* error) {
if (c->disconnected) {
error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING("Disconnected",
&error, 1);
- } else if (c->deferred_reset_backoff) {
- c->deferred_reset_backoff = false;
+ } else if (c->retry_immediately) {
+ c->retry_immediately = false;
error = GRPC_ERROR_NONE;
} else {
GRPC_ERROR_REF(error);
@@ -837,7 +837,7 @@ static bool publish_transport_locked(grpc_subchannel* c) {
/* publish */
c->connected_subchannel.reset(grpc_core::New<grpc_core::ConnectedSubchannel>(
- stk, c->channelz_subchannel, socket_uuid));
+ stk, c->args, c->channelz_subchannel, socket_uuid));
gpr_log(GPR_INFO, "New connected subchannel at %p for subchannel %p",
c->connected_subchannel.get(), c);
@@ -887,12 +887,12 @@ static void on_subchannel_connected(void* arg, grpc_error* error) {
void grpc_subchannel_reset_backoff(grpc_subchannel* subchannel) {
gpr_mu_lock(&subchannel->mu);
+ subchannel->backoff->Reset();
if (subchannel->have_alarm) {
- subchannel->deferred_reset_backoff = true;
+ subchannel->retry_immediately = true;
grpc_timer_cancel(&subchannel->alarm);
} else {
subchannel->backoff_begun = false;
- subchannel->backoff->Reset();
maybe_start_connecting_locked(subchannel);
}
gpr_mu_unlock(&subchannel->mu);
@@ -1068,16 +1068,18 @@ grpc_arg grpc_create_subchannel_address_arg(const grpc_resolved_address* addr) {
namespace grpc_core {
ConnectedSubchannel::ConnectedSubchannel(
- grpc_channel_stack* channel_stack,
+ grpc_channel_stack* channel_stack, const grpc_channel_args* args,
grpc_core::RefCountedPtr<grpc_core::channelz::SubchannelNode>
channelz_subchannel,
intptr_t socket_uuid)
: RefCounted<ConnectedSubchannel>(&grpc_trace_stream_refcount),
channel_stack_(channel_stack),
+ args_(grpc_channel_args_copy(args)),
channelz_subchannel_(std::move(channelz_subchannel)),
socket_uuid_(socket_uuid) {}
ConnectedSubchannel::~ConnectedSubchannel() {
+ grpc_channel_args_destroy(args_);
GRPC_CHANNEL_STACK_UNREF(channel_stack_, "connected_subchannel_dtor");
}
diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h
index 69c2456ec2..14f87f2c68 100644
--- a/src/core/ext/filters/client_channel/subchannel.h
+++ b/src/core/ext/filters/client_channel/subchannel.h
@@ -85,28 +85,31 @@ class ConnectedSubchannel : public RefCounted<ConnectedSubchannel> {
size_t parent_data_size;
};
- explicit ConnectedSubchannel(
- grpc_channel_stack* channel_stack,
+ ConnectedSubchannel(
+ grpc_channel_stack* channel_stack, const grpc_channel_args* args,
grpc_core::RefCountedPtr<grpc_core::channelz::SubchannelNode>
channelz_subchannel,
intptr_t socket_uuid);
~ConnectedSubchannel();
- grpc_channel_stack* channel_stack() { return channel_stack_; }
void NotifyOnStateChange(grpc_pollset_set* interested_parties,
grpc_connectivity_state* state,
grpc_closure* closure);
void Ping(grpc_closure* on_initiate, grpc_closure* on_ack);
grpc_error* CreateCall(const CallArgs& args, grpc_subchannel_call** call);
- channelz::SubchannelNode* channelz_subchannel() {
+
+ grpc_channel_stack* channel_stack() const { return channel_stack_; }
+ const grpc_channel_args* args() const { return args_; }
+ channelz::SubchannelNode* channelz_subchannel() const {
return channelz_subchannel_.get();
}
- intptr_t socket_uuid() { return socket_uuid_; }
+ intptr_t socket_uuid() const { return socket_uuid_; }
size_t GetInitialCallSizeEstimate(size_t parent_data_size) const;
private:
grpc_channel_stack* channel_stack_;
+ grpc_channel_args* args_;
// ref counted pointer to the channelz node in this connected subchannel's
// owning subchannel.
grpc_core::RefCountedPtr<grpc_core::channelz::SubchannelNode>
diff --git a/src/core/ext/filters/client_channel/subchannel_index.cc b/src/core/ext/filters/client_channel/subchannel_index.cc
index 1c23a6c4be..aa8441f17b 100644
--- a/src/core/ext/filters/client_channel/subchannel_index.cc
+++ b/src/core/ext/filters/client_channel/subchannel_index.cc
@@ -91,7 +91,7 @@ void grpc_subchannel_key_destroy(grpc_subchannel_key* k) {
gpr_free(k);
}
-static void sck_avl_destroy(void* p, void* user_data) {
+static void sck_avl_destroy(void* p, void* unused) {
grpc_subchannel_key_destroy(static_cast<grpc_subchannel_key*>(p));
}
@@ -104,7 +104,7 @@ static long sck_avl_compare(void* a, void* b, void* unused) {
static_cast<grpc_subchannel_key*>(b));
}
-static void scv_avl_destroy(void* p, void* user_data) {
+static void scv_avl_destroy(void* p, void* unused) {
GRPC_SUBCHANNEL_WEAK_UNREF((grpc_subchannel*)p, "subchannel_index");
}
@@ -137,7 +137,7 @@ void grpc_subchannel_index_shutdown(void) {
void grpc_subchannel_index_unref(void) {
if (gpr_unref(&g_refcount)) {
gpr_mu_destroy(&g_mu);
- grpc_avl_unref(g_subchannel_index, grpc_core::ExecCtx::Get());
+ grpc_avl_unref(g_subchannel_index, nullptr);
}
}
@@ -147,13 +147,12 @@ grpc_subchannel* grpc_subchannel_index_find(grpc_subchannel_key* key) {
// Lock, and take a reference to the subchannel index.
// We don't need to do the search under a lock as avl's are immutable.
gpr_mu_lock(&g_mu);
- grpc_avl index = grpc_avl_ref(g_subchannel_index, grpc_core::ExecCtx::Get());
+ grpc_avl index = grpc_avl_ref(g_subchannel_index, nullptr);
gpr_mu_unlock(&g_mu);
grpc_subchannel* c = GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(
- (grpc_subchannel*)grpc_avl_get(index, key, grpc_core::ExecCtx::Get()),
- "index_find");
- grpc_avl_unref(index, grpc_core::ExecCtx::Get());
+ (grpc_subchannel*)grpc_avl_get(index, key, nullptr), "index_find");
+ grpc_avl_unref(index, nullptr);
return c;
}
@@ -169,13 +168,11 @@ grpc_subchannel* grpc_subchannel_index_register(grpc_subchannel_key* key,
// Compare and swap loop:
// - take a reference to the current index
gpr_mu_lock(&g_mu);
- grpc_avl index =
- grpc_avl_ref(g_subchannel_index, grpc_core::ExecCtx::Get());
+ grpc_avl index = grpc_avl_ref(g_subchannel_index, nullptr);
gpr_mu_unlock(&g_mu);
// - Check to see if a subchannel already exists
- c = static_cast<grpc_subchannel*>(
- grpc_avl_get(index, key, grpc_core::ExecCtx::Get()));
+ c = static_cast<grpc_subchannel*>(grpc_avl_get(index, key, nullptr));
if (c != nullptr) {
c = GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(c, "index_register");
}
@@ -184,11 +181,9 @@ grpc_subchannel* grpc_subchannel_index_register(grpc_subchannel_key* key,
need_to_unref_constructed = true;
} else {
// no -> update the avl and compare/swap
- grpc_avl updated =
- grpc_avl_add(grpc_avl_ref(index, grpc_core::ExecCtx::Get()),
- subchannel_key_copy(key),
- GRPC_SUBCHANNEL_WEAK_REF(constructed, "index_register"),
- grpc_core::ExecCtx::Get());
+ grpc_avl updated = grpc_avl_add(
+ grpc_avl_ref(index, nullptr), subchannel_key_copy(key),
+ GRPC_SUBCHANNEL_WEAK_REF(constructed, "index_register"), nullptr);
// it may happen (but it's expected to be unlikely)
// that some other thread has changed the index:
@@ -200,9 +195,9 @@ grpc_subchannel* grpc_subchannel_index_register(grpc_subchannel_key* key,
}
gpr_mu_unlock(&g_mu);
- grpc_avl_unref(updated, grpc_core::ExecCtx::Get());
+ grpc_avl_unref(updated, nullptr);
}
- grpc_avl_unref(index, grpc_core::ExecCtx::Get());
+ grpc_avl_unref(index, nullptr);
}
if (need_to_unref_constructed) {
@@ -219,24 +214,22 @@ void grpc_subchannel_index_unregister(grpc_subchannel_key* key,
// Compare and swap loop:
// - take a reference to the current index
gpr_mu_lock(&g_mu);
- grpc_avl index =
- grpc_avl_ref(g_subchannel_index, grpc_core::ExecCtx::Get());
+ grpc_avl index = grpc_avl_ref(g_subchannel_index, nullptr);
gpr_mu_unlock(&g_mu);
// Check to see if this key still refers to the previously
// registered subchannel
- grpc_subchannel* c = static_cast<grpc_subchannel*>(
- grpc_avl_get(index, key, grpc_core::ExecCtx::Get()));
+ grpc_subchannel* c =
+ static_cast<grpc_subchannel*>(grpc_avl_get(index, key, nullptr));
if (c != constructed) {
- grpc_avl_unref(index, grpc_core::ExecCtx::Get());
+ grpc_avl_unref(index, nullptr);
break;
}
// compare and swap the update (some other thread may have
// mutated the index behind us)
grpc_avl updated =
- grpc_avl_remove(grpc_avl_ref(index, grpc_core::ExecCtx::Get()), key,
- grpc_core::ExecCtx::Get());
+ grpc_avl_remove(grpc_avl_ref(index, nullptr), key, nullptr);
gpr_mu_lock(&g_mu);
if (index.root == g_subchannel_index.root) {
@@ -245,8 +238,8 @@ void grpc_subchannel_index_unregister(grpc_subchannel_key* key,
}
gpr_mu_unlock(&g_mu);
- grpc_avl_unref(updated, grpc_core::ExecCtx::Get());
- grpc_avl_unref(index, grpc_core::ExecCtx::Get());
+ grpc_avl_unref(updated, nullptr);
+ grpc_avl_unref(index, nullptr);
}
}
diff --git a/src/core/ext/transport/chttp2/client/chttp2_connector.cc b/src/core/ext/transport/chttp2/client/chttp2_connector.cc
index 60a32022f5..42a2e2e896 100644
--- a/src/core/ext/transport/chttp2/client/chttp2_connector.cc
+++ b/src/core/ext/transport/chttp2/client/chttp2_connector.cc
@@ -117,8 +117,9 @@ static void on_handshake_done(void* arg, grpc_error* error) {
c->args.interested_parties);
c->result->transport =
grpc_create_chttp2_transport(args->args, args->endpoint, true);
- c->result->socket_uuid =
- grpc_chttp2_transport_get_socket_uuid(c->result->transport);
+ grpc_core::RefCountedPtr<grpc_core::channelz::SocketNode> socket_node =
+ grpc_chttp2_transport_get_socket_node(c->result->transport);
+ c->result->socket_uuid = socket_node == nullptr ? 0 : socket_node->uuid();
GPR_ASSERT(c->result->transport);
// TODO(roth): We ideally want to wait until we receive HTTP/2
// settings from the server before we consider the connection
diff --git a/src/core/ext/transport/chttp2/server/chttp2_server.cc b/src/core/ext/transport/chttp2/server/chttp2_server.cc
index 33d2b22aa5..3d09187b9b 100644
--- a/src/core/ext/transport/chttp2/server/chttp2_server.cc
+++ b/src/core/ext/transport/chttp2/server/chttp2_server.cc
@@ -149,7 +149,7 @@ static void on_handshake_done(void* arg, grpc_error* error) {
grpc_server_setup_transport(
connection_state->svr_state->server, transport,
connection_state->accepting_pollset, args->args,
- grpc_chttp2_transport_get_socket_uuid(transport), resource_user);
+ grpc_chttp2_transport_get_socket_node(transport), resource_user);
// Use notify_on_receive_settings callback to enforce the
// handshake deadline.
connection_state->transport =
diff --git a/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc b/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc
index b9024a87e2..c29c1e58cd 100644
--- a/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc
+++ b/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc
@@ -61,7 +61,7 @@ void grpc_server_add_insecure_channel_from_fd(grpc_server* server,
grpc_endpoint_add_to_pollset(server_endpoint, pollsets[i]);
}
- grpc_server_setup_transport(server, transport, nullptr, server_args, 0);
+ grpc_server_setup_transport(server, transport, nullptr, server_args, nullptr);
grpc_chttp2_transport_start_reading(transport, nullptr, nullptr);
}
diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc
index 7377287e8c..9b6574b612 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc
+++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc
@@ -3145,14 +3145,11 @@ static const grpc_transport_vtable vtable = {sizeof(grpc_chttp2_stream),
static const grpc_transport_vtable* get_vtable(void) { return &vtable; }
-intptr_t grpc_chttp2_transport_get_socket_uuid(grpc_transport* transport) {
+grpc_core::RefCountedPtr<grpc_core::channelz::SocketNode>
+grpc_chttp2_transport_get_socket_node(grpc_transport* transport) {
grpc_chttp2_transport* t =
reinterpret_cast<grpc_chttp2_transport*>(transport);
- if (t->channelz_socket != nullptr) {
- return t->channelz_socket->uuid();
- } else {
- return 0;
- }
+ return t->channelz_socket;
}
grpc_transport* grpc_create_chttp2_transport(
diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.h b/src/core/ext/transport/chttp2/transport/chttp2_transport.h
index b3fe1c082e..c22cfb0ad7 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_transport.h
+++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.h
@@ -21,6 +21,7 @@
#include <grpc/support/port_platform.h>
+#include "src/core/lib/channel/channelz.h"
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/iomgr/endpoint.h"
#include "src/core/lib/transport/transport.h"
@@ -35,7 +36,8 @@ grpc_transport* grpc_create_chttp2_transport(
const grpc_channel_args* channel_args, grpc_endpoint* ep, bool is_client,
grpc_resource_user* resource_user = nullptr);
-intptr_t grpc_chttp2_transport_get_socket_uuid(grpc_transport* transport);
+grpc_core::RefCountedPtr<grpc_core::channelz::SocketNode>
+grpc_chttp2_transport_get_socket_node(grpc_transport* transport);
/// Takes ownership of \a read_buffer, which (if non-NULL) contains
/// leftover bytes previously read from the endpoint (e.g., by handshakers).
diff --git a/src/core/ext/transport/inproc/inproc_transport.cc b/src/core/ext/transport/inproc/inproc_transport.cc
index 61968de4d5..0b9bf5dd11 100644
--- a/src/core/ext/transport/inproc/inproc_transport.cc
+++ b/src/core/ext/transport/inproc/inproc_transport.cc
@@ -1236,7 +1236,7 @@ grpc_channel* grpc_inproc_channel_create(grpc_server* server,
// TODO(ncteisen): design and support channelz GetSocket for inproc.
grpc_server_setup_transport(server, server_transport, nullptr, server_args,
- 0);
+ nullptr);
grpc_channel* channel = grpc_channel_create(
"inproc", client_args, GRPC_CLIENT_DIRECT_CHANNEL, client_transport);
diff --git a/src/core/lib/channel/channelz.cc b/src/core/lib/channel/channelz.cc
index 8d589f5983..8a596ad460 100644
--- a/src/core/lib/channel/channelz.cc
+++ b/src/core/lib/channel/channelz.cc
@@ -203,33 +203,34 @@ ServerNode::ServerNode(grpc_server* server, size_t channel_tracer_max_nodes)
ServerNode::~ServerNode() {}
-char* ServerNode::RenderServerSockets(intptr_t start_socket_id) {
+char* ServerNode::RenderServerSockets(intptr_t start_socket_id,
+ intptr_t max_results) {
+ // if user does not set max_results, we choose 500.
+ size_t pagination_limit = max_results == 0 ? 500 : max_results;
grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT);
grpc_json* json = top_level_json;
grpc_json* json_iterator = nullptr;
- ChildRefsList socket_refs;
- // uuids index into entities one-off (idx 0 is really uuid 1, since 0 is
- // reserved). However, we want to support requests coming in with
- // start_server_id=0, which signifies "give me everything."
- size_t start_idx = start_socket_id == 0 ? 0 : start_socket_id - 1;
- grpc_server_populate_server_sockets(server_, &socket_refs, start_idx);
+ ChildSocketsList socket_refs;
+ grpc_server_populate_server_sockets(server_, &socket_refs, start_socket_id);
+ // declared early so it can be used outside of the loop.
+ size_t i = 0;
if (!socket_refs.empty()) {
// create list of socket refs
grpc_json* array_parent = grpc_json_create_child(
nullptr, json, "socketRef", nullptr, GRPC_JSON_ARRAY, false);
- for (size_t i = 0; i < socket_refs.size(); ++i) {
- json_iterator =
- grpc_json_create_child(json_iterator, array_parent, nullptr, nullptr,
- GRPC_JSON_OBJECT, false);
- grpc_json_add_number_string_child(json_iterator, nullptr, "socketId",
- socket_refs[i]);
+ for (i = 0; i < GPR_MIN(socket_refs.size(), pagination_limit); ++i) {
+ grpc_json* socket_ref_json = grpc_json_create_child(
+ nullptr, array_parent, nullptr, nullptr, GRPC_JSON_OBJECT, false);
+ json_iterator = grpc_json_add_number_string_child(
+ socket_ref_json, nullptr, "socketId", socket_refs[i]->uuid());
+ grpc_json_create_child(json_iterator, socket_ref_json, "name",
+ socket_refs[i]->remote(), GRPC_JSON_STRING, false);
}
}
- // For now we do not have any pagination rules. In the future we could
- // pick a constant for max_channels_sent for a GetServers request.
- // Tracking: https://github.com/grpc/grpc/issues/16019.
- json_iterator = grpc_json_create_child(nullptr, json, "end", nullptr,
- GRPC_JSON_TRUE, false);
+ if (i == socket_refs.size()) {
+ json_iterator = grpc_json_create_child(nullptr, json, "end", nullptr,
+ GRPC_JSON_TRUE, false);
+ }
char* json_str = grpc_json_dump_to_string(top_level_json, 0);
grpc_json_destroy(top_level_json);
return json_str;
diff --git a/src/core/lib/channel/channelz.h b/src/core/lib/channel/channelz.h
index 64ab5cb3a6..e43792126f 100644
--- a/src/core/lib/channel/channelz.h
+++ b/src/core/lib/channel/channelz.h
@@ -59,6 +59,9 @@ namespace channelz {
// add human readable names as in the channelz.proto
typedef InlinedVector<intptr_t, 10> ChildRefsList;
+class SocketNode;
+typedef InlinedVector<SocketNode*, 10> ChildSocketsList;
+
namespace testing {
class CallCountingHelperPeer;
class ChannelNodePeer;
@@ -207,7 +210,8 @@ class ServerNode : public BaseNode {
grpc_json* RenderJson() override;
- char* RenderServerSockets(intptr_t start_socket_id);
+ char* RenderServerSockets(intptr_t start_socket_id,
+ intptr_t pagination_limit);
// proxy methods to composed classes.
void AddTraceEvent(ChannelTrace::Severity severity, grpc_slice data) {
@@ -251,6 +255,8 @@ class SocketNode : public BaseNode {
gpr_atm_no_barrier_fetch_add(&keepalives_sent_, static_cast<gpr_atm>(1));
}
+ const char* remote() { return remote_.get(); }
+
private:
gpr_atm streams_started_ = 0;
gpr_atm streams_succeeded_ = 0;
diff --git a/src/core/lib/channel/channelz_registry.cc b/src/core/lib/channel/channelz_registry.cc
index bc23b90a66..7cca247d64 100644
--- a/src/core/lib/channel/channelz_registry.cc
+++ b/src/core/lib/channel/channelz_registry.cc
@@ -252,7 +252,8 @@ char* grpc_channelz_get_server(intptr_t server_id) {
}
char* grpc_channelz_get_server_sockets(intptr_t server_id,
- intptr_t start_socket_id) {
+ intptr_t start_socket_id,
+ intptr_t max_results) {
grpc_core::channelz::BaseNode* base_node =
grpc_core::channelz::ChannelzRegistry::Get(server_id);
if (base_node == nullptr ||
@@ -263,7 +264,7 @@ char* grpc_channelz_get_server_sockets(intptr_t server_id,
// actually a server node
grpc_core::channelz::ServerNode* server_node =
static_cast<grpc_core::channelz::ServerNode*>(base_node);
- return server_node->RenderServerSockets(start_socket_id);
+ return server_node->RenderServerSockets(start_socket_id, max_results);
}
char* grpc_channelz_get_channel(intptr_t channel_id) {
diff --git a/src/core/lib/debug/trace.cc b/src/core/lib/debug/trace.cc
index 01c1e867d9..cafdb15c69 100644
--- a/src/core/lib/debug/trace.cc
+++ b/src/core/lib/debug/trace.cc
@@ -21,6 +21,7 @@
#include "src/core/lib/debug/trace.h"
#include <string.h>
+#include <type_traits>
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
@@ -79,6 +80,8 @@ void TraceFlagList::LogAllTracers() {
// Flags register themselves on the list during construction
TraceFlag::TraceFlag(bool default_enabled, const char* name) : name_(name) {
+ static_assert(std::is_trivially_destructible<TraceFlag>::value,
+ "TraceFlag needs to be trivially destructible.");
set_enabled(default_enabled);
TraceFlagList::Add(this);
}
diff --git a/src/core/lib/debug/trace.h b/src/core/lib/debug/trace.h
index 5ed52454bd..4623494520 100644
--- a/src/core/lib/debug/trace.h
+++ b/src/core/lib/debug/trace.h
@@ -53,7 +53,8 @@ void grpc_tracer_enable_flag(grpc_core::TraceFlag* flag);
class TraceFlag {
public:
TraceFlag(bool default_enabled, const char* name);
- ~TraceFlag() {}
+ // This needs to be trivially destructible as it is used as global variable.
+ ~TraceFlag() = default;
const char* name() const { return name_; }
diff --git a/src/core/lib/gpr/sync_posix.cc b/src/core/lib/gpr/sync_posix.cc
index 69bd609485..c09a7598ac 100644
--- a/src/core/lib/gpr/sync_posix.cc
+++ b/src/core/lib/gpr/sync_posix.cc
@@ -30,11 +30,18 @@
// For debug of the timer manager crash only.
// TODO (mxyan): remove after bug is fixed.
#ifdef GRPC_DEBUG_TIMER_MANAGER
+#include <string.h>
void (*g_grpc_debug_timer_manager_stats)(
int64_t timer_manager_init_count, int64_t timer_manager_shutdown_count,
int64_t fork_count, int64_t timer_wait_err, int64_t timer_cv_value,
int64_t timer_mu_value, int64_t abstime_sec_value,
- int64_t abstime_nsec_value) = nullptr;
+ int64_t abstime_nsec_value, int64_t abs_deadline_sec_value,
+ int64_t abs_deadline_nsec_value, int64_t now1_sec_value,
+ int64_t now1_nsec_value, int64_t now2_sec_value, int64_t now2_nsec_value,
+ int64_t add_result_sec_value, int64_t add_result_nsec_value,
+ int64_t sub_result_sec_value, int64_t sub_result_nsec_value,
+ int64_t next_value, int64_t start_time_sec,
+ int64_t start_time_nsec) = nullptr;
int64_t g_timer_manager_init_count = 0;
int64_t g_timer_manager_shutdown_count = 0;
int64_t g_fork_count = 0;
@@ -43,6 +50,19 @@ int64_t g_timer_cv_value = 0;
int64_t g_timer_mu_value = 0;
int64_t g_abstime_sec_value = -1;
int64_t g_abstime_nsec_value = -1;
+int64_t g_abs_deadline_sec_value = -1;
+int64_t g_abs_deadline_nsec_value = -1;
+int64_t g_now1_sec_value = -1;
+int64_t g_now1_nsec_value = -1;
+int64_t g_now2_sec_value = -1;
+int64_t g_now2_nsec_value = -1;
+int64_t g_add_result_sec_value = -1;
+int64_t g_add_result_nsec_value = -1;
+int64_t g_sub_result_sec_value = -1;
+int64_t g_sub_result_nsec_value = -1;
+int64_t g_next_value = -1;
+int64_t g_start_time_sec = -1;
+int64_t g_start_time_nsec = -1;
#endif // GRPC_DEBUG_TIMER_MANAGER
#ifdef GPR_LOW_LEVEL_COUNTERS
@@ -90,17 +110,74 @@ void gpr_cv_init(gpr_cv* cv) {
void gpr_cv_destroy(gpr_cv* cv) { GPR_ASSERT(pthread_cond_destroy(cv) == 0); }
+// For debug of the timer manager crash only.
+// TODO (mxyan): remove after bug is fixed.
+#ifdef GRPC_DEBUG_TIMER_MANAGER
+static gpr_timespec gpr_convert_clock_type_debug_timespec(
+ gpr_timespec t, gpr_clock_type clock_type, gpr_timespec& now1,
+ gpr_timespec& now2, gpr_timespec& add_result, gpr_timespec& sub_result) {
+ if (t.clock_type == clock_type) {
+ return t;
+ }
+
+ if (t.tv_sec == INT64_MAX || t.tv_sec == INT64_MIN) {
+ t.clock_type = clock_type;
+ return t;
+ }
+
+ if (clock_type == GPR_TIMESPAN) {
+ return gpr_time_sub(t, gpr_now(t.clock_type));
+ }
+
+ if (t.clock_type == GPR_TIMESPAN) {
+ return gpr_time_add(gpr_now(clock_type), t);
+ }
+
+ now1 = gpr_now(t.clock_type);
+ sub_result = gpr_time_sub(t, now1);
+ now2 = gpr_now(clock_type);
+ add_result = gpr_time_add(now2, sub_result);
+ return add_result;
+}
+
+#define gpr_convert_clock_type_debug(t, clock_type, now1, now2, add_result, \
+ sub_result) \
+ gpr_convert_clock_type_debug_timespec((t), (clock_type), (now1), (now2), \
+ (add_result), (sub_result))
+#else
+#define gpr_convert_clock_type_debug(t, clock_type, now1, now2, add_result, \
+ sub_result) \
+ gpr_convert_clock_type((t), (clock_type))
+#endif
+
int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) {
int err = 0;
+#ifdef GRPC_DEBUG_TIMER_MANAGER
+ // For debug of the timer manager crash only.
+ // TODO (mxyan): remove after bug is fixed.
+ gpr_timespec abs_deadline_copy;
+ abs_deadline_copy.tv_sec = abs_deadline.tv_sec;
+ abs_deadline_copy.tv_nsec = abs_deadline.tv_nsec;
+ gpr_timespec now1;
+ gpr_timespec now2;
+ gpr_timespec add_result;
+ gpr_timespec sub_result;
+ memset(&now1, 0, sizeof(now1));
+ memset(&now2, 0, sizeof(now2));
+ memset(&add_result, 0, sizeof(add_result));
+ memset(&sub_result, 0, sizeof(sub_result));
+#endif
if (gpr_time_cmp(abs_deadline, gpr_inf_future(abs_deadline.clock_type)) ==
0) {
err = pthread_cond_wait(cv, mu);
} else {
struct timespec abs_deadline_ts;
#if GPR_LINUX
- abs_deadline = gpr_convert_clock_type(abs_deadline, GPR_CLOCK_MONOTONIC);
+ abs_deadline = gpr_convert_clock_type_debug(
+ abs_deadline, GPR_CLOCK_MONOTONIC, now1, now2, add_result, sub_result);
#else
- abs_deadline = gpr_convert_clock_type(abs_deadline, GPR_CLOCK_REALTIME);
+ abs_deadline = gpr_convert_clock_type_debug(
+ abs_deadline, GPR_CLOCK_REALTIME, now1, now2, add_result, sub_result);
#endif // GPR_LINUX
abs_deadline_ts.tv_sec = static_cast<time_t>(abs_deadline.tv_sec);
abs_deadline_ts.tv_nsec = abs_deadline.tv_nsec;
@@ -123,10 +200,25 @@ int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) {
g_timer_wait_err = err;
g_timer_cv_value = (int64_t)cv;
g_timer_mu_value = (int64_t)mu;
+ g_abs_deadline_sec_value = abs_deadline_copy.tv_sec;
+ g_abs_deadline_nsec_value = abs_deadline_copy.tv_nsec;
+ g_now1_sec_value = now1.tv_sec;
+ g_now1_nsec_value = now1.tv_nsec;
+ g_now2_sec_value = now2.tv_sec;
+ g_now2_nsec_value = now2.tv_nsec;
+ g_add_result_sec_value = add_result.tv_sec;
+ g_add_result_nsec_value = add_result.tv_nsec;
+ g_sub_result_sec_value = sub_result.tv_sec;
+ g_sub_result_nsec_value = sub_result.tv_nsec;
g_grpc_debug_timer_manager_stats(
g_timer_manager_init_count, g_timer_manager_shutdown_count,
g_fork_count, g_timer_wait_err, g_timer_cv_value, g_timer_mu_value,
- g_abstime_sec_value, g_abstime_nsec_value);
+ g_abstime_sec_value, g_abstime_nsec_value, g_abs_deadline_sec_value,
+ g_abs_deadline_nsec_value, g_now1_sec_value, g_now1_nsec_value,
+ g_now2_sec_value, g_now2_nsec_value, g_add_result_sec_value,
+ g_add_result_nsec_value, g_sub_result_sec_value,
+ g_sub_result_nsec_value, g_next_value, g_start_time_sec,
+ g_start_time_nsec);
}
}
#endif
diff --git a/src/core/lib/iomgr/call_combiner.cc b/src/core/lib/iomgr/call_combiner.cc
index 90dda45ba3..6b5759a036 100644
--- a/src/core/lib/iomgr/call_combiner.cc
+++ b/src/core/lib/iomgr/call_combiner.cc
@@ -39,10 +39,57 @@ static gpr_atm encode_cancel_state_error(grpc_error* error) {
return static_cast<gpr_atm>(1) | (gpr_atm)error;
}
+#ifdef GRPC_TSAN_ENABLED
+static void tsan_closure(void* user_data, grpc_error* error) {
+ grpc_call_combiner* call_combiner =
+ static_cast<grpc_call_combiner*>(user_data);
+ // We ref-count the lock, and check if it's already taken.
+ // If it was taken, we should do nothing. Otherwise, we will mark it as
+ // locked. Note that if two different threads try to do this, only one of
+ // them will be able to mark the lock as acquired, while they both run their
+ // callbacks. In such cases (which should never happen for call_combiner),
+ // TSAN will correctly produce an error.
+ //
+ // TODO(soheil): This only covers the callbacks scheduled by
+ // grpc_call_combiner_(start|finish). If in the future, a
+ // callback gets scheduled using other mechanisms, we will need
+ // to add APIs to externally lock call combiners.
+ grpc_core::RefCountedPtr<grpc_call_combiner::TsanLock> lock =
+ call_combiner->tsan_lock;
+ bool prev = false;
+ if (lock->taken.compare_exchange_strong(prev, true)) {
+ TSAN_ANNOTATE_RWLOCK_ACQUIRED(&lock->taken, true);
+ } else {
+ lock.reset();
+ }
+ GRPC_CLOSURE_RUN(call_combiner->original_closure, GRPC_ERROR_REF(error));
+ if (lock != nullptr) {
+ TSAN_ANNOTATE_RWLOCK_RELEASED(&lock->taken, true);
+ bool prev = true;
+ GPR_ASSERT(lock->taken.compare_exchange_strong(prev, false));
+ }
+}
+#endif
+
+static void call_combiner_sched_closure(grpc_call_combiner* call_combiner,
+ grpc_closure* closure,
+ grpc_error* error) {
+#ifdef GRPC_TSAN_ENABLED
+ call_combiner->original_closure = closure;
+ GRPC_CLOSURE_SCHED(&call_combiner->tsan_closure, error);
+#else
+ GRPC_CLOSURE_SCHED(closure, error);
+#endif
+}
+
void grpc_call_combiner_init(grpc_call_combiner* call_combiner) {
gpr_atm_no_barrier_store(&call_combiner->cancel_state, 0);
gpr_atm_no_barrier_store(&call_combiner->size, 0);
gpr_mpscq_init(&call_combiner->queue);
+#ifdef GRPC_TSAN_ENABLED
+ GRPC_CLOSURE_INIT(&call_combiner->tsan_closure, tsan_closure, call_combiner,
+ grpc_schedule_on_exec_ctx);
+#endif
}
void grpc_call_combiner_destroy(grpc_call_combiner* call_combiner) {
@@ -87,7 +134,7 @@ void grpc_call_combiner_start(grpc_call_combiner* call_combiner,
gpr_log(GPR_INFO, " EXECUTING IMMEDIATELY");
}
// Queue was empty, so execute this closure immediately.
- GRPC_CLOSURE_SCHED(closure, error);
+ call_combiner_sched_closure(call_combiner, closure, error);
} else {
if (grpc_call_combiner_trace.enabled()) {
gpr_log(GPR_INFO, " QUEUING");
@@ -134,7 +181,8 @@ void grpc_call_combiner_stop(grpc_call_combiner* call_combiner DEBUG_ARGS,
gpr_log(GPR_INFO, " EXECUTING FROM QUEUE: closure=%p error=%s",
closure, grpc_error_string(closure->error_data.error));
}
- GRPC_CLOSURE_SCHED(closure, closure->error_data.error);
+ call_combiner_sched_closure(call_combiner, closure,
+ closure->error_data.error);
break;
}
} else if (grpc_call_combiner_trace.enabled()) {
diff --git a/src/core/lib/iomgr/call_combiner.h b/src/core/lib/iomgr/call_combiner.h
index c943fb1557..4ec0044f05 100644
--- a/src/core/lib/iomgr/call_combiner.h
+++ b/src/core/lib/iomgr/call_combiner.h
@@ -27,7 +27,10 @@
#include "src/core/lib/gpr/mpscq.h"
#include "src/core/lib/gprpp/inlined_vector.h"
+#include "src/core/lib/gprpp/ref_counted.h"
+#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/iomgr/closure.h"
+#include "src/core/lib/iomgr/dynamic_annotations.h"
// A simple, lock-free mechanism for serializing activity related to a
// single call. This is similar to a combiner but is more lightweight.
@@ -40,14 +43,38 @@
extern grpc_core::TraceFlag grpc_call_combiner_trace;
-typedef struct {
+struct grpc_call_combiner {
gpr_atm size = 0; // size_t, num closures in queue or currently executing
gpr_mpscq queue;
// Either 0 (if not cancelled and no cancellation closure set),
// a grpc_closure* (if the lowest bit is 0),
// or a grpc_error* (if the lowest bit is 1).
gpr_atm cancel_state = 0;
-} grpc_call_combiner;
+#ifdef GRPC_TSAN_ENABLED
+ // A fake ref-counted lock that is kept alive after the destruction of
+ // grpc_call_combiner, when we are running the original closure.
+ //
+ // Ideally we want to lock and unlock the call combiner as a pointer, when the
+ // callback is called. However, original_closure is free to trigger
+ // anything on the call combiner (including destruction of grpc_call).
+ // Thus, we need a ref-counted structure that can outlive the call combiner.
+ struct TsanLock
+ : public grpc_core::RefCounted<TsanLock,
+ grpc_core::NonPolymorphicRefCount> {
+ TsanLock() { TSAN_ANNOTATE_RWLOCK_CREATE(&taken); }
+ ~TsanLock() { TSAN_ANNOTATE_RWLOCK_DESTROY(&taken); }
+
+ // To avoid double-locking by the same thread, we should acquire/release
+ // the lock only when taken is false. On each acquire taken must be set to
+ // true.
+ std::atomic<bool> taken{false};
+ };
+ grpc_core::RefCountedPtr<TsanLock> tsan_lock =
+ grpc_core::MakeRefCounted<TsanLock>();
+ grpc_closure tsan_closure;
+ grpc_closure* original_closure;
+#endif
+};
// Assumes memory was initialized to zero.
void grpc_call_combiner_init(grpc_call_combiner* call_combiner);
diff --git a/src/core/lib/iomgr/dynamic_annotations.h b/src/core/lib/iomgr/dynamic_annotations.h
new file mode 100644
index 0000000000..713928023a
--- /dev/null
+++ b/src/core/lib/iomgr/dynamic_annotations.h
@@ -0,0 +1,67 @@
+/*
+ *
+ * Copyright 2018 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPC_CORE_LIB_IOMGR_DYNAMIC_ANNOTATIONS_H
+#define GRPC_CORE_LIB_IOMGR_DYNAMIC_ANNOTATIONS_H
+
+#include <grpc/support/port_platform.h>
+
+#ifdef GRPC_TSAN_ENABLED
+
+#define TSAN_ANNOTATE_HAPPENS_BEFORE(addr) \
+ AnnotateHappensBefore(__FILE__, __LINE__, (void*)(addr))
+#define TSAN_ANNOTATE_HAPPENS_AFTER(addr) \
+ AnnotateHappensAfter(__FILE__, __LINE__, (void*)(addr))
+#define TSAN_ANNOTATE_RWLOCK_CREATE(addr) \
+ AnnotateRWLockCreate(__FILE__, __LINE__, (void*)(addr))
+#define TSAN_ANNOTATE_RWLOCK_DESTROY(addr) \
+ AnnotateRWLockDestroy(__FILE__, __LINE__, (void*)(addr))
+#define TSAN_ANNOTATE_RWLOCK_ACQUIRED(addr, is_w) \
+ AnnotateRWLockAcquired(__FILE__, __LINE__, (void*)(addr), (is_w))
+#define TSAN_ANNOTATE_RWLOCK_RELEASED(addr, is_w) \
+ AnnotateRWLockReleased(__FILE__, __LINE__, (void*)(addr), (is_w))
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+void AnnotateHappensBefore(const char* file, int line, const volatile void* cv);
+void AnnotateHappensAfter(const char* file, int line, const volatile void* cv);
+void AnnotateRWLockCreate(const char* file, int line,
+ const volatile void* lock);
+void AnnotateRWLockDestroy(const char* file, int line,
+ const volatile void* lock);
+void AnnotateRWLockAcquired(const char* file, int line,
+ const volatile void* lock, long is_w);
+void AnnotateRWLockReleased(const char* file, int line,
+ const volatile void* lock, long is_w);
+#ifdef __cplusplus
+}
+#endif
+
+#else /* GRPC_TSAN_ENABLED */
+
+#define TSAN_ANNOTATE_HAPPENS_BEFORE(addr)
+#define TSAN_ANNOTATE_HAPPENS_AFTER(addr)
+#define TSAN_ANNOTATE_RWLOCK_CREATE(addr)
+#define TSAN_ANNOTATE_RWLOCK_DESTROY(addr)
+#define TSAN_ANNOTATE_RWLOCK_ACQUIRED(addr, is_w)
+#define TSAN_ANNOTATE_RWLOCK_RELEASED(addr, is_w)
+
+#endif /* GRPC_TSAN_ENABLED */
+
+#endif /* GRPC_CORE_LIB_IOMGR_DYNAMIC_ANNOTATIONS_H */
diff --git a/src/core/lib/iomgr/exec_ctx.cc b/src/core/lib/iomgr/exec_ctx.cc
index d68fa0714b..683dd2f649 100644
--- a/src/core/lib/iomgr/exec_ctx.cc
+++ b/src/core/lib/iomgr/exec_ctx.cc
@@ -53,6 +53,13 @@ static void exec_ctx_sched(grpc_closure* closure, grpc_error* error) {
static gpr_timespec g_start_time;
+// For debug of the timer manager crash only.
+// TODO (mxyan): remove after bug is fixed.
+#ifdef GRPC_DEBUG_TIMER_MANAGER
+extern int64_t g_start_time_sec;
+extern int64_t g_start_time_nsec;
+#endif // GRPC_DEBUG_TIMER_MANAGER
+
static grpc_millis timespec_to_millis_round_down(gpr_timespec ts) {
ts = gpr_time_sub(ts, g_start_time);
double x = GPR_MS_PER_SEC * static_cast<double>(ts.tv_sec) +
@@ -117,6 +124,12 @@ void ExecCtx::TestOnlyGlobalInit(gpr_timespec new_val) {
void ExecCtx::GlobalInit(void) {
g_start_time = gpr_now(GPR_CLOCK_MONOTONIC);
+ // For debug of the timer manager crash only.
+ // TODO (mxyan): remove after bug is fixed.
+#ifdef GRPC_DEBUG_TIMER_MANAGER
+ g_start_time_sec = g_start_time.tv_sec;
+ g_start_time_nsec = g_start_time.tv_nsec;
+#endif
gpr_tls_init(&exec_ctx_);
}
diff --git a/src/core/lib/iomgr/sockaddr_utils.cc b/src/core/lib/iomgr/sockaddr_utils.cc
index 1b66dceb13..0839bdfef2 100644
--- a/src/core/lib/iomgr/sockaddr_utils.cc
+++ b/src/core/lib/iomgr/sockaddr_utils.cc
@@ -217,6 +217,7 @@ void grpc_string_to_sockaddr(grpc_resolved_address* out, char* addr, int port) {
}
char* grpc_sockaddr_to_uri(const grpc_resolved_address* resolved_addr) {
+ if (resolved_addr->len == 0) return nullptr;
grpc_resolved_address addr_normalized;
if (grpc_sockaddr_is_v4mapped(resolved_addr, &addr_normalized)) {
resolved_addr = &addr_normalized;
diff --git a/src/core/lib/iomgr/tcp_windows.cc b/src/core/lib/iomgr/tcp_windows.cc
index 4b5250803d..86ee1010cf 100644
--- a/src/core/lib/iomgr/tcp_windows.cc
+++ b/src/core/lib/iomgr/tcp_windows.cc
@@ -42,6 +42,7 @@
#include "src/core/lib/iomgr/tcp_windows.h"
#include "src/core/lib/iomgr/timer.h"
#include "src/core/lib/slice/slice_internal.h"
+#include "src/core/lib/slice/slice_string_helpers.h"
#if defined(__MSYS__) && defined(GPR_ARCH_64)
/* Nasty workaround for nasty bug when using the 64 bits msys compiler
@@ -112,7 +113,10 @@ typedef struct grpc_tcp {
grpc_closure* read_cb;
grpc_closure* write_cb;
- grpc_slice read_slice;
+
+ /* garbage after the last read */
+ grpc_slice_buffer last_read_buffer;
+
grpc_slice_buffer* write_slices;
grpc_slice_buffer* read_slices;
@@ -131,6 +135,7 @@ static void tcp_free(grpc_tcp* tcp) {
grpc_winsocket_destroy(tcp->socket);
gpr_mu_destroy(&tcp->mu);
gpr_free(tcp->peer_string);
+ grpc_slice_buffer_destroy_internal(&tcp->last_read_buffer);
grpc_resource_user_unref(tcp->resource_user);
if (tcp->shutting_down) GRPC_ERROR_UNREF(tcp->shutdown_error);
gpr_free(tcp);
@@ -179,9 +184,12 @@ static void on_read(void* tcpp, grpc_error* error) {
grpc_tcp* tcp = (grpc_tcp*)tcpp;
grpc_closure* cb = tcp->read_cb;
grpc_winsocket* socket = tcp->socket;
- grpc_slice sub;
grpc_winsocket_callback_info* info = &socket->read_info;
+ if (grpc_tcp_trace.enabled()) {
+ gpr_log(GPR_INFO, "TCP:%p on_read", tcp);
+ }
+
GRPC_ERROR_REF(error);
if (error == GRPC_ERROR_NONE) {
@@ -189,13 +197,35 @@ static void on_read(void* tcpp, grpc_error* error) {
char* utf8_message = gpr_format_message(info->wsa_error);
error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(utf8_message);
gpr_free(utf8_message);
- grpc_slice_unref_internal(tcp->read_slice);
+ grpc_slice_buffer_reset_and_unref_internal(tcp->read_slices);
} else {
if (info->bytes_transfered != 0 && !tcp->shutting_down) {
- sub = grpc_slice_sub_no_ref(tcp->read_slice, 0, info->bytes_transfered);
- grpc_slice_buffer_add(tcp->read_slices, sub);
+ GPR_ASSERT((size_t)info->bytes_transfered <= tcp->read_slices->length);
+ if (static_cast<size_t>(info->bytes_transfered) !=
+ tcp->read_slices->length) {
+ grpc_slice_buffer_trim_end(
+ tcp->read_slices,
+ tcp->read_slices->length -
+ static_cast<size_t>(info->bytes_transfered),
+ &tcp->last_read_buffer);
+ }
+ GPR_ASSERT((size_t)info->bytes_transfered == tcp->read_slices->length);
+
+ if (grpc_tcp_trace.enabled()) {
+ size_t i;
+ for (i = 0; i < tcp->read_slices->count; i++) {
+ char* dump = grpc_dump_slice(tcp->read_slices->slices[i],
+ GPR_DUMP_HEX | GPR_DUMP_ASCII);
+ gpr_log(GPR_INFO, "READ %p (peer=%s): %s", tcp, tcp->peer_string,
+ dump);
+ gpr_free(dump);
+ }
+ }
} else {
- grpc_slice_unref_internal(tcp->read_slice);
+ if (grpc_tcp_trace.enabled()) {
+ gpr_log(GPR_INFO, "TCP:%p unref read_slice", tcp);
+ }
+ grpc_slice_buffer_reset_and_unref_internal(tcp->read_slices);
error = tcp->shutting_down
? GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
"TCP stream shutting down", &tcp->shutdown_error, 1)
@@ -209,6 +239,8 @@ static void on_read(void* tcpp, grpc_error* error) {
GRPC_CLOSURE_SCHED(cb, error);
}
+#define DEFAULT_TARGET_READ_SIZE 8192
+#define MAX_WSABUF_COUNT 16
static void win_read(grpc_endpoint* ep, grpc_slice_buffer* read_slices,
grpc_closure* cb) {
grpc_tcp* tcp = (grpc_tcp*)ep;
@@ -217,7 +249,12 @@ static void win_read(grpc_endpoint* ep, grpc_slice_buffer* read_slices,
int status;
DWORD bytes_read = 0;
DWORD flags = 0;
- WSABUF buffer;
+ WSABUF buffers[MAX_WSABUF_COUNT];
+ size_t i;
+
+ if (grpc_tcp_trace.enabled()) {
+ gpr_log(GPR_INFO, "TCP:%p win_read", tcp);
+ }
if (tcp->shutting_down) {
GRPC_CLOSURE_SCHED(
@@ -229,18 +266,27 @@ static void win_read(grpc_endpoint* ep, grpc_slice_buffer* read_slices,
tcp->read_cb = cb;
tcp->read_slices = read_slices;
grpc_slice_buffer_reset_and_unref_internal(read_slices);
+ grpc_slice_buffer_swap(read_slices, &tcp->last_read_buffer);
- tcp->read_slice = GRPC_SLICE_MALLOC(8192);
+ if (tcp->read_slices->length < DEFAULT_TARGET_READ_SIZE / 2 &&
+ tcp->read_slices->count < MAX_WSABUF_COUNT) {
+ // TODO(jtattermusch): slice should be allocated using resource quota
+ grpc_slice_buffer_add(tcp->read_slices,
+ GRPC_SLICE_MALLOC(DEFAULT_TARGET_READ_SIZE));
+ }
- buffer.len = (ULONG)GRPC_SLICE_LENGTH(
- tcp->read_slice); // we know slice size fits in 32bit.
- buffer.buf = (char*)GRPC_SLICE_START_PTR(tcp->read_slice);
+ GPR_ASSERT(tcp->read_slices->count <= MAX_WSABUF_COUNT);
+ for (i = 0; i < tcp->read_slices->count; i++) {
+ buffers[i].len = (ULONG)GRPC_SLICE_LENGTH(
+ tcp->read_slices->slices[i]); // we know slice size fits in 32bit.
+ buffers[i].buf = (char*)GRPC_SLICE_START_PTR(tcp->read_slices->slices[i]);
+ }
TCP_REF(tcp, "read");
/* First let's try a synchronous, non-blocking read. */
- status =
- WSARecv(tcp->socket->socket, &buffer, 1, &bytes_read, &flags, NULL, NULL);
+ status = WSARecv(tcp->socket->socket, buffers, (DWORD)tcp->read_slices->count,
+ &bytes_read, &flags, NULL, NULL);
info->wsa_error = status == 0 ? 0 : WSAGetLastError();
/* Did we get data immediately ? Yay. */
@@ -252,8 +298,8 @@ static void win_read(grpc_endpoint* ep, grpc_slice_buffer* read_slices,
/* Otherwise, let's retry, by queuing a read. */
memset(&tcp->socket->read_info.overlapped, 0, sizeof(OVERLAPPED));
- status = WSARecv(tcp->socket->socket, &buffer, 1, &bytes_read, &flags,
- &info->overlapped, NULL);
+ status = WSARecv(tcp->socket->socket, buffers, (DWORD)tcp->read_slices->count,
+ &bytes_read, &flags, &info->overlapped, NULL);
if (status != 0) {
int wsa_error = WSAGetLastError();
@@ -275,6 +321,10 @@ static void on_write(void* tcpp, grpc_error* error) {
grpc_winsocket_callback_info* info = &handle->write_info;
grpc_closure* cb;
+ if (grpc_tcp_trace.enabled()) {
+ gpr_log(GPR_INFO, "TCP:%p on_write", tcp);
+ }
+
GRPC_ERROR_REF(error);
gpr_mu_lock(&tcp->mu);
@@ -303,11 +353,21 @@ static void win_write(grpc_endpoint* ep, grpc_slice_buffer* slices,
unsigned i;
DWORD bytes_sent;
int status;
- WSABUF local_buffers[16];
+ WSABUF local_buffers[MAX_WSABUF_COUNT];
WSABUF* allocated = NULL;
WSABUF* buffers = local_buffers;
size_t len;
+ if (grpc_tcp_trace.enabled()) {
+ size_t i;
+ for (i = 0; i < slices->count; i++) {
+ char* data =
+ grpc_dump_slice(slices->slices[i], GPR_DUMP_HEX | GPR_DUMP_ASCII);
+ gpr_log(GPR_INFO, "WRITE %p (peer=%s): %s", tcp, tcp->peer_string, data);
+ gpr_free(data);
+ }
+ }
+
if (tcp->shutting_down) {
GRPC_CLOSURE_SCHED(
cb, GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
@@ -412,6 +472,7 @@ static void win_shutdown(grpc_endpoint* ep, grpc_error* why) {
static void win_destroy(grpc_endpoint* ep) {
grpc_network_status_unregister_endpoint(ep);
grpc_tcp* tcp = (grpc_tcp*)ep;
+ grpc_slice_buffer_reset_and_unref_internal(&tcp->last_read_buffer);
TCP_UNREF(tcp, "destroy");
}
@@ -463,6 +524,7 @@ grpc_endpoint* grpc_tcp_create(grpc_winsocket* socket,
GRPC_CLOSURE_INIT(&tcp->on_read, on_read, tcp, grpc_schedule_on_exec_ctx);
GRPC_CLOSURE_INIT(&tcp->on_write, on_write, tcp, grpc_schedule_on_exec_ctx);
tcp->peer_string = gpr_strdup(peer_string);
+ grpc_slice_buffer_init(&tcp->last_read_buffer);
tcp->resource_user = grpc_resource_user_create(resource_quota, peer_string);
/* Tell network status tracking code about the new endpoint */
grpc_network_status_register_endpoint(&tcp->base);
diff --git a/src/core/lib/iomgr/timer_manager.cc b/src/core/lib/iomgr/timer_manager.cc
index ceba79f678..cb123298cf 100644
--- a/src/core/lib/iomgr/timer_manager.cc
+++ b/src/core/lib/iomgr/timer_manager.cc
@@ -67,6 +67,7 @@ static void timer_thread(void* completed_thread_ptr);
extern int64_t g_timer_manager_init_count;
extern int64_t g_timer_manager_shutdown_count;
extern int64_t g_fork_count;
+extern int64_t g_next_value;
#endif // GRPC_DEBUG_TIMER_MANAGER
static void gc_completed_threads(void) {
@@ -193,6 +194,11 @@ static bool wait_until(grpc_millis next) {
gpr_log(GPR_INFO, "sleep until kicked");
}
+ // For debug of the timer manager crash only.
+ // TODO (mxyan): remove after bug is fixed.
+#ifdef GRPC_DEBUG_TIMER_MANAGER
+ g_next_value = next;
+#endif
gpr_cv_wait(&g_cv_wait, &g_mu,
grpc_millis_to_timespec(next, GPR_CLOCK_MONOTONIC));
diff --git a/src/core/lib/security/credentials/google_default/google_default_credentials.cc b/src/core/lib/security/credentials/google_default/google_default_credentials.cc
index fcab252959..0674540d01 100644
--- a/src/core/lib/security/credentials/google_default/google_default_credentials.cc
+++ b/src/core/lib/security/credentials/google_default/google_default_credentials.cc
@@ -49,9 +49,16 @@
/* -- Default credentials. -- */
-static int g_compute_engine_detection_done = 0;
-static int g_need_compute_engine_creds = 0;
+/* A sticky bit that will be set only if the result of metadata server detection
+ * is positive. We do not set the bit if the result is negative. Because it
+ * means the detection is done via network test that is unreliable and the
+ * unreliable result should not be referred by successive calls. */
+static int g_metadata_server_available = 0;
+static int g_is_on_gce = 0;
static gpr_mu g_state_mu;
+/* Protect a metadata_server_detector instance that can be modified by more than
+ * one gRPC threads */
+static gpr_mu* g_polling_mu;
static gpr_once g_once = GPR_ONCE_INIT;
static grpc_core::internal::grpc_gce_tenancy_checker g_gce_tenancy_checker =
grpc_alts_is_running_on_gcp;
@@ -63,7 +70,7 @@ typedef struct {
int is_done;
int success;
grpc_http_response response;
-} compute_engine_detector;
+} metadata_server_detector;
static void google_default_credentials_destruct(
grpc_channel_credentials* creds) {
@@ -89,15 +96,21 @@ static grpc_security_status google_default_create_security_connector(
bool use_alts =
is_grpclb_load_balancer || is_backend_from_grpclb_load_balancer;
grpc_security_status status = GRPC_SECURITY_ERROR;
+ /* Return failure if ALTS is selected but not running on GCE. */
+ if (use_alts && !g_is_on_gce) {
+ gpr_log(GPR_ERROR, "ALTS is selected, but not running on GCE.");
+ goto end;
+ }
status = use_alts ? c->alts_creds->vtable->create_security_connector(
c->alts_creds, call_creds, target, args, sc, new_args)
: c->ssl_creds->vtable->create_security_connector(
c->ssl_creds, call_creds, target, args, sc, new_args);
- /* grpclb-specific channel args are removed from the channel args set
- * to ensure backends and fallback adresses will have the same set of channel
- * args. By doing that, it guarantees the connections to backends will not be
- * torn down and re-connected when switching in and out of fallback mode.
- */
+/* grpclb-specific channel args are removed from the channel args set
+ * to ensure backends and fallback adresses will have the same set of channel
+ * args. By doing that, it guarantees the connections to backends will not be
+ * torn down and re-connected when switching in and out of fallback mode.
+ */
+end:
if (use_alts) {
static const char* args_to_remove[] = {
GRPC_ARG_ADDRESS_IS_GRPCLB_LOAD_BALANCER,
@@ -113,6 +126,93 @@ static grpc_channel_credentials_vtable google_default_credentials_vtable = {
google_default_credentials_destruct,
google_default_create_security_connector, nullptr};
+static void on_metadata_server_detection_http_response(void* user_data,
+ grpc_error* error) {
+ metadata_server_detector* detector =
+ static_cast<metadata_server_detector*>(user_data);
+ if (error == GRPC_ERROR_NONE && detector->response.status == 200 &&
+ detector->response.hdr_count > 0) {
+ /* Internet providers can return a generic response to all requests, so
+ it is necessary to check that metadata header is present also. */
+ size_t i;
+ for (i = 0; i < detector->response.hdr_count; i++) {
+ grpc_http_header* header = &detector->response.hdrs[i];
+ if (strcmp(header->key, "Metadata-Flavor") == 0 &&
+ strcmp(header->value, "Google") == 0) {
+ detector->success = 1;
+ break;
+ }
+ }
+ }
+ gpr_mu_lock(g_polling_mu);
+ detector->is_done = 1;
+ GRPC_LOG_IF_ERROR(
+ "Pollset kick",
+ grpc_pollset_kick(grpc_polling_entity_pollset(&detector->pollent),
+ nullptr));
+ gpr_mu_unlock(g_polling_mu);
+}
+
+static void destroy_pollset(void* p, grpc_error* e) {
+ grpc_pollset_destroy(static_cast<grpc_pollset*>(p));
+}
+
+static int is_metadata_server_reachable() {
+ metadata_server_detector detector;
+ grpc_httpcli_request request;
+ grpc_httpcli_context context;
+ grpc_closure destroy_closure;
+ /* The http call is local. If it takes more than one sec, it is for sure not
+ on compute engine. */
+ grpc_millis max_detection_delay = GPR_MS_PER_SEC;
+ grpc_pollset* pollset =
+ static_cast<grpc_pollset*>(gpr_zalloc(grpc_pollset_size()));
+ grpc_pollset_init(pollset, &g_polling_mu);
+ detector.pollent = grpc_polling_entity_create_from_pollset(pollset);
+ detector.is_done = 0;
+ detector.success = 0;
+ memset(&detector.response, 0, sizeof(detector.response));
+ memset(&request, 0, sizeof(grpc_httpcli_request));
+ request.host = (char*)GRPC_COMPUTE_ENGINE_DETECTION_HOST;
+ request.http.path = (char*)"/";
+ grpc_httpcli_context_init(&context);
+ grpc_resource_quota* resource_quota =
+ grpc_resource_quota_create("google_default_credentials");
+ grpc_httpcli_get(
+ &context, &detector.pollent, resource_quota, &request,
+ grpc_core::ExecCtx::Get()->Now() + max_detection_delay,
+ GRPC_CLOSURE_CREATE(on_metadata_server_detection_http_response, &detector,
+ grpc_schedule_on_exec_ctx),
+ &detector.response);
+ grpc_resource_quota_unref_internal(resource_quota);
+ grpc_core::ExecCtx::Get()->Flush();
+ /* Block until we get the response. This is not ideal but this should only be
+ called once for the lifetime of the process by the default credentials. */
+ gpr_mu_lock(g_polling_mu);
+ while (!detector.is_done) {
+ grpc_pollset_worker* worker = nullptr;
+ if (!GRPC_LOG_IF_ERROR(
+ "pollset_work",
+ grpc_pollset_work(grpc_polling_entity_pollset(&detector.pollent),
+ &worker, GRPC_MILLIS_INF_FUTURE))) {
+ detector.is_done = 1;
+ detector.success = 0;
+ }
+ }
+ gpr_mu_unlock(g_polling_mu);
+ grpc_httpcli_context_destroy(&context);
+ GRPC_CLOSURE_INIT(&destroy_closure, destroy_pollset,
+ grpc_polling_entity_pollset(&detector.pollent),
+ grpc_schedule_on_exec_ctx);
+ grpc_pollset_shutdown(grpc_polling_entity_pollset(&detector.pollent),
+ &destroy_closure);
+ g_polling_mu = nullptr;
+ grpc_core::ExecCtx::Get()->Flush();
+ gpr_free(grpc_polling_entity_pollset(&detector.pollent));
+ grpc_http_response_destroy(&detector.response);
+ return detector.success;
+}
+
/* Takes ownership of creds_path if not NULL. */
static grpc_error* create_default_creds_from_path(
char* creds_path, grpc_call_credentials** creds) {
@@ -182,7 +282,6 @@ grpc_channel_credentials* grpc_google_default_credentials_create(void) {
grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Failed to create Google credentials");
grpc_error* err;
- int need_compute_engine_creds = 0;
grpc_core::ExecCtx exec_ctx;
GRPC_API_TRACE("grpc_google_default_credentials_create(void)", 0, ());
@@ -202,16 +301,21 @@ grpc_channel_credentials* grpc_google_default_credentials_create(void) {
error = grpc_error_add_child(error, err);
gpr_mu_lock(&g_state_mu);
- /* At last try to see if we're on compute engine (do the detection only once
- since it requires a network test). */
- if (!g_compute_engine_detection_done) {
- g_need_compute_engine_creds = g_gce_tenancy_checker();
- g_compute_engine_detection_done = 1;
+
+ /* Try a platform-provided hint for GCE. */
+ if (!g_metadata_server_available) {
+ g_is_on_gce = g_gce_tenancy_checker();
+ g_metadata_server_available = g_is_on_gce;
+ }
+ /* TODO: Add a platform-provided hint for GAE. */
+
+ /* Do a network test for metadata server. */
+ if (!g_metadata_server_available) {
+ g_metadata_server_available = is_metadata_server_reachable();
}
- need_compute_engine_creds = g_need_compute_engine_creds;
gpr_mu_unlock(&g_state_mu);
- if (need_compute_engine_creds) {
+ if (g_metadata_server_available) {
call_creds = grpc_google_compute_engine_credentials_create(nullptr);
if (call_creds == nullptr) {
error = grpc_error_add_child(
@@ -259,7 +363,7 @@ void grpc_flush_cached_google_default_credentials(void) {
grpc_core::ExecCtx exec_ctx;
gpr_once_init(&g_once, init_default_credentials);
gpr_mu_lock(&g_state_mu);
- g_compute_engine_detection_done = 0;
+ g_metadata_server_available = 0;
gpr_mu_unlock(&g_state_mu);
}
diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc
index 5dc81b29bb..67b38e6f0c 100644
--- a/src/core/lib/surface/server.cc
+++ b/src/core/lib/surface/server.cc
@@ -28,6 +28,8 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
+#include <utility>
+
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/connected_channel.h"
#include "src/core/lib/debug/stats.h"
@@ -109,7 +111,7 @@ struct channel_data {
uint32_t registered_method_max_probes;
grpc_closure finish_destroy_channel_closure;
grpc_closure channel_connectivity_changed;
- intptr_t socket_uuid;
+ grpc_core::RefCountedPtr<grpc_core::channelz::SocketNode> socket_node;
};
typedef struct shutdown_tag {
@@ -192,10 +194,13 @@ struct call_data {
};
struct request_matcher {
+ request_matcher(grpc_server* server);
+ ~request_matcher();
+
grpc_server* server;
- call_data* pending_head;
- call_data* pending_tail;
- gpr_locked_mpscq* requests_per_cq;
+ std::atomic<call_data*> pending_head{nullptr};
+ call_data* pending_tail = nullptr;
+ gpr_locked_mpscq* requests_per_cq = nullptr;
};
struct registered_method {
@@ -344,22 +349,30 @@ static void channel_broadcaster_shutdown(channel_broadcaster* cb,
* request_matcher
*/
-static void request_matcher_init(request_matcher* rm, grpc_server* server) {
- memset(rm, 0, sizeof(*rm));
- rm->server = server;
- rm->requests_per_cq = static_cast<gpr_locked_mpscq*>(
- gpr_malloc(sizeof(*rm->requests_per_cq) * server->cq_count));
+namespace {
+request_matcher::request_matcher(grpc_server* server) : server(server) {
+ requests_per_cq = static_cast<gpr_locked_mpscq*>(
+ gpr_malloc(sizeof(*requests_per_cq) * server->cq_count));
for (size_t i = 0; i < server->cq_count; i++) {
- gpr_locked_mpscq_init(&rm->requests_per_cq[i]);
+ gpr_locked_mpscq_init(&requests_per_cq[i]);
}
}
-static void request_matcher_destroy(request_matcher* rm) {
- for (size_t i = 0; i < rm->server->cq_count; i++) {
- GPR_ASSERT(gpr_locked_mpscq_pop(&rm->requests_per_cq[i]) == nullptr);
- gpr_locked_mpscq_destroy(&rm->requests_per_cq[i]);
+request_matcher::~request_matcher() {
+ for (size_t i = 0; i < server->cq_count; i++) {
+ GPR_ASSERT(gpr_locked_mpscq_pop(&requests_per_cq[i]) == nullptr);
+ gpr_locked_mpscq_destroy(&requests_per_cq[i]);
}
- gpr_free(rm->requests_per_cq);
+ gpr_free(requests_per_cq);
+}
+} // namespace
+
+static void request_matcher_init(request_matcher* rm, grpc_server* server) {
+ new (rm) request_matcher(server);
+}
+
+static void request_matcher_destroy(request_matcher* rm) {
+ rm->~request_matcher();
}
static void kill_zombie(void* elem, grpc_error* error) {
@@ -368,9 +381,10 @@ static void kill_zombie(void* elem, grpc_error* error) {
}
static void request_matcher_zombify_all_pending_calls(request_matcher* rm) {
- while (rm->pending_head) {
- call_data* calld = rm->pending_head;
- rm->pending_head = calld->pending_next;
+ call_data* calld;
+ while ((calld = rm->pending_head.load(std::memory_order_relaxed)) !=
+ nullptr) {
+ rm->pending_head.store(calld->pending_next, std::memory_order_relaxed);
gpr_atm_no_barrier_store(&calld->state, ZOMBIED);
GRPC_CLOSURE_INIT(
&calld->kill_zombie_closure, kill_zombie,
@@ -568,8 +582,9 @@ static void publish_new_rpc(void* arg, grpc_error* error) {
}
gpr_atm_no_barrier_store(&calld->state, PENDING);
- if (rm->pending_head == nullptr) {
- rm->pending_tail = rm->pending_head = calld;
+ if (rm->pending_head.load(std::memory_order_relaxed) == nullptr) {
+ rm->pending_head.store(calld, std::memory_order_relaxed);
+ rm->pending_tail = calld;
} else {
rm->pending_tail->pending_next = calld;
rm->pending_tail = calld;
@@ -937,6 +952,7 @@ static grpc_error* init_channel_elem(grpc_channel_element* elem,
static void destroy_channel_elem(grpc_channel_element* elem) {
size_t i;
channel_data* chand = static_cast<channel_data*>(elem->channel_data);
+ chand->socket_node.reset();
if (chand->registered_methods) {
for (i = 0; i < chand->registered_method_slots; i++) {
grpc_slice_unref_internal(chand->registered_methods[i].method);
@@ -1142,11 +1158,11 @@ void grpc_server_get_pollsets(grpc_server* server, grpc_pollset*** pollsets,
*pollsets = server->pollsets;
}
-void grpc_server_setup_transport(grpc_server* s, grpc_transport* transport,
- grpc_pollset* accepting_pollset,
- const grpc_channel_args* args,
- intptr_t socket_uuid,
- grpc_resource_user* resource_user) {
+void grpc_server_setup_transport(
+ grpc_server* s, grpc_transport* transport, grpc_pollset* accepting_pollset,
+ const grpc_channel_args* args,
+ grpc_core::RefCountedPtr<grpc_core::channelz::SocketNode> socket_node,
+ grpc_resource_user* resource_user) {
size_t num_registered_methods;
size_t alloc;
registered_method* rm;
@@ -1167,7 +1183,7 @@ void grpc_server_setup_transport(grpc_server* s, grpc_transport* transport,
chand->server = s;
server_ref(s);
chand->channel = channel;
- chand->socket_uuid = socket_uuid;
+ chand->socket_node = std::move(socket_node);
size_t cq_idx;
for (cq_idx = 0; cq_idx < s->cq_count; cq_idx++) {
@@ -1243,14 +1259,13 @@ void grpc_server_setup_transport(grpc_server* s, grpc_transport* transport,
}
void grpc_server_populate_server_sockets(
- grpc_server* s, grpc_core::channelz::ChildRefsList* server_sockets,
+ grpc_server* s, grpc_core::channelz::ChildSocketsList* server_sockets,
intptr_t start_idx) {
gpr_mu_lock(&s->mu_global);
channel_data* c = nullptr;
for (c = s->root_channel_data.next; c != &s->root_channel_data; c = c->next) {
- intptr_t socket_uuid = c->socket_uuid;
- if (socket_uuid >= start_idx) {
- server_sockets->push_back(socket_uuid);
+ if (c->socket_node != nullptr && c->socket_node->uuid() >= start_idx) {
+ server_sockets->push_back(c->socket_node.get());
}
}
gpr_mu_unlock(&s->mu_global);
@@ -1433,30 +1448,39 @@ static grpc_call_error queue_call_request(grpc_server* server, size_t cq_idx,
rm = &rc->data.registered.method->matcher;
break;
}
- if (gpr_locked_mpscq_push(&rm->requests_per_cq[cq_idx], &rc->request_link)) {
- /* this was the first queued request: we need to lock and start
- matching calls */
- gpr_mu_lock(&server->mu_call);
- while ((calld = rm->pending_head) != nullptr) {
- rc = reinterpret_cast<requested_call*>(
- gpr_locked_mpscq_pop(&rm->requests_per_cq[cq_idx]));
- if (rc == nullptr) break;
- rm->pending_head = calld->pending_next;
- gpr_mu_unlock(&server->mu_call);
- if (!gpr_atm_full_cas(&calld->state, PENDING, ACTIVATED)) {
- // Zombied Call
- GRPC_CLOSURE_INIT(
- &calld->kill_zombie_closure, kill_zombie,
- grpc_call_stack_element(grpc_call_get_call_stack(calld->call), 0),
- grpc_schedule_on_exec_ctx);
- GRPC_CLOSURE_SCHED(&calld->kill_zombie_closure, GRPC_ERROR_NONE);
- } else {
- publish_call(server, calld, cq_idx, rc);
- }
- gpr_mu_lock(&server->mu_call);
- }
+
+ // Fast path: if there is no pending request to be processed, immediately
+ // return.
+ if (!gpr_locked_mpscq_push(&rm->requests_per_cq[cq_idx], &rc->request_link) ||
+ // Note: We are reading the pending_head without holding the server's call
+ // mutex. Even if we read a non-null value here due to reordering,
+ // we will check it below again after grabbing the lock.
+ rm->pending_head.load(std::memory_order_relaxed) == nullptr) {
+ return GRPC_CALL_OK;
+ }
+ // Slow path: This was the first queued request and there are pendings:
+ // We need to lock and start matching calls.
+ gpr_mu_lock(&server->mu_call);
+ while ((calld = rm->pending_head.load(std::memory_order_relaxed)) !=
+ nullptr) {
+ rc = reinterpret_cast<requested_call*>(
+ gpr_locked_mpscq_pop(&rm->requests_per_cq[cq_idx]));
+ if (rc == nullptr) break;
+ rm->pending_head.store(calld->pending_next, std::memory_order_relaxed);
gpr_mu_unlock(&server->mu_call);
+ if (!gpr_atm_full_cas(&calld->state, PENDING, ACTIVATED)) {
+ // Zombied Call
+ GRPC_CLOSURE_INIT(
+ &calld->kill_zombie_closure, kill_zombie,
+ grpc_call_stack_element(grpc_call_get_call_stack(calld->call), 0),
+ grpc_schedule_on_exec_ctx);
+ GRPC_CLOSURE_SCHED(&calld->kill_zombie_closure, GRPC_ERROR_NONE);
+ } else {
+ publish_call(server, calld, cq_idx, rc);
+ }
+ gpr_mu_lock(&server->mu_call);
}
+ gpr_mu_unlock(&server->mu_call);
return GRPC_CALL_OK;
}
diff --git a/src/core/lib/surface/server.h b/src/core/lib/surface/server.h
index 27038fdb7a..393bb24214 100644
--- a/src/core/lib/surface/server.h
+++ b/src/core/lib/surface/server.h
@@ -44,15 +44,15 @@ void grpc_server_add_listener(grpc_server* server, void* listener,
/* Setup a transport - creates a channel stack, binds the transport to the
server */
-void grpc_server_setup_transport(grpc_server* server, grpc_transport* transport,
- grpc_pollset* accepting_pollset,
- const grpc_channel_args* args,
- intptr_t socket_uuid,
- grpc_resource_user* resource_user = nullptr);
+void grpc_server_setup_transport(
+ grpc_server* server, grpc_transport* transport,
+ grpc_pollset* accepting_pollset, const grpc_channel_args* args,
+ grpc_core::RefCountedPtr<grpc_core::channelz::SocketNode> socket_node,
+ grpc_resource_user* resource_user = nullptr);
/* fills in the uuids of all sockets used for connections on this server */
void grpc_server_populate_server_sockets(
- grpc_server* server, grpc_core::channelz::ChildRefsList* server_sockets,
+ grpc_server* server, grpc_core::channelz::ChildSocketsList* server_sockets,
intptr_t start_idx);
/* fills in the uuids of all listen sockets on this server */
diff --git a/src/cpp/client/channel_cc.cc b/src/cpp/client/channel_cc.cc
index d1c55319f7..a31d0b30b1 100644
--- a/src/cpp/client/channel_cc.cc
+++ b/src/cpp/client/channel_cc.cc
@@ -149,8 +149,9 @@ internal::Call Channel::CreateCallInternal(const internal::RpcMethod& method,
// ClientRpcInfo should be set before call because set_call also checks
// whether the call has been cancelled, and if the call was cancelled, we
// should notify the interceptors too/
- auto* info = context->set_client_rpc_info(
- method.name(), this, interceptor_creators_, interceptor_pos);
+ auto* info =
+ context->set_client_rpc_info(method.name(), method.method_type(), this,
+ interceptor_creators_, interceptor_pos);
context->set_call(c_call, shared_from_this());
return internal::Call(c_call, this, cq, info);
diff --git a/src/cpp/server/channelz/channelz_service.cc b/src/cpp/server/channelz/channelz_service.cc
index 9ecb9de7e4..c44a9ac0de 100644
--- a/src/cpp/server/channelz/channelz_service.cc
+++ b/src/cpp/server/channelz/channelz_service.cc
@@ -79,8 +79,8 @@ Status ChannelzService::GetServer(ServerContext* unused,
Status ChannelzService::GetServerSockets(
ServerContext* unused, const channelz::v1::GetServerSocketsRequest* request,
channelz::v1::GetServerSocketsResponse* response) {
- char* json_str = grpc_channelz_get_server_sockets(request->server_id(),
- request->start_socket_id());
+ char* json_str = grpc_channelz_get_server_sockets(
+ request->server_id(), request->start_socket_id(), request->max_results());
if (json_str == nullptr) {
return Status(StatusCode::INTERNAL,
"grpc_channelz_get_server_sockets returned null");
diff --git a/src/cpp/server/health/default_health_check_service.cc b/src/cpp/server/health/default_health_check_service.cc
index c951c69d51..44aebd2f9d 100644
--- a/src/cpp/server/health/default_health_check_service.cc
+++ b/src/cpp/server/health/default_health_check_service.cc
@@ -42,18 +42,37 @@ DefaultHealthCheckService::DefaultHealthCheckService() {
void DefaultHealthCheckService::SetServingStatus(
const grpc::string& service_name, bool serving) {
std::unique_lock<std::mutex> lock(mu_);
+ if (shutdown_) {
+ // Set to NOT_SERVING in case service_name is not in the map.
+ serving = false;
+ }
services_map_[service_name].SetServingStatus(serving ? SERVING : NOT_SERVING);
}
void DefaultHealthCheckService::SetServingStatus(bool serving) {
const ServingStatus status = serving ? SERVING : NOT_SERVING;
std::unique_lock<std::mutex> lock(mu_);
+ if (shutdown_) {
+ return;
+ }
for (auto& p : services_map_) {
ServiceData& service_data = p.second;
service_data.SetServingStatus(status);
}
}
+void DefaultHealthCheckService::Shutdown() {
+ std::unique_lock<std::mutex> lock(mu_);
+ if (shutdown_) {
+ return;
+ }
+ shutdown_ = true;
+ for (auto& p : services_map_) {
+ ServiceData& service_data = p.second;
+ service_data.SetServingStatus(NOT_SERVING);
+ }
+}
+
DefaultHealthCheckService::ServingStatus
DefaultHealthCheckService::GetServingStatus(
const grpc::string& service_name) const {
diff --git a/src/cpp/server/health/default_health_check_service.h b/src/cpp/server/health/default_health_check_service.h
index 450bd543f5..9551cd2e2c 100644
--- a/src/cpp/server/health/default_health_check_service.h
+++ b/src/cpp/server/health/default_health_check_service.h
@@ -237,6 +237,8 @@ class DefaultHealthCheckService final : public HealthCheckServiceInterface {
bool serving) override;
void SetServingStatus(bool serving) override;
+ void Shutdown() override;
+
ServingStatus GetServingStatus(const grpc::string& service_name) const;
HealthCheckServiceImpl* GetHealthCheckService(
@@ -272,6 +274,7 @@ class DefaultHealthCheckService final : public HealthCheckServiceInterface {
const std::shared_ptr<HealthCheckServiceImpl::CallHandler>& handler);
mutable std::mutex mu_;
+ bool shutdown_ = false; // Guarded by mu_.
std::map<grpc::string, ServiceData> services_map_; // Guarded by mu_.
std::unique_ptr<HealthCheckServiceImpl> impl_;
};
diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc
index 69af43a656..1e3c57446f 100644
--- a/src/cpp/server/server_cc.cc
+++ b/src/cpp/server/server_cc.cc
@@ -236,9 +236,10 @@ class Server::SyncRequest final : public internal::CompletionQueueTag {
: nullptr),
request_(nullptr),
method_(mrd->method_),
- call_(mrd->call_, server, &cq_, server->max_receive_message_size(),
- ctx_.set_server_rpc_info(method_->name(),
- server->interceptor_creators_)),
+ call_(
+ mrd->call_, server, &cq_, server->max_receive_message_size(),
+ ctx_.set_server_rpc_info(method_->name(), method_->method_type(),
+ server->interceptor_creators_)),
server_(server),
global_callbacks_(nullptr),
resources_(false) {
@@ -427,7 +428,8 @@ class Server::CallbackRequest final : public internal::CompletionQueueTag {
req_->call_, req_->server_, req_->cq_,
req_->server_->max_receive_message_size(),
req_->ctx_.set_server_rpc_info(
- req_->method_->name(), req_->server_->interceptor_creators_));
+ req_->method_->name(), req_->method_->method_type(),
+ req_->server_->interceptor_creators_));
req_->interceptor_methods_.SetCall(call_);
req_->interceptor_methods_.SetReverse();
@@ -1041,10 +1043,12 @@ void ServerInterface::BaseAsyncRequest::
ServerInterface::RegisteredAsyncRequest::RegisteredAsyncRequest(
ServerInterface* server, ServerContext* context,
internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq,
- ServerCompletionQueue* notification_cq, void* tag, const char* name)
+ ServerCompletionQueue* notification_cq, void* tag, const char* name,
+ internal::RpcMethod::RpcType type)
: BaseAsyncRequest(server, context, stream, call_cq, notification_cq, tag,
true),
- name_(name) {}
+ name_(name),
+ type_(type) {}
void ServerInterface::RegisteredAsyncRequest::IssueRequest(
void* registered_method, grpc_byte_buffer** payload,
@@ -1091,6 +1095,7 @@ bool ServerInterface::GenericAsyncRequest::FinalizeResult(void** tag,
call_, server_, call_cq_, server_->max_receive_message_size(),
context_->set_server_rpc_info(
static_cast<GenericServerContext*>(context_)->method_.c_str(),
+ internal::RpcMethod::BIDI_STREAMING,
*server_->interceptor_creators()));
return BaseAsyncRequest::FinalizeResult(tag, status);
}
diff --git a/src/proto/grpc/channelz/channelz.proto b/src/proto/grpc/channelz/channelz.proto
index 6202e5e817..20de23f7fa 100644
--- a/src/proto/grpc/channelz/channelz.proto
+++ b/src/proto/grpc/channelz/channelz.proto
@@ -177,6 +177,7 @@ message SubchannelRef {
// SocketRef is a reference to a Socket.
message SocketRef {
+ // The globally unique id for this socket. Must be a positive number.
int64 socket_id = 3;
// An optional name associated with the socket.
string name = 4;
@@ -288,7 +289,8 @@ message SocketData {
// include stream level or TCP level flow control info.
google.protobuf.Int64Value remote_flow_control_window = 12;
- // Socket options set on this socket. May be absent.
+ // Socket options set on this socket. May be absent if 'summary' is set
+ // on GetSocketRequest.
repeated SocketOption option = 13;
}
@@ -439,12 +441,21 @@ service Channelz {
message GetTopChannelsRequest {
// start_channel_id indicates that only channels at or above this id should be
// included in the results.
+ // To request the first page, this should be set to 0. To request
+ // subsequent pages, the client generates this value by adding 1 to
+ // the highest seen result ID.
int64 start_channel_id = 1;
+
+ // If non-zero, the server will return a page of results containing
+ // at most this many items. If zero, the server will choose a
+ // reasonable page size. Must never be negative.
+ int64 max_results = 2;
}
message GetTopChannelsResponse {
// list of channels that the connection detail service knows about. Sorted in
// ascending channel_id order.
+ // Must contain at least 1 result, otherwise 'end' must be true.
repeated Channel channel = 1;
// If set, indicates that the list of channels is the final list. Requesting
// more channels can only return more if they are created after this RPC
@@ -455,12 +466,21 @@ message GetTopChannelsResponse {
message GetServersRequest {
// start_server_id indicates that only servers at or above this id should be
// included in the results.
+ // To request the first page, this must be set to 0. To request
+ // subsequent pages, the client generates this value by adding 1 to
+ // the highest seen result ID.
int64 start_server_id = 1;
+
+ // If non-zero, the server will return a page of results containing
+ // at most this many items. If zero, the server will choose a
+ // reasonable page size. Must never be negative.
+ int64 max_results = 2;
}
message GetServersResponse {
// list of servers that the connection detail service knows about. Sorted in
// ascending server_id order.
+ // Must contain at least 1 result, otherwise 'end' must be true.
repeated Server server = 1;
// If set, indicates that the list of servers is the final list. Requesting
// more servers will only return more if they are created after this RPC
@@ -483,12 +503,21 @@ message GetServerSocketsRequest {
int64 server_id = 1;
// start_socket_id indicates that only sockets at or above this id should be
// included in the results.
+ // To request the first page, this must be set to 0. To request
+ // subsequent pages, the client generates this value by adding 1 to
+ // the highest seen result ID.
int64 start_socket_id = 2;
+
+ // If non-zero, the server will return a page of results containing
+ // at most this many items. If zero, the server will choose a
+ // reasonable page size. Must never be negative.
+ int64 max_results = 3;
}
message GetServerSocketsResponse {
// list of socket refs that the connection detail service knows about. Sorted in
// ascending socket_id order.
+ // Must contain at least 1 result, otherwise 'end' must be true.
repeated SocketRef socket_ref = 1;
// If set, indicates that the list of sockets is the final list. Requesting
// more sockets will only return more if they are created after this RPC
@@ -521,6 +550,11 @@ message GetSubchannelResponse {
message GetSocketRequest {
// socket_id is the identifier of the specific socket to get.
int64 socket_id = 1;
+
+ // If true, the response will contain only high level information
+ // that is inexpensive to obtain. Fields thay may be omitted are
+ // documented.
+ bool summary = 2;
}
message GetSocketResponse {
diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py
index ab154d8512..35fa82d56b 100644
--- a/src/python/grpcio/grpc/_channel.py
+++ b/src/python/grpcio/grpc/_channel.py
@@ -175,6 +175,7 @@ def _event_handler(state, response_deserializer):
return handle_event
+#pylint: disable=too-many-statements
def _consume_request_iterator(request_iterator, state, call, request_serializer,
event_handler):
if cygrpc.is_fork_support_enabled():
diff --git a/src/python/grpcio/grpc/_cython/BUILD.bazel b/src/python/grpcio/grpc/_cython/BUILD.bazel
index e318298d0a..42db7b8721 100644
--- a/src/python/grpcio/grpc/_cython/BUILD.bazel
+++ b/src/python/grpcio/grpc/_cython/BUILD.bazel
@@ -6,46 +6,47 @@ pyx_library(
name = "cygrpc",
srcs = [
"__init__.py",
- "cygrpc.pxd",
- "cygrpc.pyx",
+ "_cygrpc/_hooks.pxd.pxi",
"_cygrpc/_hooks.pyx.pxi",
- "_cygrpc/grpc_string.pyx.pxi",
+ "_cygrpc/arguments.pxd.pxi",
"_cygrpc/arguments.pyx.pxi",
+ "_cygrpc/call.pxd.pxi",
"_cygrpc/call.pyx.pxi",
- "_cygrpc/channelz.pyx.pxi",
+ "_cygrpc/channel.pxd.pxi",
"_cygrpc/channel.pyx.pxi",
- "_cygrpc/credentials.pyx.pxi",
+ "_cygrpc/channelz.pyx.pxi",
+ "_cygrpc/completion_queue.pxd.pxi",
"_cygrpc/completion_queue.pyx.pxi",
- "_cygrpc/event.pyx.pxi",
- "_cygrpc/fork_posix.pyx.pxi",
- "_cygrpc/metadata.pyx.pxi",
- "_cygrpc/operation.pyx.pxi",
- "_cygrpc/records.pyx.pxi",
- "_cygrpc/security.pyx.pxi",
- "_cygrpc/server.pyx.pxi",
- "_cygrpc/tag.pyx.pxi",
- "_cygrpc/time.pyx.pxi",
- "_cygrpc/grpc_gevent.pyx.pxi",
- "_cygrpc/grpc.pxi",
- "_cygrpc/_hooks.pxd.pxi",
- "_cygrpc/arguments.pxd.pxi",
- "_cygrpc/call.pxd.pxi",
- "_cygrpc/channel.pxd.pxi",
"_cygrpc/credentials.pxd.pxi",
- "_cygrpc/completion_queue.pxd.pxi",
+ "_cygrpc/credentials.pyx.pxi",
"_cygrpc/event.pxd.pxi",
+ "_cygrpc/event.pyx.pxi",
"_cygrpc/fork_posix.pxd.pxi",
+ "_cygrpc/fork_posix.pyx.pxi",
+ "_cygrpc/grpc.pxi",
+ "_cygrpc/grpc_gevent.pxd.pxi",
+ "_cygrpc/grpc_gevent.pyx.pxi",
+ "_cygrpc/grpc_string.pyx.pxi",
"_cygrpc/metadata.pxd.pxi",
+ "_cygrpc/metadata.pyx.pxi",
"_cygrpc/operation.pxd.pxi",
+ "_cygrpc/operation.pyx.pxi",
+ "_cygrpc/propagation_bits.pxd.pxi",
+ "_cygrpc/propagation_bits.pyx.pxi",
"_cygrpc/records.pxd.pxi",
+ "_cygrpc/records.pyx.pxi",
"_cygrpc/security.pxd.pxi",
+ "_cygrpc/security.pyx.pxi",
"_cygrpc/server.pxd.pxi",
+ "_cygrpc/server.pyx.pxi",
"_cygrpc/tag.pxd.pxi",
+ "_cygrpc/tag.pyx.pxi",
"_cygrpc/time.pxd.pxi",
- "_cygrpc/grpc_gevent.pxd.pxi",
+ "_cygrpc/time.pyx.pxi",
+ "cygrpc.pxd",
+ "cygrpc.pyx",
],
deps = [
"//:grpc",
],
)
-
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/_hooks.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/_hooks.pyx.pxi
index 38cf629dc2..cd4a51a635 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/_hooks.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/_hooks.pyx.pxi
@@ -15,3 +15,18 @@
cdef object _custom_op_on_c_call(int op, grpc_call *call):
raise NotImplementedError("No custom hooks are implemented")
+
+def install_census_context_from_call(Call call):
+ pass
+
+def uninstall_context():
+ pass
+
+def build_context():
+ pass
+
+cdef class CensusContext:
+ pass
+
+def set_census_context_on_call(_CallState call_state, CensusContext census_ctx):
+ pass
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi
index a81ff4d823..135d224095 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi
@@ -159,7 +159,8 @@ cdef void _call(
_ChannelState channel_state, _CallState call_state,
grpc_completion_queue *c_completion_queue, on_success, int flags, method,
host, object deadline, CallCredentials credentials,
- object operationses_and_user_tags, object metadata) except *:
+ object operationses_and_user_tags, object metadata,
+ object context) except *:
"""Invokes an RPC.
Args:
@@ -185,6 +186,7 @@ cdef void _call(
which is an object to be used as a tag. A SendInitialMetadataOperation
must be present in the first element of this value.
metadata: The metadata for this call.
+ context: Context object for distributed tracing.
"""
cdef grpc_slice method_slice
cdef grpc_slice host_slice
@@ -208,6 +210,8 @@ cdef void _call(
grpc_slice_unref(method_slice)
if host_slice_ptr:
grpc_slice_unref(host_slice)
+ if context is not None:
+ set_census_context_on_call(call_state, context)
if credentials is not None:
c_call_credentials = credentials.c()
c_call_error = grpc_call_set_credentials(
@@ -257,7 +261,8 @@ cdef class IntegratedCall:
cdef IntegratedCall _integrated_call(
_ChannelState state, int flags, method, host, object deadline,
- object metadata, CallCredentials credentials, operationses_and_user_tags):
+ object metadata, CallCredentials credentials, operationses_and_user_tags,
+ object context):
call_state = _CallState()
def on_success(started_tags):
@@ -266,7 +271,7 @@ cdef IntegratedCall _integrated_call(
_call(
state, call_state, state.c_call_completion_queue, on_success, flags,
- method, host, deadline, credentials, operationses_and_user_tags, metadata)
+ method, host, deadline, credentials, operationses_and_user_tags, metadata, context)
return IntegratedCall(state, call_state)
@@ -308,7 +313,8 @@ cdef class SegregatedCall:
cdef SegregatedCall _segregated_call(
_ChannelState state, int flags, method, host, object deadline,
- object metadata, CallCredentials credentials, operationses_and_user_tags):
+ object metadata, CallCredentials credentials, operationses_and_user_tags,
+ object context):
cdef _CallState call_state = _CallState()
cdef SegregatedCall segregated_call
cdef grpc_completion_queue *c_completion_queue
@@ -325,7 +331,8 @@ cdef SegregatedCall _segregated_call(
try:
_call(
state, call_state, c_completion_queue, on_success, flags, method, host,
- deadline, credentials, operationses_and_user_tags, metadata)
+ deadline, credentials, operationses_and_user_tags, metadata,
+ context)
except:
_destroy_c_completion_queue(c_completion_queue)
raise
@@ -443,10 +450,11 @@ cdef class Channel:
def integrated_call(
self, int flags, method, host, object deadline, object metadata,
- CallCredentials credentials, operationses_and_tags):
+ CallCredentials credentials, operationses_and_tags,
+ object context = None):
return _integrated_call(
self._state, flags, method, host, deadline, metadata, credentials,
- operationses_and_tags)
+ operationses_and_tags, context)
def next_call_event(self):
def on_success(tag):
@@ -461,10 +469,11 @@ cdef class Channel:
def segregated_call(
self, int flags, method, host, object deadline, object metadata,
- CallCredentials credentials, operationses_and_tags):
+ CallCredentials credentials, operationses_and_tags,
+ object context = None):
return _segregated_call(
self._state, flags, method, host, deadline, metadata, credentials,
- operationses_and_tags)
+ operationses_and_tags, context)
def check_connectivity_state(self, bint try_to_connect):
with self._state.condition:
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/channelz.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/channelz.pyx.pxi
index 113f7976dd..36c8cd121c 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/channelz.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/channelz.pyx.pxi
@@ -36,15 +36,17 @@ def channelz_get_server(server_id):
' server_id==%s is valid' % server_id)
return c_returned_str
-def channelz_get_server_sockets(server_id, start_socket_id):
+def channelz_get_server_sockets(server_id, start_socket_id, max_results):
cdef char *c_returned_str = grpc_channelz_get_server_sockets(
server_id,
start_socket_id,
+ max_results,
)
if c_returned_str == NULL:
raise ValueError('Failed to get server sockets, please ensure your' \
- ' server_id==%s and start_socket_id==%s is valid' %
- (server_id, start_socket_id))
+ ' server_id==%s and start_socket_id==%s and' \
+ ' max_results==%s is valid' %
+ (server_id, start_socket_id, max_results))
return c_returned_str
def channelz_get_channel(channel_id):
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
index 5bbc10af25..fc7a9ba439 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
@@ -389,7 +389,8 @@ cdef extern from "grpc/grpc.h":
char* grpc_channelz_get_servers(intptr_t start_server_id)
char* grpc_channelz_get_server(intptr_t server_id)
char* grpc_channelz_get_server_sockets(intptr_t server_id,
- intptr_t start_socket_id)
+ intptr_t start_socket_id,
+ intptr_t max_results)
char* grpc_channelz_get_channel(intptr_t channel_id)
char* grpc_channelz_get_subchannel(intptr_t subchannel_id)
char* grpc_channelz_get_socket(intptr_t socket_id)
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/propagation_bits.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/propagation_bits.pxd.pxi
new file mode 100644
index 0000000000..cd6e94c816
--- /dev/null
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/propagation_bits.pxd.pxi
@@ -0,0 +1,20 @@
+# Copyright 2018 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.
+
+cdef extern from "grpc/impl/codegen/propagation_bits.h":
+ cdef int _GRPC_PROPAGATE_DEADLINE "GRPC_PROPAGATE_DEADLINE"
+ cdef int _GRPC_PROPAGATE_CENSUS_STATS_CONTEXT "GRPC_PROPAGATE_CENSUS_STATS_CONTEXT"
+ cdef int _GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT "GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT"
+ cdef int _GRPC_PROPAGATE_CANCELLATION "GRPC_PROPAGATE_CANCELLATION"
+ cdef int _GRPC_PROPAGATE_DEFAULTS "GRPC_PROPAGATE_DEFAULTS"
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/propagation_bits.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/propagation_bits.pyx.pxi
new file mode 100644
index 0000000000..2dcc76a2db
--- /dev/null
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/propagation_bits.pyx.pxi
@@ -0,0 +1,20 @@
+# Copyright 2018 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.
+
+class PropagationConstants:
+ GRPC_PROPAGATE_DEADLINE = _GRPC_PROPAGATE_DEADLINE
+ GRPC_PROPAGATE_CENSUS_STATS_CONTEXT = _GRPC_PROPAGATE_CENSUS_STATS_CONTEXT
+ GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT = _GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT
+ GRPC_PROPAGATE_CANCELLATION = _GRPC_PROPAGATE_CANCELLATION
+ GRPC_PROPAGATE_DEFAULTS = _GRPC_PROPAGATE_DEFAULTS
diff --git a/src/python/grpcio/grpc/_cython/cygrpc.pxd b/src/python/grpcio/grpc/_cython/cygrpc.pxd
index 8258b857bc..64cae6b34d 100644
--- a/src/python/grpcio/grpc/_cython/cygrpc.pxd
+++ b/src/python/grpcio/grpc/_cython/cygrpc.pxd
@@ -29,6 +29,7 @@ include "_cygrpc/server.pxd.pxi"
include "_cygrpc/tag.pxd.pxi"
include "_cygrpc/time.pxd.pxi"
include "_cygrpc/_hooks.pxd.pxi"
+include "_cygrpc/propagation_bits.pxd.pxi"
include "_cygrpc/grpc_gevent.pxd.pxi"
diff --git a/src/python/grpcio/grpc/_cython/cygrpc.pyx b/src/python/grpcio/grpc/_cython/cygrpc.pyx
index 9ab919375c..ce98fa3a8e 100644
--- a/src/python/grpcio/grpc/_cython/cygrpc.pyx
+++ b/src/python/grpcio/grpc/_cython/cygrpc.pyx
@@ -36,6 +36,7 @@ include "_cygrpc/tag.pyx.pxi"
include "_cygrpc/time.pyx.pxi"
include "_cygrpc/_hooks.pyx.pxi"
include "_cygrpc/channelz.pyx.pxi"
+include "_cygrpc/propagation_bits.pyx.pxi"
include "_cygrpc/grpc_gevent.pyx.pxi"
diff --git a/src/python/grpcio/grpc/_interceptor.py b/src/python/grpcio/grpc/_interceptor.py
index 2a8ddd8ce4..fc0ad77eb9 100644
--- a/src/python/grpcio/grpc/_interceptor.py
+++ b/src/python/grpcio/grpc/_interceptor.py
@@ -135,9 +135,12 @@ class _FailureOutcome(grpc.RpcError, grpc.Future, grpc.Call):
def __iter__(self):
return self
- def next(self):
+ def __next__(self):
raise self._exception
+ def next(self):
+ return self.__next__()
+
class _UnaryOutcome(grpc.Call, grpc.Future):
diff --git a/src/python/grpcio/grpc/_server.py b/src/python/grpcio/grpc/_server.py
index 7276a7fd90..e939f615df 100644
--- a/src/python/grpcio/grpc/_server.py
+++ b/src/python/grpcio/grpc/_server.py
@@ -480,43 +480,51 @@ def _status(rpc_event, state, serialized_response):
def _unary_response_in_pool(rpc_event, state, behavior, argument_thunk,
request_deserializer, response_serializer):
- argument = argument_thunk()
- if argument is not None:
- response, proceed = _call_behavior(rpc_event, state, behavior, argument,
- request_deserializer)
- if proceed:
- serialized_response = _serialize_response(
- rpc_event, state, response, response_serializer)
- if serialized_response is not None:
- _status(rpc_event, state, serialized_response)
+ cygrpc.install_census_context_from_call(rpc_event.call)
+ try:
+ argument = argument_thunk()
+ if argument is not None:
+ response, proceed = _call_behavior(rpc_event, state, behavior,
+ argument, request_deserializer)
+ if proceed:
+ serialized_response = _serialize_response(
+ rpc_event, state, response, response_serializer)
+ if serialized_response is not None:
+ _status(rpc_event, state, serialized_response)
+ finally:
+ cygrpc.uninstall_context()
def _stream_response_in_pool(rpc_event, state, behavior, argument_thunk,
request_deserializer, response_serializer):
- argument = argument_thunk()
- if argument is not None:
- response_iterator, proceed = _call_behavior(
- rpc_event, state, behavior, argument, request_deserializer)
- if proceed:
- while True:
- response, proceed = _take_response_from_response_iterator(
- rpc_event, state, response_iterator)
- if proceed:
- if response is None:
- _status(rpc_event, state, None)
- break
- else:
- serialized_response = _serialize_response(
- rpc_event, state, response, response_serializer)
- if serialized_response is not None:
- proceed = _send_response(rpc_event, state,
- serialized_response)
- if not proceed:
- break
- else:
+ cygrpc.install_census_context_from_call(rpc_event.call)
+ try:
+ argument = argument_thunk()
+ if argument is not None:
+ response_iterator, proceed = _call_behavior(
+ rpc_event, state, behavior, argument, request_deserializer)
+ if proceed:
+ while True:
+ response, proceed = _take_response_from_response_iterator(
+ rpc_event, state, response_iterator)
+ if proceed:
+ if response is None:
+ _status(rpc_event, state, None)
break
- else:
- break
+ else:
+ serialized_response = _serialize_response(
+ rpc_event, state, response, response_serializer)
+ if serialized_response is not None:
+ proceed = _send_response(
+ rpc_event, state, serialized_response)
+ if not proceed:
+ break
+ else:
+ break
+ else:
+ break
+ finally:
+ cygrpc.uninstall_context()
def _handle_unary_unary(rpc_event, state, method_handler, thread_pool):
diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py
index ce65c594fe..c6ca970bee 100644
--- a/src/python/grpcio/grpc_core_dependencies.py
+++ b/src/python/grpcio/grpc_core_dependencies.py
@@ -322,7 +322,6 @@ CORE_SOURCE_FILES = [
'src/core/ext/filters/client_channel/http_connect_handshaker.cc',
'src/core/ext/filters/client_channel/http_proxy.cc',
'src/core/ext/filters/client_channel/lb_policy.cc',
- 'src/core/ext/filters/client_channel/lb_policy_factory.cc',
'src/core/ext/filters/client_channel/lb_policy_registry.cc',
'src/core/ext/filters/client_channel/parse_address.cc',
'src/core/ext/filters/client_channel/proxy_mapper.cc',
@@ -331,6 +330,7 @@ CORE_SOURCE_FILES = [
'src/core/ext/filters/client_channel/resolver_registry.cc',
'src/core/ext/filters/client_channel/resolver_result_parsing.cc',
'src/core/ext/filters/client_channel/retry_throttle.cc',
+ 'src/core/ext/filters/client_channel/server_address.cc',
'src/core/ext/filters/client_channel/subchannel.cc',
'src/core/ext/filters/client_channel/subchannel_index.cc',
'src/core/ext/filters/deadline/deadline_filter.cc',
diff --git a/src/python/grpcio_channelz/MANIFEST.in b/src/python/grpcio_channelz/MANIFEST.in
index 5597f375ba..ee93e21a69 100644
--- a/src/python/grpcio_channelz/MANIFEST.in
+++ b/src/python/grpcio_channelz/MANIFEST.in
@@ -1,3 +1,4 @@
include grpc_version.py
recursive-include grpc_channelz *.py
global-exclude *.pyc
+include LICENSE
diff --git a/src/python/grpcio_channelz/channelz_commands.py b/src/python/grpcio_channelz/channelz_commands.py
index e9ad355034..7f158c2a4b 100644
--- a/src/python/grpcio_channelz/channelz_commands.py
+++ b/src/python/grpcio_channelz/channelz_commands.py
@@ -21,10 +21,12 @@ import setuptools
ROOT_DIR = os.path.abspath(os.path.dirname(os.path.abspath(__file__)))
CHANNELZ_PROTO = os.path.join(ROOT_DIR,
'../../proto/grpc/channelz/channelz.proto')
+LICENSE = os.path.join(ROOT_DIR, '../../../LICENSE')
-class CopyProtoModules(setuptools.Command):
- """Command to copy proto modules from grpc/src/proto."""
+class Preprocess(setuptools.Command):
+ """Command to copy proto modules from grpc/src/proto and LICENSE from
+ the root directory"""
description = ''
user_options = []
@@ -40,6 +42,8 @@ class CopyProtoModules(setuptools.Command):
shutil.copyfile(CHANNELZ_PROTO,
os.path.join(ROOT_DIR,
'grpc_channelz/v1/channelz.proto'))
+ if os.path.isfile(LICENSE):
+ shutil.copyfile(LICENSE, os.path.join(ROOT_DIR, 'LICENSE'))
class BuildPackageProtos(setuptools.Command):
diff --git a/src/python/grpcio_channelz/grpc_channelz/v1/channelz.py b/src/python/grpcio_channelz/grpc_channelz/v1/channelz.py
index 573b9d0d5a..00eca311dc 100644
--- a/src/python/grpcio_channelz/grpc_channelz/v1/channelz.py
+++ b/src/python/grpcio_channelz/grpc_channelz/v1/channelz.py
@@ -66,7 +66,8 @@ class ChannelzServicer(_channelz_pb2_grpc.ChannelzServicer):
try:
return json_format.Parse(
cygrpc.channelz_get_server_sockets(request.server_id,
- request.start_socket_id),
+ request.start_socket_id,
+ request.max_results),
_channelz_pb2.GetServerSocketsResponse(),
)
except ValueError as e:
diff --git a/src/python/grpcio_channelz/setup.py b/src/python/grpcio_channelz/setup.py
index a495052376..f8c0e93913 100644
--- a/src/python/grpcio_channelz/setup.py
+++ b/src/python/grpcio_channelz/setup.py
@@ -69,7 +69,7 @@ try:
'grpcio-tools=={version}'.format(version=grpc_version.VERSION),)
COMMAND_CLASS = {
# Run preprocess from the repository *before* doing any packaging!
- 'preprocess': _channelz_commands.CopyProtoModules,
+ 'preprocess': _channelz_commands.Preprocess,
'build_package_protos': _channelz_commands.BuildPackageProtos,
}
except ImportError:
diff --git a/src/python/grpcio_health_checking/MANIFEST.in b/src/python/grpcio_health_checking/MANIFEST.in
index 996c74a9d4..3a22311b8e 100644
--- a/src/python/grpcio_health_checking/MANIFEST.in
+++ b/src/python/grpcio_health_checking/MANIFEST.in
@@ -1,3 +1,4 @@
include grpc_version.py
recursive-include grpc_health *.py
global-exclude *.pyc
+include LICENSE
diff --git a/src/python/grpcio_health_checking/health_commands.py b/src/python/grpcio_health_checking/health_commands.py
index 933f965aa2..3820ef0bba 100644
--- a/src/python/grpcio_health_checking/health_commands.py
+++ b/src/python/grpcio_health_checking/health_commands.py
@@ -20,10 +20,12 @@ import setuptools
ROOT_DIR = os.path.abspath(os.path.dirname(os.path.abspath(__file__)))
HEALTH_PROTO = os.path.join(ROOT_DIR, '../../proto/grpc/health/v1/health.proto')
+LICENSE = os.path.join(ROOT_DIR, '../../../LICENSE')
-class CopyProtoModules(setuptools.Command):
- """Command to copy proto modules from grpc/src/proto."""
+class Preprocess(setuptools.Command):
+ """Command to copy proto modules from grpc/src/proto and LICENSE from
+ the root directory"""
description = ''
user_options = []
@@ -39,6 +41,8 @@ class CopyProtoModules(setuptools.Command):
shutil.copyfile(HEALTH_PROTO,
os.path.join(ROOT_DIR,
'grpc_health/v1/health.proto'))
+ if os.path.isfile(LICENSE):
+ shutil.copyfile(LICENSE, os.path.join(ROOT_DIR, 'LICENSE'))
class BuildPackageProtos(setuptools.Command):
diff --git a/src/python/grpcio_health_checking/setup.py b/src/python/grpcio_health_checking/setup.py
index db2edae2ce..5a09a80f6a 100644
--- a/src/python/grpcio_health_checking/setup.py
+++ b/src/python/grpcio_health_checking/setup.py
@@ -68,7 +68,7 @@ try:
'grpcio-tools=={version}'.format(version=grpc_version.VERSION),)
COMMAND_CLASS = {
# Run preprocess from the repository *before* doing any packaging!
- 'preprocess': _health_commands.CopyProtoModules,
+ 'preprocess': _health_commands.Preprocess,
'build_package_protos': _health_commands.BuildPackageProtos,
}
except ImportError:
diff --git a/src/python/grpcio_reflection/MANIFEST.in b/src/python/grpcio_reflection/MANIFEST.in
index d6fb6ce73a..10b01fa41d 100644
--- a/src/python/grpcio_reflection/MANIFEST.in
+++ b/src/python/grpcio_reflection/MANIFEST.in
@@ -1,3 +1,4 @@
include grpc_version.py
recursive-include grpc_reflection *.py
global-exclude *.pyc
+include LICENSE
diff --git a/src/python/grpcio_reflection/reflection_commands.py b/src/python/grpcio_reflection/reflection_commands.py
index 6f91f6b875..311ca4c4db 100644
--- a/src/python/grpcio_reflection/reflection_commands.py
+++ b/src/python/grpcio_reflection/reflection_commands.py
@@ -21,10 +21,12 @@ import setuptools
ROOT_DIR = os.path.abspath(os.path.dirname(os.path.abspath(__file__)))
REFLECTION_PROTO = os.path.join(
ROOT_DIR, '../../proto/grpc/reflection/v1alpha/reflection.proto')
+LICENSE = os.path.join(ROOT_DIR, '../../../LICENSE')
-class CopyProtoModules(setuptools.Command):
- """Command to copy proto modules from grpc/src/proto."""
+class Preprocess(setuptools.Command):
+ """Command to copy proto modules from grpc/src/proto and LICENSE from
+ the root directory"""
description = ''
user_options = []
@@ -41,6 +43,8 @@ class CopyProtoModules(setuptools.Command):
REFLECTION_PROTO,
os.path.join(ROOT_DIR,
'grpc_reflection/v1alpha/reflection.proto'))
+ if os.path.isfile(LICENSE):
+ shutil.copyfile(LICENSE, os.path.join(ROOT_DIR, 'LICENSE'))
class BuildPackageProtos(setuptools.Command):
diff --git a/src/python/grpcio_reflection/setup.py b/src/python/grpcio_reflection/setup.py
index b4087d87b4..f205069acd 100644
--- a/src/python/grpcio_reflection/setup.py
+++ b/src/python/grpcio_reflection/setup.py
@@ -69,7 +69,7 @@ try:
'grpcio-tools=={version}'.format(version=grpc_version.VERSION),)
COMMAND_CLASS = {
# Run preprocess from the repository *before* doing any packaging!
- 'preprocess': _reflection_commands.CopyProtoModules,
+ 'preprocess': _reflection_commands.Preprocess,
'build_package_protos': _reflection_commands.BuildPackageProtos,
}
except ImportError:
diff --git a/src/python/grpcio_testing/MANIFEST.in b/src/python/grpcio_testing/MANIFEST.in
index 39b3565217..559dfaf786 100644
--- a/src/python/grpcio_testing/MANIFEST.in
+++ b/src/python/grpcio_testing/MANIFEST.in
@@ -1,3 +1,4 @@
include grpc_version.py
recursive-include grpc_testing *.py
global-exclude *.pyc
+include LICENSE
diff --git a/src/python/grpcio_testing/setup.py b/src/python/grpcio_testing/setup.py
index 6ceb1fc5c9..18db71e0f0 100644
--- a/src/python/grpcio_testing/setup.py
+++ b/src/python/grpcio_testing/setup.py
@@ -24,6 +24,23 @@ os.chdir(os.path.dirname(os.path.abspath(__file__)))
# Break import style to ensure that we can find same-directory modules.
import grpc_version
+
+class _NoOpCommand(setuptools.Command):
+ """No-op command."""
+
+ description = ''
+ user_options = []
+
+ def initialize_options(self):
+ pass
+
+ def finalize_options(self):
+ pass
+
+ def run(self):
+ pass
+
+
PACKAGE_DIRECTORIES = {
'': '.',
}
@@ -33,6 +50,19 @@ INSTALL_REQUIRES = (
'grpcio>={version}'.format(version=grpc_version.VERSION),
)
+try:
+ import testing_commands as _testing_commands
+ # we are in the build environment, otherwise the above import fails
+ COMMAND_CLASS = {
+ # Run preprocess from the repository *before* doing any packaging!
+ 'preprocess': _testing_commands.Preprocess,
+ }
+except ImportError:
+ COMMAND_CLASS = {
+ # wire up commands to no-op not to break the external dependencies
+ 'preprocess': _NoOpCommand,
+ }
+
setuptools.setup(
name='grpcio-testing',
version=grpc_version.VERSION,
@@ -43,4 +73,5 @@ setuptools.setup(
url='https://grpc.io',
package_dir=PACKAGE_DIRECTORIES,
packages=setuptools.find_packages('.'),
- install_requires=INSTALL_REQUIRES)
+ install_requires=INSTALL_REQUIRES,
+ cmdclass=COMMAND_CLASS)
diff --git a/src/python/grpcio_testing/testing_commands.py b/src/python/grpcio_testing/testing_commands.py
new file mode 100644
index 0000000000..fb40d37efb
--- /dev/null
+++ b/src/python/grpcio_testing/testing_commands.py
@@ -0,0 +1,39 @@
+# Copyright 2018 gRPC Authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""Provides distutils command classes for the GRPC Python setup process."""
+
+import os
+import shutil
+
+import setuptools
+
+ROOT_DIR = os.path.abspath(os.path.dirname(os.path.abspath(__file__)))
+LICENSE = os.path.join(ROOT_DIR, '../../../LICENSE')
+
+
+class Preprocess(setuptools.Command):
+ """Command to copy LICENSE from root directory."""
+
+ description = ''
+ user_options = []
+
+ def initialize_options(self):
+ pass
+
+ def finalize_options(self):
+ pass
+
+ def run(self):
+ if os.path.isfile(LICENSE):
+ shutil.copyfile(LICENSE, os.path.join(ROOT_DIR, 'LICENSE'))
diff --git a/src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py b/src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py
index 84f8594689..8ca5189522 100644
--- a/src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py
+++ b/src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py
@@ -69,32 +69,28 @@ class _ChannelServerPair(object):
def __init__(self):
# Server will enable channelz service
- # Bind as attribute, so its `del` can be called explicitly, during
- # the destruction process. Otherwise, if the removal of server
- # rely on gc cycle, the test will become non-deterministic.
- self._server = grpc.server(
+ self.server = grpc.server(
futures.ThreadPoolExecutor(max_workers=3),
options=_DISABLE_REUSE_PORT + _ENABLE_CHANNELZ)
- port = self._server.add_insecure_port('[::]:0')
- self._server.add_generic_rpc_handlers((_GenericHandler(),))
- self._server.start()
+ port = self.server.add_insecure_port('[::]:0')
+ self.server.add_generic_rpc_handlers((_GenericHandler(),))
+ self.server.start()
# Channel will enable channelz service...
self.channel = grpc.insecure_channel('localhost:%d' % port,
_ENABLE_CHANNELZ)
- def __del__(self):
- self._server.__del__()
- self.channel.close()
-
def _generate_channel_server_pairs(n):
return [_ChannelServerPair() for i in range(n)]
-def _clean_channel_server_pairs(pairs):
+def _close_channel_server_pairs(pairs):
for pair in pairs:
- pair.__del__()
+ pair.server.stop(None)
+ # TODO(ericgribkoff) This del should not be required
+ del pair.server
+ pair.channel.close()
class ChannelzServicerTest(unittest.TestCase):
@@ -147,9 +143,9 @@ class ChannelzServicerTest(unittest.TestCase):
self._channelz_stub = channelz_pb2_grpc.ChannelzStub(self._channel)
def tearDown(self):
- self._server.__del__()
+ self._server.stop(None)
self._channel.close()
- _clean_channel_server_pairs(self._pairs)
+ _close_channel_server_pairs(self._pairs)
def test_get_top_channels_basic(self):
self._pairs = _generate_channel_server_pairs(1)
@@ -278,20 +274,12 @@ class ChannelzServicerTest(unittest.TestCase):
self.assertEqual(gtc_resp.channel[i].data.calls_failed,
gsc_resp.subchannel.data.calls_failed)
- @unittest.skip('Servers in core are not guaranteed to be destroyed ' \
- 'immediately when the reference goes out of scope, so ' \
- 'servers from multiple test cases are not hermetic. ' \
- 'TODO(https://github.com/grpc/grpc/issues/17258)')
def test_server_basic(self):
self._pairs = _generate_channel_server_pairs(1)
resp = self._channelz_stub.GetServers(
channelz_pb2.GetServersRequest(start_server_id=0))
self.assertEqual(len(resp.server), 1)
- @unittest.skip('Servers in core are not guaranteed to be destroyed ' \
- 'immediately when the reference goes out of scope, so ' \
- 'servers from multiple test cases are not hermetic. ' \
- 'TODO(https://github.com/grpc/grpc/issues/17258)')
def test_get_one_server(self):
self._pairs = _generate_channel_server_pairs(1)
gss_resp = self._channelz_stub.GetServers(
@@ -303,10 +291,6 @@ class ChannelzServicerTest(unittest.TestCase):
self.assertEqual(gss_resp.server[0].ref.server_id,
gs_resp.server.ref.server_id)
- @unittest.skip('Servers in core are not guaranteed to be destroyed ' \
- 'immediately when the reference goes out of scope, so ' \
- 'servers from multiple test cases are not hermetic. ' \
- 'TODO(https://github.com/grpc/grpc/issues/17258)')
def test_server_call(self):
self._pairs = _generate_channel_server_pairs(1)
k_success = 23
@@ -401,10 +385,6 @@ class ChannelzServicerTest(unittest.TestCase):
self.assertEqual(gs_resp.socket.data.messages_received,
test_constants.STREAM_LENGTH)
- @unittest.skip('Servers in core are not guaranteed to be destroyed ' \
- 'immediately when the reference goes out of scope, so ' \
- 'servers from multiple test cases are not hermetic. ' \
- 'TODO(https://github.com/grpc/grpc/issues/17258)')
def test_server_sockets(self):
self._pairs = _generate_channel_server_pairs(1)
self._send_successful_unary_unary(0)
@@ -423,10 +403,6 @@ class ChannelzServicerTest(unittest.TestCase):
# If the RPC call failed, it will raise a grpc.RpcError
# So, if there is no exception raised, considered pass
- @unittest.skip('Servers in core are not guaranteed to be destroyed ' \
- 'immediately when the reference goes out of scope, so ' \
- 'servers from multiple test cases are not hermetic. ' \
- 'TODO(https://github.com/grpc/grpc/issues/17258)')
def test_server_listen_sockets(self):
self._pairs = _generate_channel_server_pairs(1)
diff --git a/src/python/grpcio_tests/tests/qps/worker_server.py b/src/python/grpcio_tests/tests/qps/worker_server.py
index 740bdcf1eb..337a94b546 100644
--- a/src/python/grpcio_tests/tests/qps/worker_server.py
+++ b/src/python/grpcio_tests/tests/qps/worker_server.py
@@ -39,7 +39,7 @@ class WorkerServer(worker_service_pb2_grpc.WorkerServiceServicer):
self._quit_event = threading.Event()
def RunServer(self, request_iterator, context):
- config = next(request_iterator).setup
+ config = next(request_iterator).setup #pylint: disable=stop-iteration-return
server, port = self._create_server(config)
cores = multiprocessing.cpu_count()
server.start()
@@ -102,7 +102,7 @@ class WorkerServer(worker_service_pb2_grpc.WorkerServiceServicer):
return (server, port)
def RunClient(self, request_iterator, context):
- config = next(request_iterator).setup
+ config = next(request_iterator).setup #pylint: disable=stop-iteration-return
client_runners = []
qps_data = histogram.Histogram(config.histogram_params.resolution,
config.histogram_params.max_possible)
diff --git a/src/python/grpcio_tests/tests/unit/_exit_scenarios.py b/src/python/grpcio_tests/tests/unit/_exit_scenarios.py
index f489db12cb..d1263c2c56 100644
--- a/src/python/grpcio_tests/tests/unit/_exit_scenarios.py
+++ b/src/python/grpcio_tests/tests/unit/_exit_scenarios.py
@@ -87,7 +87,7 @@ def hang_stream_stream(request_iterator, servicer_context):
def hang_partial_stream_stream(request_iterator, servicer_context):
for _ in range(test_constants.STREAM_LENGTH // 2):
- yield next(request_iterator)
+ yield next(request_iterator) #pylint: disable=stop-iteration-return
time.sleep(WAIT_TIME)
diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h
index 56d222c7ec..e61a35d09f 100644
--- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h
+++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h
@@ -272,7 +272,7 @@ extern grpc_channelz_get_servers_type grpc_channelz_get_servers_import;
typedef char*(*grpc_channelz_get_server_type)(intptr_t server_id);
extern grpc_channelz_get_server_type grpc_channelz_get_server_import;
#define grpc_channelz_get_server grpc_channelz_get_server_import
-typedef char*(*grpc_channelz_get_server_sockets_type)(intptr_t server_id, intptr_t start_socket_id);
+typedef char*(*grpc_channelz_get_server_sockets_type)(intptr_t server_id, intptr_t start_socket_id, intptr_t max_results);
extern grpc_channelz_get_server_sockets_type grpc_channelz_get_server_sockets_import;
#define grpc_channelz_get_server_sockets grpc_channelz_get_server_sockets_import
typedef char*(*grpc_channelz_get_channel_type)(intptr_t channel_id);
diff --git a/templates/gRPC-C++.podspec.template b/templates/gRPC-C++.podspec.template
index ab330415af..94d5a4fb09 100644
--- a/templates/gRPC-C++.podspec.template
+++ b/templates/gRPC-C++.podspec.template
@@ -127,12 +127,20 @@
def ruby_multiline_list(files, indent):
return (',\n' + indent*' ').join('\'%s\'' % f for f in files)
+
+ def modify_podspec_version_string(pod_version, grpc_version):
+ # Append -preX when it is a pre-release
+ if len(str(grpc_version).split('-')) > 1:
+ return pod_version + '-' + str(grpc_version).split('-')[-1]
+ else:
+ return pod_version
+
%>
Pod::Spec.new do |s|
s.name = 'gRPC-C++'
# TODO (mxyan): use version that match gRPC version when pod is stabilized
# version = '${settings.version}'
- version = '0.0.4'
+ version = '${modify_podspec_version_string('0.0.6', settings.version)}'
s.version = version
s.summary = 'gRPC C++ library'
s.homepage = 'https://grpc.io'
diff --git a/test/core/bad_client/bad_client.cc b/test/core/bad_client/bad_client.cc
index 4f5d2a2862..ae1e42a4e0 100644
--- a/test/core/bad_client/bad_client.cc
+++ b/test/core/bad_client/bad_client.cc
@@ -66,7 +66,7 @@ static void server_setup_transport(void* ts, grpc_transport* transport) {
thd_args* a = static_cast<thd_args*>(ts);
grpc_core::ExecCtx exec_ctx;
grpc_server_setup_transport(a->server, transport, nullptr,
- grpc_server_get_channel_args(a->server), 0);
+ grpc_server_get_channel_args(a->server), nullptr);
}
/* Sets the read_done event */
diff --git a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc
index 76769b2b64..1a7a7c9ccc 100644
--- a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc
+++ b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc
@@ -21,10 +21,10 @@
#include <grpc/grpc.h>
#include <grpc/support/alloc.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/resolver/dns/c_ares/grpc_ares_wrapper.h"
#include "src/core/ext/filters/client_channel/resolver_registry.h"
+#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/iomgr/combiner.h"
#include "src/core/lib/iomgr/resolve_address.h"
@@ -63,8 +63,9 @@ static grpc_address_resolver_vtable test_resolver = {my_resolve_address,
static grpc_ares_request* my_dns_lookup_ares_locked(
const char* dns_server, const char* addr, const char* default_port,
grpc_pollset_set* interested_parties, grpc_closure* on_done,
- grpc_lb_addresses** lb_addrs, bool check_grpclb, char** service_config_json,
- int query_timeout_ms, grpc_combiner* combiner) {
+ grpc_core::UniquePtr<grpc_core::ServerAddressList>* addresses,
+ bool check_grpclb, char** service_config_json, int query_timeout_ms,
+ grpc_combiner* combiner) {
gpr_mu_lock(&g_mu);
GPR_ASSERT(0 == strcmp("test", addr));
grpc_error* error = GRPC_ERROR_NONE;
@@ -74,9 +75,8 @@ static grpc_ares_request* my_dns_lookup_ares_locked(
error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Forced Failure");
} else {
gpr_mu_unlock(&g_mu);
- *lb_addrs = grpc_lb_addresses_create(1, nullptr);
- grpc_lb_addresses_set_address(*lb_addrs, 0, nullptr, 0, false, nullptr,
- nullptr);
+ *addresses = grpc_core::MakeUnique<grpc_core::ServerAddressList>();
+ (*addresses)->emplace_back(nullptr, 0, nullptr);
}
GRPC_CLOSURE_SCHED(on_done, error);
return nullptr;
diff --git a/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc b/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc
index cdbe33dbe7..16210b8164 100644
--- a/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc
+++ b/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc
@@ -22,6 +22,7 @@
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
#include "src/core/ext/filters/client_channel/resolver_registry.h"
+#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gprpp/memory.h"
#include "src/core/lib/iomgr/combiner.h"
@@ -40,8 +41,9 @@ static grpc_combiner* g_combiner;
static grpc_ares_request* (*g_default_dns_lookup_ares_locked)(
const char* dns_server, const char* name, const char* default_port,
grpc_pollset_set* interested_parties, grpc_closure* on_done,
- grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json,
- int query_timeout_ms, grpc_combiner* combiner);
+ grpc_core::UniquePtr<grpc_core::ServerAddressList>* addresses,
+ bool check_grpclb, char** service_config_json, int query_timeout_ms,
+ grpc_combiner* combiner);
// Counter incremented by test_resolve_address_impl indicating the number of
// times a system-level resolution has happened.
@@ -90,11 +92,12 @@ static grpc_address_resolver_vtable test_resolver = {
static grpc_ares_request* test_dns_lookup_ares_locked(
const char* dns_server, const char* name, const char* default_port,
grpc_pollset_set* interested_parties, grpc_closure* on_done,
- grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json,
- int query_timeout_ms, grpc_combiner* combiner) {
+ grpc_core::UniquePtr<grpc_core::ServerAddressList>* addresses,
+ bool check_grpclb, char** service_config_json, int query_timeout_ms,
+ grpc_combiner* combiner) {
grpc_ares_request* result = g_default_dns_lookup_ares_locked(
- dns_server, name, default_port, g_iomgr_args.pollset_set, on_done, addrs,
- check_grpclb, service_config_json, query_timeout_ms, combiner);
+ dns_server, name, default_port, g_iomgr_args.pollset_set, on_done,
+ addresses, check_grpclb, service_config_json, query_timeout_ms, combiner);
++g_resolution_count;
static grpc_millis last_resolution_time = 0;
if (last_resolution_time == 0) {
diff --git a/test/core/client_channel/resolvers/fake_resolver_test.cc b/test/core/client_channel/resolvers/fake_resolver_test.cc
index 6362b95e50..3b06fe063a 100644
--- a/test/core/client_channel/resolvers/fake_resolver_test.cc
+++ b/test/core/client_channel/resolvers/fake_resolver_test.cc
@@ -22,10 +22,10 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
-#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
#include "src/core/ext/filters/client_channel/parse_address.h"
#include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h"
#include "src/core/ext/filters/client_channel/resolver_registry.h"
+#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/iomgr/combiner.h"
@@ -63,12 +63,14 @@ void on_resolution_cb(void* arg, grpc_error* error) {
// We only check the addresses channel arg because that's the only one
// explicitly set by the test via
// FakeResolverResponseGenerator::SetResponse().
- const grpc_lb_addresses* actual_lb_addresses =
- grpc_lb_addresses_find_channel_arg(res->resolver_result);
- const grpc_lb_addresses* expected_lb_addresses =
- grpc_lb_addresses_find_channel_arg(res->expected_resolver_result);
- GPR_ASSERT(
- grpc_lb_addresses_cmp(actual_lb_addresses, expected_lb_addresses) == 0);
+ const grpc_core::ServerAddressList* actual_addresses =
+ grpc_core::FindServerAddressListChannelArg(res->resolver_result);
+ const grpc_core::ServerAddressList* expected_addresses =
+ grpc_core::FindServerAddressListChannelArg(res->expected_resolver_result);
+ GPR_ASSERT(actual_addresses->size() == expected_addresses->size());
+ for (size_t i = 0; i < expected_addresses->size(); ++i) {
+ GPR_ASSERT((*actual_addresses)[i] == (*expected_addresses)[i]);
+ }
grpc_channel_args_destroy(res->resolver_result);
grpc_channel_args_destroy(res->expected_resolver_result);
gpr_event_set(&res->ev, (void*)1);
@@ -80,27 +82,35 @@ static grpc_channel_args* create_new_resolver_result() {
const size_t num_addresses = 2;
char* uri_string;
char* balancer_name;
- // Create grpc_lb_addresses.
- grpc_lb_addresses* addresses =
- grpc_lb_addresses_create(num_addresses, nullptr);
+ // Create address list.
+ grpc_core::ServerAddressList addresses;
for (size_t i = 0; i < num_addresses; ++i) {
gpr_asprintf(&uri_string, "ipv4:127.0.0.1:100%" PRIuPTR,
test_counter * num_addresses + i);
grpc_uri* uri = grpc_uri_parse(uri_string, true);
gpr_asprintf(&balancer_name, "balancer%" PRIuPTR,
test_counter * num_addresses + i);
- grpc_lb_addresses_set_address_from_uri(
- addresses, i, uri, bool(num_addresses % 2), balancer_name, nullptr);
+ grpc_resolved_address address;
+ GPR_ASSERT(grpc_parse_uri(uri, &address));
+ grpc_core::InlinedVector<grpc_arg, 2> args_to_add;
+ const bool is_balancer = num_addresses % 2;
+ if (is_balancer) {
+ args_to_add.emplace_back(grpc_channel_arg_integer_create(
+ const_cast<char*>(GRPC_ARG_ADDRESS_IS_BALANCER), 1));
+ args_to_add.emplace_back(grpc_channel_arg_string_create(
+ const_cast<char*>(GRPC_ARG_ADDRESS_BALANCER_NAME), balancer_name));
+ }
+ grpc_channel_args* args = grpc_channel_args_copy_and_add(
+ nullptr, args_to_add.data(), args_to_add.size());
+ addresses.emplace_back(address.addr, address.len, args);
gpr_free(balancer_name);
grpc_uri_destroy(uri);
gpr_free(uri_string);
}
- // Convert grpc_lb_addresses to grpc_channel_args.
- const grpc_arg addresses_arg =
- grpc_lb_addresses_create_channel_arg(addresses);
+ // Embed the address list in channel args.
+ const grpc_arg addresses_arg = CreateServerAddressListChannelArg(&addresses);
grpc_channel_args* results =
grpc_channel_args_copy_and_add(nullptr, &addresses_arg, 1);
- grpc_lb_addresses_destroy(addresses);
++test_counter;
return results;
}
diff --git a/test/core/end2end/fixtures/h2_sockpair+trace.cc b/test/core/end2end/fixtures/h2_sockpair+trace.cc
index 4f393b22d0..45f78b5964 100644
--- a/test/core/end2end/fixtures/h2_sockpair+trace.cc
+++ b/test/core/end2end/fixtures/h2_sockpair+trace.cc
@@ -53,7 +53,7 @@ static void server_setup_transport(void* ts, grpc_transport* transport) {
grpc_endpoint_pair* sfd = static_cast<grpc_endpoint_pair*>(f->fixture_data);
grpc_endpoint_add_to_pollset(sfd->server, grpc_cq_pollset(f->cq));
grpc_server_setup_transport(f->server, transport, nullptr,
- grpc_server_get_channel_args(f->server), 0);
+ grpc_server_get_channel_args(f->server), nullptr);
}
typedef struct {
diff --git a/test/core/end2end/fixtures/h2_sockpair.cc b/test/core/end2end/fixtures/h2_sockpair.cc
index 1627fe0eb4..77bce7ebb3 100644
--- a/test/core/end2end/fixtures/h2_sockpair.cc
+++ b/test/core/end2end/fixtures/h2_sockpair.cc
@@ -47,7 +47,7 @@ static void server_setup_transport(void* ts, grpc_transport* transport) {
grpc_endpoint_pair* sfd = static_cast<grpc_endpoint_pair*>(f->fixture_data);
grpc_endpoint_add_to_pollset(sfd->server, grpc_cq_pollset(f->cq));
grpc_server_setup_transport(f->server, transport, nullptr,
- grpc_server_get_channel_args(f->server), 0);
+ grpc_server_get_channel_args(f->server), nullptr);
}
typedef struct {
diff --git a/test/core/end2end/fixtures/h2_sockpair_1byte.cc b/test/core/end2end/fixtures/h2_sockpair_1byte.cc
index 8f1024b774..ac37841dc4 100644
--- a/test/core/end2end/fixtures/h2_sockpair_1byte.cc
+++ b/test/core/end2end/fixtures/h2_sockpair_1byte.cc
@@ -47,7 +47,7 @@ static void server_setup_transport(void* ts, grpc_transport* transport) {
grpc_endpoint_pair* sfd = static_cast<grpc_endpoint_pair*>(f->fixture_data);
grpc_endpoint_add_to_pollset(sfd->server, grpc_cq_pollset(f->cq));
grpc_server_setup_transport(f->server, transport, nullptr,
- grpc_server_get_channel_args(f->server), 0);
+ grpc_server_get_channel_args(f->server), nullptr);
}
typedef struct {
diff --git a/test/core/end2end/fuzzers/api_fuzzer.cc b/test/core/end2end/fuzzers/api_fuzzer.cc
index 9b6eddee6e..fe47127984 100644
--- a/test/core/end2end/fuzzers/api_fuzzer.cc
+++ b/test/core/end2end/fuzzers/api_fuzzer.cc
@@ -24,8 +24,8 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
-#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
+#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/env.h"
@@ -325,7 +325,7 @@ typedef struct addr_req {
char* addr;
grpc_closure* on_done;
grpc_resolved_addresses** addrs;
- grpc_lb_addresses** lb_addrs;
+ grpc_core::UniquePtr<grpc_core::ServerAddressList>* addresses;
} addr_req;
static void finish_resolve(void* arg, grpc_error* error) {
@@ -340,11 +340,9 @@ static void finish_resolve(void* arg, grpc_error* error) {
gpr_malloc(sizeof(*addrs->addrs)));
addrs->addrs[0].len = 0;
*r->addrs = addrs;
- } else if (r->lb_addrs != nullptr) {
- grpc_lb_addresses* lb_addrs = grpc_lb_addresses_create(1, nullptr);
- grpc_lb_addresses_set_address(lb_addrs, 0, nullptr, 0, false, nullptr,
- nullptr);
- *r->lb_addrs = lb_addrs;
+ } else if (r->addresses != nullptr) {
+ *r->addresses = grpc_core::MakeUnique<grpc_core::ServerAddressList>();
+ (*r->addresses)->emplace_back(nullptr, 0, nullptr);
}
GRPC_CLOSURE_SCHED(r->on_done, GRPC_ERROR_NONE);
} else {
@@ -354,18 +352,17 @@ static void finish_resolve(void* arg, grpc_error* error) {
}
gpr_free(r->addr);
- gpr_free(r);
+ grpc_core::Delete(r);
}
void my_resolve_address(const char* addr, const char* default_port,
grpc_pollset_set* interested_parties,
grpc_closure* on_done,
- grpc_resolved_addresses** addresses) {
- addr_req* r = static_cast<addr_req*>(gpr_malloc(sizeof(*r)));
+ grpc_resolved_addresses** addrs) {
+ addr_req* r = grpc_core::New<addr_req>();
r->addr = gpr_strdup(addr);
r->on_done = on_done;
- r->addrs = addresses;
- r->lb_addrs = nullptr;
+ r->addrs = addrs;
grpc_timer_init(
&r->timer, GPR_MS_PER_SEC + grpc_core::ExecCtx::Get()->Now(),
GRPC_CLOSURE_CREATE(finish_resolve, r, grpc_schedule_on_exec_ctx));
@@ -377,13 +374,14 @@ static grpc_address_resolver_vtable fuzzer_resolver = {my_resolve_address,
grpc_ares_request* my_dns_lookup_ares_locked(
const char* dns_server, const char* addr, const char* default_port,
grpc_pollset_set* interested_parties, grpc_closure* on_done,
- grpc_lb_addresses** lb_addrs, bool check_grpclb, char** service_config_json,
- int query_timeout, grpc_combiner* combiner) {
+ grpc_core::UniquePtr<grpc_core::ServerAddressList>* addresses,
+ bool check_grpclb, char** service_config_json, int query_timeout,
+ grpc_combiner* combiner) {
addr_req* r = static_cast<addr_req*>(gpr_malloc(sizeof(*r)));
r->addr = gpr_strdup(addr);
r->on_done = on_done;
r->addrs = nullptr;
- r->lb_addrs = lb_addrs;
+ r->addresses = addresses;
grpc_timer_init(
&r->timer, GPR_MS_PER_SEC + grpc_core::ExecCtx::Get()->Now(),
GRPC_CLOSURE_CREATE(finish_resolve, r, grpc_schedule_on_exec_ctx));
@@ -420,7 +418,7 @@ static void do_connect(void* arg, grpc_error* error) {
grpc_transport* transport =
grpc_create_chttp2_transport(nullptr, server, false);
- grpc_server_setup_transport(g_server, transport, nullptr, nullptr, 0);
+ grpc_server_setup_transport(g_server, transport, nullptr, nullptr, nullptr);
grpc_chttp2_transport_start_reading(transport, nullptr, nullptr);
GRPC_CLOSURE_SCHED(fc->closure, GRPC_ERROR_NONE);
diff --git a/test/core/end2end/fuzzers/server_fuzzer.cc b/test/core/end2end/fuzzers/server_fuzzer.cc
index bd686215dd..d370dc7de8 100644
--- a/test/core/end2end/fuzzers/server_fuzzer.cc
+++ b/test/core/end2end/fuzzers/server_fuzzer.cc
@@ -62,7 +62,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
grpc_server_start(server);
grpc_transport* transport =
grpc_create_chttp2_transport(nullptr, mock_endpoint, false);
- grpc_server_setup_transport(server, transport, nullptr, nullptr, 0);
+ grpc_server_setup_transport(server, transport, nullptr, nullptr, nullptr);
grpc_chttp2_transport_start_reading(transport, nullptr, nullptr);
grpc_call* call1 = nullptr;
diff --git a/test/core/end2end/goaway_server_test.cc b/test/core/end2end/goaway_server_test.cc
index 66e8ca5161..7e3b418cd9 100644
--- a/test/core/end2end/goaway_server_test.cc
+++ b/test/core/end2end/goaway_server_test.cc
@@ -28,8 +28,8 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <string.h>
-#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
+#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/lib/iomgr/resolve_address.h"
#include "src/core/lib/iomgr/sockaddr.h"
#include "test/core/end2end/cq_verifier.h"
@@ -47,8 +47,9 @@ static int g_resolve_port = -1;
static grpc_ares_request* (*iomgr_dns_lookup_ares_locked)(
const char* dns_server, const char* addr, const char* default_port,
grpc_pollset_set* interested_parties, grpc_closure* on_done,
- grpc_lb_addresses** addresses, bool check_grpclb,
- char** service_config_json, int query_timeout_ms, grpc_combiner* combiner);
+ grpc_core::UniquePtr<grpc_core::ServerAddressList>* addresses,
+ bool check_grpclb, char** service_config_json, int query_timeout_ms,
+ grpc_combiner* combiner);
static void (*iomgr_cancel_ares_request_locked)(grpc_ares_request* request);
@@ -103,11 +104,12 @@ static grpc_address_resolver_vtable test_resolver = {
static grpc_ares_request* my_dns_lookup_ares_locked(
const char* dns_server, const char* addr, const char* default_port,
grpc_pollset_set* interested_parties, grpc_closure* on_done,
- grpc_lb_addresses** lb_addrs, bool check_grpclb, char** service_config_json,
- int query_timeout_ms, grpc_combiner* combiner) {
+ grpc_core::UniquePtr<grpc_core::ServerAddressList>* addresses,
+ bool check_grpclb, char** service_config_json, int query_timeout_ms,
+ grpc_combiner* combiner) {
if (0 != strcmp(addr, "test")) {
return iomgr_dns_lookup_ares_locked(
- dns_server, addr, default_port, interested_parties, on_done, lb_addrs,
+ dns_server, addr, default_port, interested_parties, on_done, addresses,
check_grpclb, service_config_json, query_timeout_ms, combiner);
}
@@ -117,15 +119,12 @@ static grpc_ares_request* my_dns_lookup_ares_locked(
gpr_mu_unlock(&g_mu);
error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Forced Failure");
} else {
- *lb_addrs = grpc_lb_addresses_create(1, nullptr);
- grpc_sockaddr_in* sa =
- static_cast<grpc_sockaddr_in*>(gpr_zalloc(sizeof(grpc_sockaddr_in)));
- sa->sin_family = GRPC_AF_INET;
- sa->sin_addr.s_addr = 0x100007f;
- sa->sin_port = grpc_htons(static_cast<uint16_t>(g_resolve_port));
- grpc_lb_addresses_set_address(*lb_addrs, 0, sa, sizeof(*sa), false, nullptr,
- nullptr);
- gpr_free(sa);
+ *addresses = grpc_core::MakeUnique<grpc_core::ServerAddressList>();
+ grpc_sockaddr_in sa;
+ sa.sin_family = GRPC_AF_INET;
+ sa.sin_addr.s_addr = 0x100007f;
+ sa.sin_port = grpc_htons(static_cast<uint16_t>(g_resolve_port));
+ (*addresses)->emplace_back(&sa, sizeof(sa), nullptr);
gpr_mu_unlock(&g_mu);
}
GRPC_CLOSURE_SCHED(on_done, error);
diff --git a/test/core/end2end/no_server_test.cc b/test/core/end2end/no_server_test.cc
index 5dda748f5a..c289e719ee 100644
--- a/test/core/end2end/no_server_test.cc
+++ b/test/core/end2end/no_server_test.cc
@@ -23,6 +23,7 @@
#include <grpc/support/log.h>
#include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
#include "test/core/end2end/cq_verifier.h"
#include "test/core/util/test_config.h"
diff --git a/test/core/end2end/tests/channelz.cc b/test/core/end2end/tests/channelz.cc
index 922783aa0d..169190eec0 100644
--- a/test/core/end2end/tests/channelz.cc
+++ b/test/core/end2end/tests/channelz.cc
@@ -259,8 +259,8 @@ static void test_channelz(grpc_end2end_test_config config) {
GPR_ASSERT(nullptr == strstr(json, "\"severity\":\"CT_INFO\""));
gpr_free(json);
- json = channelz_server->RenderServerSockets(0);
- GPR_ASSERT(nullptr != strstr(json, "\"socketRef\":"));
+ json = channelz_server->RenderServerSockets(0, 100);
+ GPR_ASSERT(nullptr != strstr(json, "\"end\":true"));
gpr_free(json);
end_test(&f);
diff --git a/test/core/security/credentials_test.cc b/test/core/security/credentials_test.cc
index b3e3c3c741..a7a6050ec0 100644
--- a/test/core/security/credentials_test.cc
+++ b/test/core/security/credentials_test.cc
@@ -919,6 +919,22 @@ static void test_google_default_creds_refresh_token(void) {
gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, ""); /* Reset. */
}
+static int default_creds_metadata_server_detection_httpcli_get_success_override(
+ const grpc_httpcli_request* request, grpc_millis deadline,
+ grpc_closure* on_done, grpc_httpcli_response* response) {
+ *response = http_response(200, "");
+ grpc_http_header* headers =
+ static_cast<grpc_http_header*>(gpr_malloc(sizeof(*headers) * 1));
+ headers[0].key = gpr_strdup("Metadata-Flavor");
+ headers[0].value = gpr_strdup("Google");
+ response->hdr_count = 1;
+ response->hdrs = headers;
+ GPR_ASSERT(strcmp(request->http.path, "/") == 0);
+ GPR_ASSERT(strcmp(request->host, "metadata.google.internal") == 0);
+ GRPC_CLOSURE_SCHED(on_done, GRPC_ERROR_NONE);
+ return 1;
+}
+
static char* null_well_known_creds_path_getter(void) { return nullptr; }
static bool test_gce_tenancy_checker(void) {
@@ -963,26 +979,73 @@ static void test_google_default_creds_gce(void) {
grpc_override_well_known_credentials_path_getter(nullptr);
}
-static void test_no_google_default_creds(void) {
+static void test_google_default_creds_non_gce(void) {
+ grpc_core::ExecCtx exec_ctx;
+ expected_md emd[] = {
+ {"authorization", "Bearer ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_"}};
+ request_metadata_state* state =
+ make_request_metadata_state(GRPC_ERROR_NONE, emd, GPR_ARRAY_SIZE(emd));
+ grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method,
+ nullptr, nullptr};
grpc_flush_cached_google_default_credentials();
gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, ""); /* Reset. */
grpc_override_well_known_credentials_path_getter(
null_well_known_creds_path_getter);
-
set_gce_tenancy_checker_for_testing(test_gce_tenancy_checker);
g_test_gce_tenancy_checker_called = false;
g_test_is_on_gce = false;
+ /* Simulate a successful detection of metadata server. */
+ grpc_httpcli_set_override(
+ default_creds_metadata_server_detection_httpcli_get_success_override,
+ httpcli_post_should_not_be_called);
+ grpc_composite_channel_credentials* creds =
+ reinterpret_cast<grpc_composite_channel_credentials*>(
+ grpc_google_default_credentials_create());
+ /* Verify that the default creds actually embeds a GCE creds. */
+ GPR_ASSERT(creds != nullptr);
+ GPR_ASSERT(creds->call_creds != nullptr);
+ grpc_httpcli_set_override(compute_engine_httpcli_get_success_override,
+ httpcli_post_should_not_be_called);
+ run_request_metadata_test(creds->call_creds, auth_md_ctx, state);
+ grpc_core::ExecCtx::Get()->Flush();
+ GPR_ASSERT(g_test_gce_tenancy_checker_called == true);
+ /* Cleanup. */
+ grpc_channel_credentials_unref(&creds->base);
+ grpc_httpcli_set_override(nullptr, nullptr);
+ grpc_override_well_known_credentials_path_getter(nullptr);
+}
+
+static int default_creds_gce_detection_httpcli_get_failure_override(
+ const grpc_httpcli_request* request, grpc_millis deadline,
+ grpc_closure* on_done, grpc_httpcli_response* response) {
+ /* No magic header. */
+ GPR_ASSERT(strcmp(request->http.path, "/") == 0);
+ GPR_ASSERT(strcmp(request->host, "metadata.google.internal") == 0);
+ *response = http_response(200, "");
+ GRPC_CLOSURE_SCHED(on_done, GRPC_ERROR_NONE);
+ return 1;
+}
+static void test_no_google_default_creds(void) {
+ grpc_flush_cached_google_default_credentials();
+ gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, ""); /* Reset. */
+ grpc_override_well_known_credentials_path_getter(
+ null_well_known_creds_path_getter);
+ set_gce_tenancy_checker_for_testing(test_gce_tenancy_checker);
+ g_test_gce_tenancy_checker_called = false;
+ g_test_is_on_gce = false;
+ grpc_httpcli_set_override(
+ default_creds_gce_detection_httpcli_get_failure_override,
+ httpcli_post_should_not_be_called);
/* Simulate a successful detection of GCE. */
GPR_ASSERT(grpc_google_default_credentials_create() == nullptr);
-
- /* Try a second one. GCE detection should not occur anymore. */
+ /* Try a second one. GCE detection should occur again. */
g_test_gce_tenancy_checker_called = false;
GPR_ASSERT(grpc_google_default_credentials_create() == nullptr);
- GPR_ASSERT(g_test_gce_tenancy_checker_called == false);
-
+ GPR_ASSERT(g_test_gce_tenancy_checker_called == true);
/* Cleanup. */
grpc_override_well_known_credentials_path_getter(nullptr);
+ grpc_httpcli_set_override(nullptr, nullptr);
}
typedef enum {
@@ -1233,6 +1296,7 @@ int main(int argc, char** argv) {
test_google_default_creds_auth_key();
test_google_default_creds_refresh_token();
test_google_default_creds_gce();
+ test_google_default_creds_non_gce();
test_no_google_default_creds();
test_metadata_plugin_success();
test_metadata_plugin_failure();
diff --git a/test/core/util/ubsan_suppressions.txt b/test/core/util/ubsan_suppressions.txt
index 63898ea3b1..8ed7d4d7fb 100644
--- a/test/core/util/ubsan_suppressions.txt
+++ b/test/core/util/ubsan_suppressions.txt
@@ -25,7 +25,6 @@ alignment:absl::little_endian::Store64
alignment:absl::little_endian::Load64
float-divide-by-zero:grpc::testing::postprocess_scenario_result
enum:grpc_op_string
-nonnull-attribute:grpc_lb_addresses_copy
signed-integer-overflow:chrono
enum:grpc_http2_error_to_grpc_status
-enum:grpc_chttp2_cancel_stream \ No newline at end of file
+enum:grpc_chttp2_cancel_stream
diff --git a/test/cpp/client/client_channel_stress_test.cc b/test/cpp/client/client_channel_stress_test.cc
index bf321d8a89..124557eb56 100644
--- a/test/cpp/client/client_channel_stress_test.cc
+++ b/test/cpp/client/client_channel_stress_test.cc
@@ -34,7 +34,9 @@
#include <grpcpp/server.h>
#include <grpcpp/server_builder.h>
+#include "src/core/ext/filters/client_channel/parse_address.h"
#include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h"
+#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/gprpp/thd.h"
#include "src/core/lib/iomgr/sockaddr.h"
@@ -216,23 +218,31 @@ class ClientChannelStressTest {
void SetNextResolution(const std::vector<AddressData>& address_data) {
grpc_core::ExecCtx exec_ctx;
- grpc_lb_addresses* addresses =
- grpc_lb_addresses_create(address_data.size(), nullptr);
- for (size_t i = 0; i < address_data.size(); ++i) {
+ grpc_core::ServerAddressList addresses;
+ for (const auto& addr : address_data) {
char* lb_uri_str;
- gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", address_data[i].port);
+ gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", addr.port);
grpc_uri* lb_uri = grpc_uri_parse(lb_uri_str, true);
GPR_ASSERT(lb_uri != nullptr);
- grpc_lb_addresses_set_address_from_uri(
- addresses, i, lb_uri, address_data[i].is_balancer,
- address_data[i].balancer_name.c_str(), nullptr);
+ grpc_resolved_address address;
+ GPR_ASSERT(grpc_parse_uri(lb_uri, &address));
+ std::vector<grpc_arg> args_to_add;
+ if (addr.is_balancer) {
+ args_to_add.emplace_back(grpc_channel_arg_integer_create(
+ const_cast<char*>(GRPC_ARG_ADDRESS_IS_BALANCER), 1));
+ args_to_add.emplace_back(grpc_channel_arg_string_create(
+ const_cast<char*>(GRPC_ARG_ADDRESS_BALANCER_NAME),
+ const_cast<char*>(addr.balancer_name.c_str())));
+ }
+ grpc_channel_args* args = grpc_channel_args_copy_and_add(
+ nullptr, args_to_add.data(), args_to_add.size());
+ addresses.emplace_back(address.addr, address.len, args);
grpc_uri_destroy(lb_uri);
gpr_free(lb_uri_str);
}
- grpc_arg fake_addresses = grpc_lb_addresses_create_channel_arg(addresses);
+ grpc_arg fake_addresses = CreateServerAddressListChannelArg(&addresses);
grpc_channel_args fake_result = {1, &fake_addresses};
response_generator_->SetResponse(&fake_result);
- grpc_lb_addresses_destroy(addresses);
}
void KeepSendingRequests() {
diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD
index 446804401a..eb600ffb17 100644
--- a/test/cpp/end2end/BUILD
+++ b/test/cpp/end2end/BUILD
@@ -36,6 +36,18 @@ grpc_cc_library(
)
grpc_cc_library(
+ name = "test_health_check_service_impl",
+ testonly = True,
+ srcs = ["test_health_check_service_impl.cc"],
+ hdrs = ["test_health_check_service_impl.h"],
+ deps = [
+ "//:grpc",
+ "//:grpc++",
+ "//src/proto/grpc/health/v1:health_proto",
+ ],
+)
+
+grpc_cc_library(
name = "interceptors_util",
testonly = True,
srcs = ["interceptors_util.cc"],
@@ -283,6 +295,7 @@ grpc_cc_test(
"gtest",
],
deps = [
+ ":test_health_check_service_impl",
":test_service_impl",
"//:gpr",
"//:grpc",
diff --git a/test/cpp/end2end/channelz_service_test.cc b/test/cpp/end2end/channelz_service_test.cc
index 29b59e4e5e..425334d972 100644
--- a/test/cpp/end2end/channelz_service_test.cc
+++ b/test/cpp/end2end/channelz_service_test.cc
@@ -54,6 +54,14 @@ using grpc::channelz::v1::GetSubchannelResponse;
using grpc::channelz::v1::GetTopChannelsRequest;
using grpc::channelz::v1::GetTopChannelsResponse;
+// This code snippet can be used to print out any responses for
+// visual debugging.
+//
+//
+// string out_str;
+// google::protobuf::TextFormat::PrintToString(resp, &out_str);
+// std::cout << "resp: " << out_str << "\n";
+
namespace grpc {
namespace testing {
namespace {
@@ -164,6 +172,19 @@ class ChannelzServerTest : public ::testing::Test {
echo_stub_ = grpc::testing::EchoTestService::NewStub(channel);
}
+ std::unique_ptr<grpc::testing::EchoTestService::Stub> NewEchoStub() {
+ static int salt = 0;
+ string target = "dns:localhost:" + to_string(proxy_port_);
+ ChannelArguments args;
+ // disable channelz. We only want to focus on proxy to backend outbound.
+ args.SetInt(GRPC_ARG_ENABLE_CHANNELZ, 0);
+ // This ensures that gRPC will not do connection sharing.
+ args.SetInt("salt", salt++);
+ std::shared_ptr<Channel> channel =
+ CreateCustomChannel(target, InsecureChannelCredentials(), args);
+ return grpc::testing::EchoTestService::NewStub(channel);
+ }
+
void SendSuccessfulEcho(int channel_idx) {
EchoRequest request;
EchoResponse response;
@@ -651,6 +672,67 @@ TEST_F(ChannelzServerTest, GetServerSocketsTest) {
EXPECT_EQ(get_server_sockets_response.socket_ref_size(), 1);
}
+TEST_F(ChannelzServerTest, GetServerSocketsPaginationTest) {
+ ResetStubs();
+ ConfigureProxy(1);
+ std::vector<std::unique_ptr<grpc::testing::EchoTestService::Stub>> stubs;
+ const int kNumServerSocketsCreated = 20;
+ for (int i = 0; i < kNumServerSocketsCreated; ++i) {
+ stubs.push_back(NewEchoStub());
+ EchoRequest request;
+ EchoResponse response;
+ request.set_message("Hello channelz");
+ request.mutable_param()->set_backend_channel_idx(0);
+ ClientContext context;
+ Status s = stubs.back()->Echo(&context, request, &response);
+ EXPECT_EQ(response.message(), request.message());
+ EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message();
+ }
+ GetServersRequest get_server_request;
+ GetServersResponse get_server_response;
+ get_server_request.set_start_server_id(0);
+ ClientContext get_server_context;
+ Status s = channelz_stub_->GetServers(&get_server_context, get_server_request,
+ &get_server_response);
+ EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message();
+ EXPECT_EQ(get_server_response.server_size(), 1);
+ // Make a request that gets all of the serversockets
+ {
+ GetServerSocketsRequest get_server_sockets_request;
+ GetServerSocketsResponse get_server_sockets_response;
+ get_server_sockets_request.set_server_id(
+ get_server_response.server(0).ref().server_id());
+ get_server_sockets_request.set_start_socket_id(0);
+ ClientContext get_server_sockets_context;
+ s = channelz_stub_->GetServerSockets(&get_server_sockets_context,
+ get_server_sockets_request,
+ &get_server_sockets_response);
+ EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message();
+ // We add one to account the the channelz stub that will end up creating
+ // a serversocket.
+ EXPECT_EQ(get_server_sockets_response.socket_ref_size(),
+ kNumServerSocketsCreated + 1);
+ EXPECT_TRUE(get_server_sockets_response.end());
+ }
+ // Now we make a request that exercises pagination.
+ {
+ GetServerSocketsRequest get_server_sockets_request;
+ GetServerSocketsResponse get_server_sockets_response;
+ get_server_sockets_request.set_server_id(
+ get_server_response.server(0).ref().server_id());
+ get_server_sockets_request.set_start_socket_id(0);
+ const int kMaxResults = 10;
+ get_server_sockets_request.set_max_results(kMaxResults);
+ ClientContext get_server_sockets_context;
+ s = channelz_stub_->GetServerSockets(&get_server_sockets_context,
+ get_server_sockets_request,
+ &get_server_sockets_response);
+ EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message();
+ EXPECT_EQ(get_server_sockets_response.socket_ref_size(), kMaxResults);
+ EXPECT_FALSE(get_server_sockets_response.end());
+ }
+}
+
TEST_F(ChannelzServerTest, GetServerListenSocketsTest) {
ResetStubs();
ConfigureProxy(1);
diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc
index 65434bac6b..a999321992 100644
--- a/test/cpp/end2end/client_callback_end2end_test.cc
+++ b/test/cpp/end2end/client_callback_end2end_test.cc
@@ -182,7 +182,7 @@ class ClientCallbackEnd2endTest
}
}
- void SendGenericEchoAsBidi(int num_rpcs) {
+ void SendGenericEchoAsBidi(int num_rpcs, int reuses) {
const grpc::string kMethodName("/grpc.testing.EchoTestService/Echo");
grpc::string test_string("");
for (int i = 0; i < num_rpcs; i++) {
@@ -191,14 +191,26 @@ class ClientCallbackEnd2endTest
ByteBuffer> {
public:
Client(ClientCallbackEnd2endTest* test, const grpc::string& method_name,
- const grpc::string& test_str) {
- test->generic_stub_->experimental().PrepareBidiStreamingCall(
- &cli_ctx_, method_name, this);
- request_.set_message(test_str);
- send_buf_ = SerializeToByteBuffer(&request_);
- StartWrite(send_buf_.get());
- StartRead(&recv_buf_);
- StartCall();
+ const grpc::string& test_str, int reuses)
+ : reuses_remaining_(reuses) {
+ activate_ = [this, test, method_name, test_str] {
+ if (reuses_remaining_ > 0) {
+ cli_ctx_.reset(new ClientContext);
+ reuses_remaining_--;
+ test->generic_stub_->experimental().PrepareBidiStreamingCall(
+ cli_ctx_.get(), method_name, this);
+ request_.set_message(test_str);
+ send_buf_ = SerializeToByteBuffer(&request_);
+ StartWrite(send_buf_.get());
+ StartRead(&recv_buf_);
+ StartCall();
+ } else {
+ std::unique_lock<std::mutex> l(mu_);
+ done_ = true;
+ cv_.notify_one();
+ }
+ };
+ activate_();
}
void OnWriteDone(bool ok) override { StartWritesDone(); }
void OnReadDone(bool ok) override {
@@ -208,9 +220,7 @@ class ClientCallbackEnd2endTest
};
void OnDone(const Status& s) override {
EXPECT_TRUE(s.ok());
- std::unique_lock<std::mutex> l(mu_);
- done_ = true;
- cv_.notify_one();
+ activate_();
}
void Await() {
std::unique_lock<std::mutex> l(mu_);
@@ -222,11 +232,13 @@ class ClientCallbackEnd2endTest
EchoRequest request_;
std::unique_ptr<ByteBuffer> send_buf_;
ByteBuffer recv_buf_;
- ClientContext cli_ctx_;
+ std::unique_ptr<ClientContext> cli_ctx_;
+ int reuses_remaining_;
+ std::function<void()> activate_;
std::mutex mu_;
std::condition_variable cv_;
bool done_ = false;
- } rpc{this, kMethodName, test_string};
+ } rpc{this, kMethodName, test_string, reuses};
rpc.Await();
}
@@ -293,7 +305,12 @@ TEST_P(ClientCallbackEnd2endTest, SequentialGenericRpcs) {
TEST_P(ClientCallbackEnd2endTest, SequentialGenericRpcsAsBidi) {
ResetStub();
- SendGenericEchoAsBidi(10);
+ SendGenericEchoAsBidi(10, 1);
+}
+
+TEST_P(ClientCallbackEnd2endTest, SequentialGenericRpcsAsBidiWithReactorReuse) {
+ ResetStub();
+ SendGenericEchoAsBidi(10, 10);
}
#if GRPC_ALLOW_EXCEPTIONS
diff --git a/test/cpp/end2end/client_interceptors_end2end_test.cc b/test/cpp/end2end/client_interceptors_end2end_test.cc
index 3a191d1e03..968b5d49d1 100644
--- a/test/cpp/end2end/client_interceptors_end2end_test.cc
+++ b/test/cpp/end2end/client_interceptors_end2end_test.cc
@@ -50,6 +50,7 @@ class HijackingInterceptor : public experimental::Interceptor {
info_ = info;
// Make sure it is the right method
EXPECT_EQ(strcmp("/grpc.testing.EchoTestService/Echo", info->method()), 0);
+ EXPECT_EQ(info->type(), experimental::ClientRpcInfo::Type::UNARY);
}
virtual void Intercept(experimental::InterceptorBatchMethods* methods) {
@@ -383,6 +384,7 @@ TEST_F(ClientInterceptorsEnd2endTest, ClientInterceptorHijackingTest) {
std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
creators;
// Add 20 dummy interceptors before hijacking interceptor
+ creators.reserve(20);
for (auto i = 0; i < 20; i++) {
creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
new DummyInterceptorFactory()));
@@ -423,6 +425,7 @@ TEST_F(ClientInterceptorsEnd2endTest,
std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
creators;
// Add 5 dummy interceptors before hijacking interceptor
+ creators.reserve(5);
for (auto i = 0; i < 5; i++) {
creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
new DummyInterceptorFactory()));
@@ -570,6 +573,7 @@ TEST_F(ClientGlobalInterceptorEnd2endTest, DummyGlobalInterceptor) {
std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
creators;
// Add 20 dummy interceptors
+ creators.reserve(20);
for (auto i = 0; i < 20; i++) {
creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
new DummyInterceptorFactory()));
@@ -595,6 +599,7 @@ TEST_F(ClientGlobalInterceptorEnd2endTest, LoggingGlobalInterceptor) {
std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
creators;
// Add 20 dummy interceptors
+ creators.reserve(20);
for (auto i = 0; i < 20; i++) {
creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
new DummyInterceptorFactory()));
@@ -620,6 +625,7 @@ TEST_F(ClientGlobalInterceptorEnd2endTest, HijackingGlobalInterceptor) {
std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
creators;
// Add 20 dummy interceptors
+ creators.reserve(20);
for (auto i = 0; i < 20; i++) {
creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
new DummyInterceptorFactory()));
diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc
index b667460cf0..929c2bb589 100644
--- a/test/cpp/end2end/client_lb_end2end_test.cc
+++ b/test/cpp/end2end/client_lb_end2end_test.cc
@@ -35,7 +35,9 @@
#include <grpcpp/server.h>
#include <grpcpp/server_builder.h>
+#include "src/core/ext/filters/client_channel/parse_address.h"
#include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h"
+#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/ext/filters/client_channel/subchannel_index.h"
#include "src/core/lib/backoff/backoff.h"
#include "src/core/lib/gpr/env.h"
@@ -116,7 +118,10 @@ class MyTestServiceImpl : public TestServiceImpl {
class ClientLbEnd2endTest : public ::testing::Test {
protected:
ClientLbEnd2endTest()
- : server_host_("localhost"), kRequestMessage_("Live long and prosper.") {
+ : server_host_("localhost"),
+ kRequestMessage_("Live long and prosper."),
+ creds_(new SecureChannelCredentials(
+ grpc_fake_transport_security_credentials_create())) {
// Make the backup poller poll very frequently in order to pick up
// updates from all the subchannels's FDs.
gpr_setenv("GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS", "1");
@@ -156,24 +161,22 @@ class ClientLbEnd2endTest : public ::testing::Test {
}
grpc_channel_args* BuildFakeResults(const std::vector<int>& ports) {
- grpc_lb_addresses* addresses =
- grpc_lb_addresses_create(ports.size(), nullptr);
- for (size_t i = 0; i < ports.size(); ++i) {
+ grpc_core::ServerAddressList addresses;
+ for (const int& port : ports) {
char* lb_uri_str;
- gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", ports[i]);
+ gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", port);
grpc_uri* lb_uri = grpc_uri_parse(lb_uri_str, true);
GPR_ASSERT(lb_uri != nullptr);
- grpc_lb_addresses_set_address_from_uri(addresses, i, lb_uri,
- false /* is balancer */,
- "" /* balancer name */, nullptr);
+ grpc_resolved_address address;
+ GPR_ASSERT(grpc_parse_uri(lb_uri, &address));
+ addresses.emplace_back(address.addr, address.len, nullptr /* args */);
grpc_uri_destroy(lb_uri);
gpr_free(lb_uri_str);
}
const grpc_arg fake_addresses =
- grpc_lb_addresses_create_channel_arg(addresses);
+ CreateServerAddressListChannelArg(&addresses);
grpc_channel_args* fake_results =
grpc_channel_args_copy_and_add(nullptr, &fake_addresses, 1);
- grpc_lb_addresses_destroy(addresses);
return fake_results;
}
@@ -215,9 +218,7 @@ class ClientLbEnd2endTest : public ::testing::Test {
} // else, default to pick first
args.SetPointer(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR,
response_generator_.get());
- std::shared_ptr<ChannelCredentials> creds(new SecureChannelCredentials(
- grpc_fake_transport_security_credentials_create()));
- return CreateCustomChannel("fake:///", std::move(creds), args);
+ return CreateCustomChannel("fake:///", creds_, args);
}
bool SendRpc(
@@ -265,6 +266,7 @@ class ClientLbEnd2endTest : public ::testing::Test {
MyTestServiceImpl service_;
std::unique_ptr<std::thread> thread_;
bool server_ready_ = false;
+ bool started_ = false;
explicit ServerData(int port = 0) {
port_ = port > 0 ? port : grpc_pick_unused_port_or_die();
@@ -272,6 +274,7 @@ class ClientLbEnd2endTest : public ::testing::Test {
void Start(const grpc::string& server_host) {
gpr_log(GPR_INFO, "starting server on port %d", port_);
+ started_ = true;
std::mutex mu;
std::unique_lock<std::mutex> lock(mu);
std::condition_variable cond;
@@ -297,9 +300,11 @@ class ClientLbEnd2endTest : public ::testing::Test {
cond->notify_one();
}
- void Shutdown(bool join = true) {
+ void Shutdown() {
+ if (!started_) return;
server_->Shutdown(grpc_timeout_milliseconds_to_deadline(0));
- if (join) thread_->join();
+ thread_->join();
+ started_ = false;
}
void SetServingStatus(const grpc::string& service, bool serving) {
@@ -378,6 +383,7 @@ class ClientLbEnd2endTest : public ::testing::Test {
grpc_core::RefCountedPtr<grpc_core::FakeResolverResponseGenerator>
response_generator_;
const grpc::string kRequestMessage_;
+ std::shared_ptr<ChannelCredentials> creds_;
};
TEST_F(ClientLbEnd2endTest, PickFirst) {
@@ -422,6 +428,30 @@ TEST_F(ClientLbEnd2endTest, PickFirstProcessPending) {
CheckRpcSendOk(second_stub, DEBUG_LOCATION);
}
+TEST_F(ClientLbEnd2endTest, PickFirstSelectsReadyAtStartup) {
+ ChannelArguments args;
+ constexpr int kInitialBackOffMs = 5000;
+ args.SetInt(GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS, kInitialBackOffMs);
+ // Create 2 servers, but start only the second one.
+ std::vector<int> ports = {grpc_pick_unused_port_or_die(),
+ grpc_pick_unused_port_or_die()};
+ CreateServers(2, ports);
+ StartServer(1);
+ auto channel1 = BuildChannel("pick_first", args);
+ auto stub1 = BuildStub(channel1);
+ SetNextResolution(ports);
+ // Wait for second server to be ready.
+ WaitForServer(stub1, 1, DEBUG_LOCATION);
+ // Create a second channel with the same addresses. Its PF instance
+ // should immediately pick the second subchannel, since it's already
+ // in READY state.
+ auto channel2 = BuildChannel("pick_first", args);
+ SetNextResolution(ports);
+ // Check that the channel reports READY without waiting for the
+ // initial backoff.
+ EXPECT_TRUE(WaitForChannelReady(channel2.get(), 1 /* timeout_seconds */));
+}
+
TEST_F(ClientLbEnd2endTest, PickFirstBackOffInitialReconnect) {
ChannelArguments args;
constexpr int kInitialBackOffMs = 100;
@@ -507,6 +537,51 @@ TEST_F(ClientLbEnd2endTest, PickFirstResetConnectionBackoff) {
EXPECT_LT(waited_ms, kInitialBackOffMs);
}
+TEST_F(ClientLbEnd2endTest,
+ PickFirstResetConnectionBackoffNextAttemptStartsImmediately) {
+ ChannelArguments args;
+ constexpr int kInitialBackOffMs = 1000;
+ args.SetInt(GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS, kInitialBackOffMs);
+ const std::vector<int> ports = {grpc_pick_unused_port_or_die()};
+ auto channel = BuildChannel("pick_first", args);
+ auto stub = BuildStub(channel);
+ SetNextResolution(ports);
+ // Wait for connect, which should fail ~immediately, because the server
+ // is not up.
+ gpr_log(GPR_INFO, "=== INITIAL CONNECTION ATTEMPT");
+ EXPECT_FALSE(
+ channel->WaitForConnected(grpc_timeout_milliseconds_to_deadline(10)));
+ // Reset connection backoff.
+ // Note that the time at which the third attempt will be started is
+ // actually computed at this point, so we record the start time here.
+ gpr_log(GPR_INFO, "=== RESETTING BACKOFF");
+ const gpr_timespec t0 = gpr_now(GPR_CLOCK_MONOTONIC);
+ experimental::ChannelResetConnectionBackoff(channel.get());
+ // Trigger a second connection attempt. This should also fail
+ // ~immediately, but the retry should be scheduled for
+ // kInitialBackOffMs instead of applying the multiplier.
+ gpr_log(GPR_INFO, "=== POLLING FOR SECOND CONNECTION ATTEMPT");
+ EXPECT_FALSE(
+ channel->WaitForConnected(grpc_timeout_milliseconds_to_deadline(10)));
+ // Bring up a server on the chosen port.
+ gpr_log(GPR_INFO, "=== STARTING BACKEND");
+ StartServers(1, ports);
+ // Wait for connect. Should happen within kInitialBackOffMs.
+ // Give an extra 100ms to account for the time spent in the second and
+ // third connection attempts themselves (since what we really want to
+ // measure is the time between the two). As long as this is less than
+ // the 1.6x increase we would see if the backoff state was not reset
+ // properly, the test is still proving that the backoff was reset.
+ constexpr int kWaitMs = kInitialBackOffMs + 100;
+ gpr_log(GPR_INFO, "=== POLLING FOR THIRD CONNECTION ATTEMPT");
+ EXPECT_TRUE(channel->WaitForConnected(
+ grpc_timeout_milliseconds_to_deadline(kWaitMs)));
+ const gpr_timespec t1 = gpr_now(GPR_CLOCK_MONOTONIC);
+ const grpc_millis waited_ms = gpr_time_to_millis(gpr_time_sub(t1, t0));
+ gpr_log(GPR_DEBUG, "Waited %" PRId64 " milliseconds", waited_ms);
+ EXPECT_LT(waited_ms, kWaitMs);
+}
+
TEST_F(ClientLbEnd2endTest, PickFirstUpdates) {
// Start servers and send one RPC per server.
const int kNumServers = 3;
@@ -899,7 +974,7 @@ TEST_F(ClientLbEnd2endTest, RoundRobinUpdateInError) {
servers_[0]->service_.ResetCounters();
// Shutdown one of the servers to be sent in the update.
- servers_[1]->Shutdown(false);
+ servers_[1]->Shutdown();
ports.emplace_back(servers_[1]->port_);
ports.emplace_back(servers_[2]->port_);
SetNextResolution(ports);
@@ -958,7 +1033,7 @@ TEST_F(ClientLbEnd2endTest, RoundRobinReresolve) {
// Kill all servers
gpr_log(GPR_INFO, "****** ABOUT TO KILL SERVERS *******");
for (size_t i = 0; i < servers_.size(); ++i) {
- servers_[i]->Shutdown(true);
+ servers_[i]->Shutdown();
}
gpr_log(GPR_INFO, "****** SERVERS KILLED *******");
gpr_log(GPR_INFO, "****** SENDING DOOMED REQUESTS *******");
@@ -1006,7 +1081,7 @@ TEST_F(ClientLbEnd2endTest, RoundRobinSingleReconnect) {
}
const auto pre_death = servers_[0]->service_.request_count();
// Kill the first server.
- servers_[0]->Shutdown(true);
+ servers_[0]->Shutdown();
// Client request still succeed. May need retrying if RR had returned a pick
// before noticing the change in the server's connectivity.
while (!SendRpc(stub)) {
diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc
index 9c4cd05061..bf990a07b5 100644
--- a/test/cpp/end2end/grpclb_end2end_test.cc
+++ b/test/cpp/end2end/grpclb_end2end_test.cc
@@ -32,7 +32,9 @@
#include <grpcpp/server.h>
#include <grpcpp/server_builder.h>
+#include "src/core/ext/filters/client_channel/parse_address.h"
#include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h"
+#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/iomgr/sockaddr.h"
@@ -486,18 +488,27 @@ class GrpclbEnd2endTest : public ::testing::Test {
grpc::string balancer_name;
};
- grpc_lb_addresses* CreateLbAddressesFromAddressDataList(
+ grpc_core::ServerAddressList CreateLbAddressesFromAddressDataList(
const std::vector<AddressData>& address_data) {
- grpc_lb_addresses* addresses =
- grpc_lb_addresses_create(address_data.size(), nullptr);
- for (size_t i = 0; i < address_data.size(); ++i) {
+ grpc_core::ServerAddressList addresses;
+ for (const auto& addr : address_data) {
char* lb_uri_str;
- gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", address_data[i].port);
+ gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", addr.port);
grpc_uri* lb_uri = grpc_uri_parse(lb_uri_str, true);
GPR_ASSERT(lb_uri != nullptr);
- grpc_lb_addresses_set_address_from_uri(
- addresses, i, lb_uri, address_data[i].is_balancer,
- address_data[i].balancer_name.c_str(), nullptr);
+ grpc_resolved_address address;
+ GPR_ASSERT(grpc_parse_uri(lb_uri, &address));
+ std::vector<grpc_arg> args_to_add;
+ if (addr.is_balancer) {
+ args_to_add.emplace_back(grpc_channel_arg_integer_create(
+ const_cast<char*>(GRPC_ARG_ADDRESS_IS_BALANCER), 1));
+ args_to_add.emplace_back(grpc_channel_arg_string_create(
+ const_cast<char*>(GRPC_ARG_ADDRESS_BALANCER_NAME),
+ const_cast<char*>(addr.balancer_name.c_str())));
+ }
+ grpc_channel_args* args = grpc_channel_args_copy_and_add(
+ nullptr, args_to_add.data(), args_to_add.size());
+ addresses.emplace_back(address.addr, address.len, args);
grpc_uri_destroy(lb_uri);
gpr_free(lb_uri_str);
}
@@ -506,23 +517,21 @@ class GrpclbEnd2endTest : public ::testing::Test {
void SetNextResolution(const std::vector<AddressData>& address_data) {
grpc_core::ExecCtx exec_ctx;
- grpc_lb_addresses* addresses =
+ grpc_core::ServerAddressList addresses =
CreateLbAddressesFromAddressDataList(address_data);
- grpc_arg fake_addresses = grpc_lb_addresses_create_channel_arg(addresses);
+ grpc_arg fake_addresses = CreateServerAddressListChannelArg(&addresses);
grpc_channel_args fake_result = {1, &fake_addresses};
response_generator_->SetResponse(&fake_result);
- grpc_lb_addresses_destroy(addresses);
}
void SetNextReresolutionResponse(
const std::vector<AddressData>& address_data) {
grpc_core::ExecCtx exec_ctx;
- grpc_lb_addresses* addresses =
+ grpc_core::ServerAddressList addresses =
CreateLbAddressesFromAddressDataList(address_data);
- grpc_arg fake_addresses = grpc_lb_addresses_create_channel_arg(addresses);
+ grpc_arg fake_addresses = CreateServerAddressListChannelArg(&addresses);
grpc_channel_args fake_result = {1, &fake_addresses};
response_generator_->SetReresolutionResponse(&fake_result);
- grpc_lb_addresses_destroy(addresses);
}
const std::vector<int> GetBackendPorts(const size_t start_index = 0) const {
diff --git a/test/cpp/end2end/health_service_end2end_test.cc b/test/cpp/end2end/health_service_end2end_test.cc
index 89c4bef09c..b96ff53a3e 100644
--- a/test/cpp/end2end/health_service_end2end_test.cc
+++ b/test/cpp/end2end/health_service_end2end_test.cc
@@ -37,6 +37,7 @@
#include "src/proto/grpc/testing/echo.grpc.pb.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
+#include "test/cpp/end2end/test_health_check_service_impl.h"
#include "test/cpp/end2end/test_service_impl.h"
#include <gtest/gtest.h>
@@ -49,62 +50,6 @@ namespace grpc {
namespace testing {
namespace {
-// A sample sync implementation of the health checking service. This does the
-// same thing as the default one.
-class HealthCheckServiceImpl : public ::grpc::health::v1::Health::Service {
- public:
- Status Check(ServerContext* context, const HealthCheckRequest* request,
- HealthCheckResponse* response) override {
- std::lock_guard<std::mutex> lock(mu_);
- auto iter = status_map_.find(request->service());
- if (iter == status_map_.end()) {
- return Status(StatusCode::NOT_FOUND, "");
- }
- response->set_status(iter->second);
- return Status::OK;
- }
-
- Status Watch(ServerContext* context, const HealthCheckRequest* request,
- ::grpc::ServerWriter<HealthCheckResponse>* writer) override {
- auto last_state = HealthCheckResponse::UNKNOWN;
- while (!context->IsCancelled()) {
- {
- std::lock_guard<std::mutex> lock(mu_);
- HealthCheckResponse response;
- auto iter = status_map_.find(request->service());
- if (iter == status_map_.end()) {
- response.set_status(response.SERVICE_UNKNOWN);
- } else {
- response.set_status(iter->second);
- }
- if (response.status() != last_state) {
- writer->Write(response, ::grpc::WriteOptions());
- }
- }
- gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
- gpr_time_from_millis(1000, GPR_TIMESPAN)));
- }
- return Status::OK;
- }
-
- void SetStatus(const grpc::string& service_name,
- HealthCheckResponse::ServingStatus status) {
- std::lock_guard<std::mutex> lock(mu_);
- status_map_[service_name] = status;
- }
-
- void SetAll(HealthCheckResponse::ServingStatus status) {
- std::lock_guard<std::mutex> lock(mu_);
- for (auto iter = status_map_.begin(); iter != status_map_.end(); ++iter) {
- iter->second = status;
- }
- }
-
- private:
- std::mutex mu_;
- std::map<const grpc::string, HealthCheckResponse::ServingStatus> status_map_;
-};
-
// A custom implementation of the health checking service interface. This is
// used to test that it prevents the server from creating a default service and
// also serves as an example of how to override the default service.
@@ -125,6 +70,8 @@ class CustomHealthCheckService : public HealthCheckServiceInterface {
: HealthCheckResponse::NOT_SERVING);
}
+ void Shutdown() override { impl_->Shutdown(); }
+
private:
HealthCheckServiceImpl* impl_; // not owned
};
@@ -260,6 +207,74 @@ class HealthServiceEnd2endTest : public ::testing::Test {
context.TryCancel();
}
+ // Verify that after HealthCheckServiceInterface::Shutdown is called
+ // 1. unary client will see NOT_SERVING.
+ // 2. unary client still sees NOT_SERVING after a SetServing(true) is called.
+ // 3. streaming (Watch) client will see an update.
+ // 4. setting a new service to serving after shutdown will add the service
+ // name but return NOT_SERVING to client.
+ // This has to be called last.
+ void VerifyHealthCheckServiceShutdown() {
+ HealthCheckServiceInterface* service = server_->GetHealthCheckService();
+ EXPECT_TRUE(service != nullptr);
+ const grpc::string kHealthyService("healthy_service");
+ const grpc::string kUnhealthyService("unhealthy_service");
+ const grpc::string kNotRegisteredService("not_registered");
+ const grpc::string kNewService("add_after_shutdown");
+ service->SetServingStatus(kHealthyService, true);
+ service->SetServingStatus(kUnhealthyService, false);
+
+ ResetStubs();
+
+ // Start Watch for service.
+ ClientContext context;
+ HealthCheckRequest request;
+ request.set_service(kHealthyService);
+ std::unique_ptr<::grpc::ClientReaderInterface<HealthCheckResponse>> reader =
+ hc_stub_->Watch(&context, request);
+
+ HealthCheckResponse response;
+ EXPECT_TRUE(reader->Read(&response));
+ EXPECT_EQ(response.SERVING, response.status());
+
+ SendHealthCheckRpc("", Status::OK, HealthCheckResponse::SERVING);
+ SendHealthCheckRpc(kHealthyService, Status::OK,
+ HealthCheckResponse::SERVING);
+ SendHealthCheckRpc(kUnhealthyService, Status::OK,
+ HealthCheckResponse::NOT_SERVING);
+ SendHealthCheckRpc(kNotRegisteredService,
+ Status(StatusCode::NOT_FOUND, ""));
+ SendHealthCheckRpc(kNewService, Status(StatusCode::NOT_FOUND, ""));
+
+ // Shutdown health check service.
+ service->Shutdown();
+
+ // Watch client gets another update.
+ EXPECT_TRUE(reader->Read(&response));
+ EXPECT_EQ(response.NOT_SERVING, response.status());
+ // Finish Watch call.
+ context.TryCancel();
+
+ SendHealthCheckRpc("", Status::OK, HealthCheckResponse::NOT_SERVING);
+ SendHealthCheckRpc(kHealthyService, Status::OK,
+ HealthCheckResponse::NOT_SERVING);
+ SendHealthCheckRpc(kUnhealthyService, Status::OK,
+ HealthCheckResponse::NOT_SERVING);
+ SendHealthCheckRpc(kNotRegisteredService,
+ Status(StatusCode::NOT_FOUND, ""));
+
+ // Setting status after Shutdown has no effect.
+ service->SetServingStatus(kHealthyService, true);
+ SendHealthCheckRpc(kHealthyService, Status::OK,
+ HealthCheckResponse::NOT_SERVING);
+
+ // Adding serving status for a new service after shutdown will return
+ // NOT_SERVING.
+ service->SetServingStatus(kNewService, true);
+ SendHealthCheckRpc(kNewService, Status::OK,
+ HealthCheckResponse::NOT_SERVING);
+ }
+
TestServiceImpl echo_test_service_;
HealthCheckServiceImpl health_check_service_impl_;
std::unique_ptr<Health::Stub> hc_stub_;
@@ -295,6 +310,13 @@ TEST_F(HealthServiceEnd2endTest, DefaultHealthService) {
Status(StatusCode::INVALID_ARGUMENT, ""));
}
+TEST_F(HealthServiceEnd2endTest, DefaultHealthServiceShutdown) {
+ EnableDefaultHealthCheckService(true);
+ EXPECT_TRUE(DefaultHealthCheckServiceEnabled());
+ SetUpServer(true, false, false, nullptr);
+ VerifyHealthCheckServiceShutdown();
+}
+
// Provide an empty service to disable the default service.
TEST_F(HealthServiceEnd2endTest, ExplicitlyDisableViaOverride) {
EnableDefaultHealthCheckService(true);
@@ -326,6 +348,21 @@ TEST_F(HealthServiceEnd2endTest, ExplicitlyOverride) {
VerifyHealthCheckServiceStreaming();
}
+TEST_F(HealthServiceEnd2endTest, ExplicitlyHealthServiceShutdown) {
+ EnableDefaultHealthCheckService(true);
+ EXPECT_TRUE(DefaultHealthCheckServiceEnabled());
+ std::unique_ptr<HealthCheckServiceInterface> override_service(
+ new CustomHealthCheckService(&health_check_service_impl_));
+ HealthCheckServiceInterface* underlying_service = override_service.get();
+ SetUpServer(false, false, true, std::move(override_service));
+ HealthCheckServiceInterface* service = server_->GetHealthCheckService();
+ EXPECT_TRUE(service == underlying_service);
+
+ ResetStubs();
+
+ VerifyHealthCheckServiceShutdown();
+}
+
} // namespace
} // namespace testing
} // namespace grpc
diff --git a/test/cpp/end2end/interceptors_util.cc b/test/cpp/end2end/interceptors_util.cc
index 5d59c1a4b7..e0ad7d1526 100644
--- a/test/cpp/end2end/interceptors_util.cc
+++ b/test/cpp/end2end/interceptors_util.cc
@@ -137,6 +137,7 @@ CreateDummyClientInterceptors() {
std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
creators;
// Add 20 dummy interceptors before hijacking interceptor
+ creators.reserve(20);
for (auto i = 0; i < 20; i++) {
creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
new DummyInterceptorFactory()));
diff --git a/test/cpp/end2end/server_interceptors_end2end_test.cc b/test/cpp/end2end/server_interceptors_end2end_test.cc
index c98b6143c6..9460a7d6c6 100644
--- a/test/cpp/end2end/server_interceptors_end2end_test.cc
+++ b/test/cpp/end2end/server_interceptors_end2end_test.cc
@@ -44,7 +44,34 @@ namespace {
class LoggingInterceptor : public experimental::Interceptor {
public:
- LoggingInterceptor(experimental::ServerRpcInfo* info) { info_ = info; }
+ LoggingInterceptor(experimental::ServerRpcInfo* info) {
+ info_ = info;
+
+ // Check the method name and compare to the type
+ const char* method = info->method();
+ experimental::ServerRpcInfo::Type type = info->type();
+
+ // Check that we use one of our standard methods with expected type.
+ // Also allow the health checking service.
+ // We accept BIDI_STREAMING for Echo in case it's an AsyncGenericService
+ // being tested (the GenericRpc test).
+ // The empty method is for the Unimplemented requests that arise
+ // when draining the CQ.
+ EXPECT_TRUE(
+ strstr(method, "/grpc.health") == method ||
+ (strcmp(method, "/grpc.testing.EchoTestService/Echo") == 0 &&
+ (type == experimental::ServerRpcInfo::Type::UNARY ||
+ type == experimental::ServerRpcInfo::Type::BIDI_STREAMING)) ||
+ (strcmp(method, "/grpc.testing.EchoTestService/RequestStream") == 0 &&
+ type == experimental::ServerRpcInfo::Type::CLIENT_STREAMING) ||
+ (strcmp(method, "/grpc.testing.EchoTestService/ResponseStream") == 0 &&
+ type == experimental::ServerRpcInfo::Type::SERVER_STREAMING) ||
+ (strcmp(method, "/grpc.testing.EchoTestService/BidiStream") == 0 &&
+ type == experimental::ServerRpcInfo::Type::BIDI_STREAMING) ||
+ strcmp(method, "/grpc.testing.EchoTestService/Unimplemented") == 0 ||
+ (strcmp(method, "") == 0 &&
+ type == experimental::ServerRpcInfo::Type::BIDI_STREAMING));
+ }
virtual void Intercept(experimental::InterceptorBatchMethods* methods) {
if (methods->QueryInterceptionHookPoint(
diff --git a/test/cpp/end2end/test_health_check_service_impl.cc b/test/cpp/end2end/test_health_check_service_impl.cc
new file mode 100644
index 0000000000..0801e30199
--- /dev/null
+++ b/test/cpp/end2end/test_health_check_service_impl.cc
@@ -0,0 +1,97 @@
+/*
+ *
+ * Copyright 2018 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "test/cpp/end2end/test_health_check_service_impl.h"
+
+#include <grpc/grpc.h>
+
+using grpc::health::v1::HealthCheckRequest;
+using grpc::health::v1::HealthCheckResponse;
+
+namespace grpc {
+namespace testing {
+
+Status HealthCheckServiceImpl::Check(ServerContext* context,
+ const HealthCheckRequest* request,
+ HealthCheckResponse* response) {
+ std::lock_guard<std::mutex> lock(mu_);
+ auto iter = status_map_.find(request->service());
+ if (iter == status_map_.end()) {
+ return Status(StatusCode::NOT_FOUND, "");
+ }
+ response->set_status(iter->second);
+ return Status::OK;
+}
+
+Status HealthCheckServiceImpl::Watch(
+ ServerContext* context, const HealthCheckRequest* request,
+ ::grpc::ServerWriter<HealthCheckResponse>* writer) {
+ auto last_state = HealthCheckResponse::UNKNOWN;
+ while (!context->IsCancelled()) {
+ {
+ std::lock_guard<std::mutex> lock(mu_);
+ HealthCheckResponse response;
+ auto iter = status_map_.find(request->service());
+ if (iter == status_map_.end()) {
+ response.set_status(response.SERVICE_UNKNOWN);
+ } else {
+ response.set_status(iter->second);
+ }
+ if (response.status() != last_state) {
+ writer->Write(response, ::grpc::WriteOptions());
+ }
+ }
+ gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
+ gpr_time_from_millis(1000, GPR_TIMESPAN)));
+ }
+ return Status::OK;
+}
+
+void HealthCheckServiceImpl::SetStatus(
+ const grpc::string& service_name,
+ HealthCheckResponse::ServingStatus status) {
+ std::lock_guard<std::mutex> lock(mu_);
+ if (shutdown_) {
+ status = HealthCheckResponse::NOT_SERVING;
+ }
+ status_map_[service_name] = status;
+}
+
+void HealthCheckServiceImpl::SetAll(HealthCheckResponse::ServingStatus status) {
+ std::lock_guard<std::mutex> lock(mu_);
+ if (shutdown_) {
+ return;
+ }
+ for (auto iter = status_map_.begin(); iter != status_map_.end(); ++iter) {
+ iter->second = status;
+ }
+}
+
+void HealthCheckServiceImpl::Shutdown() {
+ std::lock_guard<std::mutex> lock(mu_);
+ if (shutdown_) {
+ return;
+ }
+ shutdown_ = true;
+ for (auto iter = status_map_.begin(); iter != status_map_.end(); ++iter) {
+ iter->second = HealthCheckResponse::NOT_SERVING;
+ }
+}
+
+} // namespace testing
+} // namespace grpc
diff --git a/test/cpp/end2end/test_health_check_service_impl.h b/test/cpp/end2end/test_health_check_service_impl.h
new file mode 100644
index 0000000000..5d36ce5320
--- /dev/null
+++ b/test/cpp/end2end/test_health_check_service_impl.h
@@ -0,0 +1,58 @@
+/*
+ *
+ * Copyright 2018 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#ifndef GRPC_TEST_CPP_END2END_TEST_HEALTH_CHECK_SERVICE_IMPL_H
+#define GRPC_TEST_CPP_END2END_TEST_HEALTH_CHECK_SERVICE_IMPL_H
+
+#include <map>
+#include <mutex>
+
+#include <grpcpp/server_context.h>
+#include <grpcpp/support/status.h>
+
+#include "src/proto/grpc/health/v1/health.grpc.pb.h"
+
+namespace grpc {
+namespace testing {
+
+// A sample sync implementation of the health checking service. This does the
+// same thing as the default one.
+class HealthCheckServiceImpl : public health::v1::Health::Service {
+ public:
+ Status Check(ServerContext* context,
+ const health::v1::HealthCheckRequest* request,
+ health::v1::HealthCheckResponse* response) override;
+ Status Watch(ServerContext* context,
+ const health::v1::HealthCheckRequest* request,
+ ServerWriter<health::v1::HealthCheckResponse>* writer) override;
+ void SetStatus(const grpc::string& service_name,
+ health::v1::HealthCheckResponse::ServingStatus status);
+ void SetAll(health::v1::HealthCheckResponse::ServingStatus status);
+
+ void Shutdown();
+
+ private:
+ std::mutex mu_;
+ bool shutdown_ = false;
+ std::map<const grpc::string, health::v1::HealthCheckResponse::ServingStatus>
+ status_map_;
+};
+
+} // namespace testing
+} // namespace grpc
+
+#endif // GRPC_TEST_CPP_END2END_TEST_HEALTH_CHECK_SERVICE_IMPL_H
diff --git a/test/cpp/microbenchmarks/BUILD b/test/cpp/microbenchmarks/BUILD
index afac414e09..097e92f583 100644
--- a/test/cpp/microbenchmarks/BUILD
+++ b/test/cpp/microbenchmarks/BUILD
@@ -47,15 +47,13 @@ grpc_cc_library(
],
)
-grpc_cc_test(
+grpc_cc_binary(
name = "bm_closure",
+ testonly = 1,
srcs = ["bm_closure.cc"],
deps = [":helpers"],
- uses_polling = False,
)
-# TODO(https://github.com/grpc/grpc/pull/16882): make this a test target
-# right now it OOMs
grpc_cc_binary(
name = "bm_arena",
testonly = 1,
@@ -63,15 +61,13 @@ grpc_cc_binary(
deps = [":helpers"],
)
-grpc_cc_test(
+grpc_cc_binary(
name = "bm_channel",
+ testonly = 1,
srcs = ["bm_channel.cc"],
deps = [":helpers"],
- uses_polling = False,
)
-# TODO(https://github.com/grpc/grpc/pull/16882): make this a test target
-# right now it fails UBSAN
grpc_cc_binary(
name = "bm_call_create",
testonly = 1,
@@ -79,25 +75,25 @@ grpc_cc_binary(
deps = [":helpers"],
)
-grpc_cc_test(
+grpc_cc_binary(
name = "bm_cq",
+ testonly = 1,
srcs = ["bm_cq.cc"],
deps = [":helpers"],
- uses_polling = False,
)
-grpc_cc_test(
+grpc_cc_binary(
name = "bm_cq_multiple_threads",
+ testonly = 1,
srcs = ["bm_cq_multiple_threads.cc"],
deps = [":helpers"],
- uses_polling = False,
)
-grpc_cc_test(
+grpc_cc_binary(
name = "bm_error",
+ testonly = 1,
srcs = ["bm_error.cc"],
deps = [":helpers"],
- uses_polling = False,
)
grpc_cc_library(
@@ -109,8 +105,9 @@ grpc_cc_library(
deps = [":helpers"],
)
-grpc_cc_test(
+grpc_cc_binary(
name = "bm_fullstack_streaming_ping_pong",
+ testonly = 1,
srcs = [
"bm_fullstack_streaming_ping_pong.cc",
],
@@ -126,8 +123,9 @@ grpc_cc_library(
deps = [":helpers"],
)
-grpc_cc_test(
+grpc_cc_binary(
name = "bm_fullstack_streaming_pump",
+ testonly = 1,
srcs = [
"bm_fullstack_streaming_pump.cc",
],
@@ -150,38 +148,27 @@ grpc_cc_library(
deps = [":helpers"],
)
-grpc_cc_test(
+grpc_cc_binary(
name = "bm_fullstack_unary_ping_pong",
+ testonly = 1,
srcs = [
"bm_fullstack_unary_ping_pong.cc",
],
deps = [":fullstack_unary_ping_pong_h"],
)
-grpc_cc_test(
+grpc_cc_binary(
name = "bm_metadata",
+ testonly = 1,
srcs = ["bm_metadata.cc"],
deps = [":helpers"],
- uses_polling = False,
)
-grpc_cc_test(
+grpc_cc_binary(
name = "bm_chttp2_hpack",
+ testonly = 1,
srcs = ["bm_chttp2_hpack.cc"],
deps = [":helpers"],
- uses_polling = False,
-)
-
-grpc_cc_test(
- name = "bm_chttp2_transport",
- srcs = ["bm_chttp2_transport.cc"],
- deps = [":helpers"],
-)
-
-grpc_cc_test(
- name = "bm_pollset",
- srcs = ["bm_pollset.cc"],
- deps = [":helpers"],
)
grpc_cc_binary(
diff --git a/test/cpp/microbenchmarks/bm_call_create.cc b/test/cpp/microbenchmarks/bm_call_create.cc
index a0157c66c2..8d12606434 100644
--- a/test/cpp/microbenchmarks/bm_call_create.cc
+++ b/test/cpp/microbenchmarks/bm_call_create.cc
@@ -526,7 +526,7 @@ static void BM_IsolatedFilter(benchmark::State& state) {
grpc_core::ExecCtx exec_ctx;
size_t channel_size = grpc_channel_stack_size(
- filters.size() == 0 ? nullptr : filters.data(), filters.size());
+ filters.size() == 0 ? nullptr : &filters[0], filters.size());
grpc_channel_stack* channel_stack =
static_cast<grpc_channel_stack*>(gpr_zalloc(channel_size));
GPR_ASSERT(GRPC_LOG_IF_ERROR(
diff --git a/test/cpp/microbenchmarks/fullstack_fixtures.h b/test/cpp/microbenchmarks/fullstack_fixtures.h
index 71e8d9972b..6bbf553bbd 100644
--- a/test/cpp/microbenchmarks/fullstack_fixtures.h
+++ b/test/cpp/microbenchmarks/fullstack_fixtures.h
@@ -200,7 +200,7 @@ class EndpointPairFixture : public BaseFixture {
}
grpc_server_setup_transport(server_->c_server(), server_transport_,
- nullptr, server_args, 0);
+ nullptr, server_args, nullptr);
grpc_chttp2_transport_start_reading(server_transport_, nullptr, nullptr);
}
diff --git a/test/cpp/naming/address_sorting_test.cc b/test/cpp/naming/address_sorting_test.cc
index 3eb0e7d725..09e705df78 100644
--- a/test/cpp/naming/address_sorting_test.cc
+++ b/test/cpp/naming/address_sorting_test.cc
@@ -37,6 +37,7 @@
#include "src/core/ext/filters/client_channel/resolver.h"
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
#include "src/core/ext/filters/client_channel/resolver_registry.h"
+#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/gpr/host_port.h"
@@ -167,30 +168,26 @@ void OverrideAddressSortingSourceAddrFactory(
address_sorting_override_source_addr_factory_for_testing(factory);
}
-grpc_lb_addresses* BuildLbAddrInputs(std::vector<TestAddress> test_addrs) {
- grpc_lb_addresses* lb_addrs = grpc_lb_addresses_create(0, nullptr);
- lb_addrs->addresses =
- (grpc_lb_address*)gpr_zalloc(sizeof(grpc_lb_address) * test_addrs.size());
- lb_addrs->num_addresses = test_addrs.size();
- for (size_t i = 0; i < test_addrs.size(); i++) {
- lb_addrs->addresses[i].address =
- TestAddressToGrpcResolvedAddress(test_addrs[i]);
+grpc_core::ServerAddressList BuildLbAddrInputs(
+ const std::vector<TestAddress>& test_addrs) {
+ grpc_core::ServerAddressList addresses;
+ for (const auto& addr : test_addrs) {
+ addresses.emplace_back(TestAddressToGrpcResolvedAddress(addr), nullptr);
}
- return lb_addrs;
+ return addresses;
}
-void VerifyLbAddrOutputs(grpc_lb_addresses* lb_addrs,
+void VerifyLbAddrOutputs(const grpc_core::ServerAddressList addresses,
std::vector<std::string> expected_addrs) {
- EXPECT_EQ(lb_addrs->num_addresses, expected_addrs.size());
- for (size_t i = 0; i < lb_addrs->num_addresses; i++) {
+ EXPECT_EQ(addresses.size(), expected_addrs.size());
+ for (size_t i = 0; i < addresses.size(); ++i) {
char* ip_addr_str;
- grpc_sockaddr_to_string(&ip_addr_str, &lb_addrs->addresses[i].address,
+ grpc_sockaddr_to_string(&ip_addr_str, &addresses[i].address(),
false /* normalize */);
EXPECT_EQ(expected_addrs[i], ip_addr_str);
gpr_free(ip_addr_str);
}
grpc_core::ExecCtx exec_ctx;
- grpc_lb_addresses_destroy(lb_addrs);
}
/* We need to run each test case inside of its own
@@ -212,11 +209,11 @@ TEST_F(AddressSortingTest, TestDepriotizesUnreachableAddresses) {
{
{"1.2.3.4:443", {"4.3.2.1:443", AF_INET}},
});
- auto* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{"1.2.3.4:443", AF_INET},
{"5.6.7.8:443", AF_INET},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(lb_addrs, {
"1.2.3.4:443",
"5.6.7.8:443",
@@ -235,7 +232,7 @@ TEST_F(AddressSortingTest, TestDepriotizesUnsupportedDomainIpv6) {
{"[2607:f8b0:400a:801::1002]:443", AF_INET6},
{"1.2.3.4:443", AF_INET},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(lb_addrs, {
"1.2.3.4:443",
"[2607:f8b0:400a:801::1002]:443",
@@ -251,11 +248,11 @@ TEST_F(AddressSortingTest, TestDepriotizesUnsupportedDomainIpv4) {
{"1.2.3.4:443", {"4.3.2.1:0", AF_INET}},
{"[2607:f8b0:400a:801::1002]:443", {"[fec0::1234]:0", AF_INET6}},
});
- grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{"[2607:f8b0:400a:801::1002]:443", AF_INET6},
{"1.2.3.4:443", AF_INET},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(lb_addrs, {
"[2607:f8b0:400a:801::1002]:443",
"1.2.3.4:443",
@@ -275,11 +272,11 @@ TEST_F(AddressSortingTest, TestDepriotizesNonMatchingScope) {
{"[fec0::5000]:443",
{"[fec0::5001]:0", AF_INET6}}, // site-local and site-local scope
});
- grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{"[2000:f8b0:400a:801::1002]:443", AF_INET6},
{"[fec0::5000]:443", AF_INET6},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(lb_addrs, {
"[fec0::5000]:443",
"[2000:f8b0:400a:801::1002]:443",
@@ -298,11 +295,11 @@ TEST_F(AddressSortingTest, TestUsesLabelFromDefaultTable) {
{"[2001::5001]:443",
{"[2001::5002]:0", AF_INET6}}, // matching labels
});
- grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{"[2002::5001]:443", AF_INET6},
{"[2001::5001]:443", AF_INET6},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(lb_addrs, {
"[2001::5001]:443",
"[2002::5001]:443",
@@ -321,11 +318,11 @@ TEST_F(AddressSortingTest, TestUsesLabelFromDefaultTableInputFlipped) {
{"[2001::5001]:443",
{"[2001::5002]:0", AF_INET6}}, // matching labels
});
- grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{"[2001::5001]:443", AF_INET6},
{"[2002::5001]:443", AF_INET6},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(lb_addrs, {
"[2001::5001]:443",
"[2002::5001]:443",
@@ -344,11 +341,11 @@ TEST_F(AddressSortingTest,
{"[3ffe::5001]:443", {"[3ffe::5002]:0", AF_INET6}},
{"1.2.3.4:443", {"5.6.7.8:0", AF_INET}},
});
- grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{"[3ffe::5001]:443", AF_INET6},
{"1.2.3.4:443", AF_INET},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(
lb_addrs, {
// The AF_INET address should be IPv4-mapped by the sort,
@@ -377,11 +374,11 @@ TEST_F(AddressSortingTest,
{"[::1]:443", {"[::1]:0", AF_INET6}},
{v4_compat_dest, {v4_compat_src, AF_INET6}},
});
- grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{v4_compat_dest, AF_INET6},
{"[::1]:443", AF_INET6},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(lb_addrs, {
"[::1]:443",
v4_compat_dest,
@@ -400,11 +397,11 @@ TEST_F(AddressSortingTest,
{"[1234::2]:443", {"[1234::2]:0", AF_INET6}},
{"[::1]:443", {"[::1]:0", AF_INET6}},
});
- grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{"[1234::2]:443", AF_INET6},
{"[::1]:443", AF_INET6},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(
lb_addrs,
{
@@ -424,11 +421,11 @@ TEST_F(AddressSortingTest,
{"[2001::1234]:443", {"[2001::5678]:0", AF_INET6}},
{"[2000::5001]:443", {"[2000::5002]:0", AF_INET6}},
});
- grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{"[2001::1234]:443", AF_INET6},
{"[2000::5001]:443", AF_INET6},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(
lb_addrs, {
// The 2000::/16 address should match the ::/0 prefix rule
@@ -448,11 +445,11 @@ TEST_F(
{"[2001::1231]:443", {"[2001::1232]:0", AF_INET6}},
{"[2000::5001]:443", {"[2000::5002]:0", AF_INET6}},
});
- grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{"[2001::1231]:443", AF_INET6},
{"[2000::5001]:443", AF_INET6},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(lb_addrs, {
"[2000::5001]:443",
"[2001::1231]:443",
@@ -469,11 +466,11 @@ TEST_F(AddressSortingTest,
{"[fec0::1234]:443", {"[fec0::5678]:0", AF_INET6}},
{"[fc00::5001]:443", {"[fc00::5002]:0", AF_INET6}},
});
- grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{"[fec0::1234]:443", AF_INET6},
{"[fc00::5001]:443", AF_INET6},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(lb_addrs, {
"[fc00::5001]:443",
"[fec0::1234]:443",
@@ -494,11 +491,11 @@ TEST_F(
{"[::ffff:1.1.1.2]:443", {"[::ffff:1.1.1.3]:0", AF_INET6}},
{"[1234::2]:443", {"[1234::3]:0", AF_INET6}},
});
- grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{"[::ffff:1.1.1.2]:443", AF_INET6},
{"[1234::2]:443", AF_INET6},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(lb_addrs, {
// ::ffff:0:2 should match the v4-mapped
// precedence entry and be deprioritized.
@@ -521,11 +518,11 @@ TEST_F(AddressSortingTest, TestPrefersSmallerScope) {
{"[fec0::1234]:443", {"[fec0::5678]:0", AF_INET6}},
{"[3ffe::5001]:443", {"[3ffe::5002]:0", AF_INET6}},
});
- grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{"[3ffe::5001]:443", AF_INET6},
{"[fec0::1234]:443", AF_INET6},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(lb_addrs, {
"[fec0::1234]:443",
"[3ffe::5001]:443",
@@ -546,11 +543,11 @@ TEST_F(AddressSortingTest, TestPrefersLongestMatchingSrcDstPrefix) {
{"[3ffe:1234::]:443", {"[3ffe:1235::]:0", AF_INET6}},
{"[3ffe:5001::]:443", {"[3ffe:4321::]:0", AF_INET6}},
});
- grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{"[3ffe:5001::]:443", AF_INET6},
{"[3ffe:1234::]:443", AF_INET6},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(lb_addrs, {
"[3ffe:1234::]:443",
"[3ffe:5001::]:443",
@@ -567,11 +564,11 @@ TEST_F(AddressSortingTest,
{"[3ffe::1234]:443", {"[3ffe::1235]:0", AF_INET6}},
{"[3ffe::5001]:443", {"[3ffe::4321]:0", AF_INET6}},
});
- grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{"[3ffe::5001]:443", AF_INET6},
{"[3ffe::1234]:443", AF_INET6},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(lb_addrs, {
"[3ffe::1234]:443",
"[3ffe::5001]:443",
@@ -587,11 +584,11 @@ TEST_F(AddressSortingTest, TestPrefersLongestPrefixStressInnerBytePrefix) {
{"[3ffe:8000::]:443", {"[3ffe:C000::]:0", AF_INET6}},
{"[3ffe:2000::]:443", {"[3ffe:3000::]:0", AF_INET6}},
});
- grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{"[3ffe:8000::]:443", AF_INET6},
{"[3ffe:2000::]:443", AF_INET6},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(lb_addrs, {
"[3ffe:2000::]:443",
"[3ffe:8000::]:443",
@@ -607,11 +604,11 @@ TEST_F(AddressSortingTest, TestPrefersLongestPrefixDiffersOnHighestBitOfByte) {
{"[3ffe:6::]:443", {"[3ffe:8::]:0", AF_INET6}},
{"[3ffe:c::]:443", {"[3ffe:8::]:0", AF_INET6}},
});
- grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{"[3ffe:6::]:443", AF_INET6},
{"[3ffe:c::]:443", AF_INET6},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(lb_addrs, {
"[3ffe:c::]:443",
"[3ffe:6::]:443",
@@ -629,11 +626,11 @@ TEST_F(AddressSortingTest, TestPrefersLongestPrefixDiffersByLastBit) {
{"[3ffe:1111:1111:1110::]:443",
{"[3ffe:1111:1111:1111::]:0", AF_INET6}},
});
- grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{"[3ffe:1111:1111:1110::]:443", AF_INET6},
{"[3ffe:1111:1111:1111::]:443", AF_INET6},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(lb_addrs, {
"[3ffe:1111:1111:1111::]:443",
"[3ffe:1111:1111:1110::]:443",
@@ -651,11 +648,11 @@ TEST_F(AddressSortingTest, TestStableSort) {
{"[3ffe::1234]:443", {"[3ffe::1236]:0", AF_INET6}},
{"[3ffe::1235]:443", {"[3ffe::1237]:0", AF_INET6}},
});
- grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{"[3ffe::1234]:443", AF_INET6},
{"[3ffe::1235]:443", AF_INET6},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(lb_addrs, {
"[3ffe::1234]:443",
"[3ffe::1235]:443",
@@ -674,14 +671,14 @@ TEST_F(AddressSortingTest, TestStableSortFiveElements) {
{"[3ffe::1234]:443", {"[3ffe::1204]:0", AF_INET6}},
{"[3ffe::1235]:443", {"[3ffe::1205]:0", AF_INET6}},
});
- grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{"[3ffe::1231]:443", AF_INET6},
{"[3ffe::1232]:443", AF_INET6},
{"[3ffe::1233]:443", AF_INET6},
{"[3ffe::1234]:443", AF_INET6},
{"[3ffe::1235]:443", AF_INET6},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(lb_addrs, {
"[3ffe::1231]:443",
"[3ffe::1232]:443",
@@ -695,14 +692,14 @@ TEST_F(AddressSortingTest, TestStableSortNoSrcAddrsExist) {
bool ipv4_supported = true;
bool ipv6_supported = true;
OverrideAddressSortingSourceAddrFactory(ipv4_supported, ipv6_supported, {});
- grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{"[3ffe::1231]:443", AF_INET6},
{"[3ffe::1232]:443", AF_INET6},
{"[3ffe::1233]:443", AF_INET6},
{"[3ffe::1234]:443", AF_INET6},
{"[3ffe::1235]:443", AF_INET6},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(lb_addrs, {
"[3ffe::1231]:443",
"[3ffe::1232]:443",
@@ -716,11 +713,11 @@ TEST_F(AddressSortingTest, TestStableSortNoSrcAddrsExistWithIpv4) {
bool ipv4_supported = true;
bool ipv6_supported = true;
OverrideAddressSortingSourceAddrFactory(ipv4_supported, ipv6_supported, {});
- grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{"[::ffff:5.6.7.8]:443", AF_INET6},
{"1.2.3.4:443", AF_INET},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(lb_addrs, {
"[::ffff:5.6.7.8]:443",
"1.2.3.4:443",
@@ -744,11 +741,11 @@ TEST_F(AddressSortingTest, TestStableSortV4CompatAndSiteLocalAddresses) {
{"[fec0::2000]:443", {"[fec0::2001]:0", AF_INET6}},
{v4_compat_dest, {v4_compat_src, AF_INET6}},
});
- grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{"[fec0::2000]:443", AF_INET6},
{v4_compat_dest, AF_INET6},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(lb_addrs,
{
// The sort should be stable since
@@ -765,11 +762,11 @@ TEST_F(AddressSortingTest, TestStableSortV4CompatAndSiteLocalAddresses) {
* (whether ipv4 loopback is available or not, an available ipv6
* loopback should be preferred). */
TEST_F(AddressSortingTest, TestPrefersIpv6Loopback) {
- grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{"[::1]:443", AF_INET6},
{"127.0.0.1:443", AF_INET},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(lb_addrs, {
"[::1]:443",
"127.0.0.1:443",
@@ -779,11 +776,11 @@ TEST_F(AddressSortingTest, TestPrefersIpv6Loopback) {
/* Flip the order of the inputs above and expect the same output order
* (try to rule out influence of arbitrary qsort ordering) */
TEST_F(AddressSortingTest, TestPrefersIpv6LoopbackInputsFlipped) {
- grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{"127.0.0.1:443", AF_INET},
{"[::1]:443", AF_INET6},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(lb_addrs, {
"[::1]:443",
"127.0.0.1:443",
diff --git a/test/cpp/naming/resolver_component_test.cc b/test/cpp/naming/resolver_component_test.cc
index fe6fcb8d9c..2ac2c237ce 100644
--- a/test/cpp/naming/resolver_component_test.cc
+++ b/test/cpp/naming/resolver_component_test.cc
@@ -41,6 +41,7 @@
#include "src/core/ext/filters/client_channel/resolver.h"
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
#include "src/core/ext/filters/client_channel/resolver_registry.h"
+#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/gpr/host_port.h"
@@ -382,23 +383,19 @@ void CheckResolverResultLocked(void* argsp, grpc_error* err) {
EXPECT_EQ(err, GRPC_ERROR_NONE);
ArgsStruct* args = (ArgsStruct*)argsp;
grpc_channel_args* channel_args = args->channel_args;
- const grpc_arg* channel_arg =
- grpc_channel_args_find(channel_args, GRPC_ARG_LB_ADDRESSES);
- GPR_ASSERT(channel_arg != nullptr);
- GPR_ASSERT(channel_arg->type == GRPC_ARG_POINTER);
- grpc_lb_addresses* addresses =
- (grpc_lb_addresses*)channel_arg->value.pointer.p;
+ grpc_core::ServerAddressList* addresses =
+ grpc_core::FindServerAddressListChannelArg(channel_args);
gpr_log(GPR_INFO, "num addrs found: %" PRIdPTR ". expected %" PRIdPTR,
- addresses->num_addresses, args->expected_addrs.size());
- GPR_ASSERT(addresses->num_addresses == args->expected_addrs.size());
+ addresses->size(), args->expected_addrs.size());
+ GPR_ASSERT(addresses->size() == args->expected_addrs.size());
std::vector<GrpcLBAddress> found_lb_addrs;
- for (size_t i = 0; i < addresses->num_addresses; i++) {
- grpc_lb_address addr = addresses->addresses[i];
+ for (size_t i = 0; i < addresses->size(); i++) {
+ grpc_core::ServerAddress& addr = (*addresses)[i];
char* str;
- grpc_sockaddr_to_string(&str, &addr.address, 1 /* normalize */);
+ grpc_sockaddr_to_string(&str, &addr.address(), 1 /* normalize */);
gpr_log(GPR_INFO, "%s", str);
found_lb_addrs.emplace_back(
- GrpcLBAddress(std::string(str), addr.is_balancer));
+ GrpcLBAddress(std::string(str), addr.IsBalancer()));
gpr_free(str);
}
if (args->expected_addrs.size() != found_lb_addrs.size()) {
diff --git a/test/cpp/performance/writes_per_rpc_test.cc b/test/cpp/performance/writes_per_rpc_test.cc
index 3c5b346884..7b22f23cf0 100644
--- a/test/cpp/performance/writes_per_rpc_test.cc
+++ b/test/cpp/performance/writes_per_rpc_test.cc
@@ -100,7 +100,7 @@ class EndpointPairFixture {
}
grpc_server_setup_transport(server_->c_server(), transport, nullptr,
- server_args, 0);
+ server_args, nullptr);
grpc_chttp2_transport_start_reading(transport, nullptr, nullptr);
}
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index 72b247c48d..0e65bf6daa 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -1084,6 +1084,7 @@ src/core/lib/iomgr/buffer_list.h \
src/core/lib/iomgr/call_combiner.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_pair.h \
src/core/lib/iomgr/error.h \
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index 0f1943de25..5011e19b03 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -923,7 +923,6 @@ src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.cc \
src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h \
src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc \
src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h \
-src/core/ext/filters/client_channel/lb_policy_factory.cc \
src/core/ext/filters/client_channel/lb_policy_factory.h \
src/core/ext/filters/client_channel/lb_policy_registry.cc \
src/core/ext/filters/client_channel/lb_policy_registry.h \
@@ -959,6 +958,8 @@ src/core/ext/filters/client_channel/resolver_result_parsing.cc \
src/core/ext/filters/client_channel/resolver_result_parsing.h \
src/core/ext/filters/client_channel/retry_throttle.cc \
src/core/ext/filters/client_channel/retry_throttle.h \
+src/core/ext/filters/client_channel/server_address.cc \
+src/core/ext/filters/client_channel/server_address.h \
src/core/ext/filters/client_channel/subchannel.cc \
src/core/ext/filters/client_channel/subchannel.h \
src/core/ext/filters/client_channel/subchannel_index.cc \
@@ -1182,6 +1183,7 @@ src/core/lib/iomgr/call_combiner.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_pair.h \
diff --git a/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh b/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh
index 74778d9d29..d35bbbd275 100755
--- a/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh
+++ b/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh
@@ -15,8 +15,8 @@
set -ex
-# A temporary solution to give Kokoro credentials.
-# The file name 4321_grpc-testing-service needs to match auth_credential in
+# A temporary solution to give Kokoro credentials.
+# The file name 4321_grpc-testing-service needs to match auth_credential in
# the build config.
mkdir -p ${KOKORO_KEYSTORE_DIR}
cp ${KOKORO_GFILE_DIR}/GrpcTesting-d0eeee2db331.json ${KOKORO_KEYSTORE_DIR}/4321_grpc-testing-service
@@ -35,14 +35,15 @@ cd $(dirname $0)/../../..
source tools/internal_ci/helper_scripts/prepare_build_linux_rc
# to get "bazel" link for kokoro build, we need to generate
-# invocation UUID, set an env var for bazel to pick it up
-# and upload "bazel_invocation_ids" file as artifact.
-export BAZEL_INTERNAL_INVOCATION_ID="$(uuidgen)"
-echo "${BAZEL_INTERNAL_INVOCATION_ID}" >"${KOKORO_ARTIFACTS_DIR}/bazel_invocation_ids"
+# invocation UUID, set a flag for bazel to use it
+# and upload "bazel_invocation_ids" file as artifact.
+BAZEL_INVOCATION_ID="$(uuidgen)"
+echo "${BAZEL_INVOCATION_ID}" >"${KOKORO_ARTIFACTS_DIR}/bazel_invocation_ids"
bazel \
--bazelrc=tools/remote_build/kokoro.bazelrc \
test \
+ --invocation_id="${BAZEL_INVOCATION_ID}" \
$@ \
-- //test/... || FAILED="true"
diff --git a/tools/remote_build/kokoro.bazelrc b/tools/remote_build/kokoro.bazelrc
index 11462bd301..2fbdd3ce02 100644
--- a/tools/remote_build/kokoro.bazelrc
+++ b/tools/remote_build/kokoro.bazelrc
@@ -26,7 +26,6 @@ build --auth_credentials=/tmpfs/src/keystore/4321_grpc-testing-service
build --auth_scope=https://www.googleapis.com/auth/cloud-source-tools
build --bes_backend=buildeventservice.googleapis.com
-build --bes_best_effort=false
build --bes_timeout=600s
build --project_id=grpc-testing
diff --git a/tools/run_tests/artifacts/build_artifact_python.sh b/tools/run_tests/artifacts/build_artifact_python.sh
index bc6e558204..605470325a 100755
--- a/tools/run_tests/artifacts/build_artifact_python.sh
+++ b/tools/run_tests/artifacts/build_artifact_python.sh
@@ -105,7 +105,8 @@ then
"${PIP}" install grpcio-tools --no-index --find-links "file://$ARTIFACT_DIR/"
# Build grpcio_testing source distribution
- ${SETARCH_CMD} "${PYTHON}" src/python/grpcio_testing/setup.py sdist
+ ${SETARCH_CMD} "${PYTHON}" src/python/grpcio_testing/setup.py preprocess \
+ sdist
cp -r src/python/grpcio_testing/dist/* "$ARTIFACT_DIR"
# Build grpcio_channelz source distribution
diff --git a/tools/run_tests/artifacts/build_package_python.sh b/tools/run_tests/artifacts/build_package_python.sh
index d93e8979fc..29801a5b86 100755
--- a/tools/run_tests/artifacts/build_package_python.sh
+++ b/tools/run_tests/artifacts/build_package_python.sh
@@ -19,20 +19,10 @@ cd "$(dirname "$0")/../../.."
mkdir -p artifacts/
+# All the python packages have been built in the artifact phase already
+# and we only collect them here to deliver them to the distribtest phase.
cp -r "${EXTERNAL_GIT_ROOT}"/input_artifacts/python_*/* artifacts/ || true
-strip_binary_wheel() {
- TEMP_WHEEL_DIR=$(mktemp -d)
- unzip "$1" -d "$TEMP_WHEEL_DIR"
- find "$TEMP_WHEEL_DIR" -name "_protoc_compiler*.so" -exec strip --strip-debug {} ";"
- find "$TEMP_WHEEL_DIR" -name "cygrpc*.so" -exec strip --strip-debug {} ";"
- (cd "$TEMP_WHEEL_DIR" && zip -r - .) > "$1"
-}
-
-for wheel in artifacts/*.whl; do
- strip_binary_wheel "$wheel"
-done
-
# TODO: all the artifact builder configurations generate a grpcio-VERSION.tar.gz
# source distribution package, and only one of them will end up
# in the artifacts/ directory. They should be all equivalent though.
diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json
index 2fea807bbb..5b0041a250 100644
--- a/tools/run_tests/generated/sources_and_headers.json
+++ b/tools/run_tests/generated/sources_and_headers.json
@@ -7447,6 +7447,7 @@
"src/proto/grpc/testing/simple_messages.grpc.pb.h",
"src/proto/grpc/testing/simple_messages.pb.h",
"src/proto/grpc/testing/simple_messages_mock.grpc.pb.h",
+ "test/cpp/end2end/test_health_check_service_impl.h",
"test/cpp/end2end/test_service_impl.h",
"test/cpp/util/byte_buffer_proto_helper.h",
"test/cpp/util/channel_trace_proto_helper.h",
@@ -7459,6 +7460,8 @@
"language": "c++",
"name": "grpc++_test_util",
"src": [
+ "test/cpp/end2end/test_health_check_service_impl.cc",
+ "test/cpp/end2end/test_health_check_service_impl.h",
"test/cpp/end2end/test_service_impl.cc",
"test/cpp/end2end/test_service_impl.h",
"test/cpp/util/byte_buffer_proto_helper.cc",
@@ -7503,6 +7506,7 @@
"src/proto/grpc/testing/simple_messages.grpc.pb.h",
"src/proto/grpc/testing/simple_messages.pb.h",
"src/proto/grpc/testing/simple_messages_mock.grpc.pb.h",
+ "test/cpp/end2end/test_health_check_service_impl.h",
"test/cpp/end2end/test_service_impl.h",
"test/cpp/util/byte_buffer_proto_helper.h",
"test/cpp/util/string_ref_helper.h",
@@ -7512,6 +7516,8 @@
"language": "c++",
"name": "grpc++_test_util_unsecure",
"src": [
+ "test/cpp/end2end/test_health_check_service_impl.cc",
+ "test/cpp/end2end/test_health_check_service_impl.h",
"test/cpp/end2end/test_service_impl.cc",
"test/cpp/end2end/test_service_impl.h",
"test/cpp/util/byte_buffer_proto_helper.cc",
@@ -9759,6 +9765,7 @@
"src/core/lib/iomgr/call_combiner.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_pair.h",
"src/core/lib/iomgr/error.h",
@@ -9911,6 +9918,7 @@
"src/core/lib/iomgr/call_combiner.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_pair.h",
"src/core/lib/iomgr/error.h",
@@ -10087,6 +10095,7 @@
"src/core/ext/filters/client_channel/resolver_registry.h",
"src/core/ext/filters/client_channel/resolver_result_parsing.h",
"src/core/ext/filters/client_channel/retry_throttle.h",
+ "src/core/ext/filters/client_channel/server_address.h",
"src/core/ext/filters/client_channel/subchannel.h",
"src/core/ext/filters/client_channel/subchannel_index.h"
],
@@ -10114,7 +10123,6 @@
"src/core/ext/filters/client_channel/http_proxy.h",
"src/core/ext/filters/client_channel/lb_policy.cc",
"src/core/ext/filters/client_channel/lb_policy.h",
- "src/core/ext/filters/client_channel/lb_policy_factory.cc",
"src/core/ext/filters/client_channel/lb_policy_factory.h",
"src/core/ext/filters/client_channel/lb_policy_registry.cc",
"src/core/ext/filters/client_channel/lb_policy_registry.h",
@@ -10133,6 +10141,8 @@
"src/core/ext/filters/client_channel/resolver_result_parsing.h",
"src/core/ext/filters/client_channel/retry_throttle.cc",
"src/core/ext/filters/client_channel/retry_throttle.h",
+ "src/core/ext/filters/client_channel/server_address.cc",
+ "src/core/ext/filters/client_channel/server_address.h",
"src/core/ext/filters/client_channel/subchannel.cc",
"src/core/ext/filters/client_channel/subchannel.h",
"src/core/ext/filters/client_channel/subchannel_index.cc",