[resolver and LB policy APIs] change address list to support multiple addresses per endpoint (#33567)

More changes as part of the dualstack design:
- Change resolver and LB policy APIs to support multiple addresses per
endpoint. Specifically, replace `ServerAddress` with
`EndpointAddresses`, which encodes more than one address. Per-address
channel args are retained at the same level, so they are now
per-endpoint. For now, `EndpointAddress` provides a single-address ctor
and a single-address accessor for backward compatibility, so
`ServerAdress` is an alias for `EndpointAddresses`; eventually, this
alias and the single-address methods will be removed.
- Add an `EndpointAddressSet` class, which represents an unordered set
of addresses to be used as a map key. This will be used in a number of
LB policies that need to store per-endpoint state.
- Change the LB policy API's `ChannelControlHelper::CreateSubchannel()`
method to take the address and per-endpoint channel args as separate
parameters, so that we don't need to construct a legacy `ServerAddress`
object as we create a new subchannel for each address in the endpoint.
- Change pick_first to flatten the address list.
- Change ring_hash to use `EndpointAddressSet` as the key for its
endpoint map, and to use the first address of the endpoint as the hash
key.
- Change WRR to use `EndpointAddressSet` as the key for its endpoint
weight map.

Note that support for multiple addresses per endpoint is guarded in RR
by the existing `round_robin_delegate_to_pick_fist` experiment and in
WRR by the existing `wrr_delegate_to_pick_first` experiment.

This PR does *not* include support for multiple addresses per endpoint
for the outlier_detection or xds_override_host LB policies; those will
come in subsequent PRs.
pull/34527/head
Mark D. Roth 1 year ago committed by GitHub
parent d68161a64f
commit fd2e8c9462
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 30
      BUILD
  2. 8
      CMakeLists.txt
  3. 4
      Makefile
  4. 3
      Package.swift
  5. 14
      build_autogenerated.yaml
  6. 2
      config.m4
  7. 2
      config.w32
  8. 2
      gRPC-C++.podspec
  9. 4
      gRPC-Core.podspec
  10. 3
      grpc.gemspec
  11. 6
      grpc.gyp
  12. 3
      package.xml
  13. 53
      src/core/BUILD
  14. 10
      src/core/ext/filters/client_channel/client_channel.cc
  15. 13
      src/core/ext/filters/client_channel/lb_policy/address_filtering.cc
  16. 10
      src/core/ext/filters/client_channel/lb_policy/address_filtering.h
  17. 7
      src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc
  18. 27
      src/core/ext/filters/client_channel/lb_policy/endpoint_list.cc
  19. 25
      src/core/ext/filters/client_channel/lb_policy/endpoint_list.h
  20. 51
      src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc
  21. 36
      src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc
  22. 8
      src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.h
  23. 28
      src/core/ext/filters/client_channel/lb_policy/outlier_detection/outlier_detection.cc
  24. 25
      src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
  25. 2
      src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.h
  26. 2
      src/core/ext/filters/client_channel/lb_policy/priority/priority.cc
  27. 114
      src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.cc
  28. 6
      src/core/ext/filters/client_channel/lb_policy/rls/rls.cc
  29. 22
      src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc
  30. 2
      src/core/ext/filters/client_channel/lb_policy/subchannel_list.h
  31. 105
      src/core/ext/filters/client_channel/lb_policy/weighted_round_robin/weighted_round_robin.cc
  32. 8
      src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc
  33. 2
      src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_args.h
  34. 23
      src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc
  35. 6
      src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc
  36. 10
      src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc
  37. 63
      src/core/ext/filters/client_channel/lb_policy/xds/xds_override_host.cc
  38. 2
      src/core/ext/filters/client_channel/lb_policy/xds/xds_wrr_locality.cc
  39. 10
      src/core/ext/filters/client_channel/resolver/binder/binder_resolver.cc
  40. 16
      src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
  41. 44
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc
  42. 13
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h
  43. 2
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc
  44. 6
      src/core/ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.cc
  45. 4
      src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc
  46. 2
      src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc
  47. 12
      src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc
  48. 2
      src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc
  49. 2
      src/core/ext/xds/xds_client_grpc.h
  50. 2
      src/core/ext/xds/xds_client_stats.h
  51. 34
      src/core/ext/xds/xds_endpoint.cc
  52. 4
      src/core/ext/xds/xds_endpoint.h
  53. 2
      src/core/ext/xds/xds_health_status.h
  54. 7
      src/core/lib/load_balancing/delegating_helper.h
  55. 13
      src/core/lib/load_balancing/lb_policy.h
  56. 147
      src/core/lib/resolver/endpoint_addresses.cc
  57. 116
      src/core/lib/resolver/endpoint_addresses.h
  58. 6
      src/core/lib/resolver/resolver.h
  59. 89
      src/core/lib/resolver/server_address.cc
  60. 61
      src/core/lib/resolver/server_address.h
  61. 2
      src/python/grpcio/grpc_core_dependencies.py
  62. 2
      test/core/client_channel/client_channel_test.cc
  63. 192
      test/core/client_channel/lb_policy/lb_policy_test_lib.h
  64. 62
      test/core/client_channel/lb_policy/pick_first_test.cc
  65. 83
      test/core/client_channel/lb_policy/round_robin_test.cc
  66. 165
      test/core/client_channel/lb_policy/weighted_round_robin_test.cc
  67. 9
      test/core/client_channel/lb_policy/xds_override_host_test.cc
  68. 4
      test/core/client_channel/resolvers/binder_resolver_test.cc
  69. 6
      test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc
  70. 4
      test/core/client_channel/resolvers/fake_resolver_test.cc
  71. 2
      test/core/end2end/BUILD
  72. 8
      test/core/end2end/fuzzers/api_fuzzer.cc
  73. 8
      test/core/end2end/goaway_server_test.cc
  74. 2
      test/core/iomgr/stranded_event_test.cc
  75. 4
      test/core/transport/chttp2/too_many_pings_test.cc
  76. 2
      test/core/util/BUILD
  77. 24
      test/core/util/test_lb_policies.cc
  78. 6
      test/core/util/test_lb_policies.h
  79. 2
      test/core/xds/xds_endpoint_resource_type_test.cc
  80. 4
      test/cpp/client/destroy_grpclb_channel_with_active_connect_stress_test.cc
  81. 13
      test/cpp/end2end/client_lb_end2end_test.cc
  82. 8
      test/cpp/end2end/grpclb_end2end_test.cc
  83. 4
      test/cpp/end2end/service_config_end2end_test.cc
  84. 6
      test/cpp/end2end/xds/xds_cluster_type_end2end_test.cc
  85. 2
      test/cpp/end2end/xds/xds_end2end_test.cc
  86. 4
      test/cpp/end2end/xds/xds_ring_hash_end2end_test.cc
  87. 5
      test/cpp/interop/backend_metrics_lb_policy.cc
  88. 8
      test/cpp/naming/address_sorting_test.cc
  89. 12
      test/cpp/naming/resolver_component_test.cc
  90. 3
      tools/doxygen/Doxyfile.c++.internal
  91. 3
      tools/doxygen/Doxyfile.core.internal

30
BUILD

@ -2918,12 +2918,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",
@ -2933,6 +2933,7 @@ grpc_cc_library(
language = "c++",
visibility = ["@grpc:client_channel"],
deps = [
"gpr",
"gpr_platform",
"sockaddr_utils",
"//src/core:channel_args",
@ -2941,6 +2942,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 = [
@ -2961,11 +2975,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",
@ -3050,6 +3064,7 @@ grpc_cc_library(
"config",
"config_vars",
"debug_location",
"endpoint_addresses",
"exec_ctx",
"gpr",
"grpc_base",
@ -3066,7 +3081,6 @@ grpc_cc_library(
"promise",
"protobuf_duration_upb",
"ref_counted_ptr",
"server_address",
"sockaddr_utils",
"stats",
"uri_parser",
@ -3164,6 +3178,7 @@ grpc_cc_library(
"config",
"config_vars",
"debug_location",
"endpoint_addresses",
"exec_ctx",
"gpr",
"grpc_base",
@ -3175,7 +3190,6 @@ grpc_cc_library(
"orphanable",
"parse_address",
"ref_counted_ptr",
"server_address",
"sockaddr_utils",
"uri_parser",
"//src/core:channel_args",
@ -3618,9 +3632,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",
],
@ -3738,12 +3752,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",

8
CMakeLists.txt generated

@ -2352,9 +2352,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
@ -3065,9 +3065,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
@ -5005,9 +5005,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
@ -24041,9 +24041,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

4
Makefile generated

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

3
Package.swift generated

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

@ -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
@ -2290,6 +2291,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
@ -2682,9 +2684,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
@ -4297,10 +4299,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
@ -4572,9 +4574,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
@ -15855,10 +15857,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
@ -16112,9 +16114,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

2
config.m4 generated

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

2
config.w32 generated

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

2
gRPC-C++.podspec generated

@ -976,6 +976,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',
@ -2045,6 +2046,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',

4
gRPC-Core.podspec generated

@ -1577,12 +1577,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',
@ -2796,6 +2797,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',

3
grpc.gemspec generated

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

6
grpc.gyp generated

@ -897,9 +897,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',
@ -1404,9 +1404,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',
@ -2139,9 +2139,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',

3
package.xml generated

@ -1462,12 +1462,13 @@
<file baseinstalldir="/" name="src/core/lib/promise/trace.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/promise/trace.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/promise/try_seq.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/resolver/endpoint_addresses.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/resolver/endpoint_addresses.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/resolver/resolver.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/resolver/resolver.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/resolver/resolver_factory.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/resolver/resolver_registry.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/resolver/resolver_registry.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/resolver/server_address.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/resolver/server_address.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/resource_quota/api.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/resource_quota/api.h" role="src" />

@ -2763,8 +2763,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",
@ -2772,7 +2774,6 @@ grpc_cc_library(
"//:grpc_trace",
"//:orphanable",
"//:ref_counted_ptr",
"//:server_address",
"//:work_serializer",
],
)
@ -2836,13 +2837,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",
],
)
@ -4062,6 +4063,7 @@ grpc_cc_library(
"//:channel_stack_builder",
"//:config",
"//:debug_location",
"//:endpoint_addresses",
"//:exec_ctx",
"//:gpr",
"//:grpc_base",
@ -4077,7 +4079,6 @@ grpc_cc_library(
"//:protobuf_duration_upb",
"//:protobuf_timestamp_upb",
"//:ref_counted_ptr",
"//:server_address",
"//:sockaddr_utils",
"//:work_serializer",
],
@ -4156,6 +4157,7 @@ grpc_cc_library(
"//:channel_arg_names",
"//:config",
"//:debug_location",
"//:endpoint_addresses",
"//:exec_ctx",
"//:gpr",
"//:grpc_base",
@ -4168,7 +4170,6 @@ grpc_cc_library(
"//:orphanable",
"//:ref_counted_ptr",
"//:rls_upb",
"//:server_address",
"//:work_serializer",
],
)
@ -4362,6 +4363,7 @@ grpc_cc_library(
"//:channel_arg_names",
"//:config",
"//:debug_location",
"//:endpoint_addresses",
"//:exec_ctx",
"//:gpr",
"//:grpc_base",
@ -4374,7 +4376,6 @@ grpc_cc_library(
"//:orphanable",
"//:parse_address",
"//:ref_counted_ptr",
"//:server_address",
"//:sockaddr_utils",
"//:tsi_ssl_credentials",
"//:uri_parser",
@ -4528,8 +4529,8 @@ grpc_cc_library(
],
language = "c++",
deps = [
"//:endpoint_addresses",
"//:gpr_platform",
"//:server_address",
],
)
@ -4565,6 +4566,7 @@ grpc_cc_library(
"//:channel_arg_names",
"//:config",
"//:debug_location",
"//:endpoint_addresses",
"//:gpr",
"//:grpc_base",
"//:grpc_client_channel",
@ -4573,7 +4575,6 @@ grpc_cc_library(
"//:grpc_trace",
"//:orphanable",
"//:ref_counted_ptr",
"//:server_address",
"//:work_serializer",
"//:xds_client",
],
@ -4607,17 +4608,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",
],
)
@ -4649,6 +4651,7 @@ grpc_cc_library(
"validation_errors",
"//:config",
"//:debug_location",
"//:endpoint_addresses",
"//:exec_ctx",
"//:gpr",
"//:gpr_platform",
@ -4657,7 +4660,6 @@ grpc_cc_library(
"//:grpc_trace",
"//:orphanable",
"//:ref_counted_ptr",
"//:server_address",
"//:work_serializer",
],
)
@ -4689,12 +4691,12 @@ grpc_cc_library(
"validation_errors",
"//:config",
"//:debug_location",
"//:endpoint_addresses",
"//:gpr",
"//:grpc_base",
"//:grpc_trace",
"//:orphanable",
"//:ref_counted_ptr",
"//:server_address",
"//:xds_client",
],
)
@ -4716,9 +4718,9 @@ grpc_cc_library(
"channel_args",
"ref_counted",
"ref_counted_string",
"//:endpoint_addresses",
"//:gpr_platform",
"//:ref_counted_ptr",
"//:server_address",
],
)
@ -4815,14 +4817,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",
],
)
@ -4860,13 +4863,13 @@ grpc_cc_library(
"//:channel_arg_names",
"//:config",
"//:debug_location",
"//:endpoint_addresses",
"//:exec_ctx",
"//:gpr",
"//:grpc_base",
"//:grpc_trace",
"//:orphanable",
"//:ref_counted_ptr",
"//:server_address",
"//:work_serializer",
],
)
@ -4909,6 +4912,7 @@ grpc_cc_library(
"//:channel_arg_names",
"//:config",
"//:debug_location",
"//:endpoint_addresses",
"//:exec_ctx",
"//:gpr",
"//:grpc_base",
@ -4916,7 +4920,6 @@ grpc_cc_library(
"//:grpc_trace",
"//:orphanable",
"//:ref_counted_ptr",
"//:server_address",
"//:sockaddr_utils",
"//:work_serializer",
],
@ -4946,6 +4949,7 @@ grpc_cc_library(
"subchannel_interface",
"//:config",
"//:debug_location",
"//:endpoint_addresses",
"//:gpr",
"//:grpc_base",
"//:grpc_trace",
@ -5008,6 +5012,7 @@ grpc_cc_library(
"validation_errors",
"//:config",
"//:debug_location",
"//:endpoint_addresses",
"//:exec_ctx",
"//:gpr",
"//:grpc_base",
@ -5065,11 +5070,13 @@ grpc_cc_library(
"lb_policy_registry",
"pollset_set",
"ref_counted",
"resolved_address",
"subchannel_interface",
"unique_type_name",
"validation_errors",
"//:config",
"//:debug_location",
"//:endpoint_addresses",
"//:exec_ctx",
"//:gpr",
"//:grpc_base",
@ -5077,7 +5084,6 @@ grpc_cc_library(
"//:grpc_trace",
"//:orphanable",
"//:ref_counted_ptr",
"//:server_address",
"//:sockaddr_utils",
"//:work_serializer",
],
@ -5111,6 +5117,7 @@ grpc_cc_library(
"//:channel_arg_names",
"//:config",
"//:debug_location",
"//:endpoint_addresses",
"//:exec_ctx",
"//:gpr",
"//:grpc_base",
@ -5118,7 +5125,6 @@ grpc_cc_library(
"//:grpc_trace",
"//:orphanable",
"//:ref_counted_ptr",
"//:server_address",
"//:work_serializer",
],
)
@ -5152,6 +5158,7 @@ grpc_cc_library(
"validation_errors",
"//:config",
"//:debug_location",
"//:endpoint_addresses",
"//:exec_ctx",
"//:gpr",
"//:grpc_base",
@ -5159,7 +5166,6 @@ grpc_cc_library(
"//:grpc_trace",
"//:orphanable",
"//:ref_counted_ptr",
"//:server_address",
"//:work_serializer",
],
)
@ -5198,10 +5204,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",
@ -5209,7 +5217,6 @@ grpc_cc_library(
"//:grpc_trace",
"//:orphanable",
"//:ref_counted_ptr",
"//:server_address",
"//:sockaddr_utils",
"//:work_serializer",
],
@ -5377,6 +5384,7 @@ grpc_cc_library(
"//:backoff",
"//:channel_arg_names",
"//:debug_location",
"//:endpoint_addresses",
"//:exec_ctx",
"//:gpr",
"//:gpr_platform",
@ -5387,7 +5395,6 @@ grpc_cc_library(
"//:grpc_trace",
"//:orphanable",
"//:ref_counted_ptr",
"//:server_address",
"//:uri_parser",
],
)
@ -5439,13 +5446,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",
],
)
@ -5465,11 +5472,11 @@ grpc_cc_library(
"iomgr_port",
"resolved_address",
"//:config",
"//:endpoint_addresses",
"//:gpr",
"//:grpc_resolver",
"//:orphanable",
"//:parse_address",
"//:server_address",
"//:uri_parser",
],
)
@ -5492,10 +5499,10 @@ grpc_cc_library(
"resolved_address",
"status_helper",
"//:config",
"//:endpoint_addresses",
"//:gpr",
"//:grpc_resolver",
"//:orphanable",
"//:server_address",
"//:uri_parser",
],
)
@ -5553,6 +5560,7 @@ grpc_cc_library(
"//:channel_arg_names",
"//:config",
"//:debug_location",
"//:endpoint_addresses",
"//:gpr",
"//:grpc_base",
"//:grpc_client_channel",
@ -5563,7 +5571,6 @@ grpc_cc_library(
"//:legacy_context",
"//:orphanable",
"//:ref_counted_ptr",
"//:server_address",
"//:uri_parser",
"//:work_serializer",
"//:xds_client",

@ -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"
@ -1082,15 +1083,16 @@ class ClientChannel::ClientChannelControlHelper
}
RefCountedPtr<SubchannelInterface> 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> 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.

@ -44,18 +44,19 @@ int HierarchicalPathArg::ChannelArgsCompare(const HierarchicalPathArg* a,
}
absl::StatusOr<HierarchicalAddressMap> MakeHierarchicalAddressMap(
const absl::StatusOr<ServerAddressList>& addresses) {
const absl::StatusOr<EndpointAddressesList>& addresses) {
if (!addresses.ok()) return addresses.status();
HierarchicalAddressMap result;
RefCountedPtr<HierarchicalPathArg> remaining_path_attr;
for (const ServerAddress& address : *addresses) {
const auto* path_arg = address.args().GetObject<HierarchicalPathArg>();
for (const EndpointAddresses& endpoint_addresses : *addresses) {
const auto* path_arg =
endpoint_addresses.args().GetObject<HierarchicalPathArg>();
if (path_arg == nullptr) continue;
const std::vector<RefCountedStringValue>& 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<RefCountedStringValue> remaining_path(it, path.end());
@ -66,7 +67,7 @@ absl::StatusOr<HierarchicalAddressMap> MakeHierarchicalAddressMap(
}
args = args.SetObject(remaining_path_attr);
}
target_list.emplace_back(address.address(), args);
target_list.emplace_back(endpoint_addresses.addresses(), args);
}
return result;
}

@ -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<HierarchicalPathArg> {
std::vector<RefCountedStringValue> 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<RefCountedStringValue, ServerAddressList,
std::map<RefCountedStringValue, EndpointAddressesList,
RefCountedStringValueLessThan>;
// Splits up the addresses into a separate list for each child.
absl::StatusOr<HierarchicalAddressMap> MakeHierarchicalAddressMap(
const absl::StatusOr<ServerAddressList>& addresses);
const absl::StatusOr<EndpointAddressesList>& addresses);
} // namespace grpc_core

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

