grpc 1.60.2 → 1.61.0.pre2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (279) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +208 -165
  3. data/include/grpc/event_engine/event_engine.h +59 -12
  4. data/include/grpc/event_engine/internal/memory_allocator_impl.h +6 -0
  5. data/include/grpc/event_engine/internal/slice_cast.h +12 -0
  6. data/include/grpc/event_engine/memory_allocator.h +3 -1
  7. data/include/grpc/event_engine/slice.h +5 -0
  8. data/include/grpc/grpc_security.h +22 -1
  9. data/include/grpc/impl/call.h +29 -0
  10. data/include/grpc/impl/channel_arg_names.h +12 -1
  11. data/include/grpc/impl/slice_type.h +1 -1
  12. data/include/grpc/module.modulemap +1 -0
  13. data/src/core/ext/filters/backend_metrics/backend_metric_filter.cc +54 -7
  14. data/src/core/ext/filters/backend_metrics/backend_metric_filter.h +20 -6
  15. data/src/core/ext/filters/channel_idle/channel_idle_filter.cc +10 -13
  16. data/src/core/ext/filters/channel_idle/channel_idle_filter.h +18 -10
  17. data/src/core/ext/filters/channel_idle/legacy_channel_idle_filter.cc +326 -0
  18. data/src/core/ext/filters/channel_idle/legacy_channel_idle_filter.h +143 -0
  19. data/src/core/ext/filters/client_channel/backend_metric.cc +2 -2
  20. data/src/core/ext/filters/client_channel/client_channel.cc +32 -6
  21. data/src/core/ext/filters/client_channel/client_channel_internal.h +2 -0
  22. data/src/core/ext/filters/client_channel/global_subchannel_pool.cc +1 -1
  23. data/src/core/ext/filters/client_channel/lb_policy/address_filtering.cc +54 -21
  24. data/src/core/ext/filters/client_channel/lb_policy/address_filtering.h +3 -2
  25. data/src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc +2 -1
  26. data/src/core/ext/filters/client_channel/lb_policy/endpoint_list.cc +12 -15
  27. data/src/core/ext/filters/client_channel/lb_policy/endpoint_list.h +8 -5
  28. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +139 -92
  29. data/src/core/ext/filters/client_channel/lb_policy/health_check_client.cc +9 -4
  30. data/src/core/ext/filters/client_channel/lb_policy/oob_backend_metric.cc +9 -4
  31. data/src/core/ext/filters/client_channel/lb_policy/outlier_detection/outlier_detection.cc +10 -11
  32. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +94 -93
  33. data/src/core/ext/filters/client_channel/lb_policy/priority/priority.cc +5 -3
  34. data/src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.cc +12 -15
  35. data/src/core/ext/filters/client_channel/lb_policy/rls/rls.cc +38 -16
  36. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +25 -28
  37. data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +10 -10
  38. data/src/core/ext/filters/client_channel/lb_policy/weighted_round_robin/weighted_round_robin.cc +37 -35
  39. data/src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc +11 -9
  40. data/src/core/ext/filters/client_channel/lb_policy/xds/cds.cc +504 -461
  41. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc +232 -122
  42. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc +8 -6
  43. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_override_host.cc +642 -251
  44. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_override_host.h +2 -6
  45. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_wrr_locality.cc +7 -8
  46. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +2 -1
  47. data/src/core/ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.cc +3 -1
  48. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +2 -2
  49. data/src/core/ext/filters/client_channel/resolver/google_c2p/google_c2p_resolver.cc +2 -2
  50. data/src/core/ext/filters/client_channel/resolver/polling_resolver.cc +6 -8
  51. data/src/core/ext/filters/client_channel/resolver/xds/xds_dependency_manager.cc +1031 -0
  52. data/src/core/ext/filters/client_channel/resolver/xds/xds_dependency_manager.h +277 -0
  53. data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc +128 -270
  54. data/src/core/ext/filters/client_channel/resolver/xds/{xds_resolver.h → xds_resolver_attributes.h} +5 -4
  55. data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver_trace.cc +25 -0
  56. data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver_trace.h +30 -0
  57. data/src/core/ext/filters/client_channel/retry_filter.cc +1 -0
  58. data/src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc +35 -17
  59. data/src/core/ext/filters/deadline/deadline_filter.cc +12 -0
  60. data/src/core/ext/filters/fault_injection/fault_injection_filter.cc +17 -13
  61. data/src/core/ext/filters/fault_injection/fault_injection_filter.h +13 -4
  62. data/src/core/ext/filters/http/client/http_client_filter.cc +23 -32
  63. data/src/core/ext/filters/http/client/http_client_filter.h +10 -5
  64. data/src/core/ext/filters/http/client_authority_filter.cc +14 -14
  65. data/src/core/ext/filters/http/client_authority_filter.h +12 -4
  66. data/src/core/ext/filters/http/http_filters_plugin.cc +42 -20
  67. data/src/core/ext/filters/http/message_compress/compression_filter.cc +55 -80
  68. data/src/core/ext/filters/http/message_compress/compression_filter.h +54 -12
  69. data/src/core/ext/filters/http/message_compress/legacy_compression_filter.cc +325 -0
  70. data/src/core/ext/filters/http/message_compress/legacy_compression_filter.h +139 -0
  71. data/src/core/ext/filters/http/server/http_server_filter.cc +41 -41
  72. data/src/core/ext/filters/http/server/http_server_filter.h +11 -4
  73. data/src/core/ext/filters/message_size/message_size_filter.cc +56 -76
  74. data/src/core/ext/filters/message_size/message_size_filter.h +35 -23
  75. data/src/core/ext/filters/rbac/rbac_filter.cc +15 -11
  76. data/src/core/ext/filters/rbac/rbac_filter.h +11 -4
  77. data/src/core/ext/filters/server_config_selector/server_config_selector_filter.cc +25 -13
  78. data/src/core/ext/filters/stateful_session/stateful_session_filter.cc +47 -50
  79. data/src/core/ext/filters/stateful_session/stateful_session_filter.h +21 -4
  80. data/src/core/ext/transport/chttp2/alpn/alpn.cc +1 -1
  81. data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +2 -2
  82. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +11 -2
  83. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +68 -145
  84. data/src/core/ext/transport/chttp2/transport/chttp2_transport.h +3 -3
  85. data/src/core/ext/transport/chttp2/transport/flow_control.cc +21 -82
  86. data/src/core/ext/transport/chttp2/transport/flow_control.h +1 -8
  87. data/src/core/ext/transport/chttp2/transport/frame.cc +506 -0
  88. data/src/core/ext/transport/chttp2/transport/frame.h +214 -0
  89. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +1 -1
  90. data/src/core/ext/transport/chttp2/transport/frame_settings.cc +33 -79
  91. data/src/core/ext/transport/chttp2/transport/frame_settings.h +4 -7
  92. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +27 -36
  93. data/src/core/ext/transport/chttp2/transport/hpack_parser.h +0 -2
  94. data/src/core/ext/transport/chttp2/transport/http2_settings.cc +122 -32
  95. data/src/core/ext/transport/chttp2/transport/http2_settings.h +142 -37
  96. data/src/core/ext/transport/chttp2/transport/internal.h +1 -22
  97. data/src/core/ext/transport/chttp2/transport/parsing.cc +23 -37
  98. data/src/core/ext/transport/chttp2/transport/writing.cc +26 -58
  99. data/src/core/ext/transport/inproc/inproc_transport.cc +172 -13
  100. data/src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb.h +712 -0
  101. data/src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.c +151 -0
  102. data/src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.h +33 -0
  103. data/src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.c +133 -0
  104. data/src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.h +50 -0
  105. data/src/core/ext/xds/certificate_provider_store.cc +2 -1
  106. data/src/core/ext/xds/certificate_provider_store.h +0 -5
  107. data/src/core/ext/xds/xds_api.cc +31 -18
  108. data/src/core/ext/xds/xds_api.h +2 -2
  109. data/src/core/ext/xds/xds_bootstrap.h +3 -0
  110. data/src/core/ext/xds/xds_certificate_provider.cc +88 -287
  111. data/src/core/ext/xds/xds_certificate_provider.h +44 -111
  112. data/src/core/ext/xds/xds_client.cc +420 -414
  113. data/src/core/ext/xds/xds_client.h +31 -22
  114. data/src/core/ext/xds/xds_client_grpc.cc +3 -1
  115. data/src/core/ext/xds/xds_cluster.cc +104 -11
  116. data/src/core/ext/xds/xds_cluster.h +9 -1
  117. data/src/core/ext/xds/xds_cluster_specifier_plugin.cc +9 -5
  118. data/src/core/ext/xds/xds_common_types.cc +14 -10
  119. data/src/core/ext/xds/xds_endpoint.cc +9 -4
  120. data/src/core/ext/xds/xds_endpoint.h +5 -1
  121. data/src/core/ext/xds/xds_health_status.cc +12 -2
  122. data/src/core/ext/xds/xds_health_status.h +4 -2
  123. data/src/core/ext/xds/xds_http_rbac_filter.cc +5 -3
  124. data/src/core/ext/xds/xds_listener.cc +14 -8
  125. data/src/core/ext/xds/xds_resource_type_impl.h +6 -4
  126. data/src/core/ext/xds/xds_route_config.cc +34 -22
  127. data/src/core/ext/xds/xds_route_config.h +1 -0
  128. data/src/core/ext/xds/xds_server_config_fetcher.cc +61 -57
  129. data/src/core/ext/xds/xds_transport.h +3 -0
  130. data/src/core/ext/xds/xds_transport_grpc.cc +47 -50
  131. data/src/core/ext/xds/xds_transport_grpc.h +4 -0
  132. data/src/core/lib/channel/call_tracer.cc +12 -0
  133. data/src/core/lib/channel/call_tracer.h +17 -3
  134. data/src/core/lib/channel/channel_args.cc +24 -14
  135. data/src/core/lib/channel/channel_args.h +74 -13
  136. data/src/core/lib/channel/channel_stack.cc +27 -0
  137. data/src/core/lib/channel/channel_stack.h +10 -10
  138. data/src/core/lib/channel/connected_channel.cc +64 -18
  139. data/src/core/lib/channel/promise_based_filter.h +1041 -1
  140. data/src/core/lib/channel/server_call_tracer_filter.cc +43 -35
  141. data/src/core/lib/compression/compression_internal.cc +0 -3
  142. data/src/core/lib/event_engine/ares_resolver.cc +35 -14
  143. data/src/core/lib/event_engine/ares_resolver.h +9 -10
  144. data/src/core/lib/event_engine/cf_engine/dns_service_resolver.cc +8 -1
  145. data/src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc +132 -0
  146. data/src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.h +61 -0
  147. data/src/core/lib/event_engine/posix_engine/posix_engine.cc +52 -36
  148. data/src/core/lib/event_engine/posix_engine/posix_engine.h +4 -9
  149. data/src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.cc +11 -3
  150. data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.cc +9 -2
  151. data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.h +7 -0
  152. data/src/core/lib/event_engine/posix_engine/timer_manager.cc +17 -27
  153. data/src/core/lib/event_engine/posix_engine/timer_manager.h +0 -3
  154. data/src/core/lib/event_engine/ref_counted_dns_resolver_interface.h +55 -0
  155. data/src/core/lib/event_engine/windows/native_windows_dns_resolver.cc +114 -0
  156. data/src/core/lib/event_engine/windows/native_windows_dns_resolver.h +51 -0
  157. data/src/core/lib/event_engine/windows/windows_engine.cc +7 -7
  158. data/src/core/lib/experiments/config.cc +13 -0
  159. data/src/core/lib/experiments/config.h +3 -0
  160. data/src/core/lib/experiments/experiments.cc +245 -366
  161. data/src/core/lib/experiments/experiments.h +50 -156
  162. data/src/core/lib/gprpp/debug_location.h +13 -0
  163. data/src/core/lib/gprpp/dual_ref_counted.h +36 -7
  164. data/src/core/lib/gprpp/orphanable.h +27 -0
  165. data/src/core/lib/gprpp/ref_counted.h +63 -22
  166. data/src/core/lib/gprpp/ref_counted_ptr.h +70 -27
  167. data/src/core/lib/gprpp/ref_counted_string.h +13 -0
  168. data/src/core/lib/gprpp/status_helper.cc +1 -2
  169. data/src/core/lib/iomgr/combiner.cc +15 -51
  170. data/src/core/lib/iomgr/event_engine_shims/endpoint.cc +31 -0
  171. data/src/core/lib/iomgr/event_engine_shims/endpoint.h +16 -0
  172. data/src/core/lib/iomgr/tcp_client_posix.cc +4 -3
  173. data/src/core/lib/load_balancing/lb_policy.h +1 -1
  174. data/src/core/lib/promise/activity.cc +17 -2
  175. data/src/core/lib/promise/activity.h +5 -4
  176. data/src/core/lib/promise/all_ok.h +80 -0
  177. data/src/core/lib/promise/detail/join_state.h +2077 -0
  178. data/src/core/lib/promise/detail/promise_factory.h +1 -0
  179. data/src/core/lib/promise/detail/promise_like.h +8 -1
  180. data/src/core/lib/promise/detail/seq_state.h +3458 -150
  181. data/src/core/lib/promise/detail/status.h +42 -5
  182. data/src/core/lib/promise/for_each.h +13 -1
  183. data/src/core/lib/promise/if.h +4 -0
  184. data/src/core/lib/promise/latch.h +6 -3
  185. data/src/core/lib/promise/party.cc +33 -31
  186. data/src/core/lib/promise/party.h +142 -6
  187. data/src/core/lib/promise/poll.h +39 -13
  188. data/src/core/lib/promise/promise.h +4 -0
  189. data/src/core/lib/promise/seq.h +107 -7
  190. data/src/core/lib/promise/status_flag.h +196 -0
  191. data/src/core/lib/promise/try_join.h +132 -0
  192. data/src/core/lib/promise/try_seq.h +132 -10
  193. data/src/core/lib/resolver/endpoint_addresses.cc +0 -1
  194. data/src/core/lib/resolver/endpoint_addresses.h +48 -0
  195. data/src/core/lib/resource_quota/arena.h +2 -2
  196. data/src/core/lib/resource_quota/memory_quota.cc +57 -8
  197. data/src/core/lib/resource_quota/memory_quota.h +6 -0
  198. data/src/core/lib/security/authorization/grpc_server_authz_filter.cc +14 -11
  199. data/src/core/lib/security/authorization/grpc_server_authz_filter.h +14 -5
  200. data/src/core/lib/security/credentials/external/aws_external_account_credentials.cc +4 -0
  201. data/src/core/lib/security/credentials/external/aws_external_account_credentials.h +4 -0
  202. data/src/core/lib/security/credentials/external/external_account_credentials.cc +28 -20
  203. data/src/core/lib/security/credentials/external/external_account_credentials.h +4 -0
  204. data/src/core/lib/security/credentials/external/file_external_account_credentials.cc +4 -0
  205. data/src/core/lib/security/credentials/external/file_external_account_credentials.h +4 -0
  206. data/src/core/lib/security/credentials/external/url_external_account_credentials.cc +4 -0
  207. data/src/core/lib/security/credentials/external/url_external_account_credentials.h +4 -0
  208. data/src/core/lib/security/credentials/plugin/plugin_credentials.cc +2 -1
  209. data/src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h +0 -3
  210. data/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc +12 -0
  211. data/src/core/lib/security/credentials/tls/grpc_tls_crl_provider.cc +22 -5
  212. data/src/core/lib/security/credentials/tls/grpc_tls_crl_provider.h +1 -5
  213. data/src/core/lib/security/credentials/tls/tls_credentials.cc +16 -0
  214. data/src/core/lib/security/credentials/xds/xds_credentials.cc +21 -28
  215. data/src/core/lib/security/credentials/xds/xds_credentials.h +2 -4
  216. data/src/core/lib/security/security_connector/tls/tls_security_connector.cc +4 -3
  217. data/src/core/lib/security/transport/auth_filters.h +71 -4
  218. data/src/core/lib/security/transport/client_auth_filter.cc +2 -4
  219. data/src/core/lib/security/transport/legacy_server_auth_filter.cc +244 -0
  220. data/src/core/lib/security/transport/server_auth_filter.cc +70 -90
  221. data/src/core/lib/slice/slice_buffer.h +3 -0
  222. data/src/core/lib/surface/builtins.cc +1 -1
  223. data/src/core/lib/surface/call.cc +683 -196
  224. data/src/core/lib/surface/call.h +26 -13
  225. data/src/core/lib/surface/call_trace.cc +42 -1
  226. data/src/core/lib/surface/channel.cc +0 -1
  227. data/src/core/lib/surface/channel.h +0 -6
  228. data/src/core/lib/surface/channel_init.h +26 -0
  229. data/src/core/lib/surface/init.cc +14 -8
  230. data/src/core/lib/surface/server.cc +256 -237
  231. data/src/core/lib/surface/server.h +26 -54
  232. data/src/core/lib/surface/version.cc +2 -2
  233. data/src/core/lib/surface/wait_for_cq_end_op.h +94 -0
  234. data/src/core/lib/transport/call_final_info.cc +38 -0
  235. data/src/core/lib/transport/call_final_info.h +54 -0
  236. data/src/core/lib/transport/connectivity_state.cc +3 -2
  237. data/src/core/lib/transport/connectivity_state.h +4 -0
  238. data/src/core/lib/transport/metadata_batch.h +4 -4
  239. data/src/core/lib/transport/transport.cc +70 -19
  240. data/src/core/lib/transport/transport.h +395 -25
  241. data/src/core/plugin_registry/grpc_plugin_registry.cc +3 -0
  242. data/src/core/plugin_registry/grpc_plugin_registry_extra.cc +0 -3
  243. data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +1 -1
  244. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +1 -1
  245. data/src/core/tsi/alts/handshaker/transport_security_common_api.cc +1 -1
  246. data/src/core/tsi/ssl_transport_security.cc +65 -43
  247. data/src/ruby/ext/grpc/rb_channel_args.c +3 -1
  248. data/src/ruby/ext/grpc/rb_grpc.c +0 -1
  249. data/src/ruby/ext/grpc/rb_grpc.h +0 -2
  250. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +4 -0
  251. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +6 -0
  252. data/src/ruby/lib/grpc/version.rb +1 -1
  253. data/third_party/upb/upb/reflection/def_pool.h +2 -2
  254. data/third_party/zlib/adler32.c +5 -27
  255. data/third_party/zlib/compress.c +5 -16
  256. data/third_party/zlib/crc32.c +86 -162
  257. data/third_party/zlib/deflate.c +233 -336
  258. data/third_party/zlib/deflate.h +8 -8
  259. data/third_party/zlib/gzguts.h +11 -12
  260. data/third_party/zlib/infback.c +7 -23
  261. data/third_party/zlib/inffast.c +1 -4
  262. data/third_party/zlib/inffast.h +1 -1
  263. data/third_party/zlib/inflate.c +30 -99
  264. data/third_party/zlib/inftrees.c +6 -11
  265. data/third_party/zlib/inftrees.h +3 -3
  266. data/third_party/zlib/trees.c +224 -302
  267. data/third_party/zlib/uncompr.c +4 -12
  268. data/third_party/zlib/zconf.h +6 -2
  269. data/third_party/zlib/zlib.h +191 -188
  270. data/third_party/zlib/zutil.c +16 -44
  271. data/third_party/zlib/zutil.h +10 -10
  272. metadata +35 -13
  273. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc +0 -1173
  274. data/src/core/lib/event_engine/memory_allocator.cc +0 -74
  275. data/src/core/lib/transport/pid_controller.cc +0 -51
  276. data/src/core/lib/transport/pid_controller.h +0 -116
  277. data/third_party/upb/upb/collections/array.h +0 -17
  278. data/third_party/upb/upb/collections/map.h +0 -17
  279. data/third_party/upb/upb/upb.hpp +0 -18
