diff --git a/BUILD b/BUILD index 348014d7db9e4..78c404c6dd816 100644 --- a/BUILD +++ b/BUILD @@ -2917,12 +2917,12 @@ grpc_cc_library( ) grpc_cc_library( - name = "server_address", + name = "endpoint_addresses", srcs = [ - "//src/core:lib/resolver/server_address.cc", + "//src/core:lib/resolver/endpoint_addresses.cc", ], hdrs = [ - "//src/core:lib/resolver/server_address.h", + "//src/core:lib/resolver/endpoint_addresses.h", ], external_deps = [ "absl/status", @@ -2932,6 +2932,7 @@ grpc_cc_library( language = "c++", visibility = ["@grpc:client_channel"], deps = [ + "gpr", "gpr_platform", "sockaddr_utils", "//src/core:channel_args", @@ -2940,6 +2941,19 @@ grpc_cc_library( ], ) +grpc_cc_library( + name = "server_address", + hdrs = [ + "//src/core:lib/resolver/server_address.h", + ], + language = "c++", + visibility = ["@grpc:client_channel"], + deps = [ + "endpoint_addresses", + "gpr_public_hdrs", + ], +) + grpc_cc_library( name = "grpc_resolver", srcs = [ @@ -2960,11 +2974,11 @@ grpc_cc_library( language = "c++", visibility = ["@grpc:client_channel"], deps = [ + "endpoint_addresses", "gpr", "grpc_trace", "orphanable", "ref_counted_ptr", - "server_address", "uri_parser", "//src/core:channel_args", "//src/core:grpc_service_config", @@ -3049,6 +3063,7 @@ grpc_cc_library( "config", "config_vars", "debug_location", + "endpoint_addresses", "exec_ctx", "gpr", "grpc_base", @@ -3065,7 +3080,6 @@ grpc_cc_library( "promise", "protobuf_duration_upb", "ref_counted_ptr", - "server_address", "sockaddr_utils", "stats", "uri_parser", @@ -3163,6 +3177,7 @@ grpc_cc_library( "config", "config_vars", "debug_location", + "endpoint_addresses", "exec_ctx", "gpr", "grpc_base", @@ -3174,7 +3189,6 @@ grpc_cc_library( "orphanable", "parse_address", "ref_counted_ptr", - "server_address", "sockaddr_utils", "uri_parser", "//src/core:channel_args", @@ -3617,9 +3631,9 @@ grpc_cc_library( language = "c++", visibility = ["@grpc:grpclb"], deps = [ + "endpoint_addresses", "gpr_platform", "grpc_public_hdrs", - "server_address", "//src/core:channel_args", "//src/core:useful", ], @@ -3737,12 +3751,12 @@ grpc_cc_library( deps = [ "config", "debug_location", + "endpoint_addresses", "gpr", "grpc_public_hdrs", "grpc_resolver", "orphanable", "ref_counted_ptr", - "server_address", "uri_parser", "work_serializer", "//src/core:channel_args", diff --git a/CMakeLists.txt b/CMakeLists.txt index 32b41e65245c4..842d20fc58a32 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2351,9 +2351,9 @@ add_library(grpc src/core/lib/promise/party.cc src/core/lib/promise/sleep.cc src/core/lib/promise/trace.cc + src/core/lib/resolver/endpoint_addresses.cc src/core/lib/resolver/resolver.cc src/core/lib/resolver/resolver_registry.cc - src/core/lib/resolver/server_address.cc src/core/lib/resource_quota/api.cc src/core/lib/resource_quota/arena.cc src/core/lib/resource_quota/memory_quota.cc @@ -3062,9 +3062,9 @@ add_library(grpc_unsecure src/core/lib/promise/party.cc src/core/lib/promise/sleep.cc src/core/lib/promise/trace.cc + src/core/lib/resolver/endpoint_addresses.cc src/core/lib/resolver/resolver.cc src/core/lib/resolver/resolver_registry.cc - src/core/lib/resolver/server_address.cc src/core/lib/resource_quota/api.cc src/core/lib/resource_quota/arena.cc src/core/lib/resource_quota/memory_quota.cc @@ -5000,9 +5000,9 @@ add_library(grpc_authorization_provider src/core/lib/promise/activity.cc src/core/lib/promise/party.cc src/core/lib/promise/trace.cc + src/core/lib/resolver/endpoint_addresses.cc src/core/lib/resolver/resolver.cc src/core/lib/resolver/resolver_registry.cc - src/core/lib/resolver/server_address.cc src/core/lib/resource_quota/api.cc src/core/lib/resource_quota/arena.cc src/core/lib/resource_quota/memory_quota.cc @@ -24016,9 +24016,9 @@ add_executable(test_core_transport_chaotic_good_frame_test src/core/lib/promise/activity.cc src/core/lib/promise/party.cc src/core/lib/promise/trace.cc + src/core/lib/resolver/endpoint_addresses.cc src/core/lib/resolver/resolver.cc src/core/lib/resolver/resolver_registry.cc - src/core/lib/resolver/server_address.cc src/core/lib/resource_quota/api.cc src/core/lib/resource_quota/arena.cc src/core/lib/resource_quota/memory_quota.cc diff --git a/Makefile b/Makefile index bea7a4683f459..0ab9ea9c5ead4 100644 --- a/Makefile +++ b/Makefile @@ -1579,9 +1579,9 @@ LIBGRPC_SRC = \ src/core/lib/promise/party.cc \ src/core/lib/promise/sleep.cc \ src/core/lib/promise/trace.cc \ + src/core/lib/resolver/endpoint_addresses.cc \ src/core/lib/resolver/resolver.cc \ src/core/lib/resolver/resolver_registry.cc \ - src/core/lib/resolver/server_address.cc \ src/core/lib/resource_quota/api.cc \ src/core/lib/resource_quota/arena.cc \ src/core/lib/resource_quota/memory_quota.cc \ @@ -2144,9 +2144,9 @@ LIBGRPC_UNSECURE_SRC = \ src/core/lib/promise/party.cc \ src/core/lib/promise/sleep.cc \ src/core/lib/promise/trace.cc \ + src/core/lib/resolver/endpoint_addresses.cc \ src/core/lib/resolver/resolver.cc \ src/core/lib/resolver/resolver_registry.cc \ - src/core/lib/resolver/server_address.cc \ src/core/lib/resource_quota/api.cc \ src/core/lib/resource_quota/arena.cc \ src/core/lib/resource_quota/memory_quota.cc \ diff --git a/Package.swift b/Package.swift index 70d7105c703b3..8dfd76a7fc2d5 100644 --- a/Package.swift +++ b/Package.swift @@ -1474,12 +1474,13 @@ let package = Package( "src/core/lib/promise/trace.cc", "src/core/lib/promise/trace.h", "src/core/lib/promise/try_seq.h", + "src/core/lib/resolver/endpoint_addresses.cc", + "src/core/lib/resolver/endpoint_addresses.h", "src/core/lib/resolver/resolver.cc", "src/core/lib/resolver/resolver.h", "src/core/lib/resolver/resolver_factory.h", "src/core/lib/resolver/resolver_registry.cc", "src/core/lib/resolver/resolver_registry.h", - "src/core/lib/resolver/server_address.cc", "src/core/lib/resolver/server_address.h", "src/core/lib/resource_quota/api.cc", "src/core/lib/resource_quota/api.h", diff --git a/build_autogenerated.yaml b/build_autogenerated.yaml index a709fed35d65c..8a2e61860023e 100644 --- a/build_autogenerated.yaml +++ b/build_autogenerated.yaml @@ -879,6 +879,7 @@ libs: - src/core/lib/promise/sleep.h - src/core/lib/promise/trace.h - src/core/lib/promise/try_seq.h + - src/core/lib/resolver/endpoint_addresses.h - src/core/lib/resolver/resolver.h - src/core/lib/resolver/resolver_factory.h - src/core/lib/resolver/resolver_registry.h @@ -1655,9 +1656,9 @@ libs: - src/core/lib/promise/party.cc - src/core/lib/promise/sleep.cc - src/core/lib/promise/trace.cc + - src/core/lib/resolver/endpoint_addresses.cc - src/core/lib/resolver/resolver.cc - src/core/lib/resolver/resolver_registry.cc - - src/core/lib/resolver/server_address.cc - src/core/lib/resource_quota/api.cc - src/core/lib/resource_quota/arena.cc - src/core/lib/resource_quota/memory_quota.cc @@ -2288,6 +2289,7 @@ libs: - src/core/lib/promise/sleep.h - src/core/lib/promise/trace.h - src/core/lib/promise/try_seq.h + - src/core/lib/resolver/endpoint_addresses.h - src/core/lib/resolver/resolver.h - src/core/lib/resolver/resolver_factory.h - src/core/lib/resolver/resolver_registry.h @@ -2680,9 +2682,9 @@ libs: - src/core/lib/promise/party.cc - src/core/lib/promise/sleep.cc - src/core/lib/promise/trace.cc + - src/core/lib/resolver/endpoint_addresses.cc - src/core/lib/resolver/resolver.cc - src/core/lib/resolver/resolver_registry.cc - - src/core/lib/resolver/server_address.cc - src/core/lib/resource_quota/api.cc - src/core/lib/resource_quota/arena.cc - src/core/lib/resource_quota/memory_quota.cc @@ -4293,10 +4295,10 @@ libs: - src/core/lib/promise/seq.h - src/core/lib/promise/trace.h - src/core/lib/promise/try_seq.h + - src/core/lib/resolver/endpoint_addresses.h - src/core/lib/resolver/resolver.h - src/core/lib/resolver/resolver_factory.h - src/core/lib/resolver/resolver_registry.h - - src/core/lib/resolver/server_address.h - src/core/lib/resource_quota/api.h - src/core/lib/resource_quota/arena.h - src/core/lib/resource_quota/memory_quota.h @@ -4568,9 +4570,9 @@ libs: - src/core/lib/promise/activity.cc - src/core/lib/promise/party.cc - src/core/lib/promise/trace.cc + - src/core/lib/resolver/endpoint_addresses.cc - src/core/lib/resolver/resolver.cc - src/core/lib/resolver/resolver_registry.cc - - src/core/lib/resolver/server_address.cc - src/core/lib/resource_quota/api.cc - src/core/lib/resource_quota/arena.cc - src/core/lib/resource_quota/memory_quota.cc @@ -15815,10 +15817,10 @@ targets: - src/core/lib/promise/seq.h - src/core/lib/promise/trace.h - src/core/lib/promise/try_seq.h + - src/core/lib/resolver/endpoint_addresses.h - src/core/lib/resolver/resolver.h - src/core/lib/resolver/resolver_factory.h - src/core/lib/resolver/resolver_registry.h - - src/core/lib/resolver/server_address.h - src/core/lib/resource_quota/api.h - src/core/lib/resource_quota/arena.h - src/core/lib/resource_quota/memory_quota.h @@ -16072,9 +16074,9 @@ targets: - src/core/lib/promise/activity.cc - src/core/lib/promise/party.cc - src/core/lib/promise/trace.cc + - src/core/lib/resolver/endpoint_addresses.cc - src/core/lib/resolver/resolver.cc - src/core/lib/resolver/resolver_registry.cc - - src/core/lib/resolver/server_address.cc - src/core/lib/resource_quota/api.cc - src/core/lib/resource_quota/arena.cc - src/core/lib/resource_quota/memory_quota.cc diff --git a/config.m4 b/config.m4 index 069ee44289015..cb82dcb5645e8 100644 --- a/config.m4 +++ b/config.m4 @@ -712,9 +712,9 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/promise/party.cc \ src/core/lib/promise/sleep.cc \ src/core/lib/promise/trace.cc \ + src/core/lib/resolver/endpoint_addresses.cc \ src/core/lib/resolver/resolver.cc \ src/core/lib/resolver/resolver_registry.cc \ - src/core/lib/resolver/server_address.cc \ src/core/lib/resource_quota/api.cc \ src/core/lib/resource_quota/arena.cc \ src/core/lib/resource_quota/memory_quota.cc \ diff --git a/config.w32 b/config.w32 index 25e49a76910af..34136004e7f62 100644 --- a/config.w32 +++ b/config.w32 @@ -677,9 +677,9 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\promise\\party.cc " + "src\\core\\lib\\promise\\sleep.cc " + "src\\core\\lib\\promise\\trace.cc " + + "src\\core\\lib\\resolver\\endpoint_addresses.cc " + "src\\core\\lib\\resolver\\resolver.cc " + "src\\core\\lib\\resolver\\resolver_registry.cc " + - "src\\core\\lib\\resolver\\server_address.cc " + "src\\core\\lib\\resource_quota\\api.cc " + "src\\core\\lib\\resource_quota\\arena.cc " + "src\\core\\lib\\resource_quota\\memory_quota.cc " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 316a1e5d74eef..b77567e339d16 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -974,6 +974,7 @@ Pod::Spec.new do |s| 'src/core/lib/promise/sleep.h', 'src/core/lib/promise/trace.h', 'src/core/lib/promise/try_seq.h', + 'src/core/lib/resolver/endpoint_addresses.h', 'src/core/lib/resolver/resolver.h', 'src/core/lib/resolver/resolver_factory.h', 'src/core/lib/resolver/resolver_registry.h', @@ -2043,6 +2044,7 @@ Pod::Spec.new do |s| 'src/core/lib/promise/sleep.h', 'src/core/lib/promise/trace.h', 'src/core/lib/promise/try_seq.h', + 'src/core/lib/resolver/endpoint_addresses.h', 'src/core/lib/resolver/resolver.h', 'src/core/lib/resolver/resolver_factory.h', 'src/core/lib/resolver/resolver_registry.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 167607b950a10..1f38f8413059c 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -1575,12 +1575,13 @@ Pod::Spec.new do |s| 'src/core/lib/promise/trace.cc', 'src/core/lib/promise/trace.h', 'src/core/lib/promise/try_seq.h', + 'src/core/lib/resolver/endpoint_addresses.cc', + 'src/core/lib/resolver/endpoint_addresses.h', 'src/core/lib/resolver/resolver.cc', 'src/core/lib/resolver/resolver.h', 'src/core/lib/resolver/resolver_factory.h', 'src/core/lib/resolver/resolver_registry.cc', 'src/core/lib/resolver/resolver_registry.h', - 'src/core/lib/resolver/server_address.cc', 'src/core/lib/resolver/server_address.h', 'src/core/lib/resource_quota/api.cc', 'src/core/lib/resource_quota/api.h', @@ -2794,6 +2795,7 @@ Pod::Spec.new do |s| 'src/core/lib/promise/sleep.h', 'src/core/lib/promise/trace.h', 'src/core/lib/promise/try_seq.h', + 'src/core/lib/resolver/endpoint_addresses.h', 'src/core/lib/resolver/resolver.h', 'src/core/lib/resolver/resolver_factory.h', 'src/core/lib/resolver/resolver_registry.h', diff --git a/grpc.gemspec b/grpc.gemspec index 643d80bd00633..a30935f085c85 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -1480,12 +1480,13 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/promise/trace.cc ) s.files += %w( src/core/lib/promise/trace.h ) s.files += %w( src/core/lib/promise/try_seq.h ) + s.files += %w( src/core/lib/resolver/endpoint_addresses.cc ) + s.files += %w( src/core/lib/resolver/endpoint_addresses.h ) s.files += %w( src/core/lib/resolver/resolver.cc ) s.files += %w( src/core/lib/resolver/resolver.h ) s.files += %w( src/core/lib/resolver/resolver_factory.h ) s.files += %w( src/core/lib/resolver/resolver_registry.cc ) s.files += %w( src/core/lib/resolver/resolver_registry.h ) - s.files += %w( src/core/lib/resolver/server_address.cc ) s.files += %w( src/core/lib/resolver/server_address.h ) s.files += %w( src/core/lib/resource_quota/api.cc ) s.files += %w( src/core/lib/resource_quota/api.h ) diff --git a/grpc.gyp b/grpc.gyp index 48849be61d9dd..f97bc1539db07 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -895,9 +895,9 @@ 'src/core/lib/promise/party.cc', 'src/core/lib/promise/sleep.cc', 'src/core/lib/promise/trace.cc', + 'src/core/lib/resolver/endpoint_addresses.cc', 'src/core/lib/resolver/resolver.cc', 'src/core/lib/resolver/resolver_registry.cc', - 'src/core/lib/resolver/server_address.cc', 'src/core/lib/resource_quota/api.cc', 'src/core/lib/resource_quota/arena.cc', 'src/core/lib/resource_quota/memory_quota.cc', @@ -1400,9 +1400,9 @@ 'src/core/lib/promise/party.cc', 'src/core/lib/promise/sleep.cc', 'src/core/lib/promise/trace.cc', + 'src/core/lib/resolver/endpoint_addresses.cc', 'src/core/lib/resolver/resolver.cc', 'src/core/lib/resolver/resolver_registry.cc', - 'src/core/lib/resolver/server_address.cc', 'src/core/lib/resource_quota/api.cc', 'src/core/lib/resource_quota/arena.cc', 'src/core/lib/resource_quota/memory_quota.cc', @@ -2135,9 +2135,9 @@ 'src/core/lib/promise/activity.cc', 'src/core/lib/promise/party.cc', 'src/core/lib/promise/trace.cc', + 'src/core/lib/resolver/endpoint_addresses.cc', 'src/core/lib/resolver/resolver.cc', 'src/core/lib/resolver/resolver_registry.cc', - 'src/core/lib/resolver/server_address.cc', 'src/core/lib/resource_quota/api.cc', 'src/core/lib/resource_quota/arena.cc', 'src/core/lib/resource_quota/memory_quota.cc', diff --git a/include/grpc/impl/channel_arg_names.h b/include/grpc/impl/channel_arg_names.h index 669529baa8738..565339a872865 100644 --- a/include/grpc/impl/channel_arg_names.h +++ b/include/grpc/impl/channel_arg_names.h @@ -370,6 +370,10 @@ /** Configure the Differentiated Services Code Point used on outgoing packets. * Integer value ranging from 0 to 63. */ #define GRPC_ARG_DSCP "grpc.dscp" +/** Connection Attempt Delay for use in Happy Eyeballs, in milliseconds. + * Defaults to 250ms. */ +#define GRPC_ARG_HAPPY_EYEBALLS_CONNECTION_ATTEMPT_DELAY_MS \ + "grpc.happy_eyeballs_connection_attempt_delay_ms" /** \} */ #endif /* GRPC_IMPL_CHANNEL_ARG_NAMES_H */ diff --git a/package.xml b/package.xml index 2bb4386c27af7..7ac8ceb0a3ae4 100644 --- a/package.xml +++ b/package.xml @@ -1462,12 +1462,13 @@ + + - diff --git a/src/core/BUILD b/src/core/BUILD index 4e59c1dc97c1b..bb810ed5c6dd3 100644 --- a/src/core/BUILD +++ b/src/core/BUILD @@ -2760,8 +2760,10 @@ grpc_cc_library( "iomgr_fwd", "pollset_set", "ref_counted", + "resolved_address", "subchannel_interface", "//:debug_location", + "//:endpoint_addresses", "//:event_engine_base_hdrs", "//:exec_ctx", "//:gpr", @@ -2769,7 +2771,6 @@ grpc_cc_library( "//:grpc_trace", "//:orphanable", "//:ref_counted_ptr", - "//:server_address", "//:work_serializer", ], ) @@ -2833,13 +2834,13 @@ grpc_cc_library( deps = [ "channel_args", "lb_policy", + "resolved_address", "subchannel_interface", "//:debug_location", "//:event_engine_base_hdrs", "//:gpr_platform", "//:grpc_security_base", "//:ref_counted_ptr", - "//:server_address", ], ) @@ -4059,6 +4060,7 @@ grpc_cc_library( "//:channel_stack_builder", "//:config", "//:debug_location", + "//:endpoint_addresses", "//:exec_ctx", "//:gpr", "//:grpc_base", @@ -4074,7 +4076,6 @@ grpc_cc_library( "//:protobuf_duration_upb", "//:protobuf_timestamp_upb", "//:ref_counted_ptr", - "//:server_address", "//:sockaddr_utils", "//:work_serializer", ], @@ -4150,6 +4151,7 @@ grpc_cc_library( "//:channel_arg_names", "//:config", "//:debug_location", + "//:endpoint_addresses", "//:exec_ctx", "//:gpr", "//:grpc_base", @@ -4162,7 +4164,6 @@ grpc_cc_library( "//:orphanable", "//:ref_counted_ptr", "//:rls_upb", - "//:server_address", "//:work_serializer", ], ) @@ -4356,6 +4357,7 @@ grpc_cc_library( "//:channel_arg_names", "//:config", "//:debug_location", + "//:endpoint_addresses", "//:exec_ctx", "//:gpr", "//:grpc_base", @@ -4368,7 +4370,6 @@ grpc_cc_library( "//:orphanable", "//:parse_address", "//:ref_counted_ptr", - "//:server_address", "//:sockaddr_utils", "//:tsi_ssl_credentials", "//:uri_parser", @@ -4522,8 +4523,8 @@ grpc_cc_library( ], language = "c++", deps = [ + "//:endpoint_addresses", "//:gpr_platform", - "//:server_address", ], ) @@ -4559,6 +4560,7 @@ grpc_cc_library( "//:channel_arg_names", "//:config", "//:debug_location", + "//:endpoint_addresses", "//:gpr", "//:grpc_base", "//:grpc_client_channel", @@ -4567,7 +4569,6 @@ grpc_cc_library( "//:grpc_trace", "//:orphanable", "//:ref_counted_ptr", - "//:server_address", "//:work_serializer", "//:xds_client", ], @@ -4601,17 +4602,18 @@ grpc_cc_library( "lb_policy_registry", "pollset_set", "ref_counted", + "resolved_address", "subchannel_interface", "validation_errors", "//:config", "//:debug_location", + "//:endpoint_addresses", "//:gpr", "//:grpc_base", "//:grpc_client_channel", "//:grpc_trace", "//:orphanable", "//:ref_counted_ptr", - "//:server_address", "//:xds_client", ], ) @@ -4643,6 +4645,7 @@ grpc_cc_library( "validation_errors", "//:config", "//:debug_location", + "//:endpoint_addresses", "//:exec_ctx", "//:gpr", "//:gpr_platform", @@ -4651,7 +4654,6 @@ grpc_cc_library( "//:grpc_trace", "//:orphanable", "//:ref_counted_ptr", - "//:server_address", "//:work_serializer", ], ) @@ -4683,12 +4685,12 @@ grpc_cc_library( "validation_errors", "//:config", "//:debug_location", + "//:endpoint_addresses", "//:gpr", "//:grpc_base", "//:grpc_trace", "//:orphanable", "//:ref_counted_ptr", - "//:server_address", "//:xds_client", ], ) @@ -4710,9 +4712,9 @@ grpc_cc_library( "channel_args", "ref_counted", "ref_counted_string", + "//:endpoint_addresses", "//:gpr_platform", "//:ref_counted_ptr", - "//:server_address", ], ) @@ -4809,14 +4811,15 @@ grpc_cc_library( "lb_policy", "lb_policy_registry", "pollset_set", + "resolved_address", "subchannel_interface", "//:config", "//:debug_location", + "//:endpoint_addresses", "//:gpr", "//:grpc_base", "//:orphanable", "//:ref_counted_ptr", - "//:server_address", "//:work_serializer", ], ) @@ -4848,14 +4851,19 @@ grpc_cc_library( "lb_policy", "lb_policy_factory", "subchannel_interface", + "time", + "useful", + "//:channel_arg_names", "//:config", "//:debug_location", + "//:endpoint_addresses", + "//:exec_ctx", "//:gpr", "//:grpc_base", "//:grpc_trace", "//:orphanable", "//:ref_counted_ptr", - "//:server_address", + "//:work_serializer", ], ) @@ -4897,6 +4905,7 @@ grpc_cc_library( "//:channel_arg_names", "//:config", "//:debug_location", + "//:endpoint_addresses", "//:exec_ctx", "//:gpr", "//:grpc_base", @@ -4904,7 +4913,6 @@ grpc_cc_library( "//:grpc_trace", "//:orphanable", "//:ref_counted_ptr", - "//:server_address", "//:sockaddr_utils", "//:work_serializer", ], @@ -4934,6 +4942,7 @@ grpc_cc_library( "subchannel_interface", "//:config", "//:debug_location", + "//:endpoint_addresses", "//:gpr", "//:grpc_base", "//:grpc_trace", @@ -4996,6 +5005,7 @@ grpc_cc_library( "validation_errors", "//:config", "//:debug_location", + "//:endpoint_addresses", "//:exec_ctx", "//:gpr", "//:grpc_base", @@ -5053,11 +5063,14 @@ grpc_cc_library( "lb_policy_registry", "pollset_set", "ref_counted", + "resolved_address", "subchannel_interface", "unique_type_name", + "useful", "validation_errors", "//:config", "//:debug_location", + "//:endpoint_addresses", "//:exec_ctx", "//:gpr", "//:grpc_base", @@ -5065,7 +5078,6 @@ grpc_cc_library( "//:grpc_trace", "//:orphanable", "//:ref_counted_ptr", - "//:server_address", "//:sockaddr_utils", "//:work_serializer", ], @@ -5099,6 +5111,7 @@ grpc_cc_library( "//:channel_arg_names", "//:config", "//:debug_location", + "//:endpoint_addresses", "//:exec_ctx", "//:gpr", "//:grpc_base", @@ -5106,7 +5119,6 @@ grpc_cc_library( "//:grpc_trace", "//:orphanable", "//:ref_counted_ptr", - "//:server_address", "//:work_serializer", ], ) @@ -5140,6 +5152,7 @@ grpc_cc_library( "validation_errors", "//:config", "//:debug_location", + "//:endpoint_addresses", "//:exec_ctx", "//:gpr", "//:grpc_base", @@ -5147,7 +5160,6 @@ grpc_cc_library( "//:grpc_trace", "//:orphanable", "//:ref_counted_ptr", - "//:server_address", "//:work_serializer", ], ) @@ -5186,10 +5198,12 @@ grpc_cc_library( "lb_policy_registry", "match", "pollset_set", + "resolved_address", "subchannel_interface", "validation_errors", "//:config", "//:debug_location", + "//:endpoint_addresses", "//:exec_ctx", "//:gpr", "//:grpc_base", @@ -5197,7 +5211,6 @@ grpc_cc_library( "//:grpc_trace", "//:orphanable", "//:ref_counted_ptr", - "//:server_address", "//:sockaddr_utils", "//:work_serializer", ], @@ -5365,6 +5378,7 @@ grpc_cc_library( "//:backoff", "//:channel_arg_names", "//:debug_location", + "//:endpoint_addresses", "//:exec_ctx", "//:gpr", "//:gpr_platform", @@ -5375,7 +5389,6 @@ grpc_cc_library( "//:grpc_trace", "//:orphanable", "//:ref_counted_ptr", - "//:server_address", "//:uri_parser", ], ) @@ -5427,13 +5440,13 @@ grpc_cc_library( "//:channel_arg_names", "//:config", "//:debug_location", + "//:endpoint_addresses", "//:gpr", "//:grpc_base", "//:grpc_resolver", "//:grpc_trace", "//:orphanable", "//:ref_counted_ptr", - "//:server_address", "//:uri_parser", ], ) @@ -5453,11 +5466,11 @@ grpc_cc_library( "iomgr_port", "resolved_address", "//:config", + "//:endpoint_addresses", "//:gpr", "//:grpc_resolver", "//:orphanable", "//:parse_address", - "//:server_address", "//:uri_parser", ], ) @@ -5480,10 +5493,10 @@ grpc_cc_library( "resolved_address", "status_helper", "//:config", + "//:endpoint_addresses", "//:gpr", "//:grpc_resolver", "//:orphanable", - "//:server_address", "//:uri_parser", ], ) @@ -5540,6 +5553,7 @@ grpc_cc_library( "//:channel_arg_names", "//:config", "//:debug_location", + "//:endpoint_addresses", "//:gpr", "//:grpc_base", "//:grpc_client_channel", @@ -5550,7 +5564,6 @@ grpc_cc_library( "//:legacy_context", "//:orphanable", "//:ref_counted_ptr", - "//:server_address", "//:uri_parser", "//:work_serializer", "//:xds_client", diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 5cab65373f54e..06a5ea881f858 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -82,6 +82,7 @@ #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/iomgr/polling_entity.h" #include "src/core/lib/iomgr/pollset_set.h" +#include "src/core/lib/iomgr/resolved_address.h" #include "src/core/lib/json/json.h" #include "src/core/lib/load_balancing/lb_policy_registry.h" #include "src/core/lib/load_balancing/subchannel_interface.h" @@ -93,8 +94,8 @@ #include "src/core/lib/promise/poll.h" #include "src/core/lib/promise/promise.h" #include "src/core/lib/promise/try_seq.h" +#include "src/core/lib/resolver/endpoint_addresses.h" #include "src/core/lib/resolver/resolver_registry.h" -#include "src/core/lib/resolver/server_address.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/service_config/service_config_call_data.h" #include "src/core/lib/service_config/service_config_impl.h" @@ -1084,15 +1085,16 @@ class ClientChannel::ClientChannelControlHelper } RefCountedPtr CreateSubchannel( - ServerAddress address, const ChannelArgs& args) override + const grpc_resolved_address& address, const ChannelArgs& per_address_args, + const ChannelArgs& args) override ABSL_EXCLUSIVE_LOCKS_REQUIRED(*chand_->work_serializer_) { if (chand_->resolver_ == nullptr) return nullptr; // Shutting down. ChannelArgs subchannel_args = ClientChannel::MakeSubchannelArgs( - args, address.args(), chand_->subchannel_pool_, + args, per_address_args, chand_->subchannel_pool_, chand_->default_authority_); // Create subchannel. RefCountedPtr subchannel = - chand_->client_channel_factory_->CreateSubchannel(address.address(), + chand_->client_channel_factory_->CreateSubchannel(address, subchannel_args); if (subchannel == nullptr) return nullptr; // Make sure the subchannel has updated keepalive time. diff --git a/src/core/ext/filters/client_channel/lb_policy/address_filtering.cc b/src/core/ext/filters/client_channel/lb_policy/address_filtering.cc index 8dcc5f8d5c411..b6e8396b95e23 100644 --- a/src/core/ext/filters/client_channel/lb_policy/address_filtering.cc +++ b/src/core/ext/filters/client_channel/lb_policy/address_filtering.cc @@ -44,18 +44,19 @@ int HierarchicalPathArg::ChannelArgsCompare(const HierarchicalPathArg* a, } absl::StatusOr MakeHierarchicalAddressMap( - const absl::StatusOr& addresses) { + const absl::StatusOr& addresses) { if (!addresses.ok()) return addresses.status(); HierarchicalAddressMap result; RefCountedPtr remaining_path_attr; - for (const ServerAddress& address : *addresses) { - const auto* path_arg = address.args().GetObject(); + for (const EndpointAddresses& endpoint_addresses : *addresses) { + const auto* path_arg = + endpoint_addresses.args().GetObject(); if (path_arg == nullptr) continue; const std::vector& path = path_arg->path(); auto it = path.begin(); if (it == path.end()) continue; - ServerAddressList& target_list = result[*it]; - ChannelArgs args = address.args(); + EndpointAddressesList& target_list = result[*it]; + ChannelArgs args = endpoint_addresses.args(); ++it; if (it != path.end()) { std::vector remaining_path(it, path.end()); @@ -66,7 +67,7 @@ absl::StatusOr MakeHierarchicalAddressMap( } args = args.SetObject(remaining_path_attr); } - target_list.emplace_back(address.address(), args); + target_list.emplace_back(endpoint_addresses.addresses(), args); } return result; } diff --git a/src/core/ext/filters/client_channel/lb_policy/address_filtering.h b/src/core/ext/filters/client_channel/lb_policy/address_filtering.h index b17c13bbb8c14..d0e2faae29451 100644 --- a/src/core/ext/filters/client_channel/lb_policy/address_filtering.h +++ b/src/core/ext/filters/client_channel/lb_policy/address_filtering.h @@ -28,7 +28,7 @@ #include "src/core/lib/gprpp/ref_counted.h" #include "src/core/lib/gprpp/ref_counted_string.h" -#include "src/core/lib/resolver/server_address.h" +#include "src/core/lib/resolver/endpoint_addresses.h" // The resolver returns a flat list of addresses. When a hierarchy of // LB policies is in use, each leaf of the hierarchy will need a @@ -102,15 +102,15 @@ class HierarchicalPathArg : public RefCounted { std::vector path_; }; -// A map from the next path element to the addresses that fall under -// that path element. +// A map from the next path element to the endpoint addresses that fall +// under that path element. using HierarchicalAddressMap = - std::map; // Splits up the addresses into a separate list for each child. absl::StatusOr MakeHierarchicalAddressMap( - const absl::StatusOr& addresses); + const absl::StatusOr& addresses); } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc b/src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc index 9478f7c2fa985..f82ac6f53d16b 100644 --- a/src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc +++ b/src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc @@ -32,10 +32,10 @@ #include "src/core/lib/config/core_configuration.h" #include "src/core/lib/gprpp/debug_location.h" #include "src/core/lib/iomgr/pollset_set.h" +#include "src/core/lib/iomgr/resolved_address.h" #include "src/core/lib/load_balancing/delegating_helper.h" #include "src/core/lib/load_balancing/lb_policy_registry.h" #include "src/core/lib/load_balancing/subchannel_interface.h" -#include "src/core/lib/resolver/server_address.h" #include "src/core/lib/transport/connectivity_state.h" namespace grpc_core { @@ -52,11 +52,12 @@ class ChildPolicyHandler::Helper : ParentOwningDelegatingChannelControlHelper(std::move(parent)) {} RefCountedPtr CreateSubchannel( - ServerAddress address, const ChannelArgs& args) override { + const grpc_resolved_address& address, const ChannelArgs& per_address_args, + const ChannelArgs& args) override { if (parent()->shutting_down_) return nullptr; if (!CalledByCurrentChild() && !CalledByPendingChild()) return nullptr; return parent()->channel_control_helper()->CreateSubchannel( - std::move(address), args); + address, per_address_args, args); } void UpdateState(grpc_connectivity_state state, const absl::Status& status, diff --git a/src/core/ext/filters/client_channel/lb_policy/endpoint_list.cc b/src/core/ext/filters/client_channel/lb_policy/endpoint_list.cc index 9269359d74848..bc0e0bb6ca243 100644 --- a/src/core/ext/filters/client_channel/lb_policy/endpoint_list.cc +++ b/src/core/ext/filters/client_channel/lb_policy/endpoint_list.cc @@ -44,7 +44,7 @@ #include "src/core/lib/load_balancing/delegating_helper.h" #include "src/core/lib/load_balancing/lb_policy.h" #include "src/core/lib/load_balancing/lb_policy_registry.h" -#include "src/core/lib/resolver/server_address.h" +#include "src/core/lib/resolver/endpoint_addresses.h" namespace grpc_core { @@ -61,8 +61,9 @@ class EndpointList::Endpoint::Helper ~Helper() override { endpoint_.reset(DEBUG_LOCATION, "Helper"); } RefCountedPtr CreateSubchannel( - ServerAddress address, const ChannelArgs& args) override { - return endpoint_->CreateSubchannel(std::move(address), args); + const grpc_resolved_address& address, const ChannelArgs& per_address_args, + const ChannelArgs& args) override { + return endpoint_->CreateSubchannel(address, per_address_args, args); } void UpdateState( @@ -86,7 +87,7 @@ class EndpointList::Endpoint::Helper // void EndpointList::Endpoint::Init( - const ServerAddress& address, const ChannelArgs& args, + const EndpointAddresses& addresses, const ChannelArgs& args, std::shared_ptr work_serializer) { ChannelArgs child_args = args.Set(GRPC_ARG_INTERNAL_PICK_FIRST_ENABLE_HEALTH_CHECKING, true) @@ -118,7 +119,7 @@ void EndpointList::Endpoint::Init( GPR_ASSERT(config.ok()); // Update child policy. LoadBalancingPolicy::UpdateArgs update_args; - update_args.addresses.emplace().emplace_back(address); + update_args.addresses.emplace().emplace_back(addresses); update_args.args = child_args; update_args.config = std::move(*config); // TODO(roth): If the child reports a non-OK status with the update, @@ -152,9 +153,10 @@ size_t EndpointList::Endpoint::Index() const { } RefCountedPtr EndpointList::Endpoint::CreateSubchannel( - ServerAddress address, const ChannelArgs& args) { + const grpc_resolved_address& address, const ChannelArgs& per_address_args, + const ChannelArgs& args) { return endpoint_list_->channel_control_helper()->CreateSubchannel( - std::move(address), args); + address, per_address_args, args); } // @@ -162,13 +164,14 @@ RefCountedPtr EndpointList::Endpoint::CreateSubchannel( // void EndpointList::Init( - const ServerAddressList& addresses, const ChannelArgs& args, - absl::AnyInvocable( - RefCountedPtr, const ServerAddress&, const ChannelArgs&)> + const EndpointAddressesList& endpoints, const ChannelArgs& args, + absl::AnyInvocable(RefCountedPtr, + const EndpointAddresses&, + const ChannelArgs&)> create_endpoint) { - for (const ServerAddress& address : addresses) { + for (const EndpointAddresses& addresses : endpoints) { endpoints_.push_back( - create_endpoint(Ref(DEBUG_LOCATION, "Endpoint"), address, args)); + create_endpoint(Ref(DEBUG_LOCATION, "Endpoint"), addresses, args)); } } diff --git a/src/core/ext/filters/client_channel/lb_policy/endpoint_list.h b/src/core/ext/filters/client_channel/lb_policy/endpoint_list.h index 66fce2871e4bf..df31bc39c0e83 100644 --- a/src/core/ext/filters/client_channel/lb_policy/endpoint_list.h +++ b/src/core/ext/filters/client_channel/lb_policy/endpoint_list.h @@ -36,9 +36,10 @@ #include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/gprpp/work_serializer.h" +#include "src/core/lib/iomgr/resolved_address.h" #include "src/core/lib/load_balancing/lb_policy.h" #include "src/core/lib/load_balancing/subchannel_interface.h" -#include "src/core/lib/resolver/server_address.h" +#include "src/core/lib/resolver/endpoint_addresses.h" namespace grpc_core { @@ -52,16 +53,17 @@ namespace grpc_core { class MyEndpointList : public EndpointList { public: MyEndpointList(RefCountedPtr lb_policy, - const ServerAddressList& addresses, const ChannelArgs& args) + const EndpointAddressesList& endpoints, + const ChannelArgs& args) : EndpointList(std::move(lb_policy), GRPC_TRACE_FLAG_ENABLED(grpc_my_tracer) ? "MyEndpointList" : nullptr) { - Init(addresses, args, + Init(endpoints, args, [&](RefCountedPtr endpoint_list, - const ServerAddress& address, const ChannelArgs& args) { + const EndpointAddresses& addresses, const ChannelArgs& args) { return MakeOrphanable( - std::move(endpoint_list), address, args, + std::move(endpoint_list), addresses, args, policy()->work_serializer()); }); } @@ -70,10 +72,10 @@ class MyEndpointList : public EndpointList { class MyEndpoint : public Endpoint { public: MyEndpoint(RefCountedPtr endpoint_list, - const ServerAddress& address, const ChannelArgs& args, + const EndpointAddresses& address, const ChannelArgs& args, std::shared_ptr work_serializer) : Endpoint(std::move(endpoint_list)) { - Init(address, args, std::move(work_serializer)); + Init(addresses, args, std::move(work_serializer)); } private: @@ -119,7 +121,7 @@ class EndpointList : public InternallyRefCounted { explicit Endpoint(RefCountedPtr endpoint_list) : endpoint_list_(std::move(endpoint_list)) {} - void Init(const ServerAddress& address, const ChannelArgs& args, + void Init(const EndpointAddresses& addresses, const ChannelArgs& args, std::shared_ptr work_serializer); // Templated for convenience, to provide a short-hand for @@ -150,7 +152,8 @@ class EndpointList : public InternallyRefCounted { // Called to create a subchannel. Subclasses may override. virtual RefCountedPtr CreateSubchannel( - ServerAddress address, const ChannelArgs& args); + const grpc_resolved_address& address, + const ChannelArgs& per_address_args, const ChannelArgs& args); RefCountedPtr endpoint_list_; @@ -181,9 +184,9 @@ class EndpointList : public InternallyRefCounted { EndpointList(RefCountedPtr policy, const char* tracer) : policy_(std::move(policy)), tracer_(tracer) {} - void Init(const ServerAddressList& addresses, const ChannelArgs& args, + void Init(const EndpointAddressesList& endpoints, const ChannelArgs& args, absl::AnyInvocable( - RefCountedPtr, const ServerAddress&, + RefCountedPtr, const EndpointAddresses&, const ChannelArgs&)> create_endpoint); 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 0655b2dfc45d6..0341ba277a887 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 @@ -134,8 +134,8 @@ #include "src/core/lib/load_balancing/lb_policy_factory.h" #include "src/core/lib/load_balancing/lb_policy_registry.h" #include "src/core/lib/load_balancing/subchannel_interface.h" +#include "src/core/lib/resolver/endpoint_addresses.h" #include "src/core/lib/resolver/resolver.h" -#include "src/core/lib/resolver/server_address.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/slice/slice.h" #include "src/core/lib/slice/slice_string_helpers.h" @@ -387,8 +387,8 @@ class GrpcLb : public LoadBalancingPolicy { // Returns a text representation suitable for logging. std::string AsText() const; - // Extracts all non-drop entries into a ServerAddressList. - ServerAddressList GetServerAddressList( + // Extracts all non-drop entries into an EndpointAddressesList. + EndpointAddressesList GetServerAddressList( GrpcLbClientStats* client_stats) const; // Returns true if the serverlist contains at least one drop entry and @@ -467,7 +467,8 @@ class GrpcLb : public LoadBalancingPolicy { : ParentOwningDelegatingChannelControlHelper(std::move(parent)) {} RefCountedPtr CreateSubchannel( - ServerAddress address, const ChannelArgs& args) override; + const grpc_resolved_address& address, + const ChannelArgs& per_address_args, const ChannelArgs& args) override; void UpdateState(grpc_connectivity_state state, const absl::Status& status, RefCountedPtr picker) override; void RequestReresolution() override; @@ -571,7 +572,7 @@ class GrpcLb : public LoadBalancingPolicy { // Whether we're in fallback mode. bool fallback_mode_ = false; // The backend addresses from the resolver. - absl::StatusOr fallback_backend_addresses_; + absl::StatusOr fallback_backend_addresses_; // The last resolution note from our parent. // To be passed to child policy when fallback_backend_addresses_ is empty. std::string resolution_note_; @@ -668,11 +669,11 @@ bool IsServerValid(const GrpcLbServer& server, size_t idx, bool log) { } // Returns addresses extracted from the serverlist. -ServerAddressList GrpcLb::Serverlist::GetServerAddressList( +EndpointAddressesList GrpcLb::Serverlist::GetServerAddressList( GrpcLbClientStats* client_stats) const { RefCountedPtr stats; if (client_stats != nullptr) stats = client_stats->Ref(); - ServerAddressList addresses; + EndpointAddressesList endpoints; for (size_t i = 0; i < serverlist_.size(); ++i) { const GrpcLbServer& server = serverlist_[i]; if (!IsServerValid(server, i, false)) continue; @@ -692,11 +693,11 @@ ServerAddressList GrpcLb::Serverlist::GetServerAddressList( : addr_uri.status().ToString().c_str()); } // Add address with a channel arg containing LB token and stats object. - addresses.emplace_back( + endpoints.emplace_back( addr, ChannelArgs().SetObject(MakeRefCounted( std::move(lb_token), stats))); } - return addresses; + return endpoints; } bool GrpcLb::Serverlist::ContainsAllDropEntries() const { @@ -779,19 +780,21 @@ GrpcLb::PickResult GrpcLb::Picker::Pick(PickArgs args) { // RefCountedPtr GrpcLb::Helper::CreateSubchannel( - ServerAddress address, const ChannelArgs& args) { + const grpc_resolved_address& address, const ChannelArgs& per_address_args, + const ChannelArgs& args) { if (parent()->shutting_down_) return nullptr; - const auto* arg = address.args().GetObject(); + const auto* arg = per_address_args.GetObject(); if (arg == nullptr) { + auto addr_str = grpc_sockaddr_to_string(&address, false); Crash( - absl::StrFormat("[grpclb %p] no TokenAndClientStatsArg for address %p", - parent(), address.ToString().c_str())); + absl::StrFormat("[grpclb %p] no TokenAndClientStatsArg for address %s", + parent(), addr_str.value_or("N/A").c_str())); } std::string lb_token = arg->lb_token(); RefCountedPtr client_stats = arg->client_stats(); return MakeRefCounted( - parent()->channel_control_helper()->CreateSubchannel(std::move(address), - args), + parent()->channel_control_helper()->CreateSubchannel( + address, per_address_args, args), parent()->Ref(DEBUG_LOCATION, "SubchannelWrapper"), std::move(lb_token), std::move(client_stats)); } @@ -1347,11 +1350,11 @@ void GrpcLb::BalancerCallState::OnBalancerStatusReceivedLocked( // helper code for creating balancer channel // -ServerAddressList ExtractBalancerAddresses(const ChannelArgs& args) { - const ServerAddressList* addresses = +EndpointAddressesList ExtractBalancerAddresses(const ChannelArgs& args) { + const EndpointAddressesList* endpoints = FindGrpclbBalancerAddressesInChannelArgs(args); - if (addresses != nullptr) return *addresses; - return ServerAddressList(); + if (endpoints != nullptr) return *endpoints; + return EndpointAddressesList(); } // Returns the channel args for the LB channel, used to create a bidirectional @@ -1514,10 +1517,10 @@ absl::Status GrpcLb::UpdateLocked(UpdateArgs args) { fallback_backend_addresses_ = std::move(args.addresses); if (fallback_backend_addresses_.ok()) { // Add null LB token attributes. - for (ServerAddress& address : *fallback_backend_addresses_) { - address = ServerAddress( - address.address(), - address.args().SetObject( + for (EndpointAddresses& addresses : *fallback_backend_addresses_) { + addresses = EndpointAddresses( + addresses.addresses(), + addresses.args().SetObject( MakeRefCounted("", nullptr))); } } @@ -1566,7 +1569,7 @@ absl::Status GrpcLb::UpdateLocked(UpdateArgs args) { absl::Status GrpcLb::UpdateBalancerChannelLocked() { // Get balancer addresses. - ServerAddressList balancer_addresses = ExtractBalancerAddresses(args_); + EndpointAddressesList balancer_addresses = ExtractBalancerAddresses(args_); absl::Status status; if (balancer_addresses.empty()) { status = absl::UnavailableError("balancer address list must be non-empty"); diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc index c45be05a6a3ae..2624c3a5c1976 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc @@ -34,25 +34,25 @@ namespace grpc_core { namespace { void* BalancerAddressesArgCopy(void* p) { - ServerAddressList* address_list = static_cast(p); - return new ServerAddressList(*address_list); + EndpointAddressesList* endpoint_list = static_cast(p); + return new EndpointAddressesList(*endpoint_list); } void BalancerAddressesArgDestroy(void* p) { - ServerAddressList* address_list = static_cast(p); - delete address_list; + EndpointAddressesList* endpoint_list = static_cast(p); + delete endpoint_list; } int BalancerAddressesArgCmp(void* p, void* q) { - ServerAddressList* address_list1 = static_cast(p); - ServerAddressList* address_list2 = static_cast(q); - if (address_list1 == nullptr || address_list2 == nullptr) { - return QsortCompare(address_list1, address_list2); + auto* endpoint_list1 = static_cast(p); + auto* endpoint_list2 = static_cast(q); + if (endpoint_list1 == nullptr || endpoint_list2 == nullptr) { + return QsortCompare(endpoint_list1, endpoint_list2); } - if (address_list1->size() > address_list2->size()) return 1; - if (address_list1->size() < address_list2->size()) return -1; - for (size_t i = 0; i < address_list1->size(); ++i) { - int retval = (*address_list1)[i].Cmp((*address_list2)[i]); + if (endpoint_list1->size() > endpoint_list2->size()) return 1; + if (endpoint_list1->size() < endpoint_list2->size()) return -1; + for (size_t i = 0; i < endpoint_list1->size(); ++i) { + int retval = (*endpoint_list1)[i].Cmp((*endpoint_list2)[i]); if (retval != 0) return retval; } return 0; @@ -65,24 +65,24 @@ const grpc_arg_pointer_vtable kBalancerAddressesArgVtable = { } // namespace grpc_arg CreateGrpclbBalancerAddressesArg( - const ServerAddressList* address_list) { + const EndpointAddressesList* endpoint_list) { return grpc_channel_arg_pointer_create( const_cast(GRPC_ARG_GRPCLB_BALANCER_ADDRESSES), - const_cast(address_list), + const_cast(endpoint_list), &kBalancerAddressesArgVtable); } -const ServerAddressList* FindGrpclbBalancerAddressesInChannelArgs( +const EndpointAddressesList* FindGrpclbBalancerAddressesInChannelArgs( const ChannelArgs& args) { - return args.GetPointer( + return args.GetPointer( GRPC_ARG_GRPCLB_BALANCER_ADDRESSES); } ChannelArgs SetGrpcLbBalancerAddresses(const ChannelArgs& args, - ServerAddressList address_list) { + EndpointAddressesList endpoint_list) { return args.Set( GRPC_ARG_GRPCLB_BALANCER_ADDRESSES, - ChannelArgs::Pointer(new ServerAddressList(std::move(address_list)), + ChannelArgs::Pointer(new EndpointAddressesList(std::move(endpoint_list)), &kBalancerAddressesArgVtable)); } diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.h b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.h index 7f80aca80e1bc..adc689c6c011f 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.h +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.h @@ -22,16 +22,16 @@ #include #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/resolver/server_address.h" +#include "src/core/lib/resolver/endpoint_addresses.h" namespace grpc_core { grpc_arg CreateGrpclbBalancerAddressesArg( - const ServerAddressList* address_list); + const EndpointAddressesList* endpoint_list); GRPC_MUST_USE_RESULT ChannelArgs SetGrpcLbBalancerAddresses(const ChannelArgs& args, - ServerAddressList address_list); -const ServerAddressList* FindGrpclbBalancerAddressesInChannelArgs( + EndpointAddressesList endpoint_list); +const EndpointAddressesList* FindGrpclbBalancerAddressesInChannelArgs( const ChannelArgs& args); } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/lb_policy/outlier_detection/outlier_detection.cc b/src/core/ext/filters/client_channel/lb_policy/outlier_detection/outlier_detection.cc index aede6d5067d99..c4434218c2684 100644 --- a/src/core/ext/filters/client_channel/lb_policy/outlier_detection/outlier_detection.cc +++ b/src/core/ext/filters/client_channel/lb_policy/outlier_detection/outlier_detection.cc @@ -50,6 +50,7 @@ #include "src/core/lib/config/core_configuration.h" #include "src/core/lib/debug/trace.h" #include "src/core/lib/experiments/experiments.h" +#include "src/core/lib/gpr/useful.h" #include "src/core/lib/gprpp/debug_location.h" #include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/gprpp/ref_counted.h" @@ -60,13 +61,14 @@ #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/iomgr/iomgr_fwd.h" #include "src/core/lib/iomgr/pollset_set.h" +#include "src/core/lib/iomgr/resolved_address.h" #include "src/core/lib/json/json.h" #include "src/core/lib/load_balancing/delegating_helper.h" #include "src/core/lib/load_balancing/lb_policy.h" #include "src/core/lib/load_balancing/lb_policy_factory.h" #include "src/core/lib/load_balancing/lb_policy_registry.h" #include "src/core/lib/load_balancing/subchannel_interface.h" -#include "src/core/lib/resolver/server_address.h" +#include "src/core/lib/resolver/endpoint_addresses.h" #include "src/core/lib/transport/connectivity_state.h" namespace grpc_core { @@ -161,6 +163,8 @@ class OutlierDetectionLb : public LoadBalancingPolicy { void AddDataWatcher(std::unique_ptr watcher) override; + void CancelDataWatcher(DataWatcherInterface* watcher) override; + RefCountedPtr subchannel_state() const { return subchannel_state_; } @@ -338,6 +342,25 @@ class OutlierDetectionLb : public LoadBalancingPolicy { bool counting_enabled_; }; + class EndpointAddressesArg : public RefCounted { + public: + explicit EndpointAddressesArg(EndpointAddressSet addresses) + : addresses_(std::move(addresses)) {} + + const EndpointAddressSet& addresses() const { return addresses_; } + + static absl::string_view ChannelArgName() { + return GRPC_ARG_NO_SUBCHANNEL_PREFIX "endpoint_addresses"; + } + static int ChannelArgsCompare(const EndpointAddressesArg* a, + const EndpointAddressesArg* b) { + return QsortCompare(a->addresses_, b->addresses_); + } + + private: + EndpointAddressSet addresses_; + }; + class Helper : public ParentOwningDelegatingChannelControlHelper { public: @@ -346,7 +369,8 @@ class OutlierDetectionLb : public LoadBalancingPolicy { std::move(outlier_detection_policy)) {} RefCountedPtr CreateSubchannel( - ServerAddress address, const ChannelArgs& args) override; + const grpc_resolved_address& address, + const ChannelArgs& per_address_args, const ChannelArgs& args) override; void UpdateState(grpc_connectivity_state state, const absl::Status& status, RefCountedPtr picker) override; }; @@ -371,10 +395,6 @@ class OutlierDetectionLb : public LoadBalancingPolicy { ~OutlierDetectionLb() override; - // Returns the address map key for an address, or the empty string if - // the address should be ignored. - static std::string MakeKeyForAddress(const ServerAddress& address); - void ShutdownLocked() override; OrphanablePtr CreateChildPolicyLocked( @@ -394,7 +414,8 @@ class OutlierDetectionLb : public LoadBalancingPolicy { grpc_connectivity_state state_ = GRPC_CHANNEL_IDLE; absl::Status status_; RefCountedPtr picker_; - std::map> subchannel_state_map_; + std::map> + subchannel_state_map_; OrphanablePtr ejection_timer_; }; @@ -425,6 +446,13 @@ void OutlierDetectionLb::SubchannelWrapper::AddDataWatcher( DelegatingSubchannel::AddDataWatcher(std::move(watcher)); } +void OutlierDetectionLb::SubchannelWrapper::CancelDataWatcher( + DataWatcherInterface* watcher) { + auto* w = static_cast(watcher); + if (w->type() == HealthProducer::Type()) watcher_wrapper_ = nullptr; + DelegatingSubchannel::CancelDataWatcher(watcher); +} + // // OutlierDetectionLb::Picker::SubchannelCallTracker // @@ -536,15 +564,6 @@ OutlierDetectionLb::~OutlierDetectionLb() { } } -std::string OutlierDetectionLb::MakeKeyForAddress( - const ServerAddress& address) { - // Use only the address, not the attributes. - auto addr_str = grpc_sockaddr_to_string(&address.address(), false); - // If address couldn't be stringified, ignore it. - if (!addr_str.ok()) return ""; - return std::move(*addr_str); -} - void OutlierDetectionLb::ShutdownLocked() { if (GRPC_TRACE_FLAG_ENABLED(grpc_outlier_detection_lb_trace)) { gpr_log(GPR_INFO, "[outlier_detection_lb %p] shutting down", this); @@ -612,17 +631,16 @@ absl::Status OutlierDetectionLb::UpdateLocked(UpdateArgs args) { } // Update subchannel state map. if (args.addresses.ok()) { - std::set current_addresses; - for (const ServerAddress& address : *args.addresses) { - std::string address_key = MakeKeyForAddress(address); - if (address_key.empty()) continue; - auto& subchannel_state = subchannel_state_map_[address_key]; + std::set current_addresses; + for (EndpointAddresses& endpoint : *args.addresses) { + EndpointAddressSet key(endpoint.addresses()); + auto& subchannel_state = subchannel_state_map_[key]; if (subchannel_state == nullptr) { subchannel_state = MakeRefCounted(); if (GRPC_TRACE_FLAG_ENABLED(grpc_outlier_detection_lb_trace)) { gpr_log(GPR_INFO, "[outlier_detection_lb %p] adding map entry for %s (%p)", - this, address_key.c_str(), subchannel_state.get()); + this, key.ToString().c_str(), subchannel_state.get()); } } else if (!config_->CountingEnabled()) { // If counting is not enabled, reset state. @@ -630,11 +648,15 @@ absl::Status OutlierDetectionLb::UpdateLocked(UpdateArgs args) { gpr_log(GPR_INFO, "[outlier_detection_lb %p] counting disabled; disabling " "ejection for %s (%p)", - this, address_key.c_str(), subchannel_state.get()); + this, key.ToString().c_str(), subchannel_state.get()); } subchannel_state->DisableEjection(); } - current_addresses.emplace(address_key); + current_addresses.emplace(key); + // Add channel arg containing the key, for use in CreateSubchannel(). + endpoint = EndpointAddresses( + endpoint.addresses(), + endpoint.args().SetObject(MakeRefCounted(key))); } for (auto it = subchannel_state_map_.begin(); it != subchannel_state_map_.end();) { @@ -644,7 +666,7 @@ absl::Status OutlierDetectionLb::UpdateLocked(UpdateArgs args) { if (GRPC_TRACE_FLAG_ENABLED(grpc_outlier_detection_lb_trace)) { gpr_log(GPR_INFO, "[outlier_detection_lb %p] removing map entry for %s (%p)", - this, it->first.c_str(), it->second.get()); + this, it->first.ToString().c_str(), it->second.get()); } it = subchannel_state_map_.erase(it); } else { @@ -715,16 +737,20 @@ OrphanablePtr OutlierDetectionLb::CreateChildPolicyLocked( // RefCountedPtr OutlierDetectionLb::Helper::CreateSubchannel( - ServerAddress address, const ChannelArgs& args) { + const grpc_resolved_address& address, const ChannelArgs& per_address_args, + const ChannelArgs& args) { if (parent()->shutting_down_) return nullptr; RefCountedPtr subchannel_state; - std::string key = MakeKeyForAddress(address); - if (GRPC_TRACE_FLAG_ENABLED(grpc_outlier_detection_lb_trace)) { - gpr_log(GPR_INFO, - "[outlier_detection_lb %p] using key %s for subchannel address %s", - parent(), key.c_str(), address.ToString().c_str()); - } - if (!key.empty()) { + auto* key_attr = per_address_args.GetObject(); + if (key_attr != nullptr) { + const EndpointAddressSet& key = key_attr->addresses(); + if (GRPC_TRACE_FLAG_ENABLED(grpc_outlier_detection_lb_trace)) { + std::string address_str = + grpc_sockaddr_to_string(&address, false).value_or(""); + gpr_log(GPR_INFO, + "[outlier_detection_lb %p] creating subchannel for %s, key %s", + parent(), address_str.c_str(), key.ToString().c_str()); + } auto it = parent()->subchannel_state_map_.find(key); if (it != parent()->subchannel_state_map_.end()) { subchannel_state = it->second->Ref(); @@ -732,8 +758,8 @@ RefCountedPtr OutlierDetectionLb::Helper::CreateSubchannel( } auto subchannel = MakeRefCounted( parent()->work_serializer(), subchannel_state, - parent()->channel_control_helper()->CreateSubchannel(std::move(address), - args)); + parent()->channel_control_helper()->CreateSubchannel( + address, per_address_args, args)); if (subchannel_state != nullptr) { subchannel_state->AddSubchannel(subchannel.get()); } @@ -964,8 +990,8 @@ void OutlierDetectionLb::EjectionTimer::OnTimerLocked() { const bool unejected = subchannel_state->MaybeUneject( config.base_ejection_time.millis(), config.max_ejection_time.millis()); if (unejected && GRPC_TRACE_FLAG_ENABLED(grpc_outlier_detection_lb_trace)) { - gpr_log(GPR_INFO, "[outlier_detection_lb %p] unejected address %s (%p)", - parent_.get(), state.first.c_str(), subchannel_state); + gpr_log(GPR_INFO, "[outlier_detection_lb %p] unejected endpoint %s (%p)", + parent_.get(), state.first.ToString().c_str(), subchannel_state); } } parent_->ejection_timer_ = 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 86955752a851c..36d297d0bd01c 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 #include #include +#include #include #include @@ -35,6 +36,8 @@ #include "absl/strings/string_view.h" #include "absl/types/optional.h" +#include +#include #include #include @@ -42,10 +45,14 @@ #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/config/core_configuration.h" #include "src/core/lib/debug/trace.h" +#include "src/core/lib/gpr/useful.h" #include "src/core/lib/gprpp/crash.h" #include "src/core/lib/gprpp/debug_location.h" #include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/gprpp/time.h" +#include "src/core/lib/gprpp/work_serializer.h" +#include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/iomgr/iomgr_fwd.h" #include "src/core/lib/json/json.h" #include "src/core/lib/json/json_args.h" @@ -53,7 +60,7 @@ #include "src/core/lib/load_balancing/lb_policy.h" #include "src/core/lib/load_balancing/lb_policy_factory.h" #include "src/core/lib/load_balancing/subchannel_interface.h" -#include "src/core/lib/resolver/server_address.h" +#include "src/core/lib/resolver/endpoint_addresses.h" #include "src/core/lib/transport/connectivity_state.h" namespace grpc_core { @@ -110,6 +117,9 @@ class PickFirst : public LoadBalancingPolicy { absl::optional connectivity_state() const { return connectivity_state_; } + const absl::Status& connectivity_status() const { + return connectivity_status_; + } // Returns the index into the subchannel list of this object. size_t Index() const { @@ -122,6 +132,13 @@ class PickFirst : public LoadBalancingPolicy { if (subchannel_ != nullptr) subchannel_->ResetBackoff(); } + void RequestConnection() { subchannel_->RequestConnection(); } + + // Requests a connection attempt to start on this subchannel, + // with appropriate Connection Attempt Delay. + // Used only during the Happy Eyeballs pass. + void RequestConnectionWithTimer(); + // Cancels any pending connectivity watch and unrefs the subchannel. void ShutdownLocked(); @@ -164,9 +181,6 @@ class PickFirst : public LoadBalancingPolicy { // subchannel. void ProcessUnselectedReadyLocked(); - // Reacts to the current connectivity state while trying to connect. - void ReactToConnectivityStateLocked(); - // Backpointer to owning subchannel list. Not owned. SubchannelList* subchannel_list_; // The subchannel. @@ -179,8 +193,8 @@ class PickFirst : public LoadBalancingPolicy { absl::Status connectivity_status_; }; - SubchannelList(RefCountedPtr policy, ServerAddressList addresses, - const ChannelArgs& args); + SubchannelList(RefCountedPtr policy, + EndpointAddressesList addresses, const ChannelArgs& args); ~SubchannelList() override; @@ -197,6 +211,14 @@ class PickFirst : public LoadBalancingPolicy { // connectivity state notifications. bool AllSubchannelsSeenInitialState(); + // Looks through subchannels_ starting from attempting_index_ to + // find the first one not currently in TRANSIENT_FAILURE, then + // triggers a connection attempt for that subchannel. If there are + // no more subchannels not in TRANSIENT_FAILURE (i.e., the Happy + // Eyeballs pass is complete), transitions to a mode where we + // try to connect to all subchannels in parallel. + void StartConnectingNextSubchannel(); + // Backpointer to owning policy. RefCountedPtr policy_; @@ -210,8 +232,17 @@ class PickFirst : public LoadBalancingPolicy { // finished processing. bool shutting_down_ = false; - bool in_transient_failure_ = false; + // The index into subchannels_ to which we are currently attempting + // to connect during the initial Happy Eyeballs pass. Once the + // initial pass is over, this will be equal to size(). size_t attempting_index_ = 0; + // Happy Eyeballs timer handle. + absl::optional + timer_handle_; + + // After the initial Happy Eyeballs pass, the number of failures + // we've seen. Every size() failures, we trigger re-resolution. + size_t num_failures_ = 0; }; class HealthWatcher @@ -261,6 +292,8 @@ class PickFirst : public LoadBalancingPolicy { const bool enable_health_watch_; // Whether we should omit our status message prefix. const bool omit_status_message_prefix_; + // Connection Attempt Delay for Happy Eyeballs. + const Duration connection_attempt_delay_; // Lateset update args. UpdateArgs latest_update_args_; @@ -291,7 +324,12 @@ PickFirst::PickFirst(Args args) omit_status_message_prefix_( channel_args() .GetBool(GRPC_ARG_INTERNAL_PICK_FIRST_OMIT_STATUS_MESSAGE_PREFIX) - .value_or(false)) { + .value_or(false)), + connection_attempt_delay_(Duration::Milliseconds( + Clamp(channel_args() + .GetInt(GRPC_ARG_HAPPY_EYEBALLS_CONNECTION_ATTEMPT_DELAY_MS) + .value_or(250), + 100, 2000))) { if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) { gpr_log(GPR_INFO, "Pick First %p created.", this); } @@ -337,7 +375,7 @@ void PickFirst::ResetBackoffLocked() { void PickFirst::AttemptToConnectUsingLatestUpdateArgsLocked() { // Create a subchannel list from latest_update_args_. - ServerAddressList addresses; + EndpointAddressesList addresses; if (latest_update_args_.addresses.ok()) { addresses = *latest_update_args_.addresses; } @@ -393,10 +431,19 @@ absl::Status PickFirst::UpdateLocked(UpdateArgs args) { } else if (args.addresses->empty()) { status = absl::UnavailableError("address list must not be empty"); } else { + // Shuffle the list if needed. auto config = static_cast(args.config.get()); if (config->shuffle_addresses()) { absl::c_shuffle(*args.addresses, bit_gen_); } + // Flatten the list so that we have one address per endpoint. + EndpointAddressesList endpoints; + for (const auto& endpoint : *args.addresses) { + for (const auto& address : endpoint.addresses()) { + endpoints.emplace_back(address, endpoint.args()); + } + } + args.addresses = std::move(endpoints); } // If the update contains a resolver error and we have a previous update // that was not a resolver error, keep using the previous addresses. @@ -562,7 +609,8 @@ void PickFirst::SubchannelList::SubchannelData::OnConnectivityStateChange( p->UnsetSelectedSubchannel(); p->subchannel_list_ = std::move(p->latest_pending_subchannel_list_); // Set our state to that of the pending subchannel list. - if (p->subchannel_list_->in_transient_failure_) { + if (p->subchannel_list_->attempting_index_ == + p->subchannel_list_->size()) { absl::Status status = absl::UnavailableError(absl::StrCat( "selected subchannel failed; switching to pending update; " "last failure: ", @@ -595,7 +643,6 @@ void PickFirst::SubchannelList::SubchannelData::OnConnectivityStateChange( // select in place of the current one. // If the subchannel is READY, use it. if (new_state == GRPC_CHANNEL_READY) { - subchannel_list_->in_transient_failure_ = false; ProcessUnselectedReadyLocked(); return; } @@ -607,94 +654,55 @@ void PickFirst::SubchannelList::SubchannelData::OnConnectivityStateChange( // see its initial notification. Start trying to connect, starting // with the first subchannel. if (!old_state.has_value()) { - subchannel_list_->subchannels_.front().ReactToConnectivityStateLocked(); + subchannel_list_->StartConnectingNextSubchannel(); return; } - // Ignore any other updates for subchannels we're not currently trying to - // connect to. - if (Index() != subchannel_list_->attempting_index_) return; - // React to the connectivity state. - ReactToConnectivityStateLocked(); -} - -void PickFirst::SubchannelList::SubchannelData:: - ReactToConnectivityStateLocked() { - PickFirst* p = subchannel_list_->policy_.get(); - // Otherwise, process connectivity state. - switch (connectivity_state_.value()) { - case GRPC_CHANNEL_READY: - // Already handled this case above, so this should not happen. - GPR_UNREACHABLE_CODE(break); + // Otherwise, process connectivity state change. + switch (*connectivity_state_) { case GRPC_CHANNEL_TRANSIENT_FAILURE: { - // Find the next subchannel not in state TRANSIENT_FAILURE. - // We skip subchannels in state TRANSIENT_FAILURE to avoid a - // large recursion that could overflow the stack. - SubchannelData* found_subchannel = nullptr; - for (size_t next_index = Index() + 1; - next_index < subchannel_list_->size(); ++next_index) { - SubchannelData* sc = &subchannel_list_->subchannels_[next_index]; - GPR_ASSERT(sc->connectivity_state_.has_value()); - if (sc->connectivity_state_ != GRPC_CHANNEL_TRANSIENT_FAILURE) { - subchannel_list_->attempting_index_ = next_index; - found_subchannel = sc; - break; + // If a connection attempt fails before the timer fires, then + // cancel the timer and start connecting on the next subchannel. + if (Index() == subchannel_list_->attempting_index_) { + if (subchannel_list_->timer_handle_.has_value()) { + p->channel_control_helper()->GetEventEngine()->Cancel( + *subchannel_list_->timer_handle_); } - } - // If we found another subchannel in the list not in state - // TRANSIENT_FAILURE, trigger the right behavior for that subchannel. - if (found_subchannel != nullptr) { - found_subchannel->ReactToConnectivityStateLocked(); - break; - } - // We didn't find another subchannel not in state TRANSIENT_FAILURE, - // so report TRANSIENT_FAILURE and wait for the first subchannel - // in the list to report IDLE before continuing. - if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) { - gpr_log(GPR_INFO, - "Pick First %p subchannel list %p failed to connect to " - "all subchannels", - p, subchannel_list_); - } - subchannel_list_->attempting_index_ = 0; - subchannel_list_->in_transient_failure_ = true; - // In case 2, swap to the new subchannel list. This means reporting - // TRANSIENT_FAILURE and dropping the existing (working) connection, - // but we can't ignore what the control plane has told us. - if (subchannel_list_ == p->latest_pending_subchannel_list_.get()) { - if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) { - gpr_log(GPR_INFO, - "Pick First %p promoting pending subchannel list %p to " - "replace %p", - p, p->latest_pending_subchannel_list_.get(), - p->subchannel_list_.get()); + ++subchannel_list_->attempting_index_; + subchannel_list_->StartConnectingNextSubchannel(); + } else if (subchannel_list_->attempting_index_ == + subchannel_list_->size()) { + // We're done with the initial Happy Eyeballs pass and in a mode + // where we're attempting to connect to every subchannel in + // parallel. We count the number of failed connection attempts, + // and when that is equal to the number of subchannels, request + // re-resolution and report TRANSIENT_FAILURE again, so that the + // caller has the most recent status message. Note that this + // isn't necessarily the same as saying that we've seen one + // failure for each subchannel in the list, because the backoff + // state may be different in each subchannel, so we may have seen + // one subchannel fail more than once and another subchannel not + // fail at all. But it's a good enough heuristic. + ++subchannel_list_->num_failures_; + if (subchannel_list_->num_failures_ % subchannel_list_->size() == 0) { + p->channel_control_helper()->RequestReresolution(); + absl::Status status = absl::UnavailableError(absl::StrCat( + (p->omit_status_message_prefix_ + ? "" + : "failed to connect to all addresses; last error: "), + connectivity_status_.ToString())); + p->UpdateState(GRPC_CHANNEL_TRANSIENT_FAILURE, status, + MakeRefCounted(status)); } - p->UnsetSelectedSubchannel(); - p->subchannel_list_ = std::move(p->latest_pending_subchannel_list_); - } - // If this is the current subchannel list (either because we were - // in case 1 or because we were in case 2 and just promoted it to - // be the current list), re-resolve and report new state. - if (subchannel_list_ == p->subchannel_list_.get()) { - p->channel_control_helper()->RequestReresolution(); - absl::Status status = absl::UnavailableError(absl::StrCat( - (p->omit_status_message_prefix_ - ? "" - : "failed to connect to all addresses; last error: "), - connectivity_status_.ToString())); - p->UpdateState(GRPC_CHANNEL_TRANSIENT_FAILURE, status, - MakeRefCounted(status)); - } - // If the first subchannel is already IDLE, trigger the next connection - // attempt immediately. Otherwise, we'll wait for it to report - // its own connectivity state change. - auto& subchannel0 = subchannel_list_->subchannels_.front(); - if (subchannel0.connectivity_state_ == GRPC_CHANNEL_IDLE) { - subchannel0.subchannel_->RequestConnection(); } break; } case GRPC_CHANNEL_IDLE: - subchannel_->RequestConnection(); + // If we've finished the first Happy Eyeballs pass, then we go + // into a mode where we immediately try to connect to every + // subchannel in parallel. + if (subchannel_list_->attempting_index_ == subchannel_list_->size()) { + subchannel_->RequestConnection(); + } break; case GRPC_CHANNEL_CONNECTING: // Only update connectivity state in case 1, and only if we're not @@ -705,13 +713,66 @@ void PickFirst::SubchannelList::SubchannelData:: MakeRefCounted(nullptr)); } break; - case GRPC_CHANNEL_SHUTDOWN: + default: + // We handled READY above, and we should never see SHUTDOWN. GPR_UNREACHABLE_CODE(break); } } +void PickFirst::SubchannelList::SubchannelData::RequestConnectionWithTimer() { + GPR_ASSERT(connectivity_state_.has_value()); + if (connectivity_state_ == GRPC_CHANNEL_IDLE) { + subchannel_->RequestConnection(); + } else { + GPR_ASSERT(connectivity_state_ == GRPC_CHANNEL_CONNECTING); + } + // If this is not the last subchannel in the list, start the timer. + if (Index() != subchannel_list_->size() - 1) { + PickFirst* p = subchannel_list_->policy_.get(); + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) { + gpr_log(GPR_INFO, + "Pick First %p subchannel list %p: starting Connection " + "Attempt Delay timer for %" PRIdPTR "ms for index %" PRIuPTR, + p, subchannel_list_, p->connection_attempt_delay_.millis(), + Index()); + } + subchannel_list_->timer_handle_ = + p->channel_control_helper()->GetEventEngine()->RunAfter( + p->connection_attempt_delay_, + [subchannel_list = + subchannel_list_->Ref(DEBUG_LOCATION, "timer")]() mutable { + ApplicationCallbackExecCtx application_exec_ctx; + ExecCtx exec_ctx; + auto* sl = subchannel_list.get(); + sl->policy_->work_serializer()->Run( + [subchannel_list = std::move(subchannel_list)]() { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) { + gpr_log(GPR_INFO, + "Pick First %p subchannel list %p: Connection " + "Attempt Delay timer fired (shutting_down=%d, " + "selected=%p)", + subchannel_list->policy_.get(), + subchannel_list.get(), + subchannel_list->shutting_down_, + subchannel_list->policy_->selected_); + } + if (subchannel_list->shutting_down_) return; + if (subchannel_list->policy_->selected_ != nullptr) return; + ++subchannel_list->attempting_index_; + subchannel_list->StartConnectingNextSubchannel(); + }, + DEBUG_LOCATION); + }); + } +} + void PickFirst::SubchannelList::SubchannelData::ProcessUnselectedReadyLocked() { PickFirst* p = subchannel_list_->policy_.get(); + // Cancel Happy Eyeballs timer, if any. + if (subchannel_list_->timer_handle_.has_value()) { + p->channel_control_helper()->GetEventEngine()->Cancel( + *subchannel_list_->timer_handle_); + } // If we get here, there are two possible cases: // 1. We do not currently have a selected subchannel, and the update is // for a subchannel in p->subchannel_list_ that we're trying to @@ -772,7 +833,7 @@ void PickFirst::SubchannelList::SubchannelData::ProcessUnselectedReadyLocked() { // PickFirst::SubchannelList::SubchannelList(RefCountedPtr policy, - ServerAddressList addresses, + EndpointAddressesList addresses, const ChannelArgs& args) : InternallyRefCounted( GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace) ? "SubchannelList" @@ -789,9 +850,11 @@ PickFirst::SubchannelList::SubchannelList(RefCountedPtr policy, } subchannels_.reserve(addresses.size()); // Create a subchannel for each address. - for (const ServerAddress& address : addresses) { + for (const EndpointAddresses& address : addresses) { + GPR_ASSERT(address.addresses().size() == 1); RefCountedPtr subchannel = - policy_->channel_control_helper()->CreateSubchannel(address, args_); + policy_->channel_control_helper()->CreateSubchannel( + address.address(), address.args(), args_); if (subchannel == nullptr) { // Subchannel could not be created. if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) { @@ -829,6 +892,9 @@ void PickFirst::SubchannelList::Orphan() { for (auto& sd : subchannels_) { sd.ShutdownLocked(); } + if (timer_handle_.has_value()) { + policy_->channel_control_helper()->GetEventEngine()->Cancel(*timer_handle_); + } Unref(); } @@ -845,6 +911,68 @@ bool PickFirst::SubchannelList::AllSubchannelsSeenInitialState() { return true; } +void PickFirst::SubchannelList::StartConnectingNextSubchannel() { + // Find the next subchannel not in state TRANSIENT_FAILURE. + // We skip subchannels in state TRANSIENT_FAILURE to avoid a + // large recursion that could overflow the stack. + for (; attempting_index_ < size(); ++attempting_index_) { + SubchannelData* sc = &subchannels_[attempting_index_]; + GPR_ASSERT(sc->connectivity_state().has_value()); + if (sc->connectivity_state() != GRPC_CHANNEL_TRANSIENT_FAILURE) { + // Found a subchannel not in TRANSIENT_FAILURE, so trigger a + // connection attempt. + sc->RequestConnectionWithTimer(); + return; + } + } + // We didn't find another subchannel not in state TRANSIENT_FAILURE, + // so report TRANSIENT_FAILURE and switch to a mode in which we try to + // connect to all addresses in parallel. + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) { + gpr_log(GPR_INFO, + "Pick First %p subchannel list %p failed to connect to " + "all subchannels", + policy_.get(), this); + } + // In case 2, swap to the new subchannel list. This means reporting + // TRANSIENT_FAILURE and dropping the existing (working) connection, + // but we can't ignore what the control plane has told us. + if (policy_->latest_pending_subchannel_list_.get() == this) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) { + gpr_log(GPR_INFO, + "Pick First %p promoting pending subchannel list %p to " + "replace %p", + policy_.get(), policy_->latest_pending_subchannel_list_.get(), + this); + } + policy_->UnsetSelectedSubchannel(); + policy_->subchannel_list_ = + std::move(policy_->latest_pending_subchannel_list_); + } + // If this is the current subchannel list (either because we were + // in case 1 or because we were in case 2 and just promoted it to + // be the current list), re-resolve and report new state. + if (policy_->subchannel_list_.get() == this) { + policy_->channel_control_helper()->RequestReresolution(); + absl::Status status = absl::UnavailableError( + absl::StrCat((policy_->omit_status_message_prefix_ + ? "" + : "failed to connect to all addresses; last error: "), + subchannels_.back().connectivity_status().ToString())); + policy_->UpdateState(GRPC_CHANNEL_TRANSIENT_FAILURE, status, + MakeRefCounted(status)); + } + // We now transition into a mode where we try to connect to all + // subchannels in parallel. For any subchannel currently in IDLE, + // trigger a connection attempt. For any subchannel not currently in + // IDLE, we will trigger a connection attempt when it does report IDLE. + for (SubchannelData& sd : subchannels_) { + if (sd.connectivity_state() == GRPC_CHANNEL_IDLE) { + sd.RequestConnection(); + } + } +} + // // factory // diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.h b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.h index ff5e0e6f2a408..4796742526d55 100644 --- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.h +++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.h @@ -19,7 +19,7 @@ #include -#include "src/core/lib/resolver/server_address.h" +#include "src/core/lib/resolver/endpoint_addresses.h" // Internal channel arg to enable health checking in pick_first. // Intended to be used by petiole policies (e.g., round_robin) that diff --git a/src/core/ext/filters/client_channel/lb_policy/priority/priority.cc b/src/core/ext/filters/client_channel/lb_policy/priority/priority.cc index 716b5f41e88a1..09bb347f53737 100644 --- a/src/core/ext/filters/client_channel/lb_policy/priority/priority.cc +++ b/src/core/ext/filters/client_channel/lb_policy/priority/priority.cc @@ -59,7 +59,7 @@ #include "src/core/lib/load_balancing/lb_policy.h" #include "src/core/lib/load_balancing/lb_policy_factory.h" #include "src/core/lib/load_balancing/lb_policy_registry.h" -#include "src/core/lib/resolver/server_address.h" +#include "src/core/lib/resolver/endpoint_addresses.h" #include "src/core/lib/transport/connectivity_state.h" namespace grpc_core { diff --git a/src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.cc b/src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.cc index 288f46d80455b..9d440ca75d65e 100644 --- a/src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.cc +++ b/src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.cc @@ -68,7 +68,7 @@ #include "src/core/lib/load_balancing/lb_policy.h" #include "src/core/lib/load_balancing/lb_policy_factory.h" #include "src/core/lib/load_balancing/lb_policy_registry.h" -#include "src/core/lib/resolver/server_address.h" +#include "src/core/lib/resolver/endpoint_addresses.h" #include "src/core/lib/transport/connectivity_state.h" namespace grpc_core { @@ -150,7 +150,7 @@ class RingHash : public LoadBalancingPolicy { public: struct RingEntry { uint64_t hash; - size_t endpoint_index; // Index into RingHash::addresses_. + size_t endpoint_index; // Index into RingHash::endpoints_. }; Ring(RingHash* ring_hash, RingHashLbConfig* config); @@ -164,7 +164,7 @@ class RingHash : public LoadBalancingPolicy { // State for a particular endpoint. Delegates to a pick_first child policy. class RingHashEndpoint : public InternallyRefCounted { public: - // index is the index into RingHash::addresses_ of this endpoint. + // index is the index into RingHash::endpoints_ of this endpoint. RingHashEndpoint(RefCountedPtr ring_hash, size_t index) : ring_hash_(std::move(ring_hash)), index_(index) {} @@ -208,7 +208,7 @@ class RingHash : public LoadBalancingPolicy { // Ref to our parent. RefCountedPtr ring_hash_; - size_t index_; // Index into RingHash::addresses_ of this endpoint. + size_t index_; // Index into RingHash::endpoints_ of this endpoint. // The pick_first child policy. OrphanablePtr child_policy_; @@ -223,7 +223,7 @@ class RingHash : public LoadBalancingPolicy { explicit Picker(RefCountedPtr ring_hash) : ring_hash_(std::move(ring_hash)), ring_(ring_hash_->ring_), - endpoints_(ring_hash_->addresses_.size()) { + endpoints_(ring_hash_->endpoints_.size()) { for (const auto& p : ring_hash_->endpoint_map_) { endpoints_[p.second->index()] = p.second->GetInfoForPicker(); } @@ -281,12 +281,12 @@ class RingHash : public LoadBalancingPolicy { void UpdateAggregatedConnectivityStateLocked(bool entered_transient_failure, absl::Status status); - // Current address list, channel args, and ring. - ServerAddressList addresses_; + // Current endpoint list, channel args, and ring. + EndpointAddressesList endpoints_; ChannelArgs args_; RefCountedPtr ring_; - std::map> endpoint_map_; + std::map> endpoint_map_; // TODO(roth): If we ever change the helper UpdateState() API to not // need the status reported for TRANSIENT_FAILURE state (because @@ -373,39 +373,40 @@ RingHash::PickResult RingHash::Picker::Pick(PickArgs args) { RingHash::Ring::Ring(RingHash* ring_hash, RingHashLbConfig* config) { // Store the weights while finding the sum. - struct AddressWeight { - std::string address; + struct EndpointWeight { + std::string address; // Key by endpoint's first address. // Default weight is 1 for the cases where a weight is not provided, // each occurrence of the address will be counted a weight value of 1. uint32_t weight = 1; double normalized_weight; }; - std::vector address_weights; + std::vector endpoint_weights; size_t sum = 0; - const ServerAddressList& addresses = ring_hash->addresses_; - address_weights.reserve(addresses.size()); - for (const auto& address : addresses) { - AddressWeight address_weight; - address_weight.address = - grpc_sockaddr_to_string(&address.address(), false).value(); + const EndpointAddressesList& endpoints = ring_hash->endpoints_; + endpoint_weights.reserve(endpoints.size()); + for (const auto& endpoint : endpoints) { + EndpointWeight endpoint_weight; + endpoint_weight.address = + grpc_sockaddr_to_string(&endpoint.addresses().front(), false).value(); // Weight should never be zero, but ignore it just in case, since // that value would screw up the ring-building algorithm. - auto weight_arg = address.args().GetInt(GRPC_ARG_ADDRESS_WEIGHT); + auto weight_arg = endpoint.args().GetInt(GRPC_ARG_ADDRESS_WEIGHT); if (weight_arg.value_or(0) > 0) { - address_weight.weight = *weight_arg; + endpoint_weight.weight = *weight_arg; } - sum += address_weight.weight; - address_weights.push_back(std::move(address_weight)); + sum += endpoint_weight.weight; + endpoint_weights.push_back(std::move(endpoint_weight)); } // Calculating normalized weights and find min and max. double min_normalized_weight = 1.0; double max_normalized_weight = 0.0; - for (auto& address : address_weights) { - address.normalized_weight = static_cast(address.weight) / sum; + for (auto& endpoint_weight : endpoint_weights) { + endpoint_weight.normalized_weight = + static_cast(endpoint_weight.weight) / sum; min_normalized_weight = - std::min(address.normalized_weight, min_normalized_weight); + std::min(endpoint_weight.normalized_weight, min_normalized_weight); max_normalized_weight = - std::max(address.normalized_weight, max_normalized_weight); + std::max(endpoint_weight.normalized_weight, max_normalized_weight); } // Scale up the number of hashes per host such that the least-weighted host // gets a whole number of hashes on the ring. Other hosts might not end up @@ -435,12 +436,12 @@ RingHash::Ring::Ring(RingHash* ring_hash, RingHashLbConfig* config) { double target_hashes = 0.0; uint64_t min_hashes_per_host = ring_size; uint64_t max_hashes_per_host = 0; - for (size_t i = 0; i < addresses.size(); ++i) { - const std::string& address_string = address_weights[i].address; + for (size_t i = 0; i < endpoints.size(); ++i) { + const std::string& address_string = endpoint_weights[i].address; hash_key_buffer.assign(address_string.begin(), address_string.end()); hash_key_buffer.emplace_back('_'); auto offset_start = hash_key_buffer.end(); - target_hashes += scale * address_weights[i].normalized_weight; + target_hashes += scale * endpoint_weights[i].normalized_weight; size_t count = 0; while (current_hashes < target_hashes) { const std::string count_str = absl::StrCat(count); @@ -536,12 +537,12 @@ void RingHash::RingHashEndpoint::CreateChildPolicy() { CoreConfiguration::Get().lb_policy_registry().CreateLoadBalancingPolicy( "pick_first", std::move(lb_policy_args)); if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_ring_hash_trace)) { - const ServerAddress& address = ring_hash_->addresses_[index_]; + const EndpointAddresses& endpoint = ring_hash_->endpoints_[index_]; gpr_log(GPR_INFO, "[RH %p] endpoint %p (index %" PRIuPTR " of %" PRIuPTR ", %s): created child policy %p", - ring_hash_.get(), this, index_, ring_hash_->addresses_.size(), - address.ToString().c_str(), child_policy_.get()); + ring_hash_.get(), this, index_, ring_hash_->endpoints_.size(), + endpoint.ToString().c_str(), child_policy_.get()); } // Add our interested_parties pollset_set to that of the newly created // child policy. This will make the child policy progress upon activity on @@ -560,7 +561,7 @@ void RingHash::RingHashEndpoint::UpdateChildPolicyLocked() { GPR_ASSERT(config.ok()); // Update child policy. LoadBalancingPolicy::UpdateArgs update_args; - update_args.addresses.emplace().emplace_back(ring_hash_->addresses_[index_]); + update_args.addresses.emplace().emplace_back(ring_hash_->endpoints_[index_]); update_args.args = ring_hash_->args_; update_args.config = std::move(*config); // TODO(roth): If the child reports a non-OK status with the update, @@ -577,7 +578,7 @@ void RingHash::RingHashEndpoint::OnStateUpdate( "[RH %p] connectivity changed for endpoint %p (%s, child_policy=%p): " "prev_state=%s new_state=%s (%s)", ring_hash_.get(), this, - ring_hash_->addresses_[index_].ToString().c_str(), child_policy_.get(), + ring_hash_->endpoints_[index_].ToString().c_str(), child_policy_.get(), ConnectivityStateName(connectivity_state_), ConnectivityStateName(new_state), status.ToString().c_str()); } @@ -631,7 +632,7 @@ absl::Status RingHash::UpdateLocked(UpdateArgs args) { gpr_log(GPR_INFO, "[RH %p] received update with %" PRIuPTR " addresses", this, args.addresses->size()); } - addresses_ = *std::move(args.addresses); + endpoints_ = *std::move(args.addresses); } else { if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_ring_hash_trace)) { gpr_log(GPR_INFO, "[RH %p] received update with addresses error: %s", @@ -639,7 +640,7 @@ absl::Status RingHash::UpdateLocked(UpdateArgs args) { } // If we already have an endpoint list, then keep using the existing // list, but still report back that the update was not accepted. - if (!addresses_.empty()) return args.addresses.status(); + if (!endpoints_.empty()) return args.addresses.status(); } // Save channel args. args_ = std::move(args.args); @@ -647,24 +648,23 @@ absl::Status RingHash::UpdateLocked(UpdateArgs args) { ring_ = MakeRefCounted( this, static_cast(args.config.get())); // Update endpoint map. - std::map> endpoint_map; - for (size_t i = 0; i < addresses_.size(); ++i) { - const ServerAddress& address = addresses_[i]; + std::map> endpoint_map; + for (size_t i = 0; i < endpoints_.size(); ++i) { + const EndpointAddresses& addresses = endpoints_[i]; + const EndpointAddressSet address_set(addresses.addresses()); // If present in old map, retain it; otherwise, create a new one. - auto it = endpoint_map_.find(address); + auto it = endpoint_map_.find(address_set); if (it != endpoint_map_.end()) { it->second->UpdateLocked(i); - endpoint_map.emplace(address, std::move(it->second)); + endpoint_map.emplace(address_set, std::move(it->second)); } else { - endpoint_map.emplace(address, MakeOrphanable(Ref(), i)); + endpoint_map.emplace(address_set, + MakeOrphanable(Ref(), i)); } } endpoint_map_ = std::move(endpoint_map); // If the address list is empty, report TRANSIENT_FAILURE. - // TODO(roth): As part of adding dualstack backend support, we need to - // also handle the case where the list of addresses for a given - // endpoint is empty. - if (addresses_.empty()) { + if (endpoints_.empty()) { absl::Status status = args.addresses.ok() ? absl::UnavailableError(absl::StrCat( "empty address list: ", args.resolution_note)) @@ -726,7 +726,7 @@ void RingHash::UpdateAggregatedConnectivityStateLocked( start_connection_attempt = true; } else if (num_connecting > 0) { state = GRPC_CHANNEL_CONNECTING; - } else if (num_transient_failure == 1 && addresses_.size() > 1) { + } else if (num_transient_failure == 1 && endpoints_.size() > 1) { state = GRPC_CHANNEL_CONNECTING; start_connection_attempt = true; } else if (num_idle > 0) { @@ -742,7 +742,7 @@ void RingHash::UpdateAggregatedConnectivityStateLocked( ", num_transient_failure=%" PRIuPTR ", size=%" PRIuPTR ") -- start_connection_attempt=%d", this, ConnectivityStateName(state), num_idle, num_connecting, - num_ready, num_transient_failure, addresses_.size(), + num_ready, num_transient_failure, endpoints_.size(), start_connection_attempt); } // In TRANSIENT_FAILURE, report the last reported failure. @@ -794,29 +794,31 @@ void RingHash::UpdateAggregatedConnectivityStateLocked( // CONNECTING, just to ensure that we don't remain in CONNECTING state // indefinitely if there are no new picks coming in. if (start_connection_attempt && entered_transient_failure) { - size_t first_idle_index = addresses_.size(); - for (size_t i = 0; i < addresses_.size(); ++i) { - auto it = endpoint_map_.find(addresses_[i]); + size_t first_idle_index = endpoints_.size(); + for (size_t i = 0; i < endpoints_.size(); ++i) { + auto it = + endpoint_map_.find(EndpointAddressSet(endpoints_[i].addresses())); GPR_ASSERT(it != endpoint_map_.end()); if (it->second->connectivity_state() == GRPC_CHANNEL_CONNECTING) { - first_idle_index = addresses_.size(); + first_idle_index = endpoints_.size(); break; } - if (first_idle_index == addresses_.size() && + if (first_idle_index == endpoints_.size() && it->second->connectivity_state() == GRPC_CHANNEL_IDLE) { first_idle_index = i; } } - if (first_idle_index != addresses_.size()) { - auto it = endpoint_map_.find(addresses_[first_idle_index]); + if (first_idle_index != endpoints_.size()) { + auto it = endpoint_map_.find( + EndpointAddressSet(endpoints_[first_idle_index].addresses())); GPR_ASSERT(it != endpoint_map_.end()); if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_ring_hash_trace)) { gpr_log(GPR_INFO, "[RH %p] triggering internal connection attempt for endpoint " "%p (%s) (index %" PRIuPTR " of %" PRIuPTR ")", this, it->second.get(), - addresses_[first_idle_index].ToString().c_str(), - first_idle_index, addresses_.size()); + endpoints_[first_idle_index].ToString().c_str(), + first_idle_index, endpoints_.size()); } it->second->RequestConnectionLocked(); } diff --git a/src/core/ext/filters/client_channel/lb_policy/rls/rls.cc b/src/core/ext/filters/client_channel/lb_policy/rls/rls.cc index 7a23aa8308440..dc71d4e4409ee 100644 --- a/src/core/ext/filters/client_channel/lb_policy/rls/rls.cc +++ b/src/core/ext/filters/client_channel/lb_policy/rls/rls.cc @@ -92,8 +92,8 @@ #include "src/core/lib/load_balancing/lb_policy.h" #include "src/core/lib/load_balancing/lb_policy_factory.h" #include "src/core/lib/load_balancing/lb_policy_registry.h" +#include "src/core/lib/resolver/endpoint_addresses.h" #include "src/core/lib/resolver/resolver_registry.h" -#include "src/core/lib/resolver/server_address.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/credentials/fake/fake_credentials.h" #include "src/core/lib/service_config/service_config_impl.h" @@ -709,7 +709,7 @@ class RlsLb : public LoadBalancingPolicy { OrphanablePtr rls_channel_ ABSL_GUARDED_BY(mu_); // Accessed only from within WorkSerializer. - absl::StatusOr addresses_; + absl::StatusOr addresses_; ChannelArgs channel_args_; RefCountedPtr config_; RefCountedPtr default_child_policy_; @@ -1877,7 +1877,7 @@ absl::Status RlsLb::UpdateLocked(UpdateArgs args) { // Swap out addresses. // If the new address list is an error and we have an existing address list, // stick with the existing addresses. - absl::StatusOr old_addresses; + absl::StatusOr old_addresses; if (args.addresses.ok()) { old_addresses = std::move(addresses_); addresses_ = std::move(args.addresses); 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 2a556d6448903..87d291ca8580f 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 @@ -51,6 +51,7 @@ #include "src/core/lib/load_balancing/lb_policy.h" #include "src/core/lib/load_balancing/lb_policy_factory.h" #include "src/core/lib/load_balancing/subchannel_interface.h" +#include "src/core/lib/resolver/endpoint_addresses.h" #include "src/core/lib/resolver/server_address.h" #include "src/core/lib/transport/connectivity_state.h" @@ -523,17 +524,17 @@ class RoundRobin : public LoadBalancingPolicy { class RoundRobinEndpointList : public EndpointList { public: RoundRobinEndpointList(RefCountedPtr round_robin, - const ServerAddressList& addresses, + const EndpointAddressesList& endpoints, const ChannelArgs& args) : EndpointList(std::move(round_robin), GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace) ? "RoundRobinEndpointList" : nullptr) { - Init(addresses, args, + Init(endpoints, args, [&](RefCountedPtr endpoint_list, - const ServerAddress& address, const ChannelArgs& args) { + const EndpointAddresses& addresses, const ChannelArgs& args) { return MakeOrphanable( - std::move(endpoint_list), address, args, + std::move(endpoint_list), addresses, args, policy()->work_serializer()); }); } @@ -542,10 +543,11 @@ class RoundRobin : public LoadBalancingPolicy { class RoundRobinEndpoint : public Endpoint { public: RoundRobinEndpoint(RefCountedPtr endpoint_list, - const ServerAddress& address, const ChannelArgs& args, + const EndpointAddresses& addresses, + const ChannelArgs& args, std::shared_ptr work_serializer) : Endpoint(std::move(endpoint_list)) { - Init(address, args, std::move(work_serializer)); + Init(addresses, args, std::move(work_serializer)); } private: @@ -685,10 +687,10 @@ void RoundRobin::ResetBackoffLocked() { } absl::Status RoundRobin::UpdateLocked(UpdateArgs args) { - ServerAddressList addresses; + EndpointAddressesList addresses; if (args.addresses.ok()) { if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) { - gpr_log(GPR_INFO, "[RR %p] received update with %" PRIuPTR " addresses", + gpr_log(GPR_INFO, "[RR %p] received update with %" PRIuPTR " endpoints", this, args.addresses->size()); } addresses = std::move(*args.addresses); @@ -712,9 +714,6 @@ absl::Status RoundRobin::UpdateLocked(UpdateArgs args) { args.args); // If the new list is empty, immediately promote it to // endpoint_list_ and report TRANSIENT_FAILURE. - // TODO(roth): As part of adding dualstack backend support, we need to - // also handle the case where the list of addresses for a given - // endpoint is empty. if (latest_pending_endpoint_list_->size() == 0) { if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace) && endpoint_list_ != nullptr) { @@ -838,7 +837,6 @@ void RoundRobin::RoundRobinEndpointList:: } // Only set connectivity state if this is the current child list. if (round_robin->endpoint_list_.get() != this) return; - // FIXME: scan children each time instead of keeping counters? // First matching rule wins: // 1) ANY child is READY => policy is READY. // 2) ANY child is CONNECTING => policy is CONNECTING. 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 7e9b4df8648d2..4738479486975 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 @@ -380,7 +380,7 @@ SubchannelList::SubchannelList( // Create a subchannel for each address. for (ServerAddress address : addresses) { RefCountedPtr subchannel = - helper->CreateSubchannel(address, args); + helper->CreateSubchannel(address.address(), address.args(), args); if (subchannel == nullptr) { // Subchannel could not be created. if (GPR_UNLIKELY(tracer_ != nullptr)) { diff --git a/src/core/ext/filters/client_channel/lb_policy/weighted_round_robin/weighted_round_robin.cc b/src/core/ext/filters/client_channel/lb_policy/weighted_round_robin/weighted_round_robin.cc index 353eb720f4935..3d35716177a8e 100644 --- a/src/core/ext/filters/client_channel/lb_policy/weighted_round_robin/weighted_round_robin.cc +++ b/src/core/ext/filters/client_channel/lb_policy/weighted_round_robin/weighted_round_robin.cc @@ -73,6 +73,7 @@ #include "src/core/lib/load_balancing/lb_policy.h" #include "src/core/lib/load_balancing/lb_policy_factory.h" #include "src/core/lib/load_balancing/subchannel_interface.h" +#include "src/core/lib/resolver/endpoint_addresses.h" #include "src/core/lib/resolver/server_address.h" #include "src/core/lib/transport/connectivity_state.h" @@ -1009,7 +1010,8 @@ class WeightedRoundRobin : public LoadBalancingPolicy { // Represents the weight for a given address. class EndpointWeight : public RefCounted { public: - EndpointWeight(RefCountedPtr wrr, std::string key) + EndpointWeight(RefCountedPtr wrr, + EndpointAddressSet key) : wrr_(std::move(wrr)), key_(std::move(key)) {} ~EndpointWeight() override; @@ -1023,7 +1025,7 @@ class WeightedRoundRobin : public LoadBalancingPolicy { private: RefCountedPtr wrr_; - const std::string key_; + const EndpointAddressSet key_; Mutex mu_; float weight_ ABSL_GUARDED_BY(&mu_) = 0; @@ -1036,12 +1038,12 @@ class WeightedRoundRobin : public LoadBalancingPolicy { class WrrEndpoint : public Endpoint { public: WrrEndpoint(RefCountedPtr endpoint_list, - const ServerAddress& address, const ChannelArgs& args, + const EndpointAddresses& addresses, const ChannelArgs& args, std::shared_ptr work_serializer) : Endpoint(std::move(endpoint_list)), weight_(policy()->GetOrCreateWeight( - address.address())) { - Init(address, args, std::move(work_serializer)); + addresses.addresses())) { + Init(addresses, args, std::move(work_serializer)); } RefCountedPtr weight() const { return weight_; } @@ -1063,7 +1065,9 @@ class WeightedRoundRobin : public LoadBalancingPolicy { }; RefCountedPtr CreateSubchannel( - ServerAddress address, const ChannelArgs& args) override; + const grpc_resolved_address& address, + const ChannelArgs& per_address_args, + const ChannelArgs& args) override; // Called when the child policy reports a connectivity state update. void OnStateUpdate(absl::optional old_state, @@ -1074,16 +1078,17 @@ class WeightedRoundRobin : public LoadBalancingPolicy { }; WrrEndpointList(RefCountedPtr wrr, - const ServerAddressList& addresses, const ChannelArgs& args) + const EndpointAddressesList& endpoints, + const ChannelArgs& args) : EndpointList(std::move(wrr), GRPC_TRACE_FLAG_ENABLED(grpc_lb_wrr_trace) ? "WrrEndpointList" : nullptr) { - Init(addresses, args, + Init(endpoints, args, [&](RefCountedPtr endpoint_list, - const ServerAddress& address, const ChannelArgs& args) { + const EndpointAddresses& addresses, const ChannelArgs& args) { return MakeOrphanable( - std::move(endpoint_list), address, args, + std::move(endpoint_list), addresses, args, policy()->work_serializer()); }); } @@ -1192,7 +1197,7 @@ class WeightedRoundRobin : public LoadBalancingPolicy { void ShutdownLocked() override; RefCountedPtr GetOrCreateWeight( - const grpc_resolved_address& address); + const std::vector& addresses); RefCountedPtr config_; @@ -1205,7 +1210,7 @@ class WeightedRoundRobin : public LoadBalancingPolicy { OrphanablePtr latest_pending_endpoint_list_; Mutex endpoint_weight_map_mu_; - std::map> endpoint_weight_map_ + std::map endpoint_weight_map_ ABSL_GUARDED_BY(&endpoint_weight_map_mu_); bool shutdown_ = false; @@ -1245,7 +1250,7 @@ void WeightedRoundRobin::EndpointWeight::MaybeUpdateWeight( gpr_log(GPR_INFO, "[WRR %p] subchannel %s: qps=%f, eps=%f, utilization=%f: " "error_util_penalty=%f, weight=%f (not updating)", - wrr_.get(), key_.c_str(), qps, eps, utilization, + wrr_.get(), key_.ToString().c_str(), qps, eps, utilization, error_utilization_penalty, weight); } return; @@ -1258,7 +1263,7 @@ void WeightedRoundRobin::EndpointWeight::MaybeUpdateWeight( "[WRR %p] subchannel %s: qps=%f, eps=%f, utilization=%f " "error_util_penalty=%f : setting weight=%f weight_=%f now=%s " "last_update_time_=%s non_empty_since_=%s", - wrr_.get(), key_.c_str(), qps, eps, utilization, + wrr_.get(), key_.ToString().c_str(), qps, eps, utilization, error_utilization_penalty, weight, weight_, now.ToString().c_str(), last_update_time_.ToString().c_str(), non_empty_since_.ToString().c_str()); @@ -1277,7 +1282,7 @@ float WeightedRoundRobin::EndpointWeight::GetWeight( "[WRR %p] subchannel %s: getting weight: now=%s " "weight_expiration_period=%s blackout_period=%s " "last_update_time_=%s non_empty_since_=%s weight_=%f", - wrr_.get(), key_.c_str(), now.ToString().c_str(), + wrr_.get(), key_.ToString().c_str(), now.ToString().c_str(), weight_expiration_period.ToString().c_str(), blackout_period.ToString().c_str(), last_update_time_.ToString().c_str(), @@ -1510,59 +1515,56 @@ void WeightedRoundRobin::ResetBackoffLocked() { absl::Status WeightedRoundRobin::UpdateLocked(UpdateArgs args) { global_stats().IncrementWrrUpdates(); config_ = std::move(args.config); - ServerAddressList addresses; + EndpointAddressesList addresses; if (args.addresses.ok()) { if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_wrr_trace)) { gpr_log(GPR_INFO, "[WRR %p] received update with %" PRIuPTR " addresses", this, args.addresses->size()); } - // Weed out duplicate addresses. Also sort the addresses so that if - // the set of the addresses don't change, their indexes in the - // subchannel list don't change, since this avoids unnecessary churn - // in the picker. Note that this does not ensure that if a given - // address remains present that it will have the same index; if, - // for example, an address at the end of the list is replaced with one - // that sorts much earlier in the list, then all of the addresses in - // between those two positions will have changed indexes. - struct AddressLessThan { - bool operator()(const ServerAddress& address1, - const ServerAddress& address2) const { - const grpc_resolved_address& addr1 = address1.address(); - const grpc_resolved_address& addr2 = address2.address(); - if (addr1.len != addr2.len) return addr1.len < addr2.len; - return memcmp(addr1.addr, addr2.addr, addr1.len) < 0; + // Weed out duplicate endpoints. Also sort the endpoints so that if + // the set of endpoints doesn't change, their indexes in the endpoint + // list don't change, since this avoids unnecessary churn in the + // picker. Note that this does not ensure that if a given endpoint + // remains present that it will have the same index; if, for example, + // an endpoint at the end of the list is replaced with one that sorts + // much earlier in the list, then all of the endpoints in between those + // two positions will have changed indexes. + struct EndpointAddressesLessThan { + bool operator()(const EndpointAddresses& endpoint1, + const EndpointAddresses& endpoint2) const { + // Compare unordered addresses only, not channel args. + EndpointAddressSet e1(endpoint1.addresses()); + EndpointAddressSet e2(endpoint2.addresses()); + return e1 < e2; } }; - std::set ordered_addresses( + std::set ordered_addresses( args.addresses->begin(), args.addresses->end()); - addresses = - ServerAddressList(ordered_addresses.begin(), ordered_addresses.end()); + addresses = EndpointAddressesList(ordered_addresses.begin(), + ordered_addresses.end()); } else { if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_wrr_trace)) { gpr_log(GPR_INFO, "[WRR %p] received update with address error: %s", this, args.addresses.status().ToString().c_str()); } - // If we already have a subchannel list, then keep using the existing + // If we already have an endpoint list, then keep using the existing // list, but still report back that the update was not accepted. if (endpoint_list_ != nullptr) return args.addresses.status(); } - // Create new subchannel list, replacing the previous pending list, if any. + // Create new endpoint list, replacing the previous pending list, if any. if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_wrr_trace) && latest_pending_endpoint_list_ != nullptr) { - gpr_log(GPR_INFO, "[WRR %p] replacing previous pending subchannel list %p", + gpr_log(GPR_INFO, "[WRR %p] replacing previous pending endpoint list %p", this, latest_pending_endpoint_list_.get()); } latest_pending_endpoint_list_ = MakeOrphanable(Ref(), std::move(addresses), args.args); // If the new list is empty, immediately promote it to // endpoint_list_ and report TRANSIENT_FAILURE. - // TODO(roth): As part of adding dualstack backend support, we need to - // also handle the case where the list of addresses for a given - // endpoint is empty. if (latest_pending_endpoint_list_->size() == 0) { if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_wrr_trace) && endpoint_list_ != nullptr) { - gpr_log(GPR_INFO, "[WRR %p] replacing previous subchannel list %p", this, + gpr_log(GPR_INFO, "[WRR %p] replacing previous endpoint list %p", this, endpoint_list_.get()); } endpoint_list_ = std::move(latest_pending_endpoint_list_); @@ -1584,18 +1586,18 @@ absl::Status WeightedRoundRobin::UpdateLocked(UpdateArgs args) { } RefCountedPtr -WeightedRoundRobin::GetOrCreateWeight(const grpc_resolved_address& address) { - auto key = grpc_sockaddr_to_uri(&address); - if (!key.ok()) return nullptr; +WeightedRoundRobin::GetOrCreateWeight( + const std::vector& addresses) { + EndpointAddressSet key(addresses); MutexLock lock(&endpoint_weight_map_mu_); - auto it = endpoint_weight_map_.find(*key); + auto it = endpoint_weight_map_.find(key); if (it != endpoint_weight_map_.end()) { auto weight = it->second->RefIfNonZero(); if (weight != nullptr) return weight; } auto weight = MakeRefCounted( - Ref(DEBUG_LOCATION, "EndpointWeight"), *key); - endpoint_weight_map_.emplace(*key, weight.get()); + Ref(DEBUG_LOCATION, "EndpointWeight"), key); + endpoint_weight_map_.emplace(key, weight.get()); return weight; } @@ -1619,10 +1621,11 @@ void WeightedRoundRobin::WrrEndpointList::WrrEndpoint::OobWatcher:: RefCountedPtr WeightedRoundRobin::WrrEndpointList::WrrEndpoint::CreateSubchannel( - ServerAddress address, const ChannelArgs& args) { + const grpc_resolved_address& address, const ChannelArgs& per_address_args, + const ChannelArgs& args) { auto* wrr = policy(); - auto subchannel = - wrr->channel_control_helper()->CreateSubchannel(std::move(address), args); + auto subchannel = wrr->channel_control_helper()->CreateSubchannel( + address, per_address_args, args); // Start OOB watch if configured. if (wrr->config_->enable_oob_load_report()) { subchannel->AddDataWatcher(MakeOobBackendMetricWatcher( @@ -1657,7 +1660,7 @@ void WeightedRoundRobin::WrrEndpointList::WrrEndpoint::OnStateUpdate( } else if (new_state == GRPC_CHANNEL_READY) { // If we transition back to READY state, restart the blackout period. // Skip this if this is the initial notification for this - // subchannel (which happens whenever we get updated addresses and + // endpoint (which happens whenever we get updated addresses and // create a new endpoint list). Also skip it if the previous state // was READY (which should never happen in practice, but we've seen // at least one bug that caused this in the outlier_detection diff --git a/src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc b/src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc index b3ccbbf9e8f9f..fad7aa96857e4 100644 --- a/src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc +++ b/src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc @@ -60,7 +60,7 @@ #include "src/core/lib/load_balancing/lb_policy.h" #include "src/core/lib/load_balancing/lb_policy_factory.h" #include "src/core/lib/load_balancing/lb_policy_registry.h" -#include "src/core/lib/resolver/server_address.h" +#include "src/core/lib/resolver/endpoint_addresses.h" #include "src/core/lib/transport/connectivity_state.h" // IWYU pragma: no_include @@ -157,7 +157,7 @@ class WeightedTargetLb : public LoadBalancingPolicy { void Orphan() override; absl::Status UpdateLocked(const WeightedTargetLbConfig::ChildConfig& config, - absl::StatusOr addresses, + absl::StatusOr addresses, const std::string& resolution_note, const ChannelArgs& args); void ResetBackoffLocked(); @@ -337,7 +337,7 @@ absl::Status WeightedTargetLb::UpdateLocked(UpdateArgs args) { target = MakeOrphanable( Ref(DEBUG_LOCATION, "WeightedChild"), name); } - absl::StatusOr addresses; + absl::StatusOr addresses; if (address_map.ok()) { auto it = address_map->find(name); if (it == address_map->end()) { @@ -588,7 +588,7 @@ WeightedTargetLb::WeightedChild::CreateChildPolicyLocked( absl::Status WeightedTargetLb::WeightedChild::UpdateLocked( const WeightedTargetLbConfig::ChildConfig& config, - absl::StatusOr addresses, + absl::StatusOr addresses, const std::string& resolution_note, const ChannelArgs& args) { if (weighted_target_policy_->shutting_down_) return absl::OkStatus(); // Update child weight. diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_args.h b/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_args.h index c7bbf197da088..1df82d2fa1823 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_args.h +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_args.h @@ -19,7 +19,7 @@ #include -#include "src/core/lib/resolver/server_address.h" +#include "src/core/lib/resolver/endpoint_addresses.h" // Channel arg indicating the xDS cluster name. // Set by xds_cluster_impl LB policy and used by GoogleDefaultCredentials. diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc index 158428996f76f..50740151c9d93 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc @@ -56,6 +56,7 @@ #include "src/core/lib/gprpp/sync.h" #include "src/core/lib/gprpp/validation_errors.h" #include "src/core/lib/iomgr/pollset_set.h" +#include "src/core/lib/iomgr/resolved_address.h" #include "src/core/lib/json/json.h" #include "src/core/lib/json/json_args.h" #include "src/core/lib/json/json_object_loader.h" @@ -64,7 +65,7 @@ #include "src/core/lib/load_balancing/lb_policy_factory.h" #include "src/core/lib/load_balancing/lb_policy_registry.h" #include "src/core/lib/load_balancing/subchannel_interface.h" -#include "src/core/lib/resolver/server_address.h" +#include "src/core/lib/resolver/endpoint_addresses.h" #include "src/core/lib/transport/connectivity_state.h" namespace grpc_core { @@ -236,7 +237,8 @@ class XdsClusterImplLb : public LoadBalancingPolicy { std::move(xds_cluster_impl_policy)) {} RefCountedPtr CreateSubchannel( - ServerAddress address, const ChannelArgs& args) override; + const grpc_resolved_address& address, + const ChannelArgs& per_address_args, const ChannelArgs& args) override; void UpdateState(grpc_connectivity_state state, const absl::Status& status, RefCountedPtr picker) override; }; @@ -248,8 +250,8 @@ class XdsClusterImplLb : public LoadBalancingPolicy { OrphanablePtr CreateChildPolicyLocked( const ChannelArgs& args); absl::Status UpdateChildPolicyLocked( - absl::StatusOr addresses, std::string resolution_note, - const ChannelArgs& args); + absl::StatusOr addresses, + std::string resolution_note, const ChannelArgs& args); void MaybeUpdatePickerLocked(); @@ -567,8 +569,8 @@ OrphanablePtr XdsClusterImplLb::CreateChildPolicyLocked( } absl::Status XdsClusterImplLb::UpdateChildPolicyLocked( - absl::StatusOr addresses, std::string resolution_note, - const ChannelArgs& args) { + absl::StatusOr addresses, + std::string resolution_note, const ChannelArgs& args) { // Create policy if needed. if (child_policy_ == nullptr) { child_policy_ = CreateChildPolicyLocked(args); @@ -594,12 +596,13 @@ absl::Status XdsClusterImplLb::UpdateChildPolicyLocked( // RefCountedPtr XdsClusterImplLb::Helper::CreateSubchannel( - ServerAddress address, const ChannelArgs& args) { + const grpc_resolved_address& address, const ChannelArgs& per_address_args, + const ChannelArgs& args) { if (parent()->shutting_down_) return nullptr; // If load reporting is enabled, wrap the subchannel such that it // includes the locality stats object, which will be used by the Picker. if (parent()->config_->lrs_load_reporting_server().has_value()) { - auto locality_name = address.args().GetObjectRef(); + auto locality_name = per_address_args.GetObjectRef(); RefCountedPtr locality_stats = parent()->xds_client_->AddClusterLocalityStats( parent()->config_->lrs_load_reporting_server().value(), @@ -608,7 +611,7 @@ RefCountedPtr XdsClusterImplLb::Helper::CreateSubchannel( if (locality_stats != nullptr) { return MakeRefCounted( parent()->channel_control_helper()->CreateSubchannel( - std::move(address), args), + address, per_address_args, args), std::move(locality_stats)); } gpr_log( @@ -623,7 +626,7 @@ RefCountedPtr XdsClusterImplLb::Helper::CreateSubchannel( } // Load reporting not enabled, so don't wrap the subchannel. return parent()->channel_control_helper()->CreateSubchannel( - std::move(address), args); + address, per_address_args, args); } void XdsClusterImplLb::Helper::UpdateState( diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc index c95f9a35f8e7e..4f6e8611b5a08 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc @@ -59,7 +59,7 @@ #include "src/core/lib/load_balancing/lb_policy.h" #include "src/core/lib/load_balancing/lb_policy_factory.h" #include "src/core/lib/load_balancing/lb_policy_registry.h" -#include "src/core/lib/resolver/server_address.h" +#include "src/core/lib/resolver/endpoint_addresses.h" #include "src/core/lib/transport/connectivity_state.h" namespace grpc_core { @@ -149,7 +149,7 @@ class XdsClusterManagerLb : public LoadBalancingPolicy { absl::Status UpdateLocked( RefCountedPtr config, - const absl::StatusOr& addresses, + const absl::StatusOr& addresses, const ChannelArgs& args); void ExitIdleLocked(); void ResetBackoffLocked(); @@ -482,7 +482,7 @@ XdsClusterManagerLb::ClusterChild::CreateChildPolicyLocked( absl::Status XdsClusterManagerLb::ClusterChild::UpdateLocked( RefCountedPtr config, - const absl::StatusOr& addresses, + const absl::StatusOr& addresses, const ChannelArgs& args) { if (xds_cluster_manager_policy_->shutting_down_) return absl::OkStatus(); // Update child weight. diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc index 5732cc02b308d..42f8673e724a2 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc @@ -69,9 +69,9 @@ #include "src/core/lib/load_balancing/lb_policy.h" #include "src/core/lib/load_balancing/lb_policy_factory.h" #include "src/core/lib/load_balancing/lb_policy_registry.h" +#include "src/core/lib/resolver/endpoint_addresses.h" #include "src/core/lib/resolver/resolver.h" #include "src/core/lib/resolver/resolver_registry.h" -#include "src/core/lib/resolver/server_address.h" #define GRPC_EDS_DEFAULT_FALLBACK_TIMEOUT 10000 @@ -390,7 +390,7 @@ class XdsClusterResolverLb : public LoadBalancingPolicy { absl::Status UpdateChildPolicyLocked(); OrphanablePtr CreateChildPolicyLocked( const ChannelArgs& args); - ServerAddressList CreateChildPolicyAddressesLocked(); + EndpointAddressesList CreateChildPolicyAddressesLocked(); std::string CreateChildPolicyResolutionNoteLocked(); RefCountedPtr CreateChildPolicyConfigLocked(); ChannelArgs CreateChildPolicyArgsLocked(const ChannelArgs& args_in); @@ -768,8 +768,8 @@ void XdsClusterResolverLb::OnResourceDoesNotExist(size_t index, // child policy-related methods // -ServerAddressList XdsClusterResolverLb::CreateChildPolicyAddressesLocked() { - ServerAddressList addresses; +EndpointAddressesList XdsClusterResolverLb::CreateChildPolicyAddressesLocked() { + EndpointAddressesList addresses; for (const auto& discovery_entry : discovery_mechanisms_) { const auto& priority_list = GetUpdatePriorityList(*discovery_entry.latest_update); @@ -790,7 +790,7 @@ ServerAddressList XdsClusterResolverLb::CreateChildPolicyAddressesLocked() { locality.lb_weight * endpoint.args().GetInt(GRPC_ARG_ADDRESS_WEIGHT).value_or(1); addresses.emplace_back( - endpoint.address(), + endpoint.addresses(), endpoint.args() .SetObject(hierarchical_path_attr) .Set(GRPC_ARG_ADDRESS_WEIGHT, endpoint_weight) diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds_override_host.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds_override_host.cc index 7c210284aadbe..10f946a04f8e1 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds_override_host.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds_override_host.cc @@ -65,6 +65,7 @@ #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/iomgr/iomgr_fwd.h" #include "src/core/lib/iomgr/pollset_set.h" +#include "src/core/lib/iomgr/resolved_address.h" #include "src/core/lib/json/json.h" #include "src/core/lib/json/json_args.h" #include "src/core/lib/json/json_object_loader.h" @@ -73,7 +74,7 @@ #include "src/core/lib/load_balancing/lb_policy_factory.h" #include "src/core/lib/load_balancing/lb_policy_registry.h" #include "src/core/lib/load_balancing/subchannel_interface.h" -#include "src/core/lib/resolver/server_address.h" +#include "src/core/lib/resolver/endpoint_addresses.h" #include "src/core/lib/transport/connectivity_state.h" namespace grpc_core { @@ -97,9 +98,9 @@ struct PtrLessThan { } }; -XdsHealthStatus GetAddressHealthStatus(const ServerAddress& address) { +XdsHealthStatus GetEndpointHealthStatus(const EndpointAddresses& endpoint) { return XdsHealthStatus(static_cast( - address.args() + endpoint.args() .GetInt(GRPC_ARG_XDS_HEALTH_STATUS) .value_or(XdsHealthStatus::HealthStatus::kUnknown))); } @@ -224,7 +225,8 @@ class XdsOverrideHostLb : public LoadBalancingPolicy { std::move(xds_override_host_policy)) {} RefCountedPtr CreateSubchannel( - ServerAddress address, const ChannelArgs& args) override; + const grpc_resolved_address& address, + const ChannelArgs& per_address_args, const ChannelArgs& args) override; void UpdateState(grpc_connectivity_state state, const absl::Status& status, RefCountedPtr picker) override; }; @@ -285,11 +287,12 @@ class XdsOverrideHostLb : public LoadBalancingPolicy { void MaybeUpdatePickerLocked(); - absl::StatusOr UpdateAddressMap( - absl::StatusOr addresses); + absl::StatusOr UpdateAddressMap( + absl::StatusOr endpoints); RefCountedPtr AdoptSubchannel( - ServerAddress address, RefCountedPtr subchannel); + const grpc_resolved_address& address, + RefCountedPtr subchannel); void UnsetSubchannel(absl::string_view key, SubchannelWrapper* subchannel); @@ -501,43 +504,45 @@ OrphanablePtr XdsOverrideHostLb::CreateChildPolicyLocked( return lb_policy; } -absl::StatusOr XdsOverrideHostLb::UpdateAddressMap( - absl::StatusOr addresses) { - if (!addresses.ok()) { +absl::StatusOr XdsOverrideHostLb::UpdateAddressMap( + absl::StatusOr endpoints) { + if (!endpoints.ok()) { if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_override_host_trace)) { gpr_log(GPR_INFO, "[xds_override_host_lb %p] address error: %s", this, - addresses.status().ToString().c_str()); + endpoints.status().ToString().c_str()); } - return addresses; + return endpoints; } - ServerAddressList return_value; + // TODO(roth): As we clarify this part of the dualstack design, add + // support for multiple addresses per endpoint. + EndpointAddressesList return_value; std::map addresses_for_map; - for (const auto& address : *addresses) { - XdsHealthStatus status = GetAddressHealthStatus(address); + for (const auto& endpoint : *endpoints) { + XdsHealthStatus status = GetEndpointHealthStatus(endpoint); if (status.status() != XdsHealthStatus::kDraining) { if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_override_host_trace)) { gpr_log(GPR_INFO, - "[xds_override_host_lb %p] address %s: not draining, " + "[xds_override_host_lb %p] endpoint %s: not draining, " "passing to child", - this, address.ToString().c_str()); + this, endpoint.ToString().c_str()); } - return_value.push_back(address); + return_value.push_back(endpoint); } else if (!config_->override_host_status_set().Contains(status)) { // Skip draining hosts if not in the override status set. if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_override_host_trace)) { gpr_log(GPR_INFO, - "[xds_override_host_lb %p] address %s: draining but not in " + "[xds_override_host_lb %p] endpoint %s: draining but not in " "override_host_status set -- ignoring", - this, address.ToString().c_str()); + this, endpoint.ToString().c_str()); } continue; } - auto key = grpc_sockaddr_to_uri(&address.address()); + auto key = grpc_sockaddr_to_uri(&endpoint.address()); if (key.ok()) { if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_override_host_trace)) { gpr_log(GPR_INFO, - "[xds_override_host_lb %p] address %s: adding map key %s", this, - address.ToString().c_str(), key->c_str()); + "[xds_override_host_lb %p] endpoint %s: adding map key %s", + this, endpoint.ToString().c_str(), key->c_str()); } addresses_for_map.emplace(std::move(*key), status); } @@ -581,8 +586,9 @@ absl::StatusOr XdsOverrideHostLb::UpdateAddressMap( RefCountedPtr XdsOverrideHostLb::AdoptSubchannel( - ServerAddress address, RefCountedPtr subchannel) { - auto key = grpc_sockaddr_to_uri(&address.address()); + const grpc_resolved_address& address, + RefCountedPtr subchannel) { + auto key = grpc_sockaddr_to_uri(&address); if (!key.ok()) { return subchannel; } @@ -646,9 +652,10 @@ void XdsOverrideHostLb::OnSubchannelConnectivityStateChange( // RefCountedPtr XdsOverrideHostLb::Helper::CreateSubchannel( - ServerAddress address, const ChannelArgs& args) { - auto subchannel = - parent()->channel_control_helper()->CreateSubchannel(address, args); + const grpc_resolved_address& address, const ChannelArgs& per_address_args, + const ChannelArgs& args) { + auto subchannel = parent()->channel_control_helper()->CreateSubchannel( + address, per_address_args, args); return parent()->AdoptSubchannel(address, subchannel); } diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds_wrr_locality.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds_wrr_locality.cc index fa4918633c96d..26f0ec9084a28 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds_wrr_locality.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds_wrr_locality.cc @@ -51,7 +51,7 @@ #include "src/core/lib/load_balancing/lb_policy.h" #include "src/core/lib/load_balancing/lb_policy_factory.h" #include "src/core/lib/load_balancing/lb_policy_registry.h" -#include "src/core/lib/resolver/server_address.h" +#include "src/core/lib/resolver/endpoint_addresses.h" namespace grpc_core { diff --git a/src/core/ext/filters/client_channel/resolver/binder/binder_resolver.cc b/src/core/ext/filters/client_channel/resolver/binder/binder_resolver.cc index 1f782b5e254df..f0fac9231557b 100644 --- a/src/core/ext/filters/client_channel/resolver/binder/binder_resolver.cc +++ b/src/core/ext/filters/client_channel/resolver/binder/binder_resolver.cc @@ -43,9 +43,9 @@ #include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/iomgr/error.h" #include "src/core/lib/iomgr/resolved_address.h" +#include "src/core/lib/resolver/endpoint_addresses.h" #include "src/core/lib/resolver/resolver.h" #include "src/core/lib/resolver/resolver_factory.h" -#include "src/core/lib/resolver/server_address.h" #include "src/core/lib/uri/uri_parser.h" namespace grpc_core { @@ -53,7 +53,7 @@ namespace { class BinderResolver : public Resolver { public: - BinderResolver(ServerAddressList addresses, ResolverArgs args) + BinderResolver(EndpointAddressesList addresses, ResolverArgs args) : result_handler_(std::move(args.result_handler)), addresses_(std::move(addresses)), channel_args_(std::move(args.args)) {} @@ -70,7 +70,7 @@ class BinderResolver : public Resolver { private: std::unique_ptr result_handler_; - ServerAddressList addresses_; + EndpointAddressesList addresses_; ChannelArgs channel_args_; }; @@ -83,7 +83,7 @@ class BinderResolverFactory : public ResolverFactory { } OrphanablePtr CreateResolver(ResolverArgs args) const override { - ServerAddressList addresses; + EndpointAddressesList addresses; if (!ParseUri(args.uri, &addresses)) return nullptr; return MakeOrphanable(std::move(addresses), std::move(args)); @@ -116,7 +116,7 @@ class BinderResolverFactory : public ResolverFactory { return absl::OkStatus(); } - static bool ParseUri(const URI& uri, ServerAddressList* addresses) { + static bool ParseUri(const URI& uri, EndpointAddressesList* addresses) { grpc_resolved_address addr; { if (!uri.authority().empty()) { 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 47706e2cbb84f..c85c850a87d7c 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 @@ -70,7 +70,7 @@ #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/config/config_vars.h" #include "src/core/lib/iomgr/resolve_address.h" -#include "src/core/lib/resolver/server_address.h" +#include "src/core/lib/resolver/endpoint_addresses.h" #include "src/core/lib/service_config/service_config_impl.h" #include "src/core/lib/transport/error_utils.h" @@ -178,9 +178,9 @@ class AresClientChannelDNSResolver : public PollingResolver { std::unique_ptr txt_request_ ABSL_GUARDED_BY(on_resolved_mu_); // Output fields from ares request. - std::unique_ptr addresses_ + std::unique_ptr addresses_ ABSL_GUARDED_BY(on_resolved_mu_); - std::unique_ptr balancer_addresses_ + std::unique_ptr balancer_addresses_ ABSL_GUARDED_BY(on_resolved_mu_); char* service_config_json_ ABSL_GUARDED_BY(on_resolved_mu_) = nullptr; }; @@ -299,7 +299,7 @@ AresClientChannelDNSResolver::AresRequestWrapper::OnResolvedLocked( if (addresses_ != nullptr) { result.addresses = std::move(*addresses_); } else { - result.addresses = ServerAddressList(); + result.addresses.emplace(); } if (service_config_json_ != nullptr) { auto service_config_string = ChooseServiceConfig(service_config_json_); @@ -320,8 +320,8 @@ AresClientChannelDNSResolver::AresRequestWrapper::OnResolvedLocked( } } if (balancer_addresses_ != nullptr) { - result.args = SetGrpcLbBalancerAddresses( - result.args, ServerAddressList(*balancer_addresses_)); + result.args = + SetGrpcLbBalancerAddresses(result.args, *balancer_addresses_); } } else { GRPC_CARES_TRACE_LOG("resolver:%p dns resolution failed: %s", this, @@ -535,7 +535,7 @@ class AresDNSResolver : public DNSResolver { absl::StatusOr>)> on_resolve_address_done_; // currently resolving addresses - std::unique_ptr addresses_; + std::unique_ptr addresses_; }; class AresSRVRequest : public AresRequest { @@ -583,7 +583,7 @@ class AresDNSResolver : public DNSResolver { absl::StatusOr>)> on_resolve_address_done_; // currently resolving addresses - std::unique_ptr balancer_addresses_; + std::unique_ptr balancer_addresses_; }; class AresTXTRequest : public AresRequest { 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 de913f360d2e8..c4ffb3975a1b3 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 @@ -73,8 +73,8 @@ #include "src/core/lib/iomgr/resolved_address.h" #include "src/core/lib/iomgr/timer.h" -using grpc_core::ServerAddress; -using grpc_core::ServerAddressList; +using grpc_core::EndpointAddresses; +using grpc_core::EndpointAddressesList; grpc_core::TraceFlag grpc_trace_cares_address_sorting(false, "cares_address_sorting"); @@ -557,7 +557,7 @@ grpc_error_handle grpc_ares_ev_driver_create_locked( } static void log_address_sorting_list(const grpc_ares_request* r, - const ServerAddressList& addresses, + const EndpointAddressesList& addresses, const char* input_output_str) { for (size_t i = 0; i < addresses.size(); i++) { auto addr_str = grpc_sockaddr_to_string(&addresses[i].address(), true); @@ -571,7 +571,7 @@ static void log_address_sorting_list(const grpc_ares_request* r, } void grpc_cares_wrapper_address_sorting_sort(const grpc_ares_request* r, - ServerAddressList* addresses) { + EndpointAddressesList* addresses) { if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_cares_address_sorting)) { log_address_sorting_list(r, *addresses, "input"); } @@ -584,10 +584,11 @@ void grpc_cares_wrapper_address_sorting_sort(const grpc_ares_request* r, sortables[i].dest_addr.len = (*addresses)[i].address().len; } address_sorting_rfc_6724_sort(sortables, addresses->size()); - ServerAddressList sorted; + EndpointAddressesList sorted; sorted.reserve(addresses->size()); for (size_t i = 0; i < addresses->size(); ++i) { - sorted.emplace_back(*static_cast(sortables[i].user_data)); + sorted.emplace_back( + *static_cast(sortables[i].user_data)); } gpr_free(sortables); *addresses = std::move(sorted); @@ -620,7 +621,8 @@ void grpc_ares_complete_request_locked(grpc_ares_request* r) // with no addresses along side it } if (r->balancer_addresses_out != nullptr) { - ServerAddressList* balancer_addresses = r->balancer_addresses_out->get(); + EndpointAddressesList* balancer_addresses = + r->balancer_addresses_out->get(); if (balancer_addresses != nullptr) { grpc_cares_wrapper_address_sorting_sort(r, balancer_addresses); } @@ -667,12 +669,12 @@ static void on_hostbyname_done_locked(void* arg, int status, int /*timeouts*/, GRPC_CARES_TRACE_LOG( "request:%p on_hostbyname_done_locked qtype=%s host=%s ARES_SUCCESS", r, hr->qtype, hr->host); - std::unique_ptr* address_list_ptr = + std::unique_ptr* address_list_ptr = hr->is_balancer ? r->balancer_addresses_out : r->addresses_out; if (*address_list_ptr == nullptr) { - *address_list_ptr = std::make_unique(); + *address_list_ptr = std::make_unique(); } - ServerAddressList& addresses = **address_list_ptr; + EndpointAddressesList& addresses = **address_list_ptr; for (size_t i = 0; hostent->h_addr_list[i] != nullptr; ++i) { grpc_core::ChannelArgs args; if (hr->is_balancer) { @@ -904,7 +906,7 @@ grpc_error_handle grpc_dns_lookup_ares_continued( static bool inner_resolve_as_ip_literal_locked( const char* name, const char* default_port, - std::unique_ptr* addrs, std::string* host, + std::unique_ptr* addrs, std::string* host, std::string* port, std::string* hostport) { if (!grpc_core::SplitHostPort(name, host, port)) { gpr_log(GPR_ERROR, @@ -930,7 +932,7 @@ static bool inner_resolve_as_ip_literal_locked( grpc_parse_ipv6_hostport(hostport->c_str(), &addr, false /* log errors */)) { GPR_ASSERT(*addrs == nullptr); - *addrs = std::make_unique(); + *addrs = std::make_unique(); (*addrs)->emplace_back(addr, grpc_core::ChannelArgs()); return true; } @@ -939,7 +941,7 @@ static bool inner_resolve_as_ip_literal_locked( static bool resolve_as_ip_literal_locked( const char* name, const char* default_port, - std::unique_ptr* addrs) { + std::unique_ptr* addrs) { std::string host; std::string port; std::string hostport; @@ -966,7 +968,7 @@ static bool target_matches_localhost(const char* name) { #ifdef GRPC_ARES_RESOLVE_LOCALHOST_MANUALLY static bool inner_maybe_resolve_localhost_manually_locked( const grpc_ares_request* r, const char* name, const char* default_port, - std::unique_ptr* addrs, std::string* host, + std::unique_ptr* addrs, std::string* host, std::string* port) { grpc_core::SplitHostPort(name, host, port); if (host->empty()) { @@ -988,7 +990,7 @@ static bool inner_maybe_resolve_localhost_manually_locked( } if (gpr_stricmp(host->c_str(), "localhost") == 0) { GPR_ASSERT(*addrs == nullptr); - *addrs = std::make_unique(); + *addrs = std::make_unique(); uint16_t numeric_port = grpc_strhtons(port->c_str()); grpc_resolved_address address; // Append the ipv6 loopback address. @@ -1019,7 +1021,7 @@ static bool inner_maybe_resolve_localhost_manually_locked( static bool grpc_ares_maybe_resolve_localhost_manually_locked( const grpc_ares_request* r, const char* name, const char* default_port, - std::unique_ptr* addrs) { + std::unique_ptr* addrs) { std::string host; std::string port; return inner_maybe_resolve_localhost_manually_locked(r, name, default_port, @@ -1029,7 +1031,7 @@ static bool grpc_ares_maybe_resolve_localhost_manually_locked( static bool grpc_ares_maybe_resolve_localhost_manually_locked( const grpc_ares_request* /*r*/, const char* /*name*/, const char* /*default_port*/, - std::unique_ptr* /*addrs*/) { + std::unique_ptr* /*addrs*/) { return false; } #endif // GRPC_ARES_RESOLVE_LOCALHOST_MANUALLY @@ -1037,7 +1039,7 @@ static bool grpc_ares_maybe_resolve_localhost_manually_locked( static grpc_ares_request* grpc_dns_lookup_hostname_ares_impl( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - std::unique_ptr* addrs, + std::unique_ptr* addrs, int query_timeout_ms) { grpc_ares_request* r = new grpc_ares_request(); grpc_core::MutexLock lock(&r->mu); @@ -1091,7 +1093,7 @@ static grpc_ares_request* grpc_dns_lookup_hostname_ares_impl( grpc_ares_request* grpc_dns_lookup_srv_ares_impl( const char* dns_server, const char* name, grpc_pollset_set* interested_parties, grpc_closure* on_done, - std::unique_ptr* balancer_addresses, + std::unique_ptr* balancer_addresses, int query_timeout_ms) { grpc_ares_request* r = new grpc_ares_request(); grpc_core::MutexLock lock(&r->mu); @@ -1168,13 +1170,13 @@ grpc_ares_request* grpc_dns_lookup_txt_ares_impl( grpc_ares_request* (*grpc_dns_lookup_hostname_ares)( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - std::unique_ptr* addrs, + std::unique_ptr* addrs, int query_timeout_ms) = grpc_dns_lookup_hostname_ares_impl; grpc_ares_request* (*grpc_dns_lookup_srv_ares)( const char* dns_server, const char* name, grpc_pollset_set* interested_parties, grpc_closure* on_done, - std::unique_ptr* balancer_addresses, + std::unique_ptr* balancer_addresses, int query_timeout_ms) = grpc_dns_lookup_srv_ares_impl; grpc_ares_request* (*grpc_dns_lookup_txt_ares)( 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 5970e131cccfc..3849579cebbf1 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 @@ -36,7 +36,7 @@ #include "src/core/lib/iomgr/closure.h" #include "src/core/lib/iomgr/error.h" #include "src/core/lib/iomgr/iomgr_fwd.h" -#include "src/core/lib/resolver/server_address.h" +#include "src/core/lib/resolver/endpoint_addresses.h" #define GRPC_DNS_ARES_DEFAULT_QUERY_TIMEOUT_MS 120000 @@ -63,10 +63,10 @@ struct grpc_ares_request { /// closure to call when the request completes grpc_closure* on_done ABSL_GUARDED_BY(mu) = nullptr; /// the pointer to receive the resolved addresses - std::unique_ptr* addresses_out + std::unique_ptr* addresses_out ABSL_GUARDED_BY(mu); /// the pointer to receive the resolved balancer addresses - std::unique_ptr* balancer_addresses_out + std::unique_ptr* balancer_addresses_out ABSL_GUARDED_BY(mu); /// the pointer to receive the service config in JSON char** service_config_json_out ABSL_GUARDED_BY(mu) = nullptr; @@ -92,7 +92,7 @@ struct grpc_ares_request { extern grpc_ares_request* (*grpc_dns_lookup_hostname_ares)( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - std::unique_ptr* addresses, + std::unique_ptr* addresses, int query_timeout_ms); // Asynchronously resolve a SRV record. @@ -100,7 +100,7 @@ extern grpc_ares_request* (*grpc_dns_lookup_hostname_ares)( extern grpc_ares_request* (*grpc_dns_lookup_srv_ares)( const char* dns_server, const char* name, grpc_pollset_set* interested_parties, grpc_closure* on_done, - std::unique_ptr* balancer_addresses, + std::unique_ptr* balancer_addresses, int query_timeout_ms); // Asynchronously resolve a TXT record. @@ -128,7 +128,8 @@ bool grpc_ares_query_ipv6(); // Sorts destinations in lb_addrs according to RFC 6724. void grpc_cares_wrapper_address_sorting_sort( - const grpc_ares_request* request, grpc_core::ServerAddressList* addresses); + const grpc_ares_request* request, + grpc_core::EndpointAddressesList* addresses); // Exposed in this header for C-core tests only extern void (*grpc_ares_test_only_inject_config)(ares_channel* channel); 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 5232479e93052..6c8a0ea65ac50 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 @@ -28,7 +28,7 @@ #include "src/core/lib/address_utils/parse_address.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/socket_windows.h" -#include "src/core/lib/resolver/server_address.h" +#include "src/core/lib/resolver/endpoint_addresses.h" bool grpc_ares_query_ipv6() { return grpc_ipv6_loopback_available(); } diff --git a/src/core/ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.cc b/src/core/ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.cc index 8d5566677ae0a..356535c6e6941 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.cc @@ -52,9 +52,9 @@ #include "src/core/lib/gprpp/validation_errors.h" #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/iomgr/resolve_address.h" +#include "src/core/lib/resolver/endpoint_addresses.h" #include "src/core/lib/resolver/resolver.h" #include "src/core/lib/resolver/resolver_factory.h" -#include "src/core/lib/resolver/server_address.h" #include "src/core/lib/service_config/service_config.h" #include "src/core/lib/service_config/service_config_impl.h" @@ -149,8 +149,8 @@ class EventEngineClientChannelDNSResolver : public PollingResolver { bool is_srv_inflight_ ABSL_GUARDED_BY(on_resolved_mu_) = false; bool is_txt_inflight_ ABSL_GUARDED_BY(on_resolved_mu_) = false; // Output fields from requests. - ServerAddressList addresses_ ABSL_GUARDED_BY(on_resolved_mu_); - ServerAddressList balancer_addresses_ ABSL_GUARDED_BY(on_resolved_mu_); + EndpointAddressesList addresses_ ABSL_GUARDED_BY(on_resolved_mu_); + EndpointAddressesList balancer_addresses_ ABSL_GUARDED_BY(on_resolved_mu_); ValidationErrors errors_ ABSL_GUARDED_BY(on_resolved_mu_); absl::StatusOr service_config_json_ ABSL_GUARDED_BY(on_resolved_mu_); 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 4de874fccc108..bcc6df9510e54 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 @@ -44,9 +44,9 @@ #include "src/core/lib/gprpp/time.h" #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/iomgr/resolved_address.h" +#include "src/core/lib/resolver/endpoint_addresses.h" #include "src/core/lib/resolver/resolver.h" #include "src/core/lib/resolver/resolver_factory.h" -#include "src/core/lib/resolver/server_address.h" #include "src/core/lib/uri/uri_parser.h" #define GRPC_DNS_INITIAL_CONNECT_BACKOFF_SECONDS 1 @@ -127,7 +127,7 @@ void NativeClientChannelDNSResolver::OnResolved( // Convert result from iomgr DNS API into Resolver::Result. Result result; if (addresses_or.ok()) { - ServerAddressList addresses; + EndpointAddressesList addresses; for (auto& addr : *addresses_or) { addresses.emplace_back(addr, ChannelArgs()); } 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 5e97f25f57ad4..193e3c2b42258 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 @@ -36,8 +36,8 @@ #include "src/core/lib/gprpp/debug_location.h" #include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/gprpp/work_serializer.h" +#include "src/core/lib/resolver/endpoint_addresses.h" #include "src/core/lib/resolver/resolver_factory.h" -#include "src/core/lib/resolver/server_address.h" #include "src/core/lib/service_config/service_config.h" #include "src/core/lib/uri/uri_parser.h" 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 659144fd6e236..8bfd6b233fc2f 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 @@ -33,9 +33,9 @@ #include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/iomgr/port.h" #include "src/core/lib/iomgr/resolved_address.h" +#include "src/core/lib/resolver/endpoint_addresses.h" #include "src/core/lib/resolver/resolver.h" #include "src/core/lib/resolver/resolver_factory.h" -#include "src/core/lib/resolver/server_address.h" #include "src/core/lib/uri/uri_parser.h" namespace grpc_core { @@ -44,7 +44,7 @@ namespace { class SockaddrResolver : public Resolver { public: - SockaddrResolver(ServerAddressList addresses, ResolverArgs args); + SockaddrResolver(EndpointAddressesList addresses, ResolverArgs args); void StartLocked() override; @@ -52,11 +52,11 @@ class SockaddrResolver : public Resolver { private: std::unique_ptr result_handler_; - ServerAddressList addresses_; + EndpointAddressesList addresses_; ChannelArgs channel_args_; }; -SockaddrResolver::SockaddrResolver(ServerAddressList addresses, +SockaddrResolver::SockaddrResolver(EndpointAddressesList addresses, ResolverArgs args) : result_handler_(std::move(args.result_handler)), addresses_(std::move(addresses)), @@ -75,7 +75,7 @@ void SockaddrResolver::StartLocked() { bool ParseUri(const URI& uri, bool parse(const URI& uri, grpc_resolved_address* dst), - ServerAddressList* addresses) { + EndpointAddressesList* addresses) { if (!uri.authority().empty()) { gpr_log(GPR_ERROR, "authority-based URIs not supported by the %s scheme", uri.scheme().c_str()); @@ -103,7 +103,7 @@ bool ParseUri(const URI& uri, OrphanablePtr CreateSockaddrResolver( ResolverArgs args, bool parse(const URI& uri, grpc_resolved_address* dst)) { - ServerAddressList addresses; + EndpointAddressesList addresses; if (!ParseUri(args.uri, parse, &addresses)) return nullptr; // Instantiate resolver. return MakeOrphanable(std::move(addresses), diff --git a/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc b/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc index f27bb0e862e4d..e401c39381645 100644 --- a/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc +++ b/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc @@ -86,9 +86,9 @@ #include "src/core/lib/iomgr/pollset_set.h" #include "src/core/lib/promise/arena_promise.h" #include "src/core/lib/promise/context.h" +#include "src/core/lib/resolver/endpoint_addresses.h" #include "src/core/lib/resolver/resolver.h" #include "src/core/lib/resolver/resolver_factory.h" -#include "src/core/lib/resolver/server_address.h" #include "src/core/lib/resource_quota/arena.h" #include "src/core/lib/service_config/service_config.h" #include "src/core/lib/service_config/service_config_impl.h" diff --git a/src/core/ext/xds/xds_client_grpc.h b/src/core/ext/xds/xds_client_grpc.h index 7ecb96cb52a20..02fe32404f81e 100644 --- a/src/core/ext/xds/xds_client_grpc.h +++ b/src/core/ext/xds/xds_client_grpc.h @@ -35,7 +35,7 @@ #include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/iomgr_fwd.h" -#include "src/core/lib/resolver/server_address.h" +#include "src/core/lib/resolver/endpoint_addresses.h" namespace grpc_core { diff --git a/src/core/ext/xds/xds_client_stats.h b/src/core/ext/xds/xds_client_stats.h index 0a5a293ba6802..2b9aba9b13450 100644 --- a/src/core/ext/xds/xds_client_stats.h +++ b/src/core/ext/xds/xds_client_stats.h @@ -38,7 +38,7 @@ #include "src/core/lib/gprpp/ref_counted.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/gprpp/sync.h" -#include "src/core/lib/resolver/server_address.h" +#include "src/core/lib/resolver/endpoint_addresses.h" namespace grpc_core { diff --git a/src/core/ext/xds/xds_endpoint.cc b/src/core/ext/xds/xds_endpoint.cc index 654063b88a811..bb34df6174153 100644 --- a/src/core/ext/xds/xds_endpoint.cc +++ b/src/core/ext/xds/xds_endpoint.cc @@ -63,7 +63,7 @@ namespace grpc_core { std::string XdsEndpointResource::Priority::Locality::ToString() const { std::vector endpoint_strings; - for (const ServerAddress& endpoint : endpoints) { + for (const EndpointAddresses& endpoint : endpoints) { endpoint_strings.emplace_back(endpoint.ToString()); } return absl::StrCat("{name=", name->AsHumanReadableString(), @@ -152,7 +152,7 @@ void MaybeLogClusterLoadAssignment( } } -absl::optional ServerAddressParse( +absl::optional EndpointAddressesParse( const envoy_config_endpoint_v3_LbEndpoint* lb_endpoint, ValidationErrors* errors) { // health_status @@ -179,6 +179,7 @@ absl::optional ServerAddressParse( } } // endpoint + // TODO(roth): add support for multiple addresses per endpoint grpc_resolved_address grpc_address; { ValidationErrors::ScopedField field(errors, ".endpoint"); @@ -220,11 +221,11 @@ absl::optional ServerAddressParse( grpc_address = *addr; } } - // Convert to ServerAddress. - return ServerAddress(grpc_address, - ChannelArgs() - .Set(GRPC_ARG_ADDRESS_WEIGHT, weight) - .Set(GRPC_ARG_XDS_HEALTH_STATUS, status->status())); + // Convert to EndpointAddresses. + return EndpointAddresses( + grpc_address, ChannelArgs() + .Set(GRPC_ARG_ADDRESS_WEIGHT, weight) + .Set(GRPC_ARG_XDS_HEALTH_STATUS, status->status())); } struct ParsedLocality { @@ -284,16 +285,17 @@ absl::optional LocalityParse( for (size_t i = 0; i < size; ++i) { ValidationErrors::ScopedField field(errors, absl::StrCat(".lb_endpoints[", i, "]")); - auto address = ServerAddressParse(lb_endpoints[i], errors); - if (address.has_value()) { - bool inserted = address_set->insert(address->address()).second; - if (!inserted) { - errors->AddError(absl::StrCat( - "duplicate endpoint address \"", - grpc_sockaddr_to_uri(&address->address()).value_or(""), - "\"")); + auto endpoint = EndpointAddressesParse(lb_endpoints[i], errors); + if (endpoint.has_value()) { + for (const auto& address : endpoint->addresses()) { + bool inserted = address_set->insert(address).second; + if (!inserted) { + errors->AddError(absl::StrCat( + "duplicate endpoint address \"", + grpc_sockaddr_to_uri(&address).value_or(""), "\"")); + } } - parsed_locality.locality.endpoints.push_back(std::move(*address)); + parsed_locality.locality.endpoints.push_back(std::move(*endpoint)); } } // priority diff --git a/src/core/ext/xds/xds_endpoint.h b/src/core/ext/xds/xds_endpoint.h index f2bdfff5c921d..3c3e34550fce3 100644 --- a/src/core/ext/xds/xds_endpoint.h +++ b/src/core/ext/xds/xds_endpoint.h @@ -40,7 +40,7 @@ #include "src/core/lib/gprpp/ref_counted.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/gprpp/sync.h" -#include "src/core/lib/resolver/server_address.h" +#include "src/core/lib/resolver/endpoint_addresses.h" namespace grpc_core { @@ -49,7 +49,7 @@ struct XdsEndpointResource : public XdsResourceType::ResourceData { struct Locality { RefCountedPtr name; uint32_t lb_weight; - ServerAddressList endpoints; + EndpointAddressesList endpoints; bool operator==(const Locality& other) const { return *name == *other.name && lb_weight == other.lb_weight && diff --git a/src/core/ext/xds/xds_health_status.h b/src/core/ext/xds/xds_health_status.h index c680a03aa6aa7..c94b2ce6e783f 100644 --- a/src/core/ext/xds/xds_health_status.h +++ b/src/core/ext/xds/xds_health_status.h @@ -25,7 +25,7 @@ #include "absl/types/optional.h" #include "absl/types/span.h" -#include "src/core/lib/resolver/server_address.h" +#include "src/core/lib/resolver/endpoint_addresses.h" // Channel arg key for xDS health status. // Value is an XdsHealthStatus::HealthStatus enum. diff --git a/src/core/lib/load_balancing/delegating_helper.h b/src/core/lib/load_balancing/delegating_helper.h index 072a4ddda7d1c..57e7f3c0f3e1b 100644 --- a/src/core/lib/load_balancing/delegating_helper.h +++ b/src/core/lib/load_balancing/delegating_helper.h @@ -31,9 +31,9 @@ #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gprpp/debug_location.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/iomgr/resolved_address.h" #include "src/core/lib/load_balancing/lb_policy.h" #include "src/core/lib/load_balancing/subchannel_interface.h" -#include "src/core/lib/resolver/server_address.h" #include "src/core/lib/security/credentials/credentials.h" namespace grpc_core { @@ -44,8 +44,9 @@ class LoadBalancingPolicy::DelegatingChannelControlHelper : public LoadBalancingPolicy::ChannelControlHelper { public: RefCountedPtr CreateSubchannel( - ServerAddress address, const ChannelArgs& args) override { - return parent_helper()->CreateSubchannel(std::move(address), args); + const grpc_resolved_address& address, const ChannelArgs& per_address_args, + const ChannelArgs& args) override { + return parent_helper()->CreateSubchannel(address, per_address_args, args); } void UpdateState(grpc_connectivity_state state, const absl::Status& status, diff --git a/src/core/lib/load_balancing/lb_policy.h b/src/core/lib/load_balancing/lb_policy.h index 8d9af107cb1c2..2422339274e97 100644 --- a/src/core/lib/load_balancing/lb_policy.h +++ b/src/core/lib/load_balancing/lb_policy.h @@ -49,8 +49,9 @@ #include "src/core/lib/gprpp/sync.h" #include "src/core/lib/gprpp/work_serializer.h" #include "src/core/lib/iomgr/iomgr_fwd.h" +#include "src/core/lib/iomgr/resolved_address.h" #include "src/core/lib/load_balancing/subchannel_interface.h" -#include "src/core/lib/resolver/server_address.h" +#include "src/core/lib/resolver/endpoint_addresses.h" namespace grpc_core { @@ -284,8 +285,10 @@ class LoadBalancingPolicy : public InternallyRefCounted { virtual ~ChannelControlHelper() = default; /// Creates a new subchannel with the specified channel args. + /// The args and per_address_args will be merged by the channel. virtual RefCountedPtr CreateSubchannel( - ServerAddress address, const ChannelArgs& args) = 0; + const grpc_resolved_address& address, + const ChannelArgs& per_address_args, const ChannelArgs& args) = 0; /// Sets the connectivity state and returns a new picker to be used /// by the client channel. @@ -341,9 +344,9 @@ class LoadBalancingPolicy : public InternallyRefCounted { /// Data passed to the UpdateLocked() method when new addresses and /// config are available. struct UpdateArgs { - /// A list of addresses, or an error indicating a failure to obtain the - /// list of addresses. - absl::StatusOr addresses; + /// A list of endpoints, each with one or more address, or an error + /// indicating a failure to obtain the list of addresses. + absl::StatusOr addresses; /// The LB policy config. RefCountedPtr config; /// A human-readable note providing context about the name resolution that diff --git a/src/core/lib/resolver/endpoint_addresses.cc b/src/core/lib/resolver/endpoint_addresses.cc new file mode 100644 index 0000000000000..c9078293c8b90 --- /dev/null +++ b/src/core/lib/resolver/endpoint_addresses.cc @@ -0,0 +1,147 @@ +// +// +// 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 + +#include "src/core/lib/resolver/endpoint_addresses.h" + +#include + +#include +#include +#include +#include + +#include "absl/status/status.h" +#include "absl/status/statusor.h" +#include "absl/strings/str_cat.h" +#include "absl/strings/str_join.h" + +#include + +#include "src/core/lib/address_utils/sockaddr_utils.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/useful.h" + +// IWYU pragma: no_include + +namespace grpc_core { + +EndpointAddresses::EndpointAddresses(const grpc_resolved_address& address, + const ChannelArgs& args) + : addresses_(1, address), args_(args) {} + +EndpointAddresses::EndpointAddresses( + std::vector addresses, const ChannelArgs& args) + : addresses_(std::move(addresses)), args_(args) { + GPR_ASSERT(!addresses_.empty()); +} + +EndpointAddresses::EndpointAddresses(const EndpointAddresses& other) + : addresses_(other.addresses_), args_(other.args_) {} + +EndpointAddresses& EndpointAddresses::operator=( + const EndpointAddresses& other) { + if (&other == this) return *this; + addresses_ = other.addresses_; + args_ = other.args_; + return *this; +} + +EndpointAddresses::EndpointAddresses(EndpointAddresses&& other) noexcept + : addresses_(std::move(other.addresses_)), args_(std::move(other.args_)) {} + +EndpointAddresses& EndpointAddresses::operator=( + EndpointAddresses&& other) noexcept { + addresses_ = std::move(other.addresses_); + args_ = std::move(other.args_); + return *this; +} + +int EndpointAddresses::Cmp(const EndpointAddresses& other) const { + for (size_t i = 0; i < addresses_.size(); ++i) { + if (other.addresses_.size() == i) return 1; + if (addresses_[i].len > other.addresses_[i].len) return 1; + if (addresses_[i].len < other.addresses_[i].len) return -1; + int retval = + memcmp(addresses_[i].addr, other.addresses_[i].addr, addresses_[i].len); + if (retval != 0) return retval; + } + if (other.addresses_.size() > addresses_.size()) return -1; + return QsortCompare(args_, other.args_); +} + +std::string EndpointAddresses::ToString() const { + std::vector addr_strings; + for (const auto& address : addresses_) { + auto addr_str = grpc_sockaddr_to_string(&address, false); + addr_strings.push_back(addr_str.ok() ? std::move(*addr_str) + : addr_str.status().ToString()); + } + std::vector parts = { + absl::StrCat("addrs=[", absl::StrJoin(addr_strings, ", "), "]")}; + if (args_ != ChannelArgs()) { + parts.emplace_back(absl::StrCat("args=", args_.ToString())); + } + return absl::StrJoin(parts, " "); +} + +bool EndpointAddressSet::operator==(const EndpointAddressSet& other) const { + if (addresses_.size() != other.addresses_.size()) return false; + auto other_it = other.addresses_.begin(); + for (auto it = addresses_.begin(); it != addresses_.end(); ++it) { + GPR_ASSERT(other_it != other.addresses_.end()); + if (it->len != other_it->len || + memcmp(it->addr, other_it->addr, it->len) != 0) { + return false; + } + ++other_it; + } + return true; +} + +bool EndpointAddressSet::operator<(const EndpointAddressSet& other) const { + auto other_it = other.addresses_.begin(); + for (auto it = addresses_.begin(); it != addresses_.end(); ++it) { + if (other_it == other.addresses_.end()) return true; + if (it->len < other_it->len) return true; + if (it->len > other_it->len) return false; + int r = memcmp(it->addr, other_it->addr, it->len); + if (r != 0) return r < 0; + } + return false; +} + +bool EndpointAddressSet::ResolvedAddressLessThan::operator()( + const grpc_resolved_address& addr1, + const grpc_resolved_address& addr2) const { + if (addr1.len < addr2.len) return true; + return memcmp(addr1.addr, addr2.addr, addr1.len) < 0; +} + +std::string EndpointAddressSet::ToString() const { + std::vector parts; + parts.reserve(addresses_.size()); + for (const auto& address : addresses_) { + parts.push_back( + grpc_sockaddr_to_string(&address, false).value_or("")); + } + return absl::StrCat("{", absl::StrJoin(parts, ", "), "}"); +} + +} // namespace grpc_core diff --git a/src/core/lib/resolver/endpoint_addresses.h b/src/core/lib/resolver/endpoint_addresses.h new file mode 100644 index 0000000000000..3a5eacd35cc47 --- /dev/null +++ b/src/core/lib/resolver/endpoint_addresses.h @@ -0,0 +1,116 @@ +// +// +// 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_SRC_CORE_LIB_RESOLVER_ENDPOINT_ADDRESSES_H +#define GRPC_SRC_CORE_LIB_RESOLVER_ENDPOINT_ADDRESSES_H + +#include + +#include +#include +#include + +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/iomgr/resolved_address.h" + +// A channel arg key prefix used for args that are intended to be used +// only internally to resolvers and LB policies and should not be part +// of the subchannel key. The channel will automatically filter out any +// args with this prefix from the subchannel's args. +#define GRPC_ARG_NO_SUBCHANNEL_PREFIX "grpc.internal.no_subchannel." + +// A channel arg indicating the weight of an address. +#define GRPC_ARG_ADDRESS_WEIGHT GRPC_ARG_NO_SUBCHANNEL_PREFIX "address.weight" + +namespace grpc_core { + +// A list of addresses for a given endpoint with an associated set of channel +// args. Any args present here will be merged into the channel args when a +// subchannel is created for each address. +class EndpointAddresses { + public: + // For backward compatibility. + // TODO(roth): Remove when callers have been updated. + EndpointAddresses(const grpc_resolved_address& address, + const ChannelArgs& args); + + // addresses must not be empty. + EndpointAddresses(std::vector addresses, + const ChannelArgs& args); + + // Copyable. + EndpointAddresses(const EndpointAddresses& other); + EndpointAddresses& operator=(const EndpointAddresses& other); + + // Movable. + EndpointAddresses(EndpointAddresses&& other) noexcept; + EndpointAddresses& operator=(EndpointAddresses&& other) noexcept; + + bool operator==(const EndpointAddresses& other) const { + return Cmp(other) == 0; + } + bool operator<(const EndpointAddresses& other) const { + return Cmp(other) < 0; + } + + int Cmp(const EndpointAddresses& other) const; + + // For backward compatibility only. + // TODO(roth): Remove when all callers have been updated. + const grpc_resolved_address& address() const { return addresses_[0]; } + + const std::vector& addresses() const { + return addresses_; + } + const ChannelArgs& args() const { return args_; } + + // TODO(ctiller): Prior to making this a public API we should ensure that the + // channel args are not part of the generated string, lest we make that debug + // format load-bearing via Hyrum's law. + std::string ToString() const; + + private: + std::vector addresses_; + ChannelArgs args_; +}; + +using EndpointAddressesList = std::vector; + +class EndpointAddressSet { + public: + explicit EndpointAddressSet( + const std::vector& addresses) + : addresses_(addresses.begin(), addresses.end()) {} + + bool operator==(const EndpointAddressSet& other) const; + bool operator<(const EndpointAddressSet& other) const; + + std::string ToString() const; + + private: + struct ResolvedAddressLessThan { + bool operator()(const grpc_resolved_address& addr1, + const grpc_resolved_address& addr2) const; + }; + + std::set addresses_; +}; + +} // namespace grpc_core + +#endif // GRPC_SRC_CORE_LIB_RESOLVER_ENDPOINT_ADDRESSES_H diff --git a/src/core/lib/resolver/resolver.h b/src/core/lib/resolver/resolver.h index 40251a8c57259..16406e47bcb12 100644 --- a/src/core/lib/resolver/resolver.h +++ b/src/core/lib/resolver/resolver.h @@ -29,7 +29,7 @@ #include "src/core/lib/debug/trace.h" #include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" -#include "src/core/lib/resolver/server_address.h" +#include "src/core/lib/resolver/endpoint_addresses.h" #include "src/core/lib/service_config/service_config.h" extern grpc_core::DebugOnlyTraceFlag grpc_trace_resolver_refcount; @@ -55,8 +55,8 @@ class Resolver : public InternallyRefCounted { public: /// Results returned by the resolver. struct Result { - /// A list of addresses, or an error. - absl::StatusOr addresses; + /// A list of endpoints, each with one or more addresses, or an error. + absl::StatusOr addresses; /// A service config, or an error. absl::StatusOr> service_config = nullptr; /// An optional human-readable note describing context about the resolution, diff --git a/src/core/lib/resolver/server_address.cc b/src/core/lib/resolver/server_address.cc deleted file mode 100644 index 96a9f7ddff6b2..0000000000000 --- a/src/core/lib/resolver/server_address.cc +++ /dev/null @@ -1,89 +0,0 @@ -// -// -// Copyright 2018 gRPC authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// - -#include - -#include "src/core/lib/resolver/server_address.h" - -#include - -#include -#include -#include -#include - -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "absl/strings/str_cat.h" -#include "absl/strings/str_join.h" - -#include "src/core/lib/address_utils/sockaddr_utils.h" -#include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/useful.h" - -// IWYU pragma: no_include - -namespace grpc_core { - -// -// ServerAddress -// - -ServerAddress::ServerAddress(const grpc_resolved_address& address, - const ChannelArgs& args) - : address_(address), args_(args) {} - -ServerAddress::ServerAddress(const ServerAddress& other) - : address_(other.address_), args_(other.args_) {} - -ServerAddress& ServerAddress::operator=(const ServerAddress& other) { - if (&other == this) return *this; - address_ = other.address_; - args_ = other.args_; - return *this; -} - -ServerAddress::ServerAddress(ServerAddress&& other) noexcept - : address_(other.address_), args_(std::move(other.args_)) {} - -ServerAddress& ServerAddress::operator=(ServerAddress&& other) noexcept { - address_ = other.address_; - args_ = std::move(other.args_); - return *this; -} - -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 QsortCompare(args_, other.args_); -} - -std::string ServerAddress::ToString() const { - auto addr_str = grpc_sockaddr_to_string(&address_, false); - std::vector parts = { - addr_str.ok() ? addr_str.value() : addr_str.status().ToString(), - }; - if (args_ != ChannelArgs()) { - parts.emplace_back(absl::StrCat("args=", args_.ToString())); - } - return absl::StrJoin(parts, " "); -} - -} // namespace grpc_core diff --git a/src/core/lib/resolver/server_address.h b/src/core/lib/resolver/server_address.h index e5c62638ecae9..a7d39481e6388 100644 --- a/src/core/lib/resolver/server_address.h +++ b/src/core/lib/resolver/server_address.h @@ -21,65 +21,14 @@ #include -#include -#include - -#include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/iomgr/resolved_address.h" - -// A channel arg key prefix used for args that are intended to be used -// only internally to resolvers and LB policies and should not be part -// of the subchannel key. The channel will automatically filter out any -// args with this prefix from the subchannel's args. -#define GRPC_ARG_NO_SUBCHANNEL_PREFIX "grpc.internal.no_subchannel." - -// A channel arg indicating the weight of an address. -#define GRPC_ARG_ADDRESS_WEIGHT GRPC_ARG_NO_SUBCHANNEL_PREFIX "address.weight" +#include "src/core/lib/resolver/endpoint_addresses.h" 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: - ServerAddress(const grpc_resolved_address& address, const ChannelArgs& args); - - // Copyable. - ServerAddress(const ServerAddress& other); - ServerAddress& operator=(const ServerAddress& other); - - // Movable. - ServerAddress(ServerAddress&& other) noexcept; - ServerAddress& operator=(ServerAddress&& other) noexcept; - - bool operator==(const ServerAddress& other) const { return Cmp(other) == 0; } - 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 ChannelArgs& args() const { return args_; } - - // TODO(ctiller): Prior to making this a public API we should ensure that the - // channel args are not part of the generated string, lest we make that debug - // format load-bearing via Hyrum's law. - std::string ToString() const; - - private: - grpc_resolved_address address_; - ChannelArgs args_; -}; - -// -// ServerAddressList -// - -using ServerAddressList = std::vector; +// For backward compatibility only. +// TODO(roth): Remove this file when all callers have been updated. +using ServerAddress = EndpointAddresses; +using ServerAddressList = EndpointAddressesList; } // namespace grpc_core diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index decede59e0063..3085704e03979 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -686,9 +686,9 @@ 'src/core/lib/promise/party.cc', 'src/core/lib/promise/sleep.cc', 'src/core/lib/promise/trace.cc', + 'src/core/lib/resolver/endpoint_addresses.cc', 'src/core/lib/resolver/resolver.cc', 'src/core/lib/resolver/resolver_registry.cc', - 'src/core/lib/resolver/server_address.cc', 'src/core/lib/resource_quota/api.cc', 'src/core/lib/resource_quota/arena.cc', 'src/core/lib/resource_quota/memory_quota.cc', diff --git a/test/core/client_channel/client_channel_test.cc b/test/core/client_channel/client_channel_test.cc index 475fd8433eb53..5e553b1ee201e 100644 --- a/test/core/client_channel/client_channel_test.cc +++ b/test/core/client_channel/client_channel_test.cc @@ -25,7 +25,7 @@ #include "src/core/ext/filters/client_channel/subchannel_pool_interface.h" #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/resolver/server_address.h" +#include "src/core/lib/resolver/endpoint_addresses.h" #include "test/core/util/test_config.h" namespace grpc_core { diff --git a/test/core/client_channel/lb_policy/lb_policy_test_lib.h b/test/core/client_channel/lb_policy/lb_policy_test_lib.h index 0f9d9aaa913aa..cc1c79d023122 100644 --- a/test/core/client_channel/lb_policy/lb_policy_test_lib.h +++ b/test/core/client_channel/lb_policy/lb_policy_test_lib.h @@ -19,6 +19,7 @@ #include +#include #include #include @@ -36,6 +37,7 @@ #include #include "absl/base/thread_annotations.h" +#include "absl/functional/any_invocable.h" #include "absl/status/status.h" #include "absl/status/statusor.h" #include "absl/strings/str_format.h" @@ -79,7 +81,7 @@ #include "src/core/lib/load_balancing/lb_policy.h" #include "src/core/lib/load_balancing/lb_policy_registry.h" #include "src/core/lib/load_balancing/subchannel_interface.h" -#include "src/core/lib/resolver/server_address.h" +#include "src/core/lib/resolver/endpoint_addresses.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/service_config/service_config_call_data.h" #include "src/core/lib/transport/connectivity_state.h" @@ -537,11 +539,14 @@ class LoadBalancingPolicyTest : public ::testing::Test { } RefCountedPtr CreateSubchannel( - ServerAddress address, const ChannelArgs& args) override { - SubchannelKey key(address.address(), args); + const grpc_resolved_address& address, + const ChannelArgs& /*per_address_args*/, + const ChannelArgs& args) override { + // TODO(roth): Need to use per_address_args here. + SubchannelKey key(address, args); auto it = test_->subchannel_pool_.find(key); if (it == test_->subchannel_pool_.end()) { - auto address_uri = grpc_sockaddr_to_uri(&address.address()); + auto address_uri = grpc_sockaddr_to_uri(&address); GPR_ASSERT(address_uri.ok()); it = test_->subchannel_pool_ .emplace(std::piecewise_construct, std::forward_as_tuple(key), @@ -749,19 +754,48 @@ class LoadBalancingPolicyTest : public ::testing::Test { return address; } - // Constructs an update containing a list of addresses. - LoadBalancingPolicy::UpdateArgs BuildUpdate( + std::vector MakeAddressList( + absl::Span addresses) { + std::vector addrs; + for (const absl::string_view& address : addresses) { + addrs.emplace_back(MakeAddress(address)); + } + return addrs; + } + + EndpointAddresses MakeEndpointAddresses( absl::Span addresses, + const ChannelArgs& args = ChannelArgs()) { + return EndpointAddresses(MakeAddressList(addresses), args); + } + + // Constructs an update containing a list of endpoints. + LoadBalancingPolicy::UpdateArgs BuildUpdate( + absl::Span endpoints, RefCountedPtr config) { LoadBalancingPolicy::UpdateArgs update; - update.addresses.emplace(); - for (const absl::string_view& address : addresses) { - update.addresses->emplace_back(MakeAddress(address), ChannelArgs()); - } + update.addresses.emplace(endpoints.begin(), endpoints.end()); update.config = std::move(config); return update; } + std::vector MakeEndpointAddressesListFromAddressList( + absl::Span addresses) { + std::vector endpoints; + for (const absl::string_view address : addresses) { + endpoints.emplace_back(MakeAddress(address), ChannelArgs()); + } + return endpoints; + } + + // Convenient overload that takes a flat address list. + LoadBalancingPolicy::UpdateArgs BuildUpdate( + absl::Span addresses, + RefCountedPtr config) { + return BuildUpdate(MakeEndpointAddressesListFromAddressList(addresses), + std::move(config)); + } + // Applies the update on the LB policy. absl::Status ApplyUpdate(LoadBalancingPolicy::UpdateArgs update_args, LoadBalancingPolicy* lb_policy) { @@ -882,6 +916,21 @@ class LoadBalancingPolicyTest : public ::testing::Test { return final_picker; } + void ExpectTransientFailureUpdate( + absl::Status expected_status, + SourceLocation location = SourceLocation()) { + auto picker = + ExpectState(GRPC_CHANNEL_TRANSIENT_FAILURE, expected_status, location); + ASSERT_NE(picker, nullptr); + ExpectPickFail( + picker.get(), + [&](const absl::Status& status) { + EXPECT_EQ(status, expected_status) + << location.file() << ":" << location.line(); + }, + location); + } + // Waits for the LB policy to fail a connection attempt. There can be // any number of CONNECTING updates, each of which must return a picker // that queues picks, followed by one update for state TRANSIENT_FAILURE, @@ -1109,26 +1158,56 @@ class LoadBalancingPolicyTest : public ::testing::Test { // Expect startup with RR with a set of addresses. RefCountedPtr ExpectRoundRobinStartup( - absl::Span addresses) { - RefCountedPtr picker; - // RR should have created a subchannel for each address. - for (size_t i = 0; i < addresses.size(); ++i) { - auto* subchannel = FindSubchannel(addresses[i]); - EXPECT_NE(subchannel, nullptr); - if (subchannel == nullptr) return nullptr; - // RR should ask each subchannel to connect. - EXPECT_TRUE(subchannel->ConnectionRequested()); - subchannel->SetConnectivityState(GRPC_CHANNEL_CONNECTING); - // Expect the initial CONNECTNG update with a picker that queues. + absl::Span endpoints) { + GPR_ASSERT(!endpoints.empty()); + // There should be a subchannel for every address. + // We will wind up connecting to the first address for every endpoint. + std::vector> endpoint_subchannels; + endpoint_subchannels.reserve(endpoints.size()); + std::vector chosen_addresses_storage; + chosen_addresses_storage.reserve(endpoints.size()); + std::vector chosen_addresses; + chosen_addresses.reserve(endpoints.size()); + for (const EndpointAddresses& endpoint : endpoints) { + endpoint_subchannels.emplace_back(); + endpoint_subchannels.back().reserve(endpoint.addresses().size()); + for (size_t i = 0; i < endpoint.addresses().size(); ++i) { + const grpc_resolved_address& address = endpoint.addresses()[i]; + std::string address_str = grpc_sockaddr_to_uri(&address).value(); + auto* subchannel = FindSubchannel(address_str); + EXPECT_NE(subchannel, nullptr); + if (subchannel == nullptr) return nullptr; + endpoint_subchannels.back().push_back(subchannel); + if (i == 0) { + chosen_addresses_storage.emplace_back(std::move(address_str)); + chosen_addresses.emplace_back(chosen_addresses_storage.back()); + } + } + } + // We should request a connection to the first address of each endpoint, + // and not to any of the subsequent addresses. + for (const auto& subchannels : endpoint_subchannels) { + EXPECT_TRUE(subchannels[0]->ConnectionRequested()); + for (size_t i = 1; i < subchannels.size(); ++i) { + EXPECT_FALSE(subchannels[i]->ConnectionRequested()); + } + } + // The subchannels that we've asked to connect should report + // CONNECTING state. + for (size_t i = 0; i < endpoint_subchannels.size(); ++i) { + endpoint_subchannels[i][0]->SetConnectivityState(GRPC_CHANNEL_CONNECTING); if (i == 0) ExpectConnectingUpdate(); - // The connection attempts succeed. - subchannel->SetConnectivityState(GRPC_CHANNEL_READY); + } + // The connection attempts should succeed. + RefCountedPtr picker; + for (size_t i = 0; i < endpoint_subchannels.size(); ++i) { + endpoint_subchannels[i][0]->SetConnectivityState(GRPC_CHANNEL_READY); if (i == 0) { // When the first subchannel becomes READY, accept any number of // CONNECTING updates with a picker that queues followed by a READY // update with a picker that repeatedly returns only the first address. picker = WaitForConnected(); - ExpectRoundRobinPicks(picker.get(), {addresses[0]}); + ExpectRoundRobinPicks(picker.get(), {chosen_addresses[0]}); } else { // When each subsequent subchannel becomes READY, we accept any number // of READY updates where the picker returns only the previously @@ -1136,13 +1215,98 @@ class LoadBalancingPolicyTest : public ::testing::Test { // returns the previously connected subchannel(s) *and* the newly // connected subchannel. picker = WaitForRoundRobinListChange( - absl::MakeSpan(addresses).subspan(0, i), - absl::MakeSpan(addresses).subspan(0, i + 1)); + absl::MakeSpan(chosen_addresses).subspan(0, i), + absl::MakeSpan(chosen_addresses).subspan(0, i + 1)); } } return picker; } + // A convenient override that takes a flat list of addresses, one per + // endpoint. + RefCountedPtr ExpectRoundRobinStartup( + absl::Span addresses) { + return ExpectRoundRobinStartup( + MakeEndpointAddressesListFromAddressList(addresses)); + } + + // Expects zero or more picker updates, each of which returns + // round-robin picks for the specified set of addresses. + void DrainRoundRobinPickerUpdates( + absl::Span addresses, + SourceLocation location = SourceLocation()) { + gpr_log(GPR_INFO, "Draining RR picker updates..."); + while (!helper_->QueueEmpty()) { + auto update = helper_->GetNextStateUpdate(location); + ASSERT_TRUE(update.has_value()); + ASSERT_EQ(update->state, GRPC_CHANNEL_READY); + ExpectRoundRobinPicks(update->picker.get(), addresses); + } + gpr_log(GPR_INFO, "Done draining RR picker updates"); + } + + // Expects zero or more CONNECTING updates. + void DrainConnectingUpdates(SourceLocation location = SourceLocation()) { + gpr_log(GPR_INFO, "Draining CONNECTING updates..."); + while (!helper_->QueueEmpty()) { + ExpectConnectingUpdate(location); + } + gpr_log(GPR_INFO, "Done draining CONNECTING updates"); + } + + // Triggers a connection failure for the current address for an + // endpoint and expects a reconnection to the specified new address. + void ExpectEndpointAddressChange( + absl::Span addresses, size_t current_index, + size_t new_index, absl::AnyInvocable expect_after_disconnect, + SourceLocation location = SourceLocation()) { + gpr_log(GPR_INFO, + "Expecting endpoint address change: addresses={%s}, " + "current_index=%" PRIuPTR ", new_index=%" PRIuPTR, + absl::StrJoin(addresses, ", ").c_str(), current_index, new_index); + ASSERT_LT(current_index, addresses.size()); + ASSERT_LT(new_index, addresses.size()); + // Find all subchannels. + std::vector subchannels; + subchannels.reserve(addresses.size()); + for (absl::string_view address : addresses) { + SubchannelState* subchannel = FindSubchannel(address); + ASSERT_NE(subchannel, nullptr) + << "can't find subchannel for " << address << "\n" + << location.file() << ":" << location.line(); + subchannels.push_back(subchannel); + } + // Cause current_address to become disconnected. + subchannels[current_index]->SetConnectivityState(GRPC_CHANNEL_IDLE); + ExpectReresolutionRequest(location); + if (expect_after_disconnect != nullptr) expect_after_disconnect(); + // Attempt each address in the list until we hit the desired new address. + for (size_t i = 0; i < subchannels.size(); ++i) { + // A connection should be requested on the subchannel for this + // index, and none of the others. + for (size_t j = 0; j < addresses.size(); ++j) { + EXPECT_EQ(subchannels[j]->ConnectionRequested(), j == i) + << location.file() << ":" << location.line(); + } + // Subchannel will report CONNECTING. + SubchannelState* subchannel = subchannels[i]; + subchannel->SetConnectivityState(GRPC_CHANNEL_CONNECTING); + // If this is the one we want to stick with, it will report READY. + if (i == new_index) { + subchannel->SetConnectivityState(GRPC_CHANNEL_READY); + break; + } + // Otherwise, report TF. + subchannel->SetConnectivityState( + GRPC_CHANNEL_TRANSIENT_FAILURE, + absl::UnavailableError("connection failed")); + // Report IDLE to leave it in the expected state in case the test + // interacts with it again. + subchannel->SetConnectivityState(GRPC_CHANNEL_IDLE); + } + gpr_log(GPR_INFO, "Done with endpoint address change"); + } + // Requests a picker on picker and expects a Fail result. // The failing status is passed to check_status. void ExpectPickFail(LoadBalancingPolicy::SubchannelPicker* picker, diff --git a/test/core/client_channel/lb_policy/outlier_detection_test.cc b/test/core/client_channel/lb_policy/outlier_detection_test.cc index b57cfc9008cfe..76984a3beaafd 100644 --- a/test/core/client_channel/lb_policy/outlier_detection_test.cc +++ b/test/core/client_channel/lb_policy/outlier_detection_test.cc @@ -28,6 +28,7 @@ #include "absl/status/status.h" #include "absl/strings/string_view.h" #include "absl/types/optional.h" +#include "absl/types/span.h" #include "gtest/gtest.h" #include @@ -36,10 +37,12 @@ #include "src/core/ext/filters/client_channel/lb_policy/backend_metric_data.h" #include "src/core/lib/experiments/experiments.h" +#include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/gprpp/time.h" #include "src/core/lib/json/json.h" #include "src/core/lib/load_balancing/lb_policy.h" +#include "src/core/lib/resolver/endpoint_addresses.h" #include "test/core/client_channel/lb_policy/lb_policy_test_lib.h" #include "test/core/util/test_config.h" @@ -205,6 +208,8 @@ TEST_F(OutlierDetectionTest, FailurePercentage) { .SetFailurePercentageThreshold(1) .SetFailurePercentageMinimumHosts(1) .SetFailurePercentageRequestVolume(1) + .SetMaxEjectionTime(Duration::Seconds(1)) + .SetBaseEjectionTime(Duration::Seconds(1)) .Build()), lb_policy()); EXPECT_TRUE(status.ok()) << status; @@ -225,10 +230,118 @@ TEST_F(OutlierDetectionTest, FailurePercentage) { for (const auto& addr : kAddresses) { if (addr != *address) remaining_addresses.push_back(addr); } - picker = WaitForRoundRobinListChange(kAddresses, remaining_addresses); + WaitForRoundRobinListChange(kAddresses, remaining_addresses); + // Advance time and run the timer callback to trigger un-ejection. + IncrementTimeBy(Duration::Seconds(10)); + gpr_log(GPR_INFO, "### un-ejection complete"); + // Expect a picker update. + WaitForRoundRobinListChange(remaining_addresses, kAddresses); +} + +TEST_F(OutlierDetectionTest, MultipleAddressesPerEndpoint) { + if (!IsRoundRobinDelegateToPickFirstEnabled()) return; + // Can't use timer duration expectation here, because the Happy + // Eyeballs timer inside pick_first will use a different duration than + // the timer in outlier_detection. + SetExpectedTimerDuration(absl::nullopt); + constexpr std::array kEndpoint1Addresses = { + "ipv4:127.0.0.1:443", "ipv4:127.0.0.1:444"}; + constexpr std::array kEndpoint2Addresses = { + "ipv4:127.0.0.1:445", "ipv4:127.0.0.1:446"}; + constexpr std::array kEndpoint3Addresses = { + "ipv4:127.0.0.1:447", "ipv4:127.0.0.1:448"}; + const std::array kEndpoints = { + MakeEndpointAddresses(kEndpoint1Addresses), + MakeEndpointAddresses(kEndpoint2Addresses), + MakeEndpointAddresses(kEndpoint3Addresses)}; + // Send initial update. + absl::Status status = ApplyUpdate( + BuildUpdate(kEndpoints, ConfigBuilder() + .SetFailurePercentageThreshold(1) + .SetFailurePercentageMinimumHosts(1) + .SetFailurePercentageRequestVolume(1) + .SetMaxEjectionTime(Duration::Seconds(1)) + .SetBaseEjectionTime(Duration::Seconds(1)) + .Build()), + lb_policy_.get()); + EXPECT_TRUE(status.ok()) << status; + // Expect normal startup. + auto picker = ExpectRoundRobinStartup(kEndpoints); + ASSERT_NE(picker, nullptr); + gpr_log(GPR_INFO, "### RR startup complete"); + // Do a pick and report a failed call. + auto address = DoPickWithFailedCall(picker.get()); + ASSERT_TRUE(address.has_value()); + gpr_log(GPR_INFO, "### failed RPC on %s", address->c_str()); + // Based on the address that the failed call went to, we determine + // which addresses to use in the subsequent steps. + absl::Span ejected_endpoint_addresses; + absl::Span sentinel_endpoint_addresses; + absl::string_view unmodified_endpoint_address; + std::vector final_addresses; + if (kEndpoint1Addresses[0] == *address) { + ejected_endpoint_addresses = kEndpoint1Addresses; + sentinel_endpoint_addresses = kEndpoint2Addresses; + unmodified_endpoint_address = kEndpoint3Addresses[0]; + final_addresses = {kEndpoint1Addresses[1], kEndpoint2Addresses[1], + kEndpoint3Addresses[0]}; + } else if (kEndpoint2Addresses[0] == *address) { + ejected_endpoint_addresses = kEndpoint2Addresses; + sentinel_endpoint_addresses = kEndpoint1Addresses; + unmodified_endpoint_address = kEndpoint3Addresses[0]; + final_addresses = {kEndpoint1Addresses[1], kEndpoint2Addresses[1], + kEndpoint3Addresses[0]}; + } else { + ejected_endpoint_addresses = kEndpoint3Addresses; + sentinel_endpoint_addresses = kEndpoint1Addresses; + unmodified_endpoint_address = kEndpoint2Addresses[0]; + final_addresses = {kEndpoint1Addresses[1], kEndpoint2Addresses[0], + kEndpoint3Addresses[1]}; + } + // Advance time and run the timer callback to trigger ejection. + IncrementTimeBy(Duration::Seconds(10)); + gpr_log(GPR_INFO, "### ejection complete"); + // Expect a picker that removes the ejected address. + WaitForRoundRobinListChange( + {kEndpoint1Addresses[0], kEndpoint2Addresses[0], kEndpoint3Addresses[0]}, + {sentinel_endpoint_addresses[0], unmodified_endpoint_address}); + gpr_log(GPR_INFO, "### ejected endpoint removed"); + // Cause the connection to the ejected endpoint to fail, and then + // have it reconnect to a different address. The endpoint is still + // ejected, so the new address should not be used. + ExpectEndpointAddressChange(ejected_endpoint_addresses, 0, 1, nullptr); + // Need to drain the picker updates before calling + // ExpectEndpointAddressChange() again, since that will expect a + // re-resolution request in the queue. + DrainRoundRobinPickerUpdates( + {sentinel_endpoint_addresses[0], unmodified_endpoint_address}); + gpr_log(GPR_INFO, "### done changing address of ejected endpoint"); + // Do the same thing for the sentinel endpoint, so that we + // know that the LB policy has seen the address change for the ejected + // endpoint. + ExpectEndpointAddressChange(sentinel_endpoint_addresses, 0, 1, [&]() { + WaitForRoundRobinListChange( + {sentinel_endpoint_addresses[0], unmodified_endpoint_address}, + {unmodified_endpoint_address}); + }); + WaitForRoundRobinListChange( + {unmodified_endpoint_address}, + {sentinel_endpoint_addresses[1], unmodified_endpoint_address}); + gpr_log(GPR_INFO, "### done changing address of ejected endpoint"); + // Advance time and run the timer callback to trigger un-ejection. + IncrementTimeBy(Duration::Seconds(10)); + gpr_log(GPR_INFO, "### un-ejection complete"); + // The ejected endpoint should come back using the new address. + WaitForRoundRobinListChange( + {sentinel_endpoint_addresses[1], unmodified_endpoint_address}, + final_addresses); } TEST_F(OutlierDetectionTest, DoesNotWorkWithPickFirst) { + // Can't use timer duration expectation here, because the Happy + // Eyeballs timer inside pick_first will use a different duration than + // the timer in outlier_detection. + SetExpectedTimerDuration(absl::nullopt); constexpr std::array kAddresses = { "ipv4:127.0.0.1:440", "ipv4:127.0.0.1:441", "ipv4:127.0.0.1:442"}; // Send initial update. diff --git a/test/core/client_channel/lb_policy/pick_first_test.cc b/test/core/client_channel/lb_policy/pick_first_test.cc index 16b928b92ed5b..088498954e42f 100644 --- a/test/core/client_channel/lb_policy/pick_first_test.cc +++ b/test/core/client_channel/lb_policy/pick_first_test.cc @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -35,11 +36,14 @@ #include #include "src/core/lib/gprpp/debug_location.h" +#include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/gprpp/time.h" #include "src/core/lib/gprpp/work_serializer.h" #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/json/json.h" #include "src/core/lib/load_balancing/lb_policy.h" +#include "src/core/lib/resolver/endpoint_addresses.h" #include "test/core/client_channel/lb_policy/lb_policy_test_lib.h" #include "test/core/util/test_config.h" @@ -51,6 +55,11 @@ class PickFirstTest : public LoadBalancingPolicyTest { protected: PickFirstTest() : LoadBalancingPolicyTest("pick_first") {} + void SetUp() override { + LoadBalancingPolicyTest::SetUp(); + SetExpectedTimerDuration(std::chrono::milliseconds(250)); + } + static RefCountedPtr MakePickFirstConfig( absl::optional shuffle_address_list = absl::nullopt) { return MakeConfig(Json::FromArray({Json::FromObject( @@ -211,6 +220,66 @@ TEST_F(PickFirstTest, FirstAddressFails) { } } +TEST_F(PickFirstTest, FlattensEndpointAddressesList) { + // Send an update containing two endpoints, the first one with two addresses. + constexpr std::array kEndpoint1Addresses = { + "ipv4:127.0.0.1:443", "ipv4:127.0.0.1:444"}; + constexpr std::array kEndpoint2Addresses = { + "ipv4:127.0.0.1:445"}; + const std::array kEndpoints = { + MakeEndpointAddresses(kEndpoint1Addresses), + MakeEndpointAddresses(kEndpoint2Addresses)}; + absl::Status status = ApplyUpdate( + BuildUpdate(kEndpoints, MakePickFirstConfig(false)), lb_policy_.get()); + EXPECT_TRUE(status.ok()) << status; + // LB policy should have created a subchannel for all 3 addresses. + auto* subchannel = FindSubchannel(kEndpoint1Addresses[0]); + ASSERT_NE(subchannel, nullptr); + auto* subchannel2 = FindSubchannel(kEndpoint1Addresses[1]); + ASSERT_NE(subchannel2, nullptr); + auto* subchannel3 = FindSubchannel(kEndpoint2Addresses[0]); + ASSERT_NE(subchannel3, nullptr); + // When the LB policy receives the first subchannel's initial connectivity + // state notification (IDLE), it will request a connection. + EXPECT_TRUE(subchannel->ConnectionRequested()); + // This causes the subchannel to start to connect, so it reports + // CONNECTING. + subchannel->SetConnectivityState(GRPC_CHANNEL_CONNECTING); + // LB policy should have reported CONNECTING state. + ExpectConnectingUpdate(); + // The other subchannels should not be connecting. + EXPECT_FALSE(subchannel2->ConnectionRequested()); + EXPECT_FALSE(subchannel3->ConnectionRequested()); + // The first subchannel's connection attempt fails. + subchannel->SetConnectivityState(GRPC_CHANNEL_TRANSIENT_FAILURE, + absl::UnavailableError("failed to connect")); + // The LB policy will start a connection attempt on the second subchannel. + EXPECT_TRUE(subchannel2->ConnectionRequested()); + EXPECT_FALSE(subchannel3->ConnectionRequested()); + // This causes the subchannel to start to connect, so it reports + // CONNECTING. + subchannel2->SetConnectivityState(GRPC_CHANNEL_CONNECTING); + // The connection attempt fails. + subchannel2->SetConnectivityState( + GRPC_CHANNEL_TRANSIENT_FAILURE, + absl::UnavailableError("failed to connect")); + // The LB policy will start a connection attempt on the third subchannel. + EXPECT_TRUE(subchannel3->ConnectionRequested()); + // This causes the subchannel to start to connect, so it reports + // CONNECTING. + subchannel3->SetConnectivityState(GRPC_CHANNEL_CONNECTING); + // This one succeeds. + subchannel3->SetConnectivityState(GRPC_CHANNEL_READY); + // The LB policy will report CONNECTING some number of times (doesn't + // matter how many) and then report READY. + auto picker = WaitForConnected(); + ASSERT_NE(picker, nullptr); + // Picker should return the same subchannel repeatedly. + for (size_t i = 0; i < 3; ++i) { + EXPECT_EQ(ExpectPickComplete(picker.get()), kEndpoint2Addresses[0]); + } +} + TEST_F(PickFirstTest, FirstTwoAddressesInTransientFailureAtStart) { // Send an update containing three addresses. // The first two addresses are already in state TRANSIENT_FAILURE when the @@ -291,9 +360,8 @@ TEST_F(PickFirstTest, AllAddressesInTransientFailureAtStart) { subchannel->SetConnectivityState(GRPC_CHANNEL_CONNECTING); // The connection attempt succeeds. subchannel->SetConnectivityState(GRPC_CHANNEL_READY); - // The LB policy will report CONNECTING some number of times (doesn't - // matter how many) and then report READY. - auto picker = WaitForConnected(); + // The LB policy will report READY. + auto picker = ExpectState(GRPC_CHANNEL_READY); ASSERT_NE(picker, nullptr); // Picker should return the same subchannel repeatedly. for (size_t i = 0; i < 3; ++i) { @@ -354,6 +422,170 @@ TEST_F(PickFirstTest, StaysInTransientFailureAfterAddressListUpdate) { } } +TEST_F(PickFirstTest, HappyEyeballs) { + // Send an update containing three addresses. + constexpr std::array kAddresses = { + "ipv4:127.0.0.1:443", "ipv4:127.0.0.1:444", "ipv4:127.0.0.1:445"}; + absl::Status status = ApplyUpdate( + BuildUpdate(kAddresses, MakePickFirstConfig(false)), lb_policy()); + EXPECT_TRUE(status.ok()) << status; + // LB policy should have created a subchannel for both addresses. + auto* subchannel = FindSubchannel(kAddresses[0]); + ASSERT_NE(subchannel, nullptr); + auto* subchannel2 = FindSubchannel(kAddresses[1]); + ASSERT_NE(subchannel2, nullptr); + auto* subchannel3 = FindSubchannel(kAddresses[2]); + ASSERT_NE(subchannel3, nullptr); + // When the LB policy receives the first subchannel's initial connectivity + // state notification (IDLE), it will request a connection. + EXPECT_TRUE(subchannel->ConnectionRequested()); + // This causes the subchannel to start to connect, so it reports + // CONNECTING. + subchannel->SetConnectivityState(GRPC_CHANNEL_CONNECTING); + // LB policy should have reported CONNECTING state. + ExpectConnectingUpdate(); + // The second subchannel should not be connecting. + EXPECT_FALSE(subchannel2->ConnectionRequested()); + // The timer fires before the connection attempt completes. + IncrementTimeBy(Duration::Milliseconds(250)); + // This causes the LB policy to start connecting to the second subchannel. + EXPECT_TRUE(subchannel2->ConnectionRequested()); + subchannel2->SetConnectivityState(GRPC_CHANNEL_CONNECTING); + // The second subchannel fails before the timer fires. + subchannel2->SetConnectivityState( + GRPC_CHANNEL_TRANSIENT_FAILURE, + absl::UnavailableError("failed to connect")); + // This causes the LB policy to start connecting to the third subchannel. + EXPECT_TRUE(subchannel3->ConnectionRequested()); + subchannel3->SetConnectivityState(GRPC_CHANNEL_CONNECTING); + // Incrementing the time here has no effect, because the LB policy + // does not use a timer for the last subchannel in the list. + // So if there are any queued updates at this point, they will be + // CONNECTING state. + IncrementTimeBy(Duration::Milliseconds(250)); + DrainConnectingUpdates(); + // The first subchannel becomes connected. + subchannel->SetConnectivityState(GRPC_CHANNEL_READY); + // The LB policy will report CONNECTING some number of times (doesn't + // matter how many) and then report READY. + auto picker = WaitForConnected(); + ASSERT_NE(picker, nullptr); + // Picker should return the same subchannel repeatedly. + for (size_t i = 0; i < 3; ++i) { + EXPECT_EQ(ExpectPickComplete(picker.get()), kAddresses[0]); + } +} + +TEST_F(PickFirstTest, HappyEyeballsCompletesWithoutSuccess) { + // Send an update containing three addresses. + constexpr std::array kAddresses = { + "ipv4:127.0.0.1:443", "ipv4:127.0.0.1:444", "ipv4:127.0.0.1:445"}; + absl::Status status = ApplyUpdate( + BuildUpdate(kAddresses, MakePickFirstConfig(false)), lb_policy()); + EXPECT_TRUE(status.ok()) << status; + // LB policy should have created a subchannel for both addresses. + auto* subchannel = FindSubchannel(kAddresses[0]); + ASSERT_NE(subchannel, nullptr); + auto* subchannel2 = FindSubchannel(kAddresses[1]); + ASSERT_NE(subchannel2, nullptr); + auto* subchannel3 = FindSubchannel(kAddresses[2]); + ASSERT_NE(subchannel3, nullptr); + // When the LB policy receives the first subchannel's initial connectivity + // state notification (IDLE), it will request a connection. + EXPECT_TRUE(subchannel->ConnectionRequested()); + // This causes the subchannel to start to connect, so it reports + // CONNECTING. + subchannel->SetConnectivityState(GRPC_CHANNEL_CONNECTING); + // LB policy should have reported CONNECTING state. + ExpectConnectingUpdate(); + // The second subchannel should not be connecting. + EXPECT_FALSE(subchannel2->ConnectionRequested()); + // The timer fires before the connection attempt completes. + IncrementTimeBy(Duration::Milliseconds(250)); + // This causes the LB policy to start connecting to the second subchannel. + EXPECT_TRUE(subchannel2->ConnectionRequested()); + subchannel2->SetConnectivityState(GRPC_CHANNEL_CONNECTING); + // The second subchannel fails before the timer fires. + subchannel2->SetConnectivityState( + GRPC_CHANNEL_TRANSIENT_FAILURE, + absl::UnavailableError("failed to connect")); + // This causes the LB policy to start connecting to the third subchannel. + EXPECT_TRUE(subchannel3->ConnectionRequested()); + subchannel3->SetConnectivityState(GRPC_CHANNEL_CONNECTING); + // Incrementing the time here has no effect, because the LB policy + // does not use a timer for the last subchannel in the list. + // So if there are any queued updates at this point, they will be + // CONNECTING state. + IncrementTimeBy(Duration::Milliseconds(250)); + DrainConnectingUpdates(); + // Set subchannel 2 back to IDLE, so it's already in that state when + // Happy Eyeballs fails. + subchannel2->SetConnectivityState(GRPC_CHANNEL_IDLE); + // Third subchannel fails to connect. + subchannel3->SetConnectivityState( + GRPC_CHANNEL_TRANSIENT_FAILURE, + absl::UnavailableError("failed to connect")); + // The LB policy should request re-resolution. + ExpectReresolutionRequest(); + // The LB policy should report TRANSIENT_FAILURE. + WaitForConnectionFailed([&](const absl::Status& status) { + EXPECT_EQ(status, absl::UnavailableError( + "failed to connect to all addresses; " + "last error: UNAVAILABLE: failed to connect")); + }); + // We are now done with the Happy Eyeballs pass, and we move into a + // mode where we try to connect to all subchannels in parallel. + // Subchannel 2 was already in state IDLE, so the LB policy will + // immediately trigger a connection request on it. It will not do so + // for subchannels 1 (in CONNECTING) or 3 (in TRANSIENT_FAILURE). + EXPECT_FALSE(subchannel->ConnectionRequested()); + EXPECT_TRUE(subchannel2->ConnectionRequested()); + EXPECT_FALSE(subchannel3->ConnectionRequested()); + // Subchannel 2 reports CONNECTING. + subchannel2->SetConnectivityState(GRPC_CHANNEL_CONNECTING); + // Now subchannel 1 reports TF. This is the first failure since we + // finished Happy Eyeballs. + subchannel->SetConnectivityState(GRPC_CHANNEL_TRANSIENT_FAILURE, + absl::UnavailableError("failed to connect")); + EXPECT_FALSE(subchannel->ConnectionRequested()); + // Now subchannel 3 reports IDLE. This should trigger another + // connection attempt. + subchannel3->SetConnectivityState(GRPC_CHANNEL_IDLE); + EXPECT_TRUE(subchannel3->ConnectionRequested()); + subchannel3->SetConnectivityState(GRPC_CHANNEL_CONNECTING); + // Subchannel 2 reports TF. This is the second failure since we + // finished Happy Eyeballs. + subchannel2->SetConnectivityState( + GRPC_CHANNEL_TRANSIENT_FAILURE, + absl::UnavailableError("failed to connect")); + EXPECT_FALSE(subchannel2->ConnectionRequested()); + // Finally, subchannel 3 reports TF. This is the third failure since + // we finished Happy Eyeballs, so the LB policy will request + // re-resolution and report TF again. + subchannel3->SetConnectivityState( + GRPC_CHANNEL_TRANSIENT_FAILURE, + absl::UnavailableError("failed to connect")); + EXPECT_FALSE(subchannel3->ConnectionRequested()); + ExpectReresolutionRequest(); + ExpectTransientFailureUpdate( + absl::UnavailableError("failed to connect to all addresses; " + "last error: UNAVAILABLE: failed to connect")); + // Now the second subchannel goes IDLE. + subchannel2->SetConnectivityState(GRPC_CHANNEL_IDLE); + // The LB policy asks it to connect. + EXPECT_TRUE(subchannel2->ConnectionRequested()); + subchannel2->SetConnectivityState(GRPC_CHANNEL_CONNECTING); + // This time, the connection attempt succeeds. + subchannel2->SetConnectivityState(GRPC_CHANNEL_READY); + // The LB policy will report READY. + auto picker = ExpectState(GRPC_CHANNEL_READY); + ASSERT_NE(picker, nullptr); + // Picker should return the same subchannel repeatedly. + for (size_t i = 0; i < 3; ++i) { + EXPECT_EQ(ExpectPickComplete(picker.get()), kAddresses[1]); + } +} + TEST_F(PickFirstTest, FirstAddressGoesIdleBeforeSecondOneFails) { // Send an update containing two addresses. constexpr std::array kAddresses = { diff --git a/test/core/client_channel/lb_policy/round_robin_test.cc b/test/core/client_channel/lb_policy/round_robin_test.cc index 665ecf9bb0943..ab0924bf5be85 100644 --- a/test/core/client_channel/lb_policy/round_robin_test.cc +++ b/test/core/client_channel/lb_policy/round_robin_test.cc @@ -21,6 +21,12 @@ #include "absl/types/span.h" #include "gtest/gtest.h" +#include + +#include "src/core/lib/experiments/experiments.h" +#include "src/core/lib/gprpp/orphanable.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/resolver/endpoint_addresses.h" #include "test/core/client_channel/lb_policy/lb_policy_test_lib.h" #include "test/core/util/test_config.h" @@ -62,6 +68,83 @@ TEST_F(RoundRobinTest, AddressUpdates) { absl::MakeSpan(kAddresses).last(2)); } +TEST_F(RoundRobinTest, MultipleAddressesPerEndpoint) { + if (!IsRoundRobinDelegateToPickFirstEnabled()) return; + constexpr std::array kEndpoint1Addresses = { + "ipv4:127.0.0.1:443", "ipv4:127.0.0.1:444"}; + constexpr std::array kEndpoint2Addresses = { + "ipv4:127.0.0.1:445", "ipv4:127.0.0.1:446"}; + const std::array kEndpoints = { + MakeEndpointAddresses(kEndpoint1Addresses), + MakeEndpointAddresses(kEndpoint2Addresses)}; + EXPECT_EQ(ApplyUpdate(BuildUpdate(kEndpoints, nullptr), lb_policy_.get()), + absl::OkStatus()); + // RR should have created a subchannel for each address. + auto* subchannel1_0 = FindSubchannel(kEndpoint1Addresses[0]); + ASSERT_NE(subchannel1_0, nullptr) << "Address: " << kEndpoint1Addresses[0]; + auto* subchannel1_1 = FindSubchannel(kEndpoint1Addresses[1]); + ASSERT_NE(subchannel1_1, nullptr) << "Address: " << kEndpoint1Addresses[1]; + auto* subchannel2_0 = FindSubchannel(kEndpoint2Addresses[0]); + ASSERT_NE(subchannel2_0, nullptr) << "Address: " << kEndpoint2Addresses[0]; + auto* subchannel2_1 = FindSubchannel(kEndpoint2Addresses[1]); + ASSERT_NE(subchannel2_1, nullptr) << "Address: " << kEndpoint2Addresses[1]; + // PF for each endpoint should try to connect to the first subchannel. + EXPECT_TRUE(subchannel1_0->ConnectionRequested()); + EXPECT_FALSE(subchannel1_1->ConnectionRequested()); + EXPECT_TRUE(subchannel2_0->ConnectionRequested()); + EXPECT_FALSE(subchannel2_1->ConnectionRequested()); + // In the first endpoint, the first subchannel reports CONNECTING. + // This causes RR to report CONNECTING. + subchannel1_0->SetConnectivityState(GRPC_CHANNEL_CONNECTING); + ExpectConnectingUpdate(); + // In the second endpoint, the first subchannel reports CONNECTING. + subchannel2_0->SetConnectivityState(GRPC_CHANNEL_CONNECTING); + // In the first endpoint, the first subchannel fails to connect. + // This causes PF to start a connection attempt on the second subchannel. + subchannel1_0->SetConnectivityState(GRPC_CHANNEL_TRANSIENT_FAILURE, + absl::UnavailableError("ugh")); + EXPECT_TRUE(subchannel1_1->ConnectionRequested()); + subchannel1_1->SetConnectivityState(GRPC_CHANNEL_CONNECTING); + // In the second endpoint, the first subchannel becomes connected. + // This causes RR to report READY with all RPCs going to a single address. + subchannel2_0->SetConnectivityState(GRPC_CHANNEL_READY); + auto picker = WaitForConnected(); + ExpectRoundRobinPicks(picker.get(), {kEndpoint2Addresses[0]}); + // In the first endpoint, the second subchannel becomes connected. + // This causes RR to add it to the rotation. + subchannel1_1->SetConnectivityState(GRPC_CHANNEL_READY); + WaitForRoundRobinListChange({kEndpoint2Addresses[0]}, + {kEndpoint1Addresses[1], kEndpoint2Addresses[0]}); + // No more connection attempts triggered. + EXPECT_FALSE(subchannel1_0->ConnectionRequested()); + EXPECT_FALSE(subchannel1_1->ConnectionRequested()); + EXPECT_FALSE(subchannel2_0->ConnectionRequested()); + EXPECT_FALSE(subchannel2_1->ConnectionRequested()); + // First endpoint first subchannel finishes backoff, but this doesn't + // affect anything -- in fact, PF isn't even watching this subchannel + // anymore, since it's connected to the other one. However, this + // ensures that the subchannel is in the right state when we try to + // reconnect below. + subchannel1_0->SetConnectivityState(GRPC_CHANNEL_IDLE); + EXPECT_FALSE(subchannel1_0->ConnectionRequested()); + // Endpoint 1 switches to a different address. + ExpectEndpointAddressChange(kEndpoint1Addresses, 1, 0, [&]() { + // RR will remove the endpoint from the rotation when it becomes + // disconnected. + WaitForRoundRobinListChange( + {kEndpoint1Addresses[1], kEndpoint2Addresses[0]}, + {kEndpoint2Addresses[0]}); + }); + // Then RR will re-add the endpoint with the new address. + WaitForRoundRobinListChange({kEndpoint2Addresses[0]}, + {kEndpoint1Addresses[0], kEndpoint2Addresses[0]}); + // No more connection attempts triggered. + EXPECT_FALSE(subchannel1_0->ConnectionRequested()); + EXPECT_FALSE(subchannel1_1->ConnectionRequested()); + EXPECT_FALSE(subchannel2_0->ConnectionRequested()); + EXPECT_FALSE(subchannel2_1->ConnectionRequested()); +} + // TODO(roth): Add test cases: // - empty address list // - subchannels failing connection attempts diff --git a/test/core/client_channel/lb_policy/weighted_round_robin_test.cc b/test/core/client_channel/lb_policy/weighted_round_robin_test.cc index 51e5013b9eaf8..75f37244f2a5e 100644 --- a/test/core/client_channel/lb_policy/weighted_round_robin_test.cc +++ b/test/core/client_channel/lb_policy/weighted_round_robin_test.cc @@ -40,12 +40,15 @@ #include #include "src/core/ext/filters/client_channel/lb_policy/backend_metric_data.h" +#include "src/core/lib/experiments/experiments.h" #include "src/core/lib/gprpp/debug_location.h" +#include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/gprpp/time.h" #include "src/core/lib/json/json.h" #include "src/core/lib/json/json_writer.h" #include "src/core/lib/load_balancing/lb_policy.h" +#include "src/core/lib/resolver/endpoint_addresses.h" #include "test/core/client_channel/lb_policy/lb_policy_test_lib.h" #include "test/core/util/test_config.h" @@ -53,17 +56,6 @@ namespace grpc_core { namespace testing { namespace { -BackendMetricData MakeBackendMetricData(double app_utilization, double qps, - double eps, - double cpu_utilization = 0) { - BackendMetricData b; - b.cpu_utilization = cpu_utilization; - b.application_utilization = app_utilization; - b.qps = qps; - b.eps = eps; - return b; -} - class WeightedRoundRobinTest : public LoadBalancingPolicyTest { protected: class ConfigBuilder { @@ -164,6 +156,17 @@ class WeightedRoundRobinTest : public LoadBalancingPolicyTest { return absl::StrJoin(pick_map, ",", absl::PairFormatter("=")); } + static BackendMetricData MakeBackendMetricData(double app_utilization, + double qps, double eps, + double cpu_utilization = 0) { + BackendMetricData b; + b.cpu_utilization = cpu_utilization; + b.application_utilization = app_utilization; + b.qps = qps; + b.eps = eps; + return b; + } + // Returns the number of picks we need to do to check the specified // expectations. static size_t NumPicksNeeded(const std::map kEndpoint1Addresses = { + "ipv4:127.0.0.1:443", "ipv4:127.0.0.1:444"}; + constexpr std::array kEndpoint2Addresses = { + "ipv4:127.0.0.1:445", "ipv4:127.0.0.1:446"}; + constexpr std::array kEndpoint3Addresses = { + "ipv4:127.0.0.1:447", "ipv4:127.0.0.1:448"}; + const std::array kEndpoints = { + MakeEndpointAddresses(kEndpoint1Addresses), + MakeEndpointAddresses(kEndpoint2Addresses), + MakeEndpointAddresses(kEndpoint3Addresses)}; + EXPECT_EQ(ApplyUpdate(BuildUpdate(kEndpoints, ConfigBuilder().Build()), + lb_policy_.get()), + absl::OkStatus()); + // WRR should have created a subchannel for each address. + auto* subchannel1_0 = FindSubchannel(kEndpoint1Addresses[0]); + ASSERT_NE(subchannel1_0, nullptr) << "Address: " << kEndpoint1Addresses[0]; + auto* subchannel1_1 = FindSubchannel(kEndpoint1Addresses[1]); + ASSERT_NE(subchannel1_1, nullptr) << "Address: " << kEndpoint1Addresses[1]; + auto* subchannel2_0 = FindSubchannel(kEndpoint2Addresses[0]); + ASSERT_NE(subchannel2_0, nullptr) << "Address: " << kEndpoint2Addresses[0]; + auto* subchannel2_1 = FindSubchannel(kEndpoint2Addresses[1]); + ASSERT_NE(subchannel2_1, nullptr) << "Address: " << kEndpoint2Addresses[1]; + auto* subchannel3_0 = FindSubchannel(kEndpoint3Addresses[0]); + ASSERT_NE(subchannel3_0, nullptr) << "Address: " << kEndpoint3Addresses[0]; + auto* subchannel3_1 = FindSubchannel(kEndpoint3Addresses[1]); + ASSERT_NE(subchannel3_1, nullptr) << "Address: " << kEndpoint3Addresses[1]; + // PF for each endpoint should try to connect to the first subchannel. + EXPECT_TRUE(subchannel1_0->ConnectionRequested()); + EXPECT_FALSE(subchannel1_1->ConnectionRequested()); + EXPECT_TRUE(subchannel2_0->ConnectionRequested()); + EXPECT_FALSE(subchannel2_1->ConnectionRequested()); + EXPECT_TRUE(subchannel3_0->ConnectionRequested()); + EXPECT_FALSE(subchannel3_1->ConnectionRequested()); + // In the first endpoint, the first subchannel reports CONNECTING. + // This causes WRR to report CONNECTING. + subchannel1_0->SetConnectivityState(GRPC_CHANNEL_CONNECTING); + ExpectConnectingUpdate(); + // In the second endpoint, the first subchannel reports CONNECTING. + subchannel2_0->SetConnectivityState(GRPC_CHANNEL_CONNECTING); + // In the third endpoint, the first subchannel reports CONNECTING. + subchannel3_0->SetConnectivityState(GRPC_CHANNEL_CONNECTING); + // In the first endpoint, the first subchannel fails to connect. + // This causes PF to start a connection attempt on the second subchannel. + subchannel1_0->SetConnectivityState(GRPC_CHANNEL_TRANSIENT_FAILURE, + absl::UnavailableError("ugh")); + EXPECT_TRUE(subchannel1_1->ConnectionRequested()); + subchannel1_1->SetConnectivityState(GRPC_CHANNEL_CONNECTING); + // In the second endpoint, the first subchannel becomes connected. + // This causes WRR to report READY with all RPCs going to a single address. + subchannel2_0->SetConnectivityState(GRPC_CHANNEL_READY); + auto picker = WaitForConnected(); + ExpectRoundRobinPicks(picker.get(), {kEndpoint2Addresses[0]}); + // In the third endpoint, the first subchannel becomes connected. + // This causes WRR to add it to the rotation. + subchannel3_0->SetConnectivityState(GRPC_CHANNEL_READY); + picker = WaitForRoundRobinListChange( + {kEndpoint2Addresses[0]}, + {kEndpoint2Addresses[0], kEndpoint3Addresses[0]}); + // In the first endpoint, the second subchannel becomes connected. + // This causes WRR to add it to the rotation. + subchannel1_1->SetConnectivityState(GRPC_CHANNEL_READY); + picker = WaitForRoundRobinListChange( + {kEndpoint2Addresses[0], kEndpoint3Addresses[0]}, + {kEndpoint1Addresses[1], kEndpoint2Addresses[0], kEndpoint3Addresses[0]}); + // No more connection attempts triggered. + EXPECT_FALSE(subchannel1_0->ConnectionRequested()); + EXPECT_FALSE(subchannel1_1->ConnectionRequested()); + EXPECT_FALSE(subchannel2_0->ConnectionRequested()); + EXPECT_FALSE(subchannel2_1->ConnectionRequested()); + EXPECT_FALSE(subchannel3_0->ConnectionRequested()); + EXPECT_FALSE(subchannel3_1->ConnectionRequested()); + // Expected weights: 3:1:3 + WaitForWeightedRoundRobinPicks( + &picker, + {{kEndpoint1Addresses[1], + MakeBackendMetricData(/*app_utilization=*/0.3, /*qps=*/100.0, + /*eps=*/0.0)}, + {kEndpoint2Addresses[0], + MakeBackendMetricData(/*app_utilization=*/0.9, /*qps=*/100.0, + /*eps=*/0.0)}, + {kEndpoint3Addresses[0], + MakeBackendMetricData(/*app_utilization=*/0.3, /*qps=*/100.0, + /*eps=*/0.0)}}, + {{kEndpoint1Addresses[1], 3}, + {kEndpoint2Addresses[0], 1}, + {kEndpoint3Addresses[0], 3}}); + // First endpoint first subchannel finishes backoff, but this doesn't + // affect anything -- in fact, PF isn't even watching this subchannel + // anymore, since it's connected to the other one. However, this + // ensures that the subchannel is in the right state when we try to + // reconnect below. + subchannel1_0->SetConnectivityState(GRPC_CHANNEL_IDLE); + EXPECT_FALSE(subchannel1_0->ConnectionRequested()); + // Endpoint 1 switches to a different address. + ExpectEndpointAddressChange( + kEndpoint1Addresses, 1, 0, + // When the subchannel disconnects, WRR will remove the endpoint from + // the rotation. + [&]() { + picker = ExpectState(GRPC_CHANNEL_READY); + WaitForWeightedRoundRobinPicks( + &picker, + {{kEndpoint2Addresses[0], + MakeBackendMetricData(/*app_utilization=*/0.9, /*qps=*/100.0, + /*eps=*/0.0)}, + {kEndpoint3Addresses[0], + MakeBackendMetricData(/*app_utilization=*/0.3, /*qps=*/100.0, + /*eps=*/0.0)}}, + {{kEndpoint2Addresses[0], 1}, {kEndpoint3Addresses[0], 3}}); + }); + // When it connects to the new address, WRR adds it to the rotation. + WaitForWeightedRoundRobinPicks( + &picker, + {{kEndpoint1Addresses[0], + MakeBackendMetricData(/*app_utilization=*/0.3, /*qps=*/100.0, + /*eps=*/0.0)}, + {kEndpoint2Addresses[0], + MakeBackendMetricData(/*app_utilization=*/0.9, /*qps=*/100.0, + /*eps=*/0.0)}, + {kEndpoint3Addresses[0], + MakeBackendMetricData(/*app_utilization=*/0.3, /*qps=*/100.0, + /*eps=*/0.0)}}, + {{kEndpoint1Addresses[0], 3}, + {kEndpoint2Addresses[0], 1}, + {kEndpoint3Addresses[0], 3}}); + // No more connection attempts triggered. + EXPECT_FALSE(subchannel1_0->ConnectionRequested()); + EXPECT_FALSE(subchannel1_1->ConnectionRequested()); + EXPECT_FALSE(subchannel2_0->ConnectionRequested()); + EXPECT_FALSE(subchannel2_1->ConnectionRequested()); + EXPECT_FALSE(subchannel3_0->ConnectionRequested()); + EXPECT_FALSE(subchannel3_1->ConnectionRequested()); +} + } // namespace } // namespace testing } // namespace grpc_core diff --git a/test/core/client_channel/lb_policy/xds_override_host_test.cc b/test/core/client_channel/lb_policy/xds_override_host_test.cc index e7c73794946f2..5deccfdb2c1f5 100644 --- a/test/core/client_channel/lb_policy/xds_override_host_test.cc +++ b/test/core/client_channel/lb_policy/xds_override_host_test.cc @@ -37,7 +37,7 @@ #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/json/json.h" #include "src/core/lib/load_balancing/lb_policy.h" -#include "src/core/lib/resolver/server_address.h" +#include "src/core/lib/resolver/endpoint_addresses.h" #include "test/core/client_channel/lb_policy/lb_policy_test_lib.h" #include "test/core/util/test_config.h" @@ -76,10 +76,11 @@ class XdsOverrideHostTest : public LoadBalancingPolicyTest { return ExpectRoundRobinStartup(addresses); } - ServerAddress MakeAddressWithHealthStatus( + EndpointAddresses MakeAddressWithHealthStatus( absl::string_view address, XdsHealthStatus::HealthStatus status) { - return ServerAddress(MakeAddress(address), - ChannelArgs().Set(GRPC_ARG_XDS_HEALTH_STATUS, status)); + return EndpointAddresses( + MakeAddress(address), + ChannelArgs().Set(GRPC_ARG_XDS_HEALTH_STATUS, status)); } void ApplyUpdateWithHealthStatuses( diff --git a/test/core/client_channel/resolvers/binder_resolver_test.cc b/test/core/client_channel/resolvers/binder_resolver_test.cc index 59b784893556b..66ad680886d20 100644 --- a/test/core/client_channel/resolvers/binder_resolver_test.cc +++ b/test/core/client_channel/resolvers/binder_resolver_test.cc @@ -26,9 +26,9 @@ #include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/iomgr/port.h" #include "src/core/lib/iomgr/resolved_address.h" +#include "src/core/lib/resolver/endpoint_addresses.h" #include "src/core/lib/resolver/resolver.h" #include "src/core/lib/resolver/resolver_factory.h" -#include "src/core/lib/resolver/server_address.h" #include "src/core/lib/uri/uri_parser.h" #include "test/core/util/test_config.h" @@ -97,7 +97,7 @@ class BinderResolverTest : public ::testing::Test { EXPECT_TRUE(expect_result_); ASSERT_TRUE(result.addresses.ok()); ASSERT_EQ(result.addresses->size(), 1); - grpc_core::ServerAddress addr = (*result.addresses)[0]; + grpc_core::EndpointAddresses addr = (*result.addresses)[0]; const struct sockaddr_un* un = reinterpret_cast(addr.address().addr); EXPECT_EQ(addr.address().len, 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 4d76c94221836..fc663837a8bf1 100644 --- a/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc @@ -56,10 +56,10 @@ #include "src/core/lib/iomgr/pollset_set.h" #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/iomgr/resolved_address.h" +#include "src/core/lib/resolver/endpoint_addresses.h" #include "src/core/lib/resolver/resolver.h" #include "src/core/lib/resolver/resolver_factory.h" #include "src/core/lib/resolver/resolver_registry.h" -#include "src/core/lib/resolver/server_address.h" #include "src/core/lib/uri/uri_parser.h" #include "test/core/util/test_config.h" @@ -72,7 +72,7 @@ static std::shared_ptr* g_work_serializer; static grpc_ares_request* (*g_default_dns_lookup_ares)( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - std::unique_ptr* addresses, + std::unique_ptr* addresses, int query_timeout_ms); // Counter incremented by TestDNSResolver::LookupHostname indicating the @@ -177,7 +177,7 @@ class TestDNSResolver : public grpc_core::DNSResolver { static grpc_ares_request* test_dns_lookup_ares( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* /*interested_parties*/, grpc_closure* on_done, - std::unique_ptr* addresses, + std::unique_ptr* addresses, int query_timeout_ms) { // A records should suffice grpc_ares_request* result = g_default_dns_lookup_ares( diff --git a/test/core/client_channel/resolvers/fake_resolver_test.cc b/test/core/client_channel/resolvers/fake_resolver_test.cc index 91926eb810de1..f6ac7c32bed7b 100644 --- a/test/core/client_channel/resolvers/fake_resolver_test.cc +++ b/test/core/client_channel/resolvers/fake_resolver_test.cc @@ -49,9 +49,9 @@ #include "src/core/lib/gprpp/work_serializer.h" #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/iomgr/resolved_address.h" +#include "src/core/lib/resolver/endpoint_addresses.h" #include "src/core/lib/resolver/resolver_factory.h" #include "src/core/lib/resolver/resolver_registry.h" -#include "src/core/lib/resolver/server_address.h" #include "src/core/lib/uri/uri_parser.h" #include "test/core/util/test_config.h" @@ -111,7 +111,7 @@ static grpc_core::Resolver::Result create_new_resolver_result() { static size_t test_counter = 0; const size_t num_addresses = 2; // Create address list. - grpc_core::ServerAddressList addresses; + grpc_core::EndpointAddressesList addresses; for (size_t i = 0; i < num_addresses; ++i) { std::string uri_string = absl::StrFormat("ipv4:127.0.0.1:100%" PRIuPTR, test_counter * num_addresses + i); diff --git a/test/core/end2end/BUILD b/test/core/end2end/BUILD index 62d28a5065af6..c57881e37fd79 100644 --- a/test/core/end2end/BUILD +++ b/test/core/end2end/BUILD @@ -520,12 +520,12 @@ grpc_cc_test( "cq_verifier", "//:channel_arg_names", "//:debug_location", + "//:endpoint_addresses", "//:exec_ctx", "//:gpr", "//:grpc", "//:grpc_public_hdrs", "//:grpc_resolver_dns_ares", - "//:server_address", "//src/core:channel_args", "//src/core:closure", "//src/core:default_event_engine", diff --git a/test/core/end2end/fuzzers/api_fuzzer.cc b/test/core/end2end/fuzzers/api_fuzzer.cc index 9cc71a3a9c02d..fcad60d6fd982 100644 --- a/test/core/end2end/fuzzers/api_fuzzer.cc +++ b/test/core/end2end/fuzzers/api_fuzzer.cc @@ -61,7 +61,7 @@ #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/iomgr/resolved_address.h" #include "src/core/lib/iomgr/timer_manager.h" -#include "src/core/lib/resolver/server_address.h" +#include "src/core/lib/resolver/endpoint_addresses.h" #include "src/core/lib/resource_quota/memory_quota.h" #include "src/core/lib/resource_quota/resource_quota.h" #include "src/core/lib/slice/slice_internal.h" @@ -91,12 +91,12 @@ static void dont_log(gpr_log_func_args* /*args*/) {} typedef struct addr_req { char* addr; grpc_closure* on_done; - std::unique_ptr* addresses; + std::unique_ptr* addresses; } addr_req; static void finish_resolve(addr_req r) { if (0 == strcmp(r.addr, "server")) { - *r.addresses = std::make_unique(); + *r.addresses = std::make_unique(); grpc_resolved_address fake_resolved_address; GPR_ASSERT( grpc_parse_ipv4_hostport("1.2.3.4:5", &fake_resolved_address, false)); @@ -213,7 +213,7 @@ class FuzzerDNSResolver : public grpc_core::DNSResolver { grpc_ares_request* my_dns_lookup_ares( const char* /*dns_server*/, const char* addr, const char* /*default_port*/, grpc_pollset_set* /*interested_parties*/, grpc_closure* on_done, - std::unique_ptr* addresses, + std::unique_ptr* addresses, int /*query_timeout*/) { addr_req r; r.addr = gpr_strdup(addr); diff --git a/test/core/end2end/goaway_server_test.cc b/test/core/end2end/goaway_server_test.cc index ed64801cdb794..46f578428144d 100644 --- a/test/core/end2end/goaway_server_test.cc +++ b/test/core/end2end/goaway_server_test.cc @@ -56,7 +56,7 @@ #include "src/core/lib/iomgr/resolved_address.h" #include "src/core/lib/iomgr/sockaddr.h" #include "src/core/lib/iomgr/socket_utils.h" -#include "src/core/lib/resolver/server_address.h" +#include "src/core/lib/resolver/endpoint_addresses.h" #include "test/core/end2end/cq_verifier.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" @@ -67,7 +67,7 @@ static int g_resolve_port = -1; static grpc_ares_request* (*iomgr_dns_lookup_ares)( const char* dns_server, const char* addr, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - std::unique_ptr* addresses, + std::unique_ptr* addresses, int query_timeout_ms); static void (*iomgr_cancel_ares_request)(grpc_ares_request* request); @@ -170,7 +170,7 @@ class TestDNSResolver : public grpc_core::DNSResolver { static grpc_ares_request* my_dns_lookup_ares( const char* dns_server, const char* addr, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - std::unique_ptr* addresses, + std::unique_ptr* addresses, int query_timeout_ms) { if (0 != strcmp(addr, "test")) { // A records should suffice @@ -185,7 +185,7 @@ static grpc_ares_request* my_dns_lookup_ares( gpr_mu_unlock(&g_mu); error = GRPC_ERROR_CREATE("Forced Failure"); } else { - *addresses = std::make_unique(); + *addresses = std::make_unique(); grpc_resolved_address address; memset(&address, 0, sizeof(address)); auto* sa = reinterpret_cast(&address.addr); diff --git a/test/core/iomgr/stranded_event_test.cc b/test/core/iomgr/stranded_event_test.cc index 0991c98b7fe06..518127c7805ad 100644 --- a/test/core/iomgr/stranded_event_test.cc +++ b/test/core/iomgr/stranded_event_test.cc @@ -297,7 +297,7 @@ class TestServer { grpc_core::Resolver::Result BuildResolverResponse( const std::vector& addresses) { grpc_core::Resolver::Result result; - result.addresses = grpc_core::ServerAddressList(); + result.addresses = grpc_core::EndpointAddressesList(); for (const auto& address_str : addresses) { absl::StatusOr uri = grpc_core::URI::Parse(address_str); if (!uri.ok()) { diff --git a/test/core/transport/chttp2/too_many_pings_test.cc b/test/core/transport/chttp2/too_many_pings_test.cc index 192472c9b2853..3e4bf36c2c2e3 100644 --- a/test/core/transport/chttp2/too_many_pings_test.cc +++ b/test/core/transport/chttp2/too_many_pings_test.cc @@ -53,8 +53,8 @@ #include "src/core/lib/gprpp/time.h" #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/iomgr/resolved_address.h" +#include "src/core/lib/resolver/endpoint_addresses.h" #include "src/core/lib/resolver/resolver.h" -#include "src/core/lib/resolver/server_address.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/uri/uri_parser.h" #include "test/core/end2end/cq_verifier.h" @@ -434,7 +434,7 @@ TEST_F(KeepaliveThrottlingTest, KeepaliveThrottlingMultipleChannels) { grpc_core::Resolver::Result BuildResolverResult( const std::vector& addresses) { grpc_core::Resolver::Result result; - result.addresses = grpc_core::ServerAddressList(); + result.addresses = grpc_core::EndpointAddressesList(); for (const auto& address_str : addresses) { absl::StatusOr uri = grpc_core::URI::Parse(address_str); if (!uri.ok()) { diff --git a/test/core/util/BUILD b/test/core/util/BUILD index e520da58a06a1..633cc51bbc1e1 100644 --- a/test/core/util/BUILD +++ b/test/core/util/BUILD @@ -299,13 +299,13 @@ grpc_cc_library( ], deps = [ "//:config", + "//:endpoint_addresses", "//:gpr", "//:grpc", "//:grpc_client_channel", "//:orphanable", "//:parse_address", "//:ref_counted_ptr", - "//:server_address", "//:uri_parser", "//src/core:channel_args", "//src/core:delegating_helper", diff --git a/test/core/util/test_lb_policies.cc b/test/core/util/test_lb_policies.cc index 543cd4f5ddc5f..9693850539751 100644 --- a/test/core/util/test_lb_policies.cc +++ b/test/core/util/test_lb_policies.cc @@ -340,9 +340,10 @@ class AddressTestLoadBalancingPolicy : public ForwardingLoadBalancingPolicy { cb_(std::move(cb)) {} RefCountedPtr CreateSubchannel( - ServerAddress address, const ChannelArgs& args) override { - cb_(address); - return parent_helper()->CreateSubchannel(std::move(address), args); + const grpc_resolved_address& address, + const ChannelArgs& per_address_args, const ChannelArgs& args) override { + cb_(EndpointAddresses(address, per_address_args)); + return parent_helper()->CreateSubchannel(address, per_address_args, args); } private: @@ -414,7 +415,7 @@ class FixedAddressLoadBalancingPolicy : public ForwardingLoadBalancingPolicy { config->address().c_str()); auto uri = URI::Parse(config->address()); args.config.reset(); - args.addresses = ServerAddressList(); + args.addresses = EndpointAddressesList(); if (uri.ok()) { grpc_resolved_address address; GPR_ASSERT(grpc_parse_uri(*uri, &address)); @@ -496,7 +497,7 @@ class OobBackendMetricTestLoadBalancingPolicy class BackendMetricWatcher : public OobBackendMetricWatcher { public: BackendMetricWatcher( - ServerAddress address, + EndpointAddresses address, RefCountedPtr parent) : address_(std::move(address)), parent_(std::move(parent)) {} @@ -506,7 +507,7 @@ class OobBackendMetricTestLoadBalancingPolicy } private: - ServerAddress address_; + EndpointAddresses address_; RefCountedPtr parent_; }; @@ -518,11 +519,14 @@ class OobBackendMetricTestLoadBalancingPolicy : ParentOwningDelegatingChannelControlHelper(std::move(parent)) {} RefCountedPtr CreateSubchannel( - ServerAddress address, const ChannelArgs& args) override { - auto subchannel = parent_helper()->CreateSubchannel(address, args); + const grpc_resolved_address& address, + const ChannelArgs& per_address_args, const ChannelArgs& args) override { + auto subchannel = + parent_helper()->CreateSubchannel(address, per_address_args, args); subchannel->AddDataWatcher(MakeOobBackendMetricWatcher( - Duration::Seconds(1), std::make_unique( - std::move(address), parent()->Ref()))); + Duration::Seconds(1), + std::make_unique( + EndpointAddresses(address, per_address_args), parent()->Ref()))); return subchannel; } }; diff --git a/test/core/util/test_lb_policies.h b/test/core/util/test_lb_policies.h index 9298b946992c6..90e6256b89c88 100644 --- a/test/core/util/test_lb_policies.h +++ b/test/core/util/test_lb_policies.h @@ -30,7 +30,7 @@ #include "src/core/ext/filters/client_channel/lb_policy/backend_metric_data.h" #include "src/core/lib/config/core_configuration.h" -#include "src/core/lib/resolver/server_address.h" +#include "src/core/lib/resolver/endpoint_addresses.h" namespace grpc_core { @@ -64,7 +64,7 @@ void RegisterInterceptRecvTrailingMetadataLoadBalancingPolicy( CoreConfiguration::Builder* builder, InterceptRecvTrailingMetadataCallback cb); -using AddressTestCallback = std::function; +using AddressTestCallback = std::function; // Registers an LB policy called "address_test_lb" that invokes cb for each // address used to create a subchannel. @@ -77,7 +77,7 @@ void RegisterFixedAddressLoadBalancingPolicy( CoreConfiguration::Builder* builder); using OobBackendMetricCallback = - std::function; + std::function; // Registers an LB policy called "oob_backend_metric_test_lb" that invokes // cb for each OOB backend metric report on each subchannel. diff --git a/test/core/xds/xds_endpoint_resource_type_test.cc b/test/core/xds/xds_endpoint_resource_type_test.cc index baafc2dda296d..259745fe3eed2 100644 --- a/test/core/xds/xds_endpoint_resource_type_test.cc +++ b/test/core/xds/xds_endpoint_resource_type_test.cc @@ -48,7 +48,7 @@ #include "src/core/lib/gprpp/crash.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/error.h" -#include "src/core/lib/resolver/server_address.h" +#include "src/core/lib/resolver/endpoint_addresses.h" #include "src/proto/grpc/testing/xds/v3/address.pb.h" #include "src/proto/grpc/testing/xds/v3/base.pb.h" #include "src/proto/grpc/testing/xds/v3/endpoint.pb.h" diff --git a/test/cpp/client/destroy_grpclb_channel_with_active_connect_stress_test.cc b/test/cpp/client/destroy_grpclb_channel_with_active_connect_stress_test.cc index 7d1c1aeaa50e5..28f7a8a79a35e 100644 --- a/test/cpp/client/destroy_grpclb_channel_with_active_connect_stress_test.cc +++ b/test/cpp/client/destroy_grpclb_channel_with_active_connect_stress_test.cc @@ -45,7 +45,7 @@ #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/sockaddr.h" -#include "src/core/lib/resolver/server_address.h" +#include "src/core/lib/resolver/endpoint_addresses.h" #include "src/core/lib/service_config/service_config_impl.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" @@ -67,7 +67,7 @@ void TryConnectAndDestroy() { ASSERT_TRUE(lb_uri.ok()); grpc_resolved_address address; ASSERT_TRUE(grpc_parse_uri(*lb_uri, &address)); - grpc_core::ServerAddressList addresses; + grpc_core::EndpointAddressesList addresses; addresses.emplace_back(address, grpc_core::ChannelArgs()); grpc_core::Resolver::Result lb_address_result; lb_address_result.service_config = grpc_core::ServiceConfigImpl::Create( diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index cee7f1c81ff6a..74bf67141d420 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -65,7 +65,7 @@ #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/gprpp/time.h" #include "src/core/lib/iomgr/tcp_client.h" -#include "src/core/lib/resolver/server_address.h" +#include "src/core/lib/resolver/endpoint_addresses.h" #include "src/core/lib/security/credentials/fake/fake_credentials.h" #include "src/core/lib/service_config/service_config.h" #include "src/core/lib/service_config/service_config_impl.h" @@ -251,7 +251,7 @@ class FakeResolverResponseGeneratorWrapper { const grpc_core::ChannelArgs& per_address_args = grpc_core::ChannelArgs()) { grpc_core::Resolver::Result result; - result.addresses = grpc_core::ServerAddressList(); + result.addresses = grpc_core::EndpointAddressesList(); for (const int& port : ports) { absl::StatusOr lb_uri = grpc_core::URI::Parse( absl::StrCat(ipv6_only ? "ipv6:[::1]:" : "ipv4:127.0.0.1:", port)); @@ -977,79 +977,6 @@ TEST_F(ClientLbEnd2endTest, EXPECT_LT(waited.millis(), 1000 * grpc_test_slowdown_factor()); } -TEST_F( - PickFirstTest, - TriesAllSubchannelsBeforeReportingTransientFailureWithSubchannelSharing) { - // Start connection injector. - ConnectionAttemptInjector injector; - // Get 5 unused ports. Each channel will have 2 unique ports followed - // by a common port. - std::vector ports1 = {grpc_pick_unused_port_or_die(), - grpc_pick_unused_port_or_die(), - grpc_pick_unused_port_or_die()}; - std::vector ports2 = {grpc_pick_unused_port_or_die(), - grpc_pick_unused_port_or_die(), ports1[2]}; - // Create channel 1. - auto response_generator1 = BuildResolverResponseGenerator(); - auto channel1 = BuildChannel("pick_first", response_generator1); - auto stub1 = BuildStub(channel1); - response_generator1.SetNextResolution(ports1); - // Allow the connection attempts for ports 0 and 1 to fail normally. - // Inject a hold for the connection attempt to port 2. - auto hold_channel1_port2 = injector.AddHold(ports1[2]); - // Trigger connection attempt. - gpr_log(GPR_INFO, "=== START CONNECTING CHANNEL 1 ==="); - channel1->GetState(/*try_to_connect=*/true); - // Wait for connection attempt to port 2. - gpr_log(GPR_INFO, "=== WAITING FOR CHANNEL 1 PORT 2 TO START ==="); - hold_channel1_port2->Wait(); - gpr_log(GPR_INFO, "=== CHANNEL 1 PORT 2 STARTED ==="); - // Now create channel 2. - auto response_generator2 = BuildResolverResponseGenerator(); - auto channel2 = BuildChannel("pick_first", response_generator2); - response_generator2.SetNextResolution(ports2); - // Inject a hold for port 0. - auto hold_channel2_port0 = injector.AddHold(ports2[0]); - // Trigger connection attempt. - gpr_log(GPR_INFO, "=== START CONNECTING CHANNEL 2 ==="); - channel2->GetState(/*try_to_connect=*/true); - // Wait for connection attempt to port 0. - gpr_log(GPR_INFO, "=== WAITING FOR CHANNEL 2 PORT 0 TO START ==="); - hold_channel2_port0->Wait(); - gpr_log(GPR_INFO, "=== CHANNEL 2 PORT 0 STARTED ==="); - // Inject a hold for port 0, which will be retried by channel 1. - auto hold_channel1_port0 = injector.AddHold(ports1[0]); - // Now allow the connection attempt to port 2 to complete. The subchannel - // will deliver a TRANSIENT_FAILURE notification to both channels. - gpr_log(GPR_INFO, "=== RESUMING CHANNEL 1 PORT 2 ==="); - hold_channel1_port2->Resume(); - // Wait for channel 1 to retry port 0, so that we know it's seen the - // connectivity state notification for port 2. - gpr_log(GPR_INFO, "=== WAITING FOR CHANNEL 1 PORT 0 ==="); - hold_channel1_port0->Wait(); - gpr_log(GPR_INFO, "=== CHANNEL 1 PORT 0 STARTED ==="); - // Channel 1 should now report TRANSIENT_FAILURE. - // Channel 2 should continue to report CONNECTING. - EXPECT_EQ(GRPC_CHANNEL_TRANSIENT_FAILURE, channel1->GetState(false)); - EXPECT_EQ(GRPC_CHANNEL_CONNECTING, channel2->GetState(false)); - // Allow channel 2 to resume port 0. Port 0 will fail, as will port 1. - // When it gets to port 2, it will see it already in state - // TRANSIENT_FAILURE due to being shared with channel 1, so it won't - // trigger another connection attempt. - gpr_log(GPR_INFO, "=== RESUMING CHANNEL 2 PORT 0 ==="); - hold_channel2_port0->Resume(); - // Channel 2 should soon report TRANSIENT_FAILURE. - EXPECT_TRUE( - WaitForChannelState(channel2.get(), [](grpc_connectivity_state state) { - if (state == GRPC_CHANNEL_TRANSIENT_FAILURE) return true; - EXPECT_EQ(state, GRPC_CHANNEL_CONNECTING); - return false; - })); - // Clean up. - gpr_log(GPR_INFO, "=== RESUMING CHANNEL 1 PORT 0 ==="); - hold_channel1_port0->Resume(); -} - TEST_F(PickFirstTest, Updates) { // Start servers and send one RPC per server. const int kNumServers = 3; @@ -1823,7 +1750,7 @@ TEST_F(RoundRobinTest, StaysInTransientFailureInSubsequentConnecting) { TEST_F(RoundRobinTest, ReportsLatestStatusInTransientFailure) { // Start connection injector. ConnectionAttemptInjector injector; - // Get port. + // Get ports. const std::vector ports = {grpc_pick_unused_port_or_die(), grpc_pick_unused_port_or_die()}; // Create channel. @@ -1842,7 +1769,6 @@ TEST_F(RoundRobinTest, ReportsLatestStatusInTransientFailure) { hold1->Wait(); hold2->Wait(); // Inject a custom failure message. - hold1->Wait(); hold1->Fail(GRPC_ERROR_CREATE("Survey says... Bzzzzt!")); // Wait until RPC fails with the right message. absl::Time deadline = @@ -1856,6 +1782,7 @@ TEST_F(RoundRobinTest, ReportsLatestStatusInTransientFailure) { "Survey says... Bzzzzt!"))(status.error_message())) { break; } + gpr_log(GPR_INFO, "STATUS MESSAGE: %s", status.error_message().c_str()); EXPECT_THAT(status.error_message(), ::testing::MatchesRegex(MakeConnectionFailureRegex( "connections to all backends failing"))); @@ -2865,7 +2792,7 @@ class ClientLbAddressTest : public ClientLbEnd2endTest { } private: - static void SaveAddress(const grpc_core::ServerAddress& address) { + static void SaveAddress(const grpc_core::EndpointAddresses& address) { ClientLbAddressTest* self = current_test_instance_; grpc_core::MutexLock lock(&self->mu_); self->addresses_seen_.emplace_back(address.ToString()); @@ -2894,8 +2821,9 @@ TEST_F(ClientLbAddressTest, Basic) { // Make sure that the attributes wind up on the subchannels. std::vector expected; for (const int port : GetServersPorts()) { - expected.emplace_back(absl::StrCat(ipv6_only_ ? "[::1]:" : "127.0.0.1:", - port, " args={test_key=test_value}")); + expected.emplace_back( + absl::StrCat("addrs=[", ipv6_only_ ? "[::1]:" : "127.0.0.1:", port, + "] args={test_key=test_value}")); } EXPECT_EQ(addresses_seen(), expected); } @@ -2938,7 +2866,7 @@ class OobBackendMetricTest : public ClientLbEnd2endTest { private: static void BackendMetricCallback( - const grpc_core::ServerAddress& address, + const grpc_core::EndpointAddresses& address, const grpc_core::BackendMetricData& backend_metric_data) { auto load_report = BackendMetricDataToOrcaLoadReport(backend_metric_data); int port = grpc_sockaddr_get_port(&address.address()); diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc index ccb2899d6c981..2ae68a5514c44 100644 --- a/test/cpp/end2end/grpclb_end2end_test.cc +++ b/test/cpp/end2end/grpclb_end2end_test.cc @@ -51,7 +51,7 @@ #include "src/core/lib/gprpp/env.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/sockaddr.h" -#include "src/core/lib/resolver/server_address.h" +#include "src/core/lib/resolver/endpoint_addresses.h" #include "src/core/lib/security/credentials/fake/fake_credentials.h" #include "src/core/lib/service_config/service_config_impl.h" #include "src/cpp/client/secure_credentials.h" @@ -555,9 +555,9 @@ class GrpclbEnd2endTest : public ::testing::Test { std::string balancer_name; }; - grpc_core::ServerAddressList CreateLbAddressesFromAddressDataList( + grpc_core::EndpointAddressesList CreateLbAddressesFromAddressDataList( const std::vector& address_data) { - grpc_core::ServerAddressList addresses; + grpc_core::EndpointAddressesList addresses; for (const auto& addr : address_data) { absl::StatusOr lb_uri = grpc_core::URI::Parse(absl::StrCat( @@ -582,7 +582,7 @@ class GrpclbEnd2endTest : public ::testing::Test { result.service_config = grpc_core::ServiceConfigImpl::Create( grpc_core::ChannelArgs(), service_config_json); GPR_ASSERT(result.service_config.ok()); - grpc_core::ServerAddressList balancer_addresses = + grpc_core::EndpointAddressesList balancer_addresses = CreateLbAddressesFromAddressDataList(balancer_address_data); result.args = grpc_core::SetGrpcLbBalancerAddresses( grpc_core::ChannelArgs(), std::move(balancer_addresses)); diff --git a/test/cpp/end2end/service_config_end2end_test.cc b/test/cpp/end2end/service_config_end2end_test.cc index 6420080c2462f..bb60f6fe66da4 100644 --- a/test/cpp/end2end/service_config_end2end_test.cc +++ b/test/cpp/end2end/service_config_end2end_test.cc @@ -55,7 +55,7 @@ #include "src/core/lib/gprpp/debug_location.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/tcp_client.h" -#include "src/core/lib/resolver/server_address.h" +#include "src/core/lib/resolver/endpoint_addresses.h" #include "src/core/lib/security/credentials/fake/fake_credentials.h" #include "src/core/lib/service_config/service_config_impl.h" #include "src/core/lib/transport/error_utils.h" @@ -176,7 +176,7 @@ class ServiceConfigEnd2endTest : public ::testing::Test { grpc_core::Resolver::Result BuildFakeResults(const std::vector& ports) { grpc_core::Resolver::Result result; - result.addresses = grpc_core::ServerAddressList(); + result.addresses = grpc_core::EndpointAddressesList(); for (const int& port : ports) { std::string lb_uri_str = absl::StrCat(ipv6_only_ ? "ipv6:[::1]:" : "ipv4:127.0.0.1:", port); diff --git a/test/cpp/end2end/xds/xds_cluster_type_end2end_test.cc b/test/cpp/end2end/xds/xds_cluster_type_end2end_test.cc index 259b37fd4763f..df8cb01265246 100644 --- a/test/cpp/end2end/xds/xds_cluster_type_end2end_test.cc +++ b/test/cpp/end2end/xds/xds_cluster_type_end2end_test.cc @@ -29,7 +29,7 @@ #include "src/core/lib/address_utils/sockaddr_utils.h" #include "src/core/lib/config/config_vars.h" #include "src/core/lib/gprpp/env.h" -#include "src/core/lib/resolver/server_address.h" +#include "src/core/lib/resolver/endpoint_addresses.h" #include "src/proto/grpc/testing/xds/v3/aggregate_cluster.grpc.pb.h" #include "test/cpp/end2end/connection_attempt_injector.h" #include "test/cpp/end2end/xds/xds_end2end_test_lib.h" @@ -55,9 +55,9 @@ class ClusterTypeTest : public XdsEnd2endTest { ResetStub(/*failover_timeout_ms=*/0, &args); } - grpc_core::ServerAddressList CreateAddressListFromPortList( + grpc_core::EndpointAddressesList CreateAddressListFromPortList( const std::vector& ports) { - grpc_core::ServerAddressList addresses; + grpc_core::EndpointAddressesList addresses; for (int port : ports) { absl::StatusOr lb_uri = grpc_core::URI::Parse( absl::StrCat(ipv6_only_ ? "ipv6:[::1]:" : "ipv4:127.0.0.1:", port)); diff --git a/test/cpp/end2end/xds/xds_end2end_test.cc b/test/cpp/end2end/xds/xds_end2end_test.cc index 660b5e14e0ee9..9a79801978a95 100644 --- a/test/cpp/end2end/xds/xds_end2end_test.cc +++ b/test/cpp/end2end/xds/xds_end2end_test.cc @@ -82,7 +82,7 @@ #include "src/core/lib/gprpp/time_util.h" #include "src/core/lib/iomgr/load_file.h" #include "src/core/lib/iomgr/sockaddr.h" -#include "src/core/lib/resolver/server_address.h" +#include "src/core/lib/resolver/endpoint_addresses.h" #include "src/core/lib/security/authorization/audit_logging.h" #include "src/core/lib/security/certificate_provider/certificate_provider_registry.h" #include "src/core/lib/security/credentials/fake/fake_credentials.h" diff --git a/test/cpp/end2end/xds/xds_ring_hash_end2end_test.cc b/test/cpp/end2end/xds/xds_ring_hash_end2end_test.cc index d6de6167e8b0e..fc16f95a30f42 100644 --- a/test/cpp/end2end/xds/xds_ring_hash_end2end_test.cc +++ b/test/cpp/end2end/xds/xds_ring_hash_end2end_test.cc @@ -62,9 +62,9 @@ class RingHashTest : public XdsEnd2endTest { ResetStub(/*failover_timeout_ms=*/0, args); } - grpc_core::ServerAddressList CreateAddressListFromPortList( + grpc_core::EndpointAddressesList CreateAddressListFromPortList( const std::vector& ports) { - grpc_core::ServerAddressList addresses; + grpc_core::EndpointAddressesList addresses; for (int port : ports) { absl::StatusOr lb_uri = grpc_core::URI::Parse( absl::StrCat(ipv6_only_ ? "ipv6:[::1]:" : "ipv4:127.0.0.1:", port)); diff --git a/test/cpp/interop/backend_metrics_lb_policy.cc b/test/cpp/interop/backend_metrics_lb_policy.cc index 82e088fe05102..a10bd4f63a5fe 100644 --- a/test/cpp/interop/backend_metrics_lb_policy.cc +++ b/test/cpp/interop/backend_metrics_lb_policy.cc @@ -139,10 +139,11 @@ class BackendMetricsLbPolicy : public LoadBalancingPolicy { : ParentOwningDelegatingChannelControlHelper(std::move(parent)) {} RefCountedPtr CreateSubchannel( - grpc_core::ServerAddress address, + const grpc_resolved_address& address, + const grpc_core::ChannelArgs& per_address_args, const grpc_core::ChannelArgs& args) override { auto subchannel = - parent_helper()->CreateSubchannel(std::move(address), args); + parent_helper()->CreateSubchannel(address, per_address_args, args); subchannel->AddDataWatcher(MakeOobBackendMetricWatcher( grpc_core::Duration::Seconds(1), std::make_unique(parent()->load_report_tracker_))); diff --git a/test/cpp/naming/address_sorting_test.cc b/test/cpp/naming/address_sorting_test.cc index f0f2c5815442b..5dedf8c0835fe 100644 --- a/test/cpp/naming/address_sorting_test.cc +++ b/test/cpp/naming/address_sorting_test.cc @@ -43,9 +43,9 @@ #include "src/core/lib/iomgr/executor.h" #include "src/core/lib/iomgr/iomgr.h" #include "src/core/lib/iomgr/resolve_address.h" +#include "src/core/lib/resolver/endpoint_addresses.h" #include "src/core/lib/resolver/resolver.h" #include "src/core/lib/resolver/resolver_registry.h" -#include "src/core/lib/resolver/server_address.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" #include "test/cpp/util/subprocess.h" @@ -168,9 +168,9 @@ void OverrideAddressSortingSourceAddrFactory( address_sorting_override_source_addr_factory_for_testing(factory); } -grpc_core::ServerAddressList BuildLbAddrInputs( +grpc_core::EndpointAddressesList BuildLbAddrInputs( const std::vector& test_addrs) { - grpc_core::ServerAddressList addresses; + grpc_core::EndpointAddressesList addresses; for (const auto& addr : test_addrs) { addresses.emplace_back(TestAddressToGrpcResolvedAddress(addr), grpc_core::ChannelArgs()); @@ -178,7 +178,7 @@ grpc_core::ServerAddressList BuildLbAddrInputs( return addresses; } -void VerifyLbAddrOutputs(const grpc_core::ServerAddressList& addresses, +void VerifyLbAddrOutputs(const grpc_core::EndpointAddressesList& addresses, std::vector expected_addrs) { EXPECT_EQ(addresses.size(), expected_addrs.size()); for (size_t i = 0; i < addresses.size(); ++i) { diff --git a/test/cpp/naming/resolver_component_test.cc b/test/cpp/naming/resolver_component_test.cc index 10dc8b0b60b54..96dcfedf03920 100644 --- a/test/cpp/naming/resolver_component_test.cc +++ b/test/cpp/naming/resolver_component_test.cc @@ -59,9 +59,9 @@ #include "src/core/lib/iomgr/iomgr.h" #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/iomgr/socket_utils.h" +#include "src/core/lib/resolver/endpoint_addresses.h" #include "src/core/lib/resolver/resolver.h" #include "src/core/lib/resolver/resolver_registry.h" -#include "src/core/lib/resolver/server_address.h" #include "test/core/util/fake_udp_and_tcp_server.h" #include "test/core/util/port.h" #include "test/core/util/socket_use_after_close_detector.h" @@ -336,7 +336,7 @@ class CheckingResultHandler : public ResultHandler { std::vector found_lb_addrs; AddActualAddresses(*result.addresses, /*is_balancer=*/false, &found_lb_addrs); - const grpc_core::ServerAddressList* balancer_addresses = + const grpc_core::EndpointAddressesList* balancer_addresses = grpc_core::FindGrpclbBalancerAddressesInChannelArgs(result.args); if (balancer_addresses != nullptr) { AddActualAddresses(*balancer_addresses, /*is_balancer=*/true, @@ -381,11 +381,11 @@ class CheckingResultHandler : public ResultHandler { } private: - static void AddActualAddresses(const grpc_core::ServerAddressList& addresses, - bool is_balancer, - std::vector* out) { + static void AddActualAddresses( + const grpc_core::EndpointAddressesList& addresses, bool is_balancer, + std::vector* out) { for (size_t i = 0; i < addresses.size(); i++) { - const grpc_core::ServerAddress& addr = addresses[i]; + const grpc_core::EndpointAddresses& addr = addresses[i]; std::string str = grpc_sockaddr_to_string(&addr.address(), true /* normalize */) .value(); diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index df4ba2589221c..4b83506ae7187 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -2478,12 +2478,13 @@ src/core/lib/promise/sleep.h \ src/core/lib/promise/trace.cc \ src/core/lib/promise/trace.h \ src/core/lib/promise/try_seq.h \ +src/core/lib/resolver/endpoint_addresses.cc \ +src/core/lib/resolver/endpoint_addresses.h \ src/core/lib/resolver/resolver.cc \ src/core/lib/resolver/resolver.h \ src/core/lib/resolver/resolver_factory.h \ src/core/lib/resolver/resolver_registry.cc \ src/core/lib/resolver/resolver_registry.h \ -src/core/lib/resolver/server_address.cc \ src/core/lib/resolver/server_address.h \ src/core/lib/resource_quota/api.cc \ src/core/lib/resource_quota/api.h \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 7e9c9247f9e54..4a3f0c9ac1cc1 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -2258,12 +2258,13 @@ src/core/lib/promise/sleep.h \ src/core/lib/promise/trace.cc \ src/core/lib/promise/trace.h \ src/core/lib/promise/try_seq.h \ +src/core/lib/resolver/endpoint_addresses.cc \ +src/core/lib/resolver/endpoint_addresses.h \ src/core/lib/resolver/resolver.cc \ src/core/lib/resolver/resolver.h \ src/core/lib/resolver/resolver_factory.h \ src/core/lib/resolver/resolver_registry.cc \ src/core/lib/resolver/resolver_registry.h \ -src/core/lib/resolver/server_address.cc \ src/core/lib/resolver/server_address.h \ src/core/lib/resource_quota/api.cc \ src/core/lib/resource_quota/api.h \