@ -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<SubchannelInterface> 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<WorkSerializer> 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<SubchannelInterface> 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<SubchannelInterface> EndpointList::Endpoint::CreateSubchannel(
//
void EndpointList::Init(
const ServerAddressList& addresses, const ChannelArgs& args,
absl::AnyInvocable<OrphanablePtr<Endpoint>(
RefCountedPtr<EndpointList>, const ServerAddress&, const ChannelArgs&)>
const EndpointAddressesList& endpoints, const ChannelArgs& args,
absl::AnyInvocable<OrphanablePtr<Endpoint>(RefCountedPtr<EndpointList>,
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));
}
}

@ -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<MyLbPolicy> 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<MyEndpointList> endpoint_list,
const ServerAddress& address, const ChannelArgs& args) {
const EndpointAddresses& addresses, const ChannelArgs& args) {
return MakeOrphanable<MyEndpoint>(
std::move(endpoint_list), address, args,
std::move(endpoint_list), addresses, args,
policy<MyLbPolicy>()->work_serializer());
});
}
@ -70,10 +72,10 @@ class MyEndpointList : public EndpointList {
class MyEndpoint : public Endpoint {
public:
MyEndpoint(RefCountedPtr<MyEndpointList> endpoint_list,
const ServerAddress& address, const ChannelArgs& args,
const EndpointAddresses& address, const ChannelArgs& args,
std::shared_ptr<WorkSerializer> 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<EndpointList> {
explicit Endpoint(RefCountedPtr<EndpointList> 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<WorkSerializer> work_serializer);
// Templated for convenience, to provide a short-hand for
@ -150,7 +152,8 @@ class EndpointList : public InternallyRefCounted<EndpointList> {
// Called to create a subchannel. Subclasses may override.
virtual RefCountedPtr<SubchannelInterface> CreateSubchannel(
ServerAddress address, const ChannelArgs& args);
const grpc_resolved_address& address,
const ChannelArgs& per_address_args, const ChannelArgs& args);
RefCountedPtr<EndpointList> endpoint_list_;
@ -181,9 +184,9 @@ class EndpointList : public InternallyRefCounted<EndpointList> {
EndpointList(RefCountedPtr<LoadBalancingPolicy> 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<OrphanablePtr<Endpoint>(
RefCountedPtr<EndpointList>, const ServerAddress&,
RefCountedPtr<EndpointList>, const EndpointAddresses&,
const ChannelArgs&)>
create_endpoint);

@ -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<SubchannelInterface> 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<SubchannelPicker> 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<ServerAddressList> fallback_backend_addresses_;
absl::StatusOr<EndpointAddressesList> 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<GrpcLbClientStats> 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<TokenAndClientStatsArg>(
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<SubchannelInterface> 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<TokenAndClientStatsArg>();
const auto* arg = per_address_args.GetObject<TokenAndClientStatsArg>();
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<GrpcLbClientStats> client_stats = arg->client_stats();
return MakeRefCounted<SubchannelWrapper>(
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<TokenAndClientStatsArg>("", 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");

@ -34,25 +34,25 @@ namespace grpc_core {
namespace {
void* BalancerAddressesArgCopy(void* p) {
ServerAddressList* address_list = static_cast<ServerAddressList*>(p);
return new ServerAddressList(*address_list);
EndpointAddressesList* endpoint_list = static_cast<EndpointAddressesList*>(p);
return new EndpointAddressesList(*endpoint_list);
}
void BalancerAddressesArgDestroy(void* p) {
ServerAddressList* address_list = static_cast<ServerAddressList*>(p);
delete address_list;
EndpointAddressesList* endpoint_list = static_cast<EndpointAddressesList*>(p);
delete endpoint_list;
}
int BalancerAddressesArgCmp(void* p, void* q) {
ServerAddressList* address_list1 = static_cast<ServerAddressList*>(p);
ServerAddressList* address_list2 = static_cast<ServerAddressList*>(q);
if (address_list1 == nullptr || address_list2 == nullptr) {
return QsortCompare(address_list1, address_list2);
auto* endpoint_list1 = static_cast<EndpointAddressesList*>(p);
auto* endpoint_list2 = static_cast<EndpointAddressesList*>(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<char*>(GRPC_ARG_GRPCLB_BALANCER_ADDRESSES),
const_cast<ServerAddressList*>(address_list),
const_cast<EndpointAddressesList*>(endpoint_list),
&kBalancerAddressesArgVtable);
}
const ServerAddressList* FindGrpclbBalancerAddressesInChannelArgs(
const EndpointAddressesList* FindGrpclbBalancerAddressesInChannelArgs(
const ChannelArgs& args) {
return args.GetPointer<const ServerAddressList>(
return args.GetPointer<const EndpointAddressesList>(
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));
}

@ -22,16 +22,16 @@
#include <grpc/grpc.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"
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

@ -60,13 +60,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 {
@ -346,7 +347,8 @@ class OutlierDetectionLb : public LoadBalancingPolicy {
std::move(outlier_detection_policy)) {}
RefCountedPtr<SubchannelInterface> 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<SubchannelPicker> picker) override;
};
@ -373,7 +375,7 @@ class OutlierDetectionLb : public LoadBalancingPolicy {
// 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);
static std::string MakeKeyForAddress(const grpc_resolved_address& address);
void ShutdownLocked() override;
@ -537,9 +539,9 @@ OutlierDetectionLb::~OutlierDetectionLb() {
}
std::string OutlierDetectionLb::MakeKeyForAddress(
const ServerAddress& address) {
const grpc_resolved_address& address) {
// Use only the address, not the attributes.
auto addr_str = grpc_sockaddr_to_string(&address.address(), false);
auto addr_str = grpc_sockaddr_to_string(&address, false);
// If address couldn't be stringified, ignore it.
if (!addr_str.ok()) return "";
return std::move(*addr_str);
@ -613,8 +615,8 @@ absl::Status OutlierDetectionLb::UpdateLocked(UpdateArgs args) {
// Update subchannel state map.
if (args.addresses.ok()) {
std::set<std::string> current_addresses;
for (const ServerAddress& address : *args.addresses) {
std::string address_key = MakeKeyForAddress(address);
for (const EndpointAddresses& endpoint : *args.addresses) {
std::string address_key = MakeKeyForAddress(endpoint.address());
if (address_key.empty()) continue;
auto& subchannel_state = subchannel_state_map_[address_key];
if (subchannel_state == nullptr) {
@ -715,14 +717,14 @@ OrphanablePtr<LoadBalancingPolicy> OutlierDetectionLb::CreateChildPolicyLocked(
//
RefCountedPtr<SubchannelInterface> 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<SubchannelState> 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());
gpr_log(GPR_INFO, "[outlier_detection_lb %p] creating subchannel, key %s",
parent(), key.c_str());
}
if (!key.empty()) {
auto it = parent()->subchannel_state_map_.find(key);
@ -732,8 +734,8 @@ RefCountedPtr<SubchannelInterface> OutlierDetectionLb::Helper::CreateSubchannel(
}
auto subchannel = MakeRefCounted<SubchannelWrapper>(
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());
}

@ -61,7 +61,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 {
@ -198,8 +198,8 @@ class PickFirst : public LoadBalancingPolicy {
absl::Status connectivity_status_;
};
SubchannelList(RefCountedPtr<PickFirst> policy, ServerAddressList addresses,
const ChannelArgs& args);
SubchannelList(RefCountedPtr<PickFirst> policy,
EndpointAddressesList addresses, const ChannelArgs& args);
~SubchannelList() override;
@ -383,7 +383,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;
}
@ -439,10 +439,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<PickFirstConfig*>(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.
@ -942,7 +951,7 @@ void PickFirst::SubchannelList::SubchannelData::ProcessUnselectedReadyLocked() {
//
PickFirst::SubchannelList::SubchannelList(RefCountedPtr<PickFirst> policy,
ServerAddressList addresses,
EndpointAddressesList addresses,
const ChannelArgs& args)
: InternallyRefCounted<SubchannelList>(
GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace) ? "SubchannelList"
@ -959,9 +968,11 @@ PickFirst::SubchannelList::SubchannelList(RefCountedPtr<PickFirst> 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<SubchannelInterface> 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)) {

@ -19,7 +19,7 @@
#include <grpc/support/port_platform.h>
#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

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

@ -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<RingHashEndpoint> {
public:
// index is the index into RingHash::addresses_ of this endpoint.
// index is the index into RingHash::endpoints_ of this endpoint.
RingHashEndpoint(RefCountedPtr<RingHash> 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<RingHash> 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<LoadBalancingPolicy> child_policy_;
@ -223,7 +223,7 @@ class RingHash : public LoadBalancingPolicy {
explicit Picker(RefCountedPtr<RingHash> 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> ring_;
std::map<ServerAddress, OrphanablePtr<RingHashEndpoint>> endpoint_map_;
std::map<EndpointAddressSet, OrphanablePtr<RingHashEndpoint>> 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<AddressWeight> address_weights;
std::vector<EndpointWeight> 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<double>(address.weight) / sum;
for (auto& endpoint_weight : endpoint_weights) {
endpoint_weight.normalized_weight =
static_cast<double>(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<Ring>(
this, static_cast<RingHashLbConfig*>(args.config.get()));
// Update endpoint map.
std::map<ServerAddress, OrphanablePtr<RingHashEndpoint>> endpoint_map;
for (size_t i = 0; i < addresses_.size(); ++i) {
const ServerAddress& address = addresses_[i];
std::map<EndpointAddressSet, OrphanablePtr<RingHashEndpoint>> 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<RingHashEndpoint>(Ref(), i));
endpoint_map.emplace(address_set,
MakeOrphanable<RingHashEndpoint>(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();
}

@ -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<RlsChannel> rls_channel_ ABSL_GUARDED_BY(mu_);
// Accessed only from within WorkSerializer.
absl::StatusOr<ServerAddressList> addresses_;
absl::StatusOr<EndpointAddressesList> addresses_;
ChannelArgs channel_args_;
RefCountedPtr<RlsLbConfig> config_;
RefCountedPtr<ChildPolicyWrapper> 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<ServerAddressList> old_addresses;
absl::StatusOr<EndpointAddressesList> old_addresses;
if (args.addresses.ok()) {
old_addresses = std::move(addresses_);
addresses_ = std::move(args.addresses);

@ -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<RoundRobin> 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<RoundRobinEndpointList> endpoint_list,
const ServerAddress& address, const ChannelArgs& args) {
const EndpointAddresses& addresses, const ChannelArgs& args) {
return MakeOrphanable<RoundRobinEndpoint>(
std::move(endpoint_list), address, args,
std::move(endpoint_list), addresses, args,
policy<RoundRobin>()->work_serializer());
});
}
@ -542,10 +543,11 @@ class RoundRobin : public LoadBalancingPolicy {
class RoundRobinEndpoint : public Endpoint {
public:
RoundRobinEndpoint(RefCountedPtr<RoundRobinEndpointList> endpoint_list,
const ServerAddress& address, const ChannelArgs& args,
const EndpointAddresses& addresses,
const ChannelArgs& args,
std::shared_ptr<WorkSerializer> 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.

@ -380,7 +380,7 @@ SubchannelList<SubchannelListType, SubchannelDataType>::SubchannelList(
// Create a subchannel for each address.
for (ServerAddress address : addresses) {
RefCountedPtr<SubchannelInterface> 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)) {

@ -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<EndpointWeight> {
public:
EndpointWeight(RefCountedPtr<WeightedRoundRobin> wrr, std::string key)
EndpointWeight(RefCountedPtr<WeightedRoundRobin> wrr,
EndpointAddressSet key)
: wrr_(std::move(wrr)), key_(std::move(key)) {}
~EndpointWeight() override;
@ -1023,7 +1025,7 @@ class WeightedRoundRobin : public LoadBalancingPolicy {
private:
RefCountedPtr<WeightedRoundRobin> 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<WrrEndpointList> endpoint_list,
const ServerAddress& address, const ChannelArgs& args,
const EndpointAddresses& addresses, const ChannelArgs& args,
std::shared_ptr<WorkSerializer> work_serializer)
: Endpoint(std::move(endpoint_list)),
weight_(policy<WeightedRoundRobin>()->GetOrCreateWeight(
address.address())) {
Init(address, args, std::move(work_serializer));
addresses.addresses())) {
Init(addresses, args, std::move(work_serializer));
}
RefCountedPtr<EndpointWeight> weight() const { return weight_; }
@ -1063,7 +1065,9 @@ class WeightedRoundRobin : public LoadBalancingPolicy {
};
RefCountedPtr<SubchannelInterface> 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<grpc_connectivity_state> old_state,
@ -1074,16 +1078,17 @@ class WeightedRoundRobin : public LoadBalancingPolicy {
};
WrrEndpointList(RefCountedPtr<WeightedRoundRobin> 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<WrrEndpointList> endpoint_list,
const ServerAddress& address, const ChannelArgs& args) {
const EndpointAddresses& addresses, const ChannelArgs& args) {
return MakeOrphanable<WrrEndpoint>(
std::move(endpoint_list), address, args,
std::move(endpoint_list), addresses, args,
policy<WeightedRoundRobin>()->work_serializer());
});
}
@ -1192,7 +1197,7 @@ class WeightedRoundRobin : public LoadBalancingPolicy {
void ShutdownLocked() override;
RefCountedPtr<EndpointWeight> GetOrCreateWeight(
const grpc_resolved_address& address);
const std::vector<grpc_resolved_address>& addresses);
RefCountedPtr<WeightedRoundRobinConfig> config_;
@ -1205,7 +1210,7 @@ class WeightedRoundRobin : public LoadBalancingPolicy {
OrphanablePtr<WrrEndpointList> latest_pending_endpoint_list_;
Mutex endpoint_weight_map_mu_;
std::map<std::string, EndpointWeight*, std::less<>> endpoint_weight_map_
std::map<EndpointAddressSet, EndpointWeight*> 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<ServerAddress, AddressLessThan> ordered_addresses(
std::set<EndpointAddresses, EndpointAddressesLessThan> 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<WrrEndpointList>(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::EndpointWeight>
WeightedRoundRobin::GetOrCreateWeight(const grpc_resolved_address& address) {
auto key = grpc_sockaddr_to_uri(&address);
if (!key.ok()) return nullptr;
WeightedRoundRobin::GetOrCreateWeight(
const std::vector<grpc_resolved_address>& 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<EndpointWeight>(
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<SubchannelInterface>
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<WeightedRoundRobin>();
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

@ -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 <type_traits>
@ -157,7 +157,7 @@ class WeightedTargetLb : public LoadBalancingPolicy {
void Orphan() override;
absl::Status UpdateLocked(const WeightedTargetLbConfig::ChildConfig& config,
absl::StatusOr<ServerAddressList> addresses,
absl::StatusOr<EndpointAddressesList> addresses,
const std::string& resolution_note,
const ChannelArgs& args);
void ResetBackoffLocked();
@ -337,7 +337,7 @@ absl::Status WeightedTargetLb::UpdateLocked(UpdateArgs args) {
target = MakeOrphanable<WeightedChild>(
Ref(DEBUG_LOCATION, "WeightedChild"), name);
}
absl::StatusOr<ServerAddressList> addresses;
absl::StatusOr<EndpointAddressesList> 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<ServerAddressList> addresses,
absl::StatusOr<EndpointAddressesList> addresses,
const std::string& resolution_note, const ChannelArgs& args) {
if (weighted_target_policy_->shutting_down_) return absl::OkStatus();
// Update child weight.

@ -19,7 +19,7 @@
#include <grpc/support/port_platform.h>
#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.

@ -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<SubchannelInterface> 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<SubchannelPicker> picker) override;
};
@ -248,8 +250,8 @@ class XdsClusterImplLb : public LoadBalancingPolicy {
OrphanablePtr<LoadBalancingPolicy> CreateChildPolicyLocked(
const ChannelArgs& args);
absl::Status UpdateChildPolicyLocked(
absl::StatusOr<ServerAddressList> addresses, std::string resolution_note,
const ChannelArgs& args);
absl::StatusOr<EndpointAddressesList> addresses,
std::string resolution_note, const ChannelArgs& args);
void MaybeUpdatePickerLocked();
@ -567,8 +569,8 @@ OrphanablePtr<LoadBalancingPolicy> XdsClusterImplLb::CreateChildPolicyLocked(
}
absl::Status XdsClusterImplLb::UpdateChildPolicyLocked(
absl::StatusOr<ServerAddressList> addresses, std::string resolution_note,
const ChannelArgs& args) {
absl::StatusOr<EndpointAddressesList> 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<SubchannelInterface> 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<XdsLocalityName>();
auto locality_name = per_address_args.GetObjectRef<XdsLocalityName>();
RefCountedPtr<XdsClusterLocalityStats> locality_stats =
parent()->xds_client_->AddClusterLocalityStats(
parent()->config_->lrs_load_reporting_server().value(),
@ -608,7 +611,7 @@ RefCountedPtr<SubchannelInterface> XdsClusterImplLb::Helper::CreateSubchannel(
if (locality_stats != nullptr) {
return MakeRefCounted<StatsSubchannelWrapper>(
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<SubchannelInterface> 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(

@ -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<LoadBalancingPolicy::Config> config,
const absl::StatusOr<ServerAddressList>& addresses,
const absl::StatusOr<EndpointAddressesList>& addresses,
const ChannelArgs& args);
void ExitIdleLocked();
void ResetBackoffLocked();
@ -482,7 +482,7 @@ XdsClusterManagerLb::ClusterChild::CreateChildPolicyLocked(
absl::Status XdsClusterManagerLb::ClusterChild::UpdateLocked(
RefCountedPtr<LoadBalancingPolicy::Config> config,
const absl::StatusOr<ServerAddressList>& addresses,
const absl::StatusOr<EndpointAddressesList>& addresses,
const ChannelArgs& args) {
if (xds_cluster_manager_policy_->shutting_down_) return absl::OkStatus();
// Update child weight.

@ -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<LoadBalancingPolicy> CreateChildPolicyLocked(
const ChannelArgs& args);
ServerAddressList CreateChildPolicyAddressesLocked();
EndpointAddressesList CreateChildPolicyAddressesLocked();
std::string CreateChildPolicyResolutionNoteLocked();
RefCountedPtr<Config> 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)

@ -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<XdsHealthStatus::HealthStatus>(
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<SubchannelInterface> 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<SubchannelPicker> picker) override;
};
@ -285,11 +287,12 @@ class XdsOverrideHostLb : public LoadBalancingPolicy {
void MaybeUpdatePickerLocked();
absl::StatusOr<ServerAddressList> UpdateAddressMap(
absl::StatusOr<ServerAddressList> addresses);
absl::StatusOr<EndpointAddressesList> UpdateAddressMap(
absl::StatusOr<EndpointAddressesList> endpoints);
RefCountedPtr<SubchannelWrapper> AdoptSubchannel(
ServerAddress address, RefCountedPtr<SubchannelInterface> subchannel);
const grpc_resolved_address& address,
RefCountedPtr<SubchannelInterface> subchannel);
void UnsetSubchannel(absl::string_view key, SubchannelWrapper* subchannel);
@ -501,43 +504,45 @@ OrphanablePtr<LoadBalancingPolicy> XdsOverrideHostLb::CreateChildPolicyLocked(
return lb_policy;
}
absl::StatusOr<ServerAddressList> XdsOverrideHostLb::UpdateAddressMap(
absl::StatusOr<ServerAddressList> addresses) {
if (!addresses.ok()) {
absl::StatusOr<EndpointAddressesList> XdsOverrideHostLb::UpdateAddressMap(
absl::StatusOr<EndpointAddressesList> 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<const std::string, XdsHealthStatus> 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<ServerAddressList> XdsOverrideHostLb::UpdateAddressMap(
RefCountedPtr<XdsOverrideHostLb::SubchannelWrapper>
XdsOverrideHostLb::AdoptSubchannel(
ServerAddress address, RefCountedPtr<SubchannelInterface> subchannel) {
auto key = grpc_sockaddr_to_uri(&address.address());
const grpc_resolved_address& address,
RefCountedPtr<SubchannelInterface> subchannel) {
auto key = grpc_sockaddr_to_uri(&address);
if (!key.ok()) {
return subchannel;
}
@ -646,9 +652,10 @@ void XdsOverrideHostLb::OnSubchannelConnectivityStateChange(
//
RefCountedPtr<SubchannelInterface> 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);
}

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

@ -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<ResultHandler> result_handler_;
ServerAddressList addresses_;
EndpointAddressesList addresses_;
ChannelArgs channel_args_;
};
@ -83,7 +83,7 @@ class BinderResolverFactory : public ResolverFactory {
}
OrphanablePtr<Resolver> CreateResolver(ResolverArgs args) const override {
ServerAddressList addresses;
EndpointAddressesList addresses;
if (!ParseUri(args.uri, &addresses)) return nullptr;
return MakeOrphanable<BinderResolver>(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()) {

@ -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<grpc_ares_request> txt_request_
ABSL_GUARDED_BY(on_resolved_mu_);
// Output fields from ares request.
std::unique_ptr<ServerAddressList> addresses_
std::unique_ptr<EndpointAddressesList> addresses_
ABSL_GUARDED_BY(on_resolved_mu_);
std::unique_ptr<ServerAddressList> balancer_addresses_
std::unique_ptr<EndpointAddressesList> 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<std::vector<grpc_resolved_address>>)>
on_resolve_address_done_;
// currently resolving addresses
std::unique_ptr<ServerAddressList> addresses_;
std::unique_ptr<EndpointAddressesList> addresses_;
};
class AresSRVRequest : public AresRequest {
@ -583,7 +583,7 @@ class AresDNSResolver : public DNSResolver {
absl::StatusOr<std::vector<grpc_resolved_address>>)>
on_resolve_address_done_;
// currently resolving addresses
std::unique_ptr<ServerAddressList> balancer_addresses_;
std::unique_ptr<EndpointAddressesList> balancer_addresses_;
};
class AresTXTRequest : public AresRequest {

@ -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<ServerAddress*>(sortables[i].user_data));
sorted.emplace_back(
*static_cast<EndpointAddresses*>(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<ServerAddressList>* address_list_ptr =
std::unique_ptr<EndpointAddressesList>* address_list_ptr =
hr->is_balancer ? r->balancer_addresses_out : r->addresses_out;
if (*address_list_ptr == nullptr) {
*address_list_ptr = std::make_unique<ServerAddressList>();
*address_list_ptr = std::make_unique<EndpointAddressesList>();
}
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<grpc_core::ServerAddressList>* addrs, std::string* host,
std::unique_ptr<grpc_core::EndpointAddressesList>* 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<ServerAddressList>();
*addrs = std::make_unique<EndpointAddressesList>();
(*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<grpc_core::ServerAddressList>* addrs) {
std::unique_ptr<grpc_core::EndpointAddressesList>* 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<grpc_core::ServerAddressList>* addrs, std::string* host,
std::unique_ptr<grpc_core::EndpointAddressesList>* 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<grpc_core::ServerAddressList>();
*addrs = std::make_unique<grpc_core::EndpointAddressesList>();
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<grpc_core::ServerAddressList>* addrs) {
std::unique_ptr<grpc_core::EndpointAddressesList>* 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<grpc_core::ServerAddressList>* /*addrs*/) {
std::unique_ptr<grpc_core::EndpointAddressesList>* /*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<grpc_core::ServerAddressList>* addrs,
std::unique_ptr<grpc_core::EndpointAddressesList>* 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<grpc_core::ServerAddressList>* balancer_addresses,
std::unique_ptr<grpc_core::EndpointAddressesList>* 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<grpc_core::ServerAddressList>* addrs,
std::unique_ptr<grpc_core::EndpointAddressesList>* 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<grpc_core::ServerAddressList>* balancer_addresses,
std::unique_ptr<grpc_core::EndpointAddressesList>* balancer_addresses,
int query_timeout_ms) = grpc_dns_lookup_srv_ares_impl;
grpc_ares_request* (*grpc_dns_lookup_txt_ares)(

@ -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<grpc_core::ServerAddressList>* addresses_out
std::unique_ptr<grpc_core::EndpointAddressesList>* addresses_out
ABSL_GUARDED_BY(mu);
/// the pointer to receive the resolved balancer addresses
std::unique_ptr<grpc_core::ServerAddressList>* balancer_addresses_out
std::unique_ptr<grpc_core::EndpointAddressesList>* 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<grpc_core::ServerAddressList>* addresses,
std::unique_ptr<grpc_core::EndpointAddressesList>* 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<grpc_core::ServerAddressList>* balancer_addresses,
std::unique_ptr<grpc_core::EndpointAddressesList>* 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);

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

@ -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<std::string> service_config_json_
ABSL_GUARDED_BY(on_resolved_mu_);

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

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

@ -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<ResultHandler> 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<Resolver> 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<SockaddrResolver>(std::move(addresses),

@ -87,9 +87,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"

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

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

@ -61,7 +61,7 @@ namespace grpc_core {
std::string XdsEndpointResource::Priority::Locality::ToString() const {
std::vector<std::string> endpoint_strings;
for (const ServerAddress& endpoint : endpoints) {
for (const EndpointAddresses& endpoint : endpoints) {
endpoint_strings.emplace_back(endpoint.ToString());
}
return absl::StrCat("{name=", name->AsHumanReadableString(),
@ -150,7 +150,7 @@ void MaybeLogClusterLoadAssignment(
}
}
absl::optional<ServerAddress> ServerAddressParse(
absl::optional<EndpointAddresses> EndpointAddressesParse(
const envoy_config_endpoint_v3_LbEndpoint* lb_endpoint,
ValidationErrors* errors) {
// health_status
@ -172,6 +172,7 @@ absl::optional<ServerAddress> ServerAddressParse(
}
}
// endpoint
// TODO(roth): add support for multiple addresses per endpoint
grpc_resolved_address grpc_address;
{
ValidationErrors::ScopedField field(errors, ".endpoint");
@ -213,11 +214,11 @@ absl::optional<ServerAddress> 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 {
@ -277,16 +278,17 @@ absl::optional<ParsedLocality> 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("<unknown>"),
"\""));
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("<unknown>"), "\""));
}
}
parsed_locality.locality.endpoints.push_back(std::move(*address));
parsed_locality.locality.endpoints.push_back(std::move(*endpoint));
}
}
// priority

@ -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<XdsLocalityName> name;
uint32_t lb_weight;
ServerAddressList endpoints;
EndpointAddressesList endpoints;
bool operator==(const Locality& other) const {
return *name == *other.name && lb_weight == other.lb_weight &&

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

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

@ -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<LoadBalancingPolicy> {
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<SubchannelInterface> 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<LoadBalancingPolicy> {
/// 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<ServerAddressList> 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<EndpointAddressesList> addresses;
/// The LB policy config.
RefCountedPtr<Config> config;
/// A human-readable note providing context about the name resolution that

@ -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 <grpc/support/port_platform.h>
#include "src/core/lib/resolver/endpoint_addresses.h"
#include <string.h>
#include <algorithm>
#include <string>
#include <utility>
#include <vector>
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_join.h"
#include <grpc/support/log.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 <sys/socket.h>
namespace grpc_core {
EndpointAddresses::EndpointAddresses(const grpc_resolved_address& address,
const ChannelArgs& args)
: addresses_(1, address), args_(args) {}
EndpointAddresses::EndpointAddresses(
std::vector<grpc_resolved_address> 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<std::string> 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<std::string> 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<std::string> parts;
parts.reserve(addresses_.size());
for (const auto& address : addresses_) {
parts.push_back(
grpc_sockaddr_to_string(&address, false).value_or("<unknown>"));
}
return absl::StrCat("{", absl::StrJoin(parts, ", "), "}");
}
} // namespace grpc_core

@ -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 <grpc/support/port_platform.h>
#include <set>
#include <string>
#include <vector>
#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<grpc_resolved_address> 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<grpc_resolved_address>& 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<grpc_resolved_address> addresses_;
ChannelArgs args_;
};
using EndpointAddressesList = std::vector<EndpointAddresses>;
class EndpointAddressSet {
public:
explicit EndpointAddressSet(
const std::vector<grpc_resolved_address>& 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<grpc_resolved_address, ResolvedAddressLessThan> addresses_;
};
} // namespace grpc_core
#endif // GRPC_SRC_CORE_LIB_RESOLVER_ENDPOINT_ADDRESSES_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<Resolver> {
public:
/// Results returned by the resolver.
struct Result {
/// A list of addresses, or an error.
absl::StatusOr<ServerAddressList> addresses;
/// A list of endpoints, each with one or more addresses, or an error.
absl::StatusOr<EndpointAddressesList> addresses;
/// A service config, or an error.
absl::StatusOr<RefCountedPtr<ServiceConfig>> service_config = nullptr;
/// An optional human-readable note describing context about the resolution,

@ -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 <grpc/support/port_platform.h>
#include "src/core/lib/resolver/server_address.h"
#include <string.h>
#include <algorithm>
#include <string>
#include <utility>
#include <vector>
#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 <sys/socket.h>
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<std::string> 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

@ -21,65 +21,14 @@
#include <grpc/support/port_platform.h>
#include <string>
#include <vector>
#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<ServerAddress>;
// For backward compatibility only.
// TODO(roth): Remove this file when all callers have been updated.
using ServerAddress = EndpointAddresses;
using ServerAddressList = EndpointAddressesList;
} // namespace grpc_core

@ -686,9 +686,9 @@ CORE_SOURCE_FILES = [
'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',

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

@ -19,6 +19,7 @@
#include <grpc/support/port_platform.h>
#include <inttypes.h>
#include <stddef.h>
#include <algorithm>
@ -36,6 +37,7 @@
#include <vector>
#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<SubchannelInterface> 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<grpc_resolved_address> MakeAddressList(
absl::Span<const absl::string_view> addresses) {
std::vector<grpc_resolved_address> addrs;
for (const absl::string_view& address : addresses) {
addrs.emplace_back(MakeAddress(address));
}
return addrs;
}
EndpointAddresses MakeEndpointAddresses(
absl::Span<const absl::string_view> addresses,
const ChannelArgs& args = ChannelArgs()) {
return EndpointAddresses(MakeAddressList(addresses), args);
}
// Constructs an update containing a list of endpoints.
LoadBalancingPolicy::UpdateArgs BuildUpdate(
absl::Span<const EndpointAddresses> endpoints,
RefCountedPtr<LoadBalancingPolicy::Config> 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<EndpointAddresses> MakeEndpointAddressesListFromAddressList(
absl::Span<const absl::string_view> addresses) {
std::vector<EndpointAddresses> 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<const absl::string_view> addresses,
RefCountedPtr<LoadBalancingPolicy::Config> 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) {
@ -1124,26 +1158,56 @@ class LoadBalancingPolicyTest : public ::testing::Test {
// Expect startup with RR with a set of addresses.
RefCountedPtr<LoadBalancingPolicy::SubchannelPicker> ExpectRoundRobinStartup(
absl::Span<const absl::string_view> addresses) {
RefCountedPtr<LoadBalancingPolicy::SubchannelPicker> 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<const EndpointAddresses> 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<std::vector<SubchannelState*>> endpoint_subchannels;
endpoint_subchannels.reserve(endpoints.size());
std::vector<std::string> chosen_addresses_storage;
chosen_addresses_storage.reserve(endpoints.size());
std::vector<absl::string_view> 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<LoadBalancingPolicy::SubchannelPicker> 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
@ -1151,13 +1215,36 @@ 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<LoadBalancingPolicy::SubchannelPicker> ExpectRoundRobinStartup(
absl::Span<const absl::string_view> 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<const absl::string_view> 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...");
@ -1167,6 +1254,59 @@ class LoadBalancingPolicyTest : public ::testing::Test {
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<const absl::string_view> addresses, size_t current_index,
size_t new_index, absl::AnyInvocable<void()> 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<SubchannelState*> 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,

@ -37,12 +37,14 @@
#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/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"
@ -219,6 +221,66 @@ TEST_F(PickFirstTest, FirstAddressFails) {
}
}
TEST_F(PickFirstTest, FlattensEndpointAddressesList) {
// Send an update containing two endpoints, the first one with two addresses.
constexpr std::array<absl::string_view, 2> kEndpoint1Addresses = {
"ipv4:127.0.0.1:443", "ipv4:127.0.0.1:444"};
constexpr std::array<absl::string_view, 1> kEndpoint2Addresses = {
"ipv4:127.0.0.1:445"};
const std::array<EndpointAddresses, 2> 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

@ -21,6 +21,12 @@
#include "absl/types/span.h"
#include "gtest/gtest.h"
#include <grpc/grpc.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/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<absl::string_view, 2> kEndpoint1Addresses = {
"ipv4:127.0.0.1:443", "ipv4:127.0.0.1:444"};
constexpr std::array<absl::string_view, 2> kEndpoint2Addresses = {
"ipv4:127.0.0.1:445", "ipv4:127.0.0.1:446"};
const std::array<EndpointAddresses, 2> 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

@ -40,12 +40,15 @@
#include <grpc/support/log.h>
#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<absl::string_view /*address*/,
@ -845,6 +848,146 @@ TEST_F(WeightedRoundRobinTest, ZeroErrorUtilPenalty) {
{{kAddresses[0], 1}, {kAddresses[1], 1}, {kAddresses[2], 1}});
}
TEST_F(WeightedRoundRobinTest, MultipleAddressesPerEndpoint) {
if (!IsWrrDelegateToPickFirstEnabled()) 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 WRR.
SetExpectedTimerDuration(absl::nullopt);
constexpr std::array<absl::string_view, 2> kEndpoint1Addresses = {
"ipv4:127.0.0.1:443", "ipv4:127.0.0.1:444"};
constexpr std::array<absl::string_view, 2> kEndpoint2Addresses = {
"ipv4:127.0.0.1:445", "ipv4:127.0.0.1:446"};
constexpr std::array<absl::string_view, 2> kEndpoint3Addresses = {
"ipv4:127.0.0.1:447", "ipv4:127.0.0.1:448"};
const std::array<EndpointAddresses, 3> 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

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

@ -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<const struct sockaddr_un*>(addr.address().addr);
EXPECT_EQ(addr.address().len,

@ -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<grpc_core::WorkSerializer>* 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<grpc_core::ServerAddressList>* addresses,
std::unique_ptr<grpc_core::EndpointAddressesList>* 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<grpc_core::ServerAddressList>* addresses,
std::unique_ptr<grpc_core::EndpointAddressesList>* addresses,
int query_timeout_ms) {
// A records should suffice
grpc_ares_request* result = g_default_dns_lookup_ares(

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

@ -522,12 +522,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",

@ -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<grpc_core::ServerAddressList>* addresses;
std::unique_ptr<grpc_core::EndpointAddressesList>* addresses;
} addr_req;
static void finish_resolve(addr_req r) {
if (0 == strcmp(r.addr, "server")) {
*r.addresses = std::make_unique<grpc_core::ServerAddressList>();
*r.addresses = std::make_unique<grpc_core::EndpointAddressesList>();
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<grpc_core::ServerAddressList>* addresses,
std::unique_ptr<grpc_core::EndpointAddressesList>* addresses,
int /*query_timeout*/) {
addr_req r;
r.addr = gpr_strdup(addr);

@ -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<grpc_core::ServerAddressList>* addresses,
std::unique_ptr<grpc_core::EndpointAddressesList>* 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<grpc_core::ServerAddressList>* addresses,
std::unique_ptr<grpc_core::EndpointAddressesList>* 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<grpc_core::ServerAddressList>();
*addresses = std::make_unique<grpc_core::EndpointAddressesList>();
grpc_resolved_address address;
memset(&address, 0, sizeof(address));
auto* sa = reinterpret_cast<grpc_sockaddr_in*>(&address.addr);

@ -297,7 +297,7 @@ class TestServer {
grpc_core::Resolver::Result BuildResolverResponse(
const std::vector<std::string>& addresses) {
grpc_core::Resolver::Result result;
result.addresses = grpc_core::ServerAddressList();
result.addresses = grpc_core::EndpointAddressesList();
for (const auto& address_str : addresses) {
absl::StatusOr<grpc_core::URI> uri = grpc_core::URI::Parse(address_str);
if (!uri.ok()) {

@ -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<std::string>& addresses) {
grpc_core::Resolver::Result result;
result.addresses = grpc_core::ServerAddressList();
result.addresses = grpc_core::EndpointAddressesList();
for (const auto& address_str : addresses) {
absl::StatusOr<grpc_core::URI> uri = grpc_core::URI::Parse(address_str);
if (!uri.ok()) {

@ -306,13 +306,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",

@ -340,9 +340,10 @@ class AddressTestLoadBalancingPolicy : public ForwardingLoadBalancingPolicy {
cb_(std::move(cb)) {}
RefCountedPtr<SubchannelInterface> 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<OobBackendMetricTestLoadBalancingPolicy> parent)
: address_(std::move(address)), parent_(std::move(parent)) {}
@ -506,7 +507,7 @@ class OobBackendMetricTestLoadBalancingPolicy
}
private:
ServerAddress address_;
EndpointAddresses address_;
RefCountedPtr<OobBackendMetricTestLoadBalancingPolicy> parent_;
};
@ -518,11 +519,14 @@ class OobBackendMetricTestLoadBalancingPolicy
: ParentOwningDelegatingChannelControlHelper(std::move(parent)) {}
RefCountedPtr<SubchannelInterface> 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<BackendMetricWatcher>(
std::move(address), parent()->Ref())));
Duration::Seconds(1),
std::make_unique<BackendMetricWatcher>(
EndpointAddresses(address, per_address_args), parent()->Ref())));
return subchannel;
}
};

@ -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<void(const ServerAddress&)>;
using AddressTestCallback = std::function<void(const EndpointAddresses&)>;
// 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<void(ServerAddress, const BackendMetricData&)>;
std::function<void(EndpointAddresses, const BackendMetricData&)>;
// Registers an LB policy called "oob_backend_metric_test_lb" that invokes
// cb for each OOB backend metric report on each subchannel.

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

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

@ -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<grpc_core::URI> lb_uri = grpc_core::URI::Parse(
absl::StrCat(ipv6_only ? "ipv6:[::1]:" : "ipv4:127.0.0.1:", port));
@ -2792,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());
@ -2821,8 +2821,9 @@ TEST_F(ClientLbAddressTest, Basic) {
// Make sure that the attributes wind up on the subchannels.
std::vector<std::string> 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);
}
@ -2865,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());

@ -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<AddressData>& address_data) {
grpc_core::ServerAddressList addresses;
grpc_core::EndpointAddressesList addresses;
for (const auto& addr : address_data) {
absl::StatusOr<grpc_core::URI> 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));

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

@ -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<int>& ports) {
grpc_core::ServerAddressList addresses;
grpc_core::EndpointAddressesList addresses;
for (int port : ports) {
absl::StatusOr<grpc_core::URI> lb_uri = grpc_core::URI::Parse(
absl::StrCat(ipv6_only_ ? "ipv6:[::1]:" : "ipv4:127.0.0.1:", port));

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

@ -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<int>& ports) {
grpc_core::ServerAddressList addresses;
grpc_core::EndpointAddressesList addresses;
for (int port : ports) {
absl::StatusOr<grpc_core::URI> lb_uri = grpc_core::URI::Parse(
absl::StrCat(ipv6_only_ ? "ipv6:[::1]:" : "ipv4:127.0.0.1:", port));

@ -139,10 +139,11 @@ class BackendMetricsLbPolicy : public LoadBalancingPolicy {
: ParentOwningDelegatingChannelControlHelper(std::move(parent)) {}
RefCountedPtr<grpc_core::SubchannelInterface> 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<OobMetricWatcher>(parent()->load_report_tracker_)));

@ -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<TestAddress>& 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<std::string> expected_addrs) {
EXPECT_EQ(addresses.size(), expected_addrs.size());
for (size_t i = 0; i < addresses.size(); ++i) {

@ -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<GrpcLBAddress> 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<GrpcLBAddress>* out) {
static void AddActualAddresses(
const grpc_core::EndpointAddressesList& addresses, bool is_balancer,
std::vector<GrpcLBAddress>* 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();

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

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

Loading…
Cancel
Save