@@ -20,11 +20,13 @@
20
20
 
21
21
  #include <stddef.h>
22
22
 
23
- #include <algorithm>
24
23
  #include <utility>
25
24
 
25
+ #include "absl/functional/function_ref.h"
26
+
26
27
  #include "src/core/lib/channel/channel_args.h"
27
28
  #include "src/core/lib/gprpp/ref_counted_ptr.h"
29
+ #include "src/core/lib/iomgr/resolved_address.h"
28
30
 
29
31
  namespace grpc_core {
30
32
 
@@ -43,32 +45,63 @@ int HierarchicalPathArg::ChannelArgsCompare(const HierarchicalPathArg* a,
43
45
  return 0;
44
46
  }
45
47
 
48
+ namespace {
49
+
50
+ class HierarchicalAddressIterator : public EndpointAddressesIterator {
51
+ public:
52
+ HierarchicalAddressIterator(
53
+ std::shared_ptr<EndpointAddressesIterator> parent_it,
54
+ RefCountedStringValue child_name)
55
+ : parent_it_(std::move(parent_it)), child_name_(std::move(child_name)) {}
56
+
57
+ void ForEach(absl::FunctionRef<void(const EndpointAddresses&)> callback)
58
+ const override {
59
+ RefCountedPtr<HierarchicalPathArg> remaining_path_attr;
60
+ parent_it_->ForEach([&](const EndpointAddresses& endpoint) {
61
+ const auto* path_arg = endpoint.args().GetObject<HierarchicalPathArg>();
62
+ if (path_arg == nullptr) return;
63
+ const std::vector<RefCountedStringValue>& path = path_arg->path();
64
+ auto it = path.begin();
65
+ if (it == path.end()) return;
66
+ if (*it != child_name_) return;
67
+ ChannelArgs args = endpoint.args();
68
+ ++it;
69
+ if (it != path.end()) {
70
+ std::vector<RefCountedStringValue> remaining_path(it, path.end());
71
+ if (remaining_path_attr == nullptr ||
72
+ remaining_path_attr->path() != remaining_path) {
73
+ remaining_path_attr =
74
+ MakeRefCounted<HierarchicalPathArg>(std::move(remaining_path));
75
+ }
76
+ args = args.SetObject(remaining_path_attr);
77
+ }
78
+ callback(EndpointAddresses(endpoint.addresses(), args));
79
+ });
80
+ }
81
+
82
+ private:
83
+ std::shared_ptr<EndpointAddressesIterator> parent_it_;
84
+ RefCountedStringValue child_name_;
85
+ };
86
+
87
+ } // namespace
88
+
46
89
  absl::StatusOr<HierarchicalAddressMap> MakeHierarchicalAddressMap(
47
- const absl::StatusOr<EndpointAddressesList>& addresses) {
90
+ absl::StatusOr<std::shared_ptr<EndpointAddressesIterator>> addresses) {
48
91
  if (!addresses.ok()) return addresses.status();
49
92
  HierarchicalAddressMap result;
50
- RefCountedPtr<HierarchicalPathArg> remaining_path_attr;
51
- for (const EndpointAddresses& endpoint_addresses : *addresses) {
52
- const auto* path_arg =
53
- endpoint_addresses.args().GetObject<HierarchicalPathArg>();
54
- if (path_arg == nullptr) continue;
93
+ (*addresses)->ForEach([&](const EndpointAddresses& endpoint) {
94
+ const auto* path_arg = endpoint.args().GetObject<HierarchicalPathArg>();
95
+ if (path_arg == nullptr) return;
55
96
  const std::vector<RefCountedStringValue>& path = path_arg->path();
56
97
  auto it = path.begin();
57
- if (it == path.end()) continue;
58
- EndpointAddressesList& target_list = result[*it];
59
- ChannelArgs args = endpoint_addresses.args();
60
- ++it;
61
- if (it != path.end()) {
62
- std::vector<RefCountedStringValue> remaining_path(it, path.end());
63
- if (remaining_path_attr == nullptr ||
64
- remaining_path_attr->path() != remaining_path) {
65
- remaining_path_attr =
66
- MakeRefCounted<HierarchicalPathArg>(std::move(remaining_path));
67
- }
68
- args = args.SetObject(remaining_path_attr);
98
+ if (it == path.end()) return;
99
+ auto& target_list = result[*it];
100
+ if (target_list == nullptr) {
101
+ target_list =
102
+ std::make_shared<HierarchicalAddressIterator>(*addresses, *it);
69
103
  }
70
- target_list.emplace_back(endpoint_addresses.addresses(), args);
71
- }
104
+ });
72
105
  return result;
73
106
  }
74
107
 
@@ -20,6 +20,7 @@
20
20
  #include <grpc/support/port_platform.h>
21
21
 
22
22
  #include <map>
23
+ #include <memory>
23
24
  #include <utility>
24
25
  #include <vector>
25
26
 
@@ -105,12 +106,12 @@ class HierarchicalPathArg : public RefCounted<HierarchicalPathArg> {
105
106
  // A map from the next path element to the endpoint addresses that fall
106
107
  // under that path element.
107
108
  using HierarchicalAddressMap =
108
- std::map<RefCountedStringValue, EndpointAddressesList,
109
+ std::map<RefCountedStringValue, std::shared_ptr<EndpointAddressesIterator>,
109
110
  RefCountedStringValueLessThan>;
110
111
 
111
112
  // Splits up the addresses into a separate list for each child.
112
113
  absl::StatusOr<HierarchicalAddressMap> MakeHierarchicalAddressMap(
113
- const absl::StatusOr<EndpointAddressesList>& addresses);
114
+ absl::StatusOr<std::shared_ptr<EndpointAddressesIterator>> addresses);
114
115
 
115
116
  } // namespace grpc_core
116
117
 
@@ -272,7 +272,8 @@ void ChildPolicyHandler::ResetBackoffLocked() {
272
272
 
273
273
  OrphanablePtr<LoadBalancingPolicy> ChildPolicyHandler::CreateChildPolicy(
274
274
  absl::string_view child_policy_name, const ChannelArgs& args) {
275
- Helper* helper = new Helper(Ref(DEBUG_LOCATION, "Helper"));
275
+ Helper* helper =
276
+ new Helper(RefAsSubclass<ChildPolicyHandler>(DEBUG_LOCATION, "Helper"));
276
277
  LoadBalancingPolicy::Args lb_policy_args;
277
278
  lb_policy_args.work_serializer = work_serializer();
278
279
  lb_policy_args.channel_control_helper =
@@ -69,6 +69,9 @@ class EndpointList::Endpoint::Helper
69
69
  grpc_connectivity_state state, const absl::Status& status,
70
70
  RefCountedPtr<LoadBalancingPolicy::SubchannelPicker> picker) override {
71
71
  auto old_state = std::exchange(endpoint_->connectivity_state_, state);
72
+ if (!old_state.has_value()) {
73
+ ++endpoint_->endpoint_list_->num_endpoints_seen_initial_state_;
74
+ }
72
75
  endpoint_->picker_ = std::move(picker);
73
76
  endpoint_->OnStateUpdate(old_state, state, status);
74
77
  }
@@ -118,7 +121,7 @@ void EndpointList::Endpoint::Init(
118
121
  GPR_ASSERT(config.ok());
119
122
  // Update child policy.
120
123
  LoadBalancingPolicy::UpdateArgs update_args;
121
- update_args.addresses.emplace().emplace_back(addresses);
124
+ update_args.addresses = std::make_shared<SingleEndpointIterator>(addresses);
122
125
  update_args.args = child_args;
123
126
  update_args.config = std::move(*config);
124
127
  // TODO(roth): If the child reports a non-OK status with the update,
@@ -163,15 +166,16 @@ RefCountedPtr<SubchannelInterface> EndpointList::Endpoint::CreateSubchannel(
163
166
  //
164
167
 
165
168
  void EndpointList::Init(
166
- const EndpointAddressesList& endpoints, const ChannelArgs& args,
167
- absl::AnyInvocable<OrphanablePtr<Endpoint>(RefCountedPtr<EndpointList>,
168
- const EndpointAddresses&,
169
- const ChannelArgs&)>
169
+ EndpointAddressesIterator* endpoints, const ChannelArgs& args,
170
+ absl::FunctionRef<OrphanablePtr<Endpoint>(RefCountedPtr<EndpointList>,
171
+ const EndpointAddresses&,
172
+ const ChannelArgs&)>
170
173
  create_endpoint) {
171
- for (const EndpointAddresses& addresses : endpoints) {
174
+ if (endpoints == nullptr) return;
175
+ endpoints->ForEach([&](const EndpointAddresses& endpoint) {
172
176
  endpoints_.push_back(
173
- create_endpoint(Ref(DEBUG_LOCATION, "Endpoint"), addresses, args));
174
- }
177
+ create_endpoint(Ref(DEBUG_LOCATION, "Endpoint"), endpoint, args));
178
+ });
175
179
  }
176
180
 
177
181
  void EndpointList::ResetBackoffLocked() {
@@ -180,11 +184,4 @@ void EndpointList::ResetBackoffLocked() {
180
184
  }
181
185
  }
182
186
 
183
- bool EndpointList::AllEndpointsSeenInitialState() const {
184
- for (const auto& endpoint : endpoints_) {
185
- if (!endpoint->connectivity_state().has_value()) return false;
186
- }
187
- return true;
188
- }
189
-
190
187
  } // namespace grpc_core
@@ -25,7 +25,7 @@
25
25
  #include <utility>
26
26
  #include <vector>
27
27
 
28
- #include "absl/functional/any_invocable.h"
28
+ #include "absl/functional/function_ref.h"
29
29
  #include "absl/status/status.h"
30
30
  #include "absl/types/optional.h"
31
31
 
@@ -53,7 +53,7 @@ namespace grpc_core {
53
53
  class MyEndpointList : public EndpointList {
54
54
  public:
55
55
  MyEndpointList(RefCountedPtr<MyLbPolicy> lb_policy,
56
- const EndpointAddressesList& endpoints,
56
+ EndpointAddressesIterator* endpoints,
57
57
  const ChannelArgs& args)
58
58
  : EndpointList(std::move(lb_policy),
59
59
  GRPC_TRACE_FLAG_ENABLED(grpc_my_tracer)
@@ -184,8 +184,8 @@ class EndpointList : public InternallyRefCounted<EndpointList> {
184
184
  EndpointList(RefCountedPtr<LoadBalancingPolicy> policy, const char* tracer)
185
185
  : policy_(std::move(policy)), tracer_(tracer) {}
186
186
 
187
- void Init(const EndpointAddressesList& endpoints, const ChannelArgs& args,
188
- absl::AnyInvocable<OrphanablePtr<Endpoint>(
187
+ void Init(EndpointAddressesIterator* endpoints, const ChannelArgs& args,
188
+ absl::FunctionRef<OrphanablePtr<Endpoint>(
189
189
  RefCountedPtr<EndpointList>, const EndpointAddresses&,
190
190
  const ChannelArgs&)>
191
191
  create_endpoint);
@@ -199,7 +199,9 @@ class EndpointList : public InternallyRefCounted<EndpointList> {
199
199
 
200
200
  // Returns true if all endpoints have seen their initial connectivity
201
201
  // state notification.
202
- bool AllEndpointsSeenInitialState() const;
202
+ bool AllEndpointsSeenInitialState() const {
203
+ return num_endpoints_seen_initial_state_ == size();
204
+ }
203
205
 
204
206
  private:
205
207
  // Returns the parent policy's helper. Needed because the accessor
@@ -210,6 +212,7 @@ class EndpointList : public InternallyRefCounted<EndpointList> {
210
212
  RefCountedPtr<LoadBalancingPolicy> policy_;
211
213
  const char* tracer_;
212
214
  std::vector<OrphanablePtr<Endpoint>> endpoints_;
215
+ size_t num_endpoints_seen_initial_state_ = 0;
213
216
  };
214
217
 
215
218
  } // namespace grpc_core
@@ -72,6 +72,7 @@
72
72
  #include <vector>
73
73
 
74
74
  #include "absl/container/inlined_vector.h"
75
+ #include "absl/functional/function_ref.h"
75
76
  #include "absl/status/status.h"
76
77
  #include "absl/status/statusor.h"
77
78
  #include "absl/strings/str_cat.h"
@@ -80,7 +81,7 @@
80
81
  #include "absl/strings/string_view.h"
81
82
  #include "absl/types/optional.h"
82
83
  #include "absl/types/variant.h"
83
- #include "upb/upb.hpp"
84
+ #include "upb/mem/arena.hpp"
84
85
 
85
86
  #include <grpc/byte_buffer.h>
86
87
  #include <grpc/byte_buffer_reader.h>
@@ -323,9 +324,8 @@ class GrpcLb : public LoadBalancingPolicy {
323
324
  }
324
325
  return;
325
326
  }
326
- WeakRefCountedPtr<SubchannelWrapper> self = WeakRef();
327
327
  lb_policy_->work_serializer()->Run(
328
- [self = std::move(self)]() {
328
+ [self = WeakRefAsSubclass<SubchannelWrapper>()]() {
329
329
  if (!self->lb_policy_->shutting_down_) {
330
330
  self->lb_policy_->CacheDeletedSubchannelLocked(
331
331
  self->wrapped_subchannel());
@@ -384,9 +384,9 @@ class GrpcLb : public LoadBalancingPolicy {
384
384
  // Returns a text representation suitable for logging.
385
385
  std::string AsText() const;
386
386
 
387
- // Extracts all non-drop entries into an EndpointAddressesList.
388
- EndpointAddressesList GetServerAddressList(
389
- GrpcLbClientStats* client_stats) const;
387
+ // Extracts all non-drop entries into an EndpointAddressesIterator.
388
+ std::shared_ptr<EndpointAddressesIterator> GetServerAddressList(
389
+ GrpcLbClientStats* client_stats);
390
390
 
391
391
  // Returns true if the serverlist contains at least one drop entry and
392
392
  // no backend address entries.
@@ -400,6 +400,8 @@ class GrpcLb : public LoadBalancingPolicy {
400
400
  const char* ShouldDrop();
401
401
 
402
402
  private:
403
+ class AddressIterator;
404
+
403
405
  std::vector<GrpcLbServer> serverlist_;
404
406
 
405
407
  // Accessed from the picker, so needs synchronization.
@@ -504,6 +506,8 @@ class GrpcLb : public LoadBalancingPolicy {
504
506
  RefCountedPtr<GrpcLb> parent_;
505
507
  };
506
508
 
509
+ class NullLbTokenEndpointIterator;
510
+
507
511
  void ShutdownLocked() override;
508
512
 
509
513
  // Helper functions used in UpdateLocked().
@@ -569,7 +573,8 @@ class GrpcLb : public LoadBalancingPolicy {
569
573
  // Whether we're in fallback mode.
570
574
  bool fallback_mode_ = false;
571
575
  // The backend addresses from the resolver.
572
- absl::StatusOr<EndpointAddressesList> fallback_backend_addresses_;
576
+ absl::StatusOr<std::shared_ptr<NullLbTokenEndpointIterator>>
577
+ fallback_backend_addresses_;
573
578
  // The last resolution note from our parent.
574
579
  // To be passed to child policy when fallback_backend_addresses_ is empty.
575
580
  std::string resolution_note_;
@@ -594,11 +599,30 @@ class GrpcLb : public LoadBalancingPolicy {
594
599
  };
595
600
 
596
601
  //
597
- // GrpcLb::Serverlist
602
+ // GrpcLb::Serverlist::AddressIterator
598
603
  //
599
604
 
600
- bool GrpcLb::Serverlist::operator==(const Serverlist& other) const {
601
- return serverlist_ == other.serverlist_;
605
+ bool IsServerValid(const GrpcLbServer& server, size_t idx, bool log) {
606
+ if (server.drop) return false;
607
+ if (GPR_UNLIKELY(server.port >> 16 != 0)) {
608
+ if (log) {
609
+ gpr_log(GPR_ERROR,
610
+ "Invalid port '%d' at index %" PRIuPTR
611
+ " of serverlist. Ignoring.",
612
+ server.port, idx);
613
+ }
614
+ return false;
615
+ }
616
+ if (GPR_UNLIKELY(server.ip_size != 4 && server.ip_size != 16)) {
617
+ if (log) {
618
+ gpr_log(GPR_ERROR,
619
+ "Expected IP to be 4 or 16 bytes, got %d at index %" PRIuPTR
620
+ " of serverlist. Ignoring",
621
+ server.ip_size, idx);
622
+ }
623
+ return false;
624
+ }
625
+ return true;
602
626
  }
603
627
 
604
628
  void ParseServer(const GrpcLbServer& server, grpc_resolved_address* addr) {
@@ -623,6 +647,53 @@ void ParseServer(const GrpcLbServer& server, grpc_resolved_address* addr) {
623
647
  }
624
648
  }
625
649
 
650
+ class GrpcLb::Serverlist::AddressIterator : public EndpointAddressesIterator {
651
+ public:
652
+ AddressIterator(RefCountedPtr<Serverlist> serverlist,
653
+ RefCountedPtr<GrpcLbClientStats> client_stats)
654
+ : serverlist_(std::move(serverlist)),
655
+ client_stats_(std::move(client_stats)) {}
656
+
657
+ void ForEach(absl::FunctionRef<void(const EndpointAddresses&)> callback)
658
+ const override {
659
+ for (size_t i = 0; i < serverlist_->serverlist_.size(); ++i) {
660
+ const GrpcLbServer& server = serverlist_->serverlist_[i];
661
+ if (!IsServerValid(server, i, false)) continue;
662
+ // Address processing.
663
+ grpc_resolved_address addr;
664
+ ParseServer(server, &addr);
665
+ // LB token processing.
666
+ const size_t lb_token_length = strnlen(
667
+ server.load_balance_token, GPR_ARRAY_SIZE(server.load_balance_token));
668
+ std::string lb_token(server.load_balance_token, lb_token_length);
669
+ if (lb_token.empty()) {
670
+ auto addr_uri = grpc_sockaddr_to_uri(&addr);
671
+ gpr_log(GPR_INFO,
672
+ "Missing LB token for backend address '%s'. The empty token "
673
+ "will be used instead",
674
+ addr_uri.ok() ? addr_uri->c_str()
675
+ : addr_uri.status().ToString().c_str());
676
+ }
677
+ // Return address with a channel arg containing LB token and stats object.
678
+ callback(EndpointAddresses(
679
+ addr, ChannelArgs().SetObject(MakeRefCounted<TokenAndClientStatsArg>(
680
+ std::move(lb_token), client_stats_))));
681
+ }
682
+ }
683
+
684
+ private:
685
+ RefCountedPtr<Serverlist> serverlist_;
686
+ RefCountedPtr<GrpcLbClientStats> client_stats_;
687
+ };
688
+
689
+ //
690
+ // GrpcLb::Serverlist
691
+ //
692
+
693
+ bool GrpcLb::Serverlist::operator==(const Serverlist& other) const {
694
+ return serverlist_ == other.serverlist_;
695
+ }
696
+
626
697
  std::string GrpcLb::Serverlist::AsText() const {
627
698
  std::vector<std::string> entries;
628
699
  for (size_t i = 0; i < serverlist_.size(); ++i) {
@@ -642,59 +713,12 @@ std::string GrpcLb::Serverlist::AsText() const {
642
713
  return absl::StrJoin(entries, "");
643
714
  }
644
715
 
645
- bool IsServerValid(const GrpcLbServer& server, size_t idx, bool log) {
646
- if (server.drop) return false;
647
- if (GPR_UNLIKELY(server.port >> 16 != 0)) {
648
- if (log) {
649
- gpr_log(GPR_ERROR,
650
- "Invalid port '%d' at index %" PRIuPTR
651
- " of serverlist. Ignoring.",
652
- server.port, idx);
653
- }
654
- return false;
655
- }
656
- if (GPR_UNLIKELY(server.ip_size != 4 && server.ip_size != 16)) {
657
- if (log) {
658
- gpr_log(GPR_ERROR,
659
- "Expected IP to be 4 or 16 bytes, got %d at index %" PRIuPTR
660
- " of serverlist. Ignoring",
661
- server.ip_size, idx);
662
- }
663
- return false;
664
- }
665
- return true;
666
- }
667
-
668
716
  // Returns addresses extracted from the serverlist.
669
- EndpointAddressesList GrpcLb::Serverlist::GetServerAddressList(
670
- GrpcLbClientStats* client_stats) const {
717
+ std::shared_ptr<EndpointAddressesIterator>
718
+ GrpcLb::Serverlist::GetServerAddressList(GrpcLbClientStats* client_stats) {
671
719
  RefCountedPtr<GrpcLbClientStats> stats;
672
720
  if (client_stats != nullptr) stats = client_stats->Ref();
673
- EndpointAddressesList endpoints;
674
- for (size_t i = 0; i < serverlist_.size(); ++i) {
675
- const GrpcLbServer& server = serverlist_[i];
676
- if (!IsServerValid(server, i, false)) continue;
677
- // Address processing.
678
- grpc_resolved_address addr;
679
- ParseServer(server, &addr);
680
- // LB token processing.
681
- const size_t lb_token_length = strnlen(
682
- server.load_balance_token, GPR_ARRAY_SIZE(server.load_balance_token));
683
- std::string lb_token(server.load_balance_token, lb_token_length);
684
- if (lb_token.empty()) {
685
- auto addr_uri = grpc_sockaddr_to_uri(&addr);
686
- gpr_log(GPR_INFO,
687
- "Missing LB token for backend address '%s'. The empty token will "
688
- "be used instead",
689
- addr_uri.ok() ? addr_uri->c_str()
690
- : addr_uri.status().ToString().c_str());
691
- }
692
- // Add address with a channel arg containing LB token and stats object.
693
- endpoints.emplace_back(
694
- addr, ChannelArgs().SetObject(MakeRefCounted<TokenAndClientStatsArg>(
695
- std::move(lb_token), stats)));
696
- }
697
- return endpoints;
721
+ return std::make_shared<AddressIterator>(Ref(), std::move(stats));
698
722
  }
699
723
 
700
724
  bool GrpcLb::Serverlist::ContainsAllDropEntries() const {
@@ -794,8 +818,8 @@ RefCountedPtr<SubchannelInterface> GrpcLb::Helper::CreateSubchannel(
794
818
  return MakeRefCounted<SubchannelWrapper>(
795
819
  parent()->channel_control_helper()->CreateSubchannel(
796
820
  address, per_address_args, args),
797
- parent()->Ref(DEBUG_LOCATION, "SubchannelWrapper"), std::move(lb_token),
798
- std::move(client_stats));
821
+ parent()->RefAsSubclass<GrpcLb>(DEBUG_LOCATION, "SubchannelWrapper"),
822
+ std::move(lb_token), std::move(client_stats));
799
823
  }
800
824
 
801
825
  void GrpcLb::Helper::UpdateState(grpc_connectivity_state state,
@@ -1503,28 +1527,45 @@ void GrpcLb::ResetBackoffLocked() {
1503
1527
  }
1504
1528
  }
1505
1529
 
1530
+ // Endpoint iterator wrapper to add null LB token attribute.
1531
+ class GrpcLb::NullLbTokenEndpointIterator : public EndpointAddressesIterator {
1532
+ public:
1533
+ explicit NullLbTokenEndpointIterator(
1534
+ std::shared_ptr<EndpointAddressesIterator> parent_it)
1535
+ : parent_it_(std::move(parent_it)) {}
1536
+
1537
+ void ForEach(absl::FunctionRef<void(const EndpointAddresses&)> callback)
1538
+ const override {
1539
+ parent_it_->ForEach([&](const EndpointAddresses& endpoint) {
1540
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_glb_trace)) {
1541
+ gpr_log(GPR_INFO, "[grpclb %p] fallback address: %s", this,
1542
+ endpoint.ToString().c_str());
1543
+ }
1544
+ callback(EndpointAddresses(endpoint.addresses(),
1545
+ endpoint.args().SetObject(empty_token_)));
1546
+ });
1547
+ }
1548
+
1549
+ private:
1550
+ std::shared_ptr<EndpointAddressesIterator> parent_it_;
1551
+ RefCountedPtr<TokenAndClientStatsArg> empty_token_ =
1552
+ MakeRefCounted<TokenAndClientStatsArg>("", nullptr);
1553
+ };
1554
+
1506
1555
  absl::Status GrpcLb::UpdateLocked(UpdateArgs args) {
1507
1556
  if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_glb_trace)) {
1508
1557
  gpr_log(GPR_INFO, "[grpclb %p] received update", this);
1509
1558
  }
1510
1559
  const bool is_initial_update = lb_channel_ == nullptr;
1511
- config_ = args.config;
1560
+ config_ = args.config.TakeAsSubclass<GrpcLbConfig>();
1512
1561
  GPR_ASSERT(config_ != nullptr);
1513
1562
  args_ = std::move(args.args);
1514
1563
  // Update fallback address list.
1515
- fallback_backend_addresses_ = std::move(args.addresses);
1516
- if (fallback_backend_addresses_.ok()) {
1517
- // Add null LB token attributes.
1518
- for (EndpointAddresses& endpoint : *fallback_backend_addresses_) {
1519
- endpoint = EndpointAddresses(
1520
- endpoint.addresses(),
1521
- endpoint.args().SetObject(
1522
- MakeRefCounted<TokenAndClientStatsArg>("", nullptr)));
1523
- if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_glb_trace)) {
1524
- gpr_log(GPR_INFO, "[grpclb %p] fallback address: %s", this,
1525
- endpoint.ToString().c_str());
1526
- }
1527
- }
1564
+ if (!args.addresses.ok()) {
1565
+ fallback_backend_addresses_ = args.addresses.status();
1566
+ } else {
1567
+ fallback_backend_addresses_ = std::make_shared<NullLbTokenEndpointIterator>(
1568
+ std::move(*args.addresses));
1528
1569
  }
1529
1570
  resolution_note_ = std::move(args.resolution_note);
1530
1571
  // Update balancer channel.
@@ -1539,8 +1580,8 @@ absl::Status GrpcLb::UpdateLocked(UpdateArgs args) {
1539
1580
  lb_fallback_timer_handle_ =
1540
1581
  channel_control_helper()->GetEventEngine()->RunAfter(
1541
1582
  fallback_at_startup_timeout_,
1542
- [self = static_cast<RefCountedPtr<GrpcLb>>(
1543
- Ref(DEBUG_LOCATION, "on_fallback_timer"))]() mutable {
1583
+ [self = RefAsSubclass<GrpcLb>(DEBUG_LOCATION,
1584
+ "on_fallback_timer")]() mutable {
1544
1585
  ApplicationCallbackExecCtx callback_exec_ctx;
1545
1586
  ExecCtx exec_ctx;
1546
1587
  auto self_ptr = self.get();
@@ -1555,7 +1596,8 @@ absl::Status GrpcLb::UpdateLocked(UpdateArgs args) {
1555
1596
  ClientChannel::GetFromChannel(Channel::FromC(lb_channel_));
1556
1597
  GPR_ASSERT(client_channel != nullptr);
1557
1598
  // Ref held by callback.
1558
- watcher_ = new StateWatcher(Ref(DEBUG_LOCATION, "StateWatcher"));
1599
+ watcher_ =
1600
+ new StateWatcher(RefAsSubclass<GrpcLb>(DEBUG_LOCATION, "StateWatcher"));
1559
1601
  client_channel->AddConnectivityWatcher(
1560
1602
  GRPC_CHANNEL_IDLE,
1561
1603
  OrphanablePtr<AsyncConnectivityStateWatcherInterface>(watcher_));
@@ -1598,11 +1640,10 @@ absl::Status GrpcLb::UpdateBalancerChannelLocked() {
1598
1640
  // Set up channelz linkage.
1599
1641
  channelz::ChannelNode* child_channelz_node =
1600
1642
  grpc_channel_get_channelz_node(lb_channel_);
1601
- channelz::ChannelNode* parent_channelz_node =
1602
- args_.GetObject<channelz::ChannelNode>();
1643
+ auto parent_channelz_node = args_.GetObjectRef<channelz::ChannelNode>();
1603
1644
  if (child_channelz_node != nullptr && parent_channelz_node != nullptr) {
1604
1645
  parent_channelz_node->AddChildChannel(child_channelz_node->uuid());
1605
- parent_channelz_node_ = parent_channelz_node->Ref();
1646
+ parent_channelz_node_ = std::move(parent_channelz_node);
1606
1647
  }
1607
1648
  }
1608
1649
  // Propagate updates to the LB channel (pick_first) through the fake
@@ -1657,8 +1698,8 @@ void GrpcLb::StartBalancerCallRetryTimerLocked() {
1657
1698
  lb_call_retry_timer_handle_ =
1658
1699
  channel_control_helper()->GetEventEngine()->RunAfter(
1659
1700
  timeout,
1660
- [self = static_cast<RefCountedPtr<GrpcLb>>(
1661
- Ref(DEBUG_LOCATION, "on_balancer_call_retry_timer"))]() mutable {
1701
+ [self = RefAsSubclass<GrpcLb>(
1702
+ DEBUG_LOCATION, "on_balancer_call_retry_timer")]() mutable {
1662
1703
  ApplicationCallbackExecCtx callback_exec_ctx;
1663
1704
  ExecCtx exec_ctx;
1664
1705
  auto self_ptr = self.get();
@@ -1740,7 +1781,7 @@ OrphanablePtr<LoadBalancingPolicy> GrpcLb::CreateChildPolicyLocked(
1740
1781
  lb_policy_args.work_serializer = work_serializer();
1741
1782
  lb_policy_args.args = args;
1742
1783
  lb_policy_args.channel_control_helper =
1743
- std::make_unique<Helper>(Ref(DEBUG_LOCATION, "Helper"));
1784
+ std::make_unique<Helper>(RefAsSubclass<GrpcLb>(DEBUG_LOCATION, "Helper"));
1744
1785
  OrphanablePtr<LoadBalancingPolicy> lb_policy =
1745
1786
  MakeOrphanable<ChildPolicyHandler>(std::move(lb_policy_args),
1746
1787
  &grpc_lb_glb_trace);
@@ -1756,6 +1797,12 @@ OrphanablePtr<LoadBalancingPolicy> GrpcLb::CreateChildPolicyLocked(
1756
1797
  return lb_policy;
1757
1798
  }
1758
1799
 
1800
+ bool EndpointIteratorIsEmpty(const EndpointAddressesIterator& endpoints) {
1801
+ bool empty = true;
1802
+ endpoints.ForEach([&](const EndpointAddresses&) { empty = false; });
1803
+ return empty;
1804
+ }
1805
+
1759
1806
  void GrpcLb::CreateOrUpdateChildPolicyLocked() {
1760
1807
  if (shutting_down_) return;
1761
1808
  // Construct update args.
@@ -1769,16 +1816,17 @@ void GrpcLb::CreateOrUpdateChildPolicyLocked() {
1769
1816
  // picks.
1770
1817
  update_args.addresses = fallback_backend_addresses_;
1771
1818
  if (fallback_backend_addresses_.ok() &&
1772
- fallback_backend_addresses_->empty()) {
1819
+ EndpointIteratorIsEmpty(**fallback_backend_addresses_)) {
1773
1820
  update_args.resolution_note = absl::StrCat(
1774
- "grpclb in fallback mode without any balancer addresses: ",
1821
+ "grpclb in fallback mode without any fallback addresses: ",
1775
1822
  resolution_note_);
1776
1823
  }
1777
1824
  } else {
1778
1825
  update_args.addresses = serverlist_->GetServerAddressList(
1779
1826
  lb_calld_ == nullptr ? nullptr : lb_calld_->client_stats());
1780
1827
  is_backend_from_grpclb_load_balancer = true;
1781
- if (update_args.addresses.ok() && update_args.addresses->empty()) {
1828
+ if (update_args.addresses.ok() &&
1829
+ EndpointIteratorIsEmpty(**update_args.addresses)) {
1782
1830
  update_args.resolution_note = "empty serverlist from grpclb balancer";
1783
1831
  }
1784
1832
  }
@@ -1818,8 +1866,8 @@ void GrpcLb::StartSubchannelCacheTimerLocked() {
1818
1866
  subchannel_cache_timer_handle_ =
1819
1867
  channel_control_helper()->GetEventEngine()->RunAfter(
1820
1868
  cached_subchannels_.begin()->first - Timestamp::Now(),
1821
- [self = static_cast<RefCountedPtr<GrpcLb>>(
1822
- Ref(DEBUG_LOCATION, "OnSubchannelCacheTimer"))]() mutable {
1869
+ [self = RefAsSubclass<GrpcLb>(DEBUG_LOCATION,
1870
+ "OnSubchannelCacheTimer")]() mutable {
1823
1871
  ApplicationCallbackExecCtx callback_exec_ctx;
1824
1872
  ExecCtx exec_ctx;
1825
1873
  auto* self_ptr = self.get();
@@ -1880,8 +1928,7 @@ void RegisterGrpcLbPolicy(CoreConfiguration::Builder* builder) {
1880
1928
  builder->lb_policy_registry()->RegisterLoadBalancingPolicyFactory(
1881
1929
  std::make_unique<GrpcLbFactory>());
1882
1930
  builder->channel_init()
1883
- ->RegisterFilter(GRPC_CLIENT_SUBCHANNEL,
1884
- &ClientLoadReportingFilter::kFilter)
1931
+ ->RegisterFilter<ClientLoadReportingFilter>(GRPC_CLIENT_SUBCHANNEL)
1885
1932
  .IfChannelArg(GRPC_ARG_GRPCLB_ENABLE_LOAD_REPORTING_FILTER, false);
1886
1933
  }
1887
1934
 
@@ -32,7 +32,7 @@
32
32
  #include "absl/strings/string_view.h"
33
33
  #include "absl/types/optional.h"
34
34
  #include "upb/base/string_view.h"
35
- #include "upb/upb.hpp"
35
+ #include "upb/mem/arena.hpp"
36
36
 
37
37
  #include <grpc/impl/channel_arg_names.h>
38
38
  #include <grpc/impl/connectivity_state.h>
@@ -356,7 +356,8 @@ void HealthProducer::Start(RefCountedPtr<Subchannel> subchannel) {
356
356
  MutexLock lock(&mu_);
357
357
  connected_subchannel_ = subchannel_->connected_subchannel();
358
358
  }
359
- auto connectivity_watcher = MakeRefCounted<ConnectivityWatcher>(WeakRef());
359
+ auto connectivity_watcher =
360
+ MakeRefCounted<ConnectivityWatcher>(WeakRefAsSubclass<HealthProducer>());
360
361
  connectivity_watcher_ = connectivity_watcher.get();
361
362
  subchannel_->WatchConnectivityState(std::move(connectivity_watcher));
362
363
  }
@@ -387,7 +388,8 @@ void HealthProducer::AddWatcher(
387
388
  health_checkers_.emplace(*health_check_service_name, nullptr).first;
388
389
  auto& health_checker = it->second;
389
390
  if (health_checker == nullptr) {
390
- health_checker = MakeOrphanable<HealthChecker>(WeakRef(), it->first);
391
+ health_checker = MakeOrphanable<HealthChecker>(
392
+ WeakRefAsSubclass<HealthProducer>(), it->first);
391
393
  }
392
394
  health_checker->AddWatcherLocked(watcher);
393
395
  }
@@ -456,7 +458,10 @@ void HealthWatcher::SetSubchannel(Subchannel* subchannel) {
456
458
  subchannel->GetOrAddDataProducer(
457
459
  HealthProducer::Type(),
458
460
  [&](Subchannel::DataProducerInterface** producer) {
459
- if (*producer != nullptr) producer_ = (*producer)->RefIfNonZero();
461
+ if (*producer != nullptr) {
462
+ producer_ =
463
+ (*producer)->RefIfNonZero().TakeAsSubclass<HealthProducer>();
464
+ }
460
465
  if (producer_ == nullptr) {
461
466
  producer_ = MakeRefCounted<HealthProducer>();
462
467
  *producer = producer_.get();