grpc 1.58.3 → 1.59.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (548) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +48 -33
  3. data/include/grpc/event_engine/event_engine.h +6 -10
  4. data/include/grpc/impl/channel_arg_names.h +4 -0
  5. data/include/grpc/support/port_platform.h +74 -1
  6. data/src/core/ext/filters/channel_idle/channel_idle_filter.cc +22 -9
  7. data/src/core/ext/filters/client_channel/client_channel.cc +422 -56
  8. data/src/core/ext/filters/client_channel/client_channel.h +52 -8
  9. data/src/core/ext/filters/client_channel/client_channel_plugin.cc +15 -1
  10. data/src/core/ext/filters/client_channel/dynamic_filters.h +2 -0
  11. data/src/core/ext/filters/client_channel/{http_proxy.cc → http_proxy_mapper.cc} +1 -1
  12. data/src/core/ext/filters/client_channel/{http_proxy.h → http_proxy_mapper.h} +3 -3
  13. data/src/core/ext/filters/client_channel/lb_policy/endpoint_list.cc +188 -0
  14. data/src/core/ext/filters/client_channel/lb_policy/endpoint_list.h +214 -0
  15. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +17 -4
  16. data/src/core/ext/filters/client_channel/lb_policy/health_check_client.cc +41 -6
  17. data/src/core/ext/filters/client_channel/lb_policy/health_check_client_internal.h +5 -3
  18. data/src/core/ext/filters/client_channel/lb_policy/outlier_detection/outlier_detection.cc +32 -103
  19. data/src/core/ext/filters/client_channel/lb_policy/outlier_detection/outlier_detection.h +0 -7
  20. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +416 -139
  21. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.h +16 -0
  22. data/src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.cc +434 -459
  23. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +410 -26
  24. data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +14 -46
  25. data/src/core/ext/filters/client_channel/lb_policy/weighted_round_robin/weighted_round_robin.cc +851 -57
  26. data/src/core/ext/filters/client_channel/lb_policy/xds/cds.cc +16 -10
  27. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc +47 -32
  28. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_override_host.cc +55 -3
  29. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +105 -175
  30. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +14 -7
  31. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +24 -6
  32. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h +36 -2
  33. data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc +54 -44
  34. data/src/core/ext/filters/client_channel/subchannel.cc +33 -0
  35. data/src/core/ext/filters/client_channel/subchannel.h +9 -0
  36. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +1 -1
  37. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +11 -6
  38. data/src/core/ext/transport/chttp2/transport/flow_control.cc +28 -22
  39. data/src/core/ext/transport/chttp2/transport/flow_control.h +27 -4
  40. data/src/core/ext/transport/chttp2/transport/frame_data.h +1 -1
  41. data/src/core/ext/transport/chttp2/transport/frame_goaway.h +1 -1
  42. data/src/core/ext/transport/chttp2/transport/frame_ping.cc +9 -0
  43. data/src/core/ext/transport/chttp2/transport/frame_ping.h +1 -1
  44. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +1 -1
  45. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.h +1 -1
  46. data/src/core/ext/transport/chttp2/transport/frame_settings.cc +1 -1
  47. data/src/core/ext/transport/chttp2/transport/frame_settings.h +1 -1
  48. data/src/core/ext/transport/chttp2/transport/frame_window_update.h +1 -1
  49. data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +1 -1
  50. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +34 -36
  51. data/src/core/ext/transport/chttp2/transport/hpack_parser.h +3 -3
  52. data/src/core/ext/transport/chttp2/transport/internal.h +66 -47
  53. data/src/core/ext/transport/chttp2/transport/{frame.h → legacy_frame.h} +3 -3
  54. data/src/core/ext/transport/chttp2/transport/parsing.cc +4 -2
  55. data/src/core/ext/transport/chttp2/transport/ping_abuse_policy.cc +10 -0
  56. data/src/core/ext/transport/chttp2/transport/ping_abuse_policy.h +4 -0
  57. data/src/core/ext/transport/chttp2/transport/stream_lists.cc +1 -1
  58. data/src/core/ext/transport/chttp2/transport/writing.cc +2 -1
  59. data/src/core/ext/transport/inproc/inproc_transport.cc +9 -0
  60. data/src/core/ext/upb-generated/envoy/admin/v3/certs.upb.c +16 -18
  61. data/src/core/ext/upb-generated/envoy/admin/v3/certs.upb.h +75 -83
  62. data/src/core/ext/upb-generated/envoy/admin/v3/clusters.upb.c +27 -29
  63. data/src/core/ext/upb-generated/envoy/admin/v3/clusters.upb.h +102 -110
  64. data/src/core/ext/upb-generated/envoy/admin/v3/config_dump.upb.c +16 -18
  65. data/src/core/ext/upb-generated/envoy/admin/v3/config_dump.upb.h +73 -81
  66. data/src/core/ext/upb-generated/envoy/admin/v3/config_dump_shared.upb.c +65 -67
  67. data/src/core/ext/upb-generated/envoy/admin/v3/config_dump_shared.upb.h +294 -302
  68. data/src/core/ext/upb-generated/envoy/admin/v3/init_dump.upb.c +4 -6
  69. data/src/core/ext/upb-generated/envoy/admin/v3/init_dump.upb.h +20 -28
  70. data/src/core/ext/upb-generated/envoy/admin/v3/listeners.upb.c +5 -7
  71. data/src/core/ext/upb-generated/envoy/admin/v3/listeners.upb.h +24 -32
  72. data/src/core/ext/upb-generated/envoy/admin/v3/memory.upb.c +7 -9
  73. data/src/core/ext/upb-generated/envoy/admin/v3/memory.upb.h +19 -27
  74. data/src/core/ext/upb-generated/envoy/admin/v3/metrics.upb.c +4 -6
  75. data/src/core/ext/upb-generated/envoy/admin/v3/metrics.upb.h +10 -18
  76. data/src/core/ext/upb-generated/envoy/admin/v3/mutex_stats.upb.c +4 -6
  77. data/src/core/ext/upb-generated/envoy/admin/v3/mutex_stats.upb.h +10 -18
  78. data/src/core/ext/upb-generated/envoy/admin/v3/server_info.upb.c +42 -44
  79. data/src/core/ext/upb-generated/envoy/admin/v3/server_info.upb.h +141 -149
  80. data/src/core/ext/upb-generated/envoy/admin/v3/tap.upb.c +3 -5
  81. data/src/core/ext/upb-generated/envoy/admin/v3/tap.upb.h +8 -16
  82. data/src/core/ext/upb-generated/envoy/annotations/deprecation.upb.c +5 -7
  83. data/src/core/ext/upb-generated/envoy/annotations/deprecation.upb.h +1 -9
  84. data/src/core/ext/upb-generated/envoy/annotations/resource.upb.c +3 -5
  85. data/src/core/ext/upb-generated/envoy/annotations/resource.upb.h +4 -12
  86. data/src/core/ext/upb-generated/envoy/config/accesslog/v3/accesslog.upb.c +36 -38
  87. data/src/core/ext/upb-generated/envoy/config/accesslog/v3/accesslog.upb.h +157 -165
  88. data/src/core/ext/upb-generated/envoy/config/bootstrap/v3/bootstrap.upb.c +87 -89
  89. data/src/core/ext/upb-generated/envoy/config/bootstrap/v3/bootstrap.upb.h +372 -380
  90. data/src/core/ext/upb-generated/envoy/config/cluster/v3/circuit_breaker.upb.c +13 -15
  91. data/src/core/ext/upb-generated/envoy/config/cluster/v3/circuit_breaker.upb.h +55 -63
  92. data/src/core/ext/upb-generated/envoy/config/cluster/v3/cluster.upb.c +111 -113
  93. data/src/core/ext/upb-generated/envoy/config/cluster/v3/cluster.upb.h +441 -449
  94. data/src/core/ext/upb-generated/envoy/config/cluster/v3/filter.upb.c +3 -5
  95. data/src/core/ext/upb-generated/envoy/config/cluster/v3/filter.upb.h +8 -16
  96. data/src/core/ext/upb-generated/envoy/config/cluster/v3/outlier_detection.upb.c +23 -25
  97. data/src/core/ext/upb-generated/envoy/config/cluster/v3/outlier_detection.upb.h +88 -96
  98. data/src/core/ext/upb-generated/envoy/config/common/matcher/v3/matcher.upb.c +40 -42
  99. data/src/core/ext/upb-generated/envoy/config/common/matcher/v3/matcher.upb.h +180 -188
  100. data/src/core/ext/upb-generated/envoy/config/core/v3/address.upb.c +26 -28
  101. data/src/core/ext/upb-generated/envoy/config/core/v3/address.upb.h +108 -116
  102. data/src/core/ext/upb-generated/envoy/config/core/v3/backoff.upb.c +3 -5
  103. data/src/core/ext/upb-generated/envoy/config/core/v3/backoff.upb.h +9 -17
  104. data/src/core/ext/upb-generated/envoy/config/core/v3/base.upb.c +65 -67
  105. data/src/core/ext/upb-generated/envoy/config/core/v3/base.upb.h +245 -253
  106. data/src/core/ext/upb-generated/envoy/config/core/v3/config_source.upb.c +27 -29
  107. data/src/core/ext/upb-generated/envoy/config/core/v3/config_source.upb.h +119 -127
  108. data/src/core/ext/upb-generated/envoy/config/core/v3/event_service_config.upb.c +2 -4
  109. data/src/core/ext/upb-generated/envoy/config/core/v3/event_service_config.upb.h +6 -14
  110. data/src/core/ext/upb-generated/envoy/config/core/v3/extension.upb.c +3 -5
  111. data/src/core/ext/upb-generated/envoy/config/core/v3/extension.upb.h +8 -16
  112. data/src/core/ext/upb-generated/envoy/config/core/v3/grpc_method_list.upb.c +4 -6
  113. data/src/core/ext/upb-generated/envoy/config/core/v3/grpc_method_list.upb.h +20 -28
  114. data/src/core/ext/upb-generated/envoy/config/core/v3/grpc_service.upb.c +49 -51
  115. data/src/core/ext/upb-generated/envoy/config/core/v3/grpc_service.upb.h +184 -192
  116. data/src/core/ext/upb-generated/envoy/config/core/v3/health_check.upb.c +49 -51
  117. data/src/core/ext/upb-generated/envoy/config/core/v3/health_check.upb.h +225 -233
  118. data/src/core/ext/upb-generated/envoy/config/core/v3/http_uri.upb.c +4 -6
  119. data/src/core/ext/upb-generated/envoy/config/core/v3/http_uri.upb.h +13 -21
  120. data/src/core/ext/upb-generated/envoy/config/core/v3/protocol.upb.c +63 -65
  121. data/src/core/ext/upb-generated/envoy/config/core/v3/protocol.upb.h +246 -254
  122. data/src/core/ext/upb-generated/envoy/config/core/v3/proxy_protocol.upb.c +5 -7
  123. data/src/core/ext/upb-generated/envoy/config/core/v3/proxy_protocol.upb.h +19 -27
  124. data/src/core/ext/upb-generated/envoy/config/core/v3/resolver.upb.c +5 -7
  125. data/src/core/ext/upb-generated/envoy/config/core/v3/resolver.upb.h +19 -27
  126. data/src/core/ext/upb-generated/envoy/config/core/v3/socket_option.upb.c +8 -10
  127. data/src/core/ext/upb-generated/envoy/config/core/v3/socket_option.upb.h +30 -38
  128. data/src/core/ext/upb-generated/envoy/config/core/v3/substitution_format_string.upb.c +7 -9
  129. data/src/core/ext/upb-generated/envoy/config/core/v3/substitution_format_string.upb.h +28 -36
  130. data/src/core/ext/upb-generated/envoy/config/core/v3/udp_socket_config.upb.c +3 -5
  131. data/src/core/ext/upb-generated/envoy/config/core/v3/udp_socket_config.upb.h +9 -17
  132. data/src/core/ext/upb-generated/envoy/config/endpoint/v3/endpoint.upb.c +12 -14
  133. data/src/core/ext/upb-generated/envoy/config/endpoint/v3/endpoint.upb.h +48 -56
  134. data/src/core/ext/upb-generated/envoy/config/endpoint/v3/endpoint_components.upb.c +23 -25
  135. data/src/core/ext/upb-generated/envoy/config/endpoint/v3/endpoint_components.upb.h +92 -100
  136. data/src/core/ext/upb-generated/envoy/config/endpoint/v3/load_report.upb.c +27 -29
  137. data/src/core/ext/upb-generated/envoy/config/endpoint/v3/load_report.upb.h +108 -116
  138. data/src/core/ext/upb-generated/envoy/config/listener/v3/api_listener.upb.c +2 -4
  139. data/src/core/ext/upb-generated/envoy/config/listener/v3/api_listener.upb.h +5 -13
  140. data/src/core/ext/upb-generated/envoy/config/listener/v3/listener.upb.c +38 -40
  141. data/src/core/ext/upb-generated/envoy/config/listener/v3/listener.upb.h +167 -175
  142. data/src/core/ext/upb-generated/envoy/config/listener/v3/listener_components.upb.c +34 -36
  143. data/src/core/ext/upb-generated/envoy/config/listener/v3/listener_components.upb.h +162 -170
  144. data/src/core/ext/upb-generated/envoy/config/listener/v3/quic_config.upb.c +10 -12
  145. data/src/core/ext/upb-generated/envoy/config/listener/v3/quic_config.upb.h +37 -45
  146. data/src/core/ext/upb-generated/envoy/config/listener/v3/udp_listener_config.upb.c +4 -6
  147. data/src/core/ext/upb-generated/envoy/config/listener/v3/udp_listener_config.upb.h +13 -21
  148. data/src/core/ext/upb-generated/envoy/config/metrics/v3/metrics_service.upb.c +6 -8
  149. data/src/core/ext/upb-generated/envoy/config/metrics/v3/metrics_service.upb.h +18 -26
  150. data/src/core/ext/upb-generated/envoy/config/metrics/v3/stats.upb.c +22 -24
  151. data/src/core/ext/upb-generated/envoy/config/metrics/v3/stats.upb.h +97 -105
  152. data/src/core/ext/upb-generated/envoy/config/overload/v3/overload.upb.c +24 -26
  153. data/src/core/ext/upb-generated/envoy/config/overload/v3/overload.upb.h +111 -119
  154. data/src/core/ext/upb-generated/envoy/config/rbac/v3/rbac.upb.c +43 -45
  155. data/src/core/ext/upb-generated/envoy/config/rbac/v3/rbac.upb.h +183 -191
  156. data/src/core/ext/upb-generated/envoy/config/route/v3/route.upb.c +20 -22
  157. data/src/core/ext/upb-generated/envoy/config/route/v3/route.upb.h +102 -110
  158. data/src/core/ext/upb-generated/envoy/config/route/v3/route_components.upb.c +253 -255
  159. data/src/core/ext/upb-generated/envoy/config/route/v3/route_components.upb.h +1108 -1116
  160. data/src/core/ext/upb-generated/envoy/config/route/v3/scoped_route.upb.c +8 -10
  161. data/src/core/ext/upb-generated/envoy/config/route/v3/scoped_route.upb.h +31 -39
  162. data/src/core/ext/upb-generated/envoy/config/tap/v3/common.upb.c +35 -37
  163. data/src/core/ext/upb-generated/envoy/config/tap/v3/common.upb.h +150 -158
  164. data/src/core/ext/upb-generated/envoy/config/trace/v3/datadog.upb.c +4 -6
  165. data/src/core/ext/upb-generated/envoy/config/trace/v3/datadog.upb.h +10 -18
  166. data/src/core/ext/upb-generated/envoy/config/trace/v3/dynamic_ot.upb.c +3 -5
  167. data/src/core/ext/upb-generated/envoy/config/trace/v3/dynamic_ot.upb.h +8 -16
  168. data/src/core/ext/upb-generated/envoy/config/trace/v3/http_tracer.upb.c +4 -6
  169. data/src/core/ext/upb-generated/envoy/config/trace/v3/http_tracer.upb.h +13 -21
  170. data/src/core/ext/upb-generated/envoy/config/trace/v3/lightstep.upb.c +5 -7
  171. data/src/core/ext/upb-generated/envoy/config/trace/v3/lightstep.upb.h +19 -27
  172. data/src/core/ext/upb-generated/envoy/config/trace/v3/opencensus.upb.c +14 -16
  173. data/src/core/ext/upb-generated/envoy/config/trace/v3/opencensus.upb.h +53 -61
  174. data/src/core/ext/upb-generated/envoy/config/trace/v3/opentelemetry.upb.c +3 -5
  175. data/src/core/ext/upb-generated/envoy/config/trace/v3/opentelemetry.upb.h +8 -16
  176. data/src/core/ext/upb-generated/envoy/config/trace/v3/service.upb.c +2 -4
  177. data/src/core/ext/upb-generated/envoy/config/trace/v3/service.upb.h +5 -13
  178. data/src/core/ext/upb-generated/envoy/config/trace/v3/skywalking.upb.c +7 -9
  179. data/src/core/ext/upb-generated/envoy/config/trace/v3/skywalking.upb.h +24 -32
  180. data/src/core/ext/upb-generated/envoy/config/trace/v3/trace.upb.c +1 -3
  181. data/src/core/ext/upb-generated/envoy/config/trace/v3/trace.upb.h +1 -9
  182. data/src/core/ext/upb-generated/envoy/config/trace/v3/xray.upb.c +7 -9
  183. data/src/core/ext/upb-generated/envoy/config/trace/v3/xray.upb.h +23 -31
  184. data/src/core/ext/upb-generated/envoy/config/trace/v3/zipkin.upb.c +8 -10
  185. data/src/core/ext/upb-generated/envoy/config/trace/v3/zipkin.upb.h +23 -31
  186. data/src/core/ext/upb-generated/envoy/data/accesslog/v3/accesslog.upb.c +114 -116
  187. data/src/core/ext/upb-generated/envoy/data/accesslog/v3/accesslog.upb.h +372 -380
  188. data/src/core/ext/upb-generated/envoy/extensions/clusters/aggregate/v3/cluster.upb.c +2 -4
  189. data/src/core/ext/upb-generated/envoy/extensions/clusters/aggregate/v3/cluster.upb.h +9 -17
  190. data/src/core/ext/upb-generated/envoy/extensions/filters/common/fault/v3/fault.upb.c +8 -10
  191. data/src/core/ext/upb-generated/envoy/extensions/filters/common/fault/v3/fault.upb.h +30 -38
  192. data/src/core/ext/upb-generated/envoy/extensions/filters/http/fault/v3/fault.upb.c +21 -23
  193. data/src/core/ext/upb-generated/envoy/extensions/filters/http/fault/v3/fault.upb.h +81 -89
  194. data/src/core/ext/upb-generated/envoy/extensions/filters/http/rbac/v3/rbac.upb.c +7 -9
  195. data/src/core/ext/upb-generated/envoy/extensions/filters/http/rbac/v3/rbac.upb.h +24 -32
  196. data/src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.c +12 -14
  197. data/src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.h +52 -60
  198. data/src/core/ext/upb-generated/envoy/extensions/filters/http/stateful_session/v3/stateful_session.upb.c +4 -6
  199. data/src/core/ext/upb-generated/envoy/extensions/filters/http/stateful_session/v3/stateful_session.upb.h +14 -22
  200. data/src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.c +114 -116
  201. data/src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.h +468 -476
  202. data/src/core/ext/upb-generated/envoy/extensions/http/stateful_session/cookie/v3/cookie.upb.c +2 -4
  203. data/src/core/ext/upb-generated/envoy/extensions/http/stateful_session/cookie/v3/cookie.upb.h +5 -13
  204. data/src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/client_side_weighted_round_robin/v3/client_side_weighted_round_robin.upb.c +7 -9
  205. data/src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/client_side_weighted_round_robin/v3/client_side_weighted_round_robin.upb.h +25 -33
  206. data/src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/common/v3/common.upb.c +11 -13
  207. data/src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/common/v3/common.upb.h +40 -48
  208. data/src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/pick_first/v3/pick_first.upb.c +2 -4
  209. data/src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/pick_first/v3/pick_first.upb.h +4 -12
  210. data/src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/ring_hash/v3/ring_hash.upb.c +8 -10
  211. data/src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/ring_hash/v3/ring_hash.upb.h +27 -35
  212. data/src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/wrr_locality/v3/wrr_locality.upb.c +2 -4
  213. data/src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/wrr_locality/v3/wrr_locality.upb.h +5 -13
  214. data/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.c +1 -3
  215. data/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.h +1 -9
  216. data/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.c +35 -37
  217. data/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.h +165 -173
  218. data/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/secret.upb.c +9 -11
  219. data/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/secret.upb.h +32 -40
  220. data/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/tls.upb.c +39 -41
  221. data/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/tls.upb.h +169 -177
  222. data/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upb.c +4 -6
  223. data/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upb.h +16 -24
  224. data/src/core/ext/upb-generated/envoy/service/discovery/v3/ads.upb.c +1 -3
  225. data/src/core/ext/upb-generated/envoy/service/discovery/v3/ads.upb.h +1 -9
  226. data/src/core/ext/upb-generated/envoy/service/discovery/v3/discovery.upb.c +55 -57
  227. data/src/core/ext/upb-generated/envoy/service/discovery/v3/discovery.upb.h +241 -249
  228. data/src/core/ext/upb-generated/envoy/service/load_stats/v3/lrs.upb.c +7 -9
  229. data/src/core/ext/upb-generated/envoy/service/load_stats/v3/lrs.upb.h +31 -39
  230. data/src/core/ext/upb-generated/envoy/service/status/v3/csds.upb.c +23 -25
  231. data/src/core/ext/upb-generated/envoy/service/status/v3/csds.upb.h +98 -106
  232. data/src/core/ext/upb-generated/envoy/type/http/v3/cookie.upb.c +4 -6
  233. data/src/core/ext/upb-generated/envoy/type/http/v3/cookie.upb.h +11 -19
  234. data/src/core/ext/upb-generated/envoy/type/http/v3/path_transformation.upb.c +4 -6
  235. data/src/core/ext/upb-generated/envoy/type/http/v3/path_transformation.upb.h +18 -26
  236. data/src/core/ext/upb-generated/envoy/type/matcher/v3/filter_state.upb.c +3 -5
  237. data/src/core/ext/upb-generated/envoy/type/matcher/v3/filter_state.upb.h +9 -17
  238. data/src/core/ext/upb-generated/envoy/type/matcher/v3/http_inputs.upb.c +6 -8
  239. data/src/core/ext/upb-generated/envoy/type/matcher/v3/http_inputs.upb.h +16 -24
  240. data/src/core/ext/upb-generated/envoy/type/matcher/v3/metadata.upb.c +6 -8
  241. data/src/core/ext/upb-generated/envoy/type/matcher/v3/metadata.upb.h +24 -32
  242. data/src/core/ext/upb-generated/envoy/type/matcher/v3/node.upb.c +3 -5
  243. data/src/core/ext/upb-generated/envoy/type/matcher/v3/node.upb.h +13 -21
  244. data/src/core/ext/upb-generated/envoy/type/matcher/v3/number.upb.c +3 -5
  245. data/src/core/ext/upb-generated/envoy/type/matcher/v3/number.upb.h +10 -18
  246. data/src/core/ext/upb-generated/envoy/type/matcher/v3/path.upb.c +2 -4
  247. data/src/core/ext/upb-generated/envoy/type/matcher/v3/path.upb.h +6 -14
  248. data/src/core/ext/upb-generated/envoy/type/matcher/v3/regex.upb.c +6 -8
  249. data/src/core/ext/upb-generated/envoy/type/matcher/v3/regex.upb.h +20 -28
  250. data/src/core/ext/upb-generated/envoy/type/matcher/v3/status_code_input.upb.c +1 -3
  251. data/src/core/ext/upb-generated/envoy/type/matcher/v3/status_code_input.upb.h +1 -9
  252. data/src/core/ext/upb-generated/envoy/type/matcher/v3/string.upb.c +8 -10
  253. data/src/core/ext/upb-generated/envoy/type/matcher/v3/string.upb.h +33 -41
  254. data/src/core/ext/upb-generated/envoy/type/matcher/v3/struct.upb.c +4 -6
  255. data/src/core/ext/upb-generated/envoy/type/matcher/v3/struct.upb.h +18 -26
  256. data/src/core/ext/upb-generated/envoy/type/matcher/v3/value.upb.c +8 -10
  257. data/src/core/ext/upb-generated/envoy/type/matcher/v3/value.upb.h +31 -39
  258. data/src/core/ext/upb-generated/envoy/type/metadata/v3/metadata.upb.c +8 -10
  259. data/src/core/ext/upb-generated/envoy/type/metadata/v3/metadata.upb.h +34 -42
  260. data/src/core/ext/upb-generated/envoy/type/tracing/v3/custom_tag.upb.c +14 -16
  261. data/src/core/ext/upb-generated/envoy/type/tracing/v3/custom_tag.upb.h +47 -55
  262. data/src/core/ext/upb-generated/envoy/type/v3/hash_policy.upb.c +4 -6
  263. data/src/core/ext/upb-generated/envoy/type/v3/hash_policy.upb.h +13 -21
  264. data/src/core/ext/upb-generated/envoy/type/v3/http.upb.c +1 -3
  265. data/src/core/ext/upb-generated/envoy/type/v3/http.upb.h +1 -9
  266. data/src/core/ext/upb-generated/envoy/type/v3/http_status.upb.c +2 -4
  267. data/src/core/ext/upb-generated/envoy/type/v3/http_status.upb.h +4 -12
  268. data/src/core/ext/upb-generated/envoy/type/v3/percent.upb.c +4 -6
  269. data/src/core/ext/upb-generated/envoy/type/v3/percent.upb.h +10 -18
  270. data/src/core/ext/upb-generated/envoy/type/v3/range.upb.c +7 -9
  271. data/src/core/ext/upb-generated/envoy/type/v3/range.upb.h +19 -27
  272. data/src/core/ext/upb-generated/envoy/type/v3/ratelimit_strategy.upb.c +6 -8
  273. data/src/core/ext/upb-generated/envoy/type/v3/ratelimit_strategy.upb.h +20 -28
  274. data/src/core/ext/upb-generated/envoy/type/v3/ratelimit_unit.upb.c +1 -3
  275. data/src/core/ext/upb-generated/envoy/type/v3/ratelimit_unit.upb.h +1 -9
  276. data/src/core/ext/upb-generated/envoy/type/v3/semantic_version.upb.c +4 -6
  277. data/src/core/ext/upb-generated/envoy/type/v3/semantic_version.upb.h +10 -18
  278. data/src/core/ext/upb-generated/envoy/type/v3/token_bucket.upb.c +4 -6
  279. data/src/core/ext/upb-generated/envoy/type/v3/token_bucket.upb.h +12 -20
  280. data/src/core/ext/upb-generated/google/api/annotations.upb.c +2 -4
  281. data/src/core/ext/upb-generated/google/api/annotations.upb.h +1 -9
  282. data/src/core/ext/upb-generated/google/api/expr/v1alpha1/checked.upb.c +45 -47
  283. data/src/core/ext/upb-generated/google/api/expr/v1alpha1/checked.upb.h +190 -198
  284. data/src/core/ext/upb-generated/google/api/expr/v1alpha1/syntax.upb.c +54 -56
  285. data/src/core/ext/upb-generated/google/api/expr/v1alpha1/syntax.upb.h +210 -218
  286. data/src/core/ext/upb-generated/google/api/http.upb.c +15 -17
  287. data/src/core/ext/upb-generated/google/api/http.upb.h +60 -68
  288. data/src/core/ext/upb-generated/google/api/httpbody.upb.c +4 -6
  289. data/src/core/ext/upb-generated/google/api/httpbody.upb.h +15 -23
  290. data/src/core/ext/upb-generated/google/protobuf/any.upb.c +3 -5
  291. data/src/core/ext/upb-generated/google/protobuf/any.upb.h +7 -15
  292. data/src/core/ext/upb-generated/google/protobuf/descriptor.upb.c +359 -204
  293. data/src/core/ext/upb-generated/google/protobuf/descriptor.upb.h +1340 -760
  294. data/src/core/ext/upb-generated/google/protobuf/duration.upb.c +3 -5
  295. data/src/core/ext/upb-generated/google/protobuf/duration.upb.h +7 -15
  296. data/src/core/ext/upb-generated/google/protobuf/empty.upb.c +1 -3
  297. data/src/core/ext/upb-generated/google/protobuf/empty.upb.h +1 -9
  298. data/src/core/ext/upb-generated/google/protobuf/struct.upb.c +11 -13
  299. data/src/core/ext/upb-generated/google/protobuf/struct.upb.h +43 -51
  300. data/src/core/ext/upb-generated/google/protobuf/timestamp.upb.c +3 -5
  301. data/src/core/ext/upb-generated/google/protobuf/timestamp.upb.h +7 -15
  302. data/src/core/ext/upb-generated/google/protobuf/wrappers.upb.c +10 -12
  303. data/src/core/ext/upb-generated/google/protobuf/wrappers.upb.h +28 -36
  304. data/src/core/ext/upb-generated/google/rpc/status.upb.c +4 -6
  305. data/src/core/ext/upb-generated/google/rpc/status.upb.h +15 -23
  306. data/src/core/ext/upb-generated/opencensus/proto/trace/v1/trace_config.upb.c +11 -13
  307. data/src/core/ext/upb-generated/opencensus/proto/trace/v1/trace_config.upb.h +35 -43
  308. data/src/core/ext/upb-generated/src/proto/grpc/gcp/altscontext.upb.c +10 -12
  309. data/src/core/ext/upb-generated/src/proto/grpc/gcp/altscontext.upb.h +28 -36
  310. data/src/core/ext/upb-generated/src/proto/grpc/gcp/handshaker.upb.c +48 -50
  311. data/src/core/ext/upb-generated/src/proto/grpc/gcp/handshaker.upb.h +190 -198
  312. data/src/core/ext/upb-generated/src/proto/grpc/gcp/transport_security_common.upb.c +5 -7
  313. data/src/core/ext/upb-generated/src/proto/grpc/gcp/transport_security_common.upb.h +15 -23
  314. data/src/core/ext/upb-generated/src/proto/grpc/health/v1/health.upb.c +3 -5
  315. data/src/core/ext/upb-generated/src/proto/grpc/health/v1/health.upb.h +7 -15
  316. data/src/core/ext/upb-generated/src/proto/grpc/lb/v1/load_balancer.upb.c +21 -23
  317. data/src/core/ext/upb-generated/src/proto/grpc/lb/v1/load_balancer.upb.h +80 -88
  318. data/src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls.upb.c +9 -11
  319. data/src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls.upb.h +29 -37
  320. data/src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls_config.upb.c +32 -34
  321. data/src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls_config.upb.h +147 -155
  322. data/src/core/ext/upb-generated/udpa/annotations/migrate.upb.c +10 -12
  323. data/src/core/ext/upb-generated/udpa/annotations/migrate.upb.h +13 -21
  324. data/src/core/ext/upb-generated/udpa/annotations/security.upb.c +4 -6
  325. data/src/core/ext/upb-generated/udpa/annotations/security.upb.h +7 -15
  326. data/src/core/ext/upb-generated/udpa/annotations/sensitive.upb.c +2 -4
  327. data/src/core/ext/upb-generated/udpa/annotations/sensitive.upb.h +1 -9
  328. data/src/core/ext/upb-generated/udpa/annotations/status.upb.c +4 -6
  329. data/src/core/ext/upb-generated/udpa/annotations/status.upb.h +7 -15
  330. data/src/core/ext/upb-generated/udpa/annotations/versioning.upb.c +3 -5
  331. data/src/core/ext/upb-generated/udpa/annotations/versioning.upb.h +4 -12
  332. data/src/core/ext/upb-generated/validate/validate.upb.c +201 -203
  333. data/src/core/ext/upb-generated/validate/validate.upb.h +924 -932
  334. data/src/core/ext/upb-generated/xds/annotations/v3/migrate.upb.c +10 -12
  335. data/src/core/ext/upb-generated/xds/annotations/v3/migrate.upb.h +13 -21
  336. data/src/core/ext/upb-generated/xds/annotations/v3/security.upb.c +4 -6
  337. data/src/core/ext/upb-generated/xds/annotations/v3/security.upb.h +7 -15
  338. data/src/core/ext/upb-generated/xds/annotations/v3/sensitive.upb.c +2 -4
  339. data/src/core/ext/upb-generated/xds/annotations/v3/sensitive.upb.h +1 -9
  340. data/src/core/ext/upb-generated/xds/annotations/v3/status.upb.c +9 -11
  341. data/src/core/ext/upb-generated/xds/annotations/v3/status.upb.h +16 -24
  342. data/src/core/ext/upb-generated/xds/annotations/v3/versioning.upb.c +3 -5
  343. data/src/core/ext/upb-generated/xds/annotations/v3/versioning.upb.h +4 -12
  344. data/src/core/ext/upb-generated/xds/core/v3/authority.upb.c +2 -4
  345. data/src/core/ext/upb-generated/xds/core/v3/authority.upb.h +4 -12
  346. data/src/core/ext/upb-generated/xds/core/v3/cidr.upb.c +3 -5
  347. data/src/core/ext/upb-generated/xds/core/v3/cidr.upb.h +8 -16
  348. data/src/core/ext/upb-generated/xds/core/v3/collection_entry.upb.c +6 -8
  349. data/src/core/ext/upb-generated/xds/core/v3/collection_entry.upb.h +20 -28
  350. data/src/core/ext/upb-generated/xds/core/v3/context_params.upb.c +4 -6
  351. data/src/core/ext/upb-generated/xds/core/v3/context_params.upb.h +9 -17
  352. data/src/core/ext/upb-generated/xds/core/v3/extension.upb.c +3 -5
  353. data/src/core/ext/upb-generated/xds/core/v3/extension.upb.h +8 -16
  354. data/src/core/ext/upb-generated/xds/core/v3/resource.upb.c +4 -6
  355. data/src/core/ext/upb-generated/xds/core/v3/resource.upb.h +12 -20
  356. data/src/core/ext/upb-generated/xds/core/v3/resource_locator.upb.c +9 -11
  357. data/src/core/ext/upb-generated/xds/core/v3/resource_locator.upb.h +35 -43
  358. data/src/core/ext/upb-generated/xds/core/v3/resource_name.upb.c +5 -7
  359. data/src/core/ext/upb-generated/xds/core/v3/resource_name.upb.h +14 -22
  360. data/src/core/ext/upb-generated/xds/data/orca/v3/orca_load_report.upb.c +16 -18
  361. data/src/core/ext/upb-generated/xds/data/orca/v3/orca_load_report.upb.h +43 -51
  362. data/src/core/ext/upb-generated/xds/service/orca/v3/orca.upb.c +3 -5
  363. data/src/core/ext/upb-generated/xds/service/orca/v3/orca.upb.h +13 -21
  364. data/src/core/ext/upb-generated/xds/type/matcher/v3/cel.upb.c +2 -4
  365. data/src/core/ext/upb-generated/xds/type/matcher/v3/cel.upb.h +5 -13
  366. data/src/core/ext/upb-generated/xds/type/matcher/v3/domain.upb.c +4 -6
  367. data/src/core/ext/upb-generated/xds/type/matcher/v3/domain.upb.h +21 -29
  368. data/src/core/ext/upb-generated/xds/type/matcher/v3/http_inputs.upb.c +1 -3
  369. data/src/core/ext/upb-generated/xds/type/matcher/v3/http_inputs.upb.h +1 -9
  370. data/src/core/ext/upb-generated/xds/type/matcher/v3/ip.upb.c +5 -7
  371. data/src/core/ext/upb-generated/xds/type/matcher/v3/ip.upb.h +24 -32
  372. data/src/core/ext/upb-generated/xds/type/matcher/v3/matcher.upb.c +24 -26
  373. data/src/core/ext/upb-generated/xds/type/matcher/v3/matcher.upb.h +103 -111
  374. data/src/core/ext/upb-generated/xds/type/matcher/v3/range.upb.c +10 -12
  375. data/src/core/ext/upb-generated/xds/type/matcher/v3/range.upb.h +61 -69
  376. data/src/core/ext/upb-generated/xds/type/matcher/v3/regex.upb.c +3 -5
  377. data/src/core/ext/upb-generated/xds/type/matcher/v3/regex.upb.h +9 -17
  378. data/src/core/ext/upb-generated/xds/type/matcher/v3/string.upb.c +8 -10
  379. data/src/core/ext/upb-generated/xds/type/matcher/v3/string.upb.h +33 -41
  380. data/src/core/ext/upb-generated/xds/type/v3/cel.upb.c +5 -7
  381. data/src/core/ext/upb-generated/xds/type/v3/cel.upb.h +18 -26
  382. data/src/core/ext/upb-generated/xds/type/v3/range.upb.c +7 -9
  383. data/src/core/ext/upb-generated/xds/type/v3/range.upb.h +19 -27
  384. data/src/core/ext/upb-generated/xds/type/v3/typed_struct.upb.c +3 -5
  385. data/src/core/ext/upb-generated/xds/type/v3/typed_struct.upb.h +8 -16
  386. data/src/core/ext/upbdefs-generated/google/protobuf/descriptor.upbdefs.c +367 -290
  387. data/src/core/ext/upbdefs-generated/google/protobuf/descriptor.upbdefs.h +10 -0
  388. data/src/core/ext/xds/xds_client.cc +6 -9
  389. data/src/core/ext/xds/xds_client.h +2 -2
  390. data/src/core/ext/xds/xds_cluster.cc +30 -42
  391. data/src/core/ext/xds/xds_cluster.h +0 -4
  392. data/src/core/ext/xds/xds_endpoint.cc +12 -19
  393. data/src/core/ext/xds/xds_endpoint.h +0 -1
  394. data/src/core/ext/xds/xds_http_filters.cc +1 -4
  395. data/src/core/ext/xds/xds_listener.cc +14 -14
  396. data/src/core/ext/xds/xds_listener.h +13 -3
  397. data/src/core/ext/xds/xds_resource_type.h +1 -7
  398. data/src/core/ext/xds/xds_resource_type_impl.h +9 -11
  399. data/src/core/ext/xds/xds_route_config.cc +10 -11
  400. data/src/core/ext/xds/xds_route_config.h +1 -1
  401. data/src/core/ext/xds/xds_server_config_fetcher.cc +53 -28
  402. data/src/core/ext/xds/xds_transport_grpc.cc +11 -1
  403. data/src/core/lib/backoff/random_early_detection.cc +4 -2
  404. data/src/core/lib/backoff/random_early_detection.h +2 -4
  405. data/src/core/lib/channel/call_tracer.cc +7 -1
  406. data/src/core/lib/channel/call_tracer.h +4 -1
  407. data/src/core/lib/channel/channelz_registry.h +4 -2
  408. data/src/core/lib/channel/connected_channel.cc +1 -1
  409. data/src/core/lib/config/config_vars.h +1 -1
  410. data/src/core/lib/config/core_configuration.cc +2 -1
  411. data/src/core/lib/config/core_configuration.h +5 -4
  412. data/src/core/lib/debug/stats_data.cc +146 -51
  413. data/src/core/lib/debug/stats_data.h +81 -20
  414. data/src/core/lib/event_engine/cf_engine/cf_engine.cc +3 -0
  415. data/src/core/lib/event_engine/cf_engine/cf_engine.h +3 -0
  416. data/src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc +3 -0
  417. data/src/core/lib/event_engine/cf_engine/cfstream_endpoint.h +3 -0
  418. data/src/core/lib/event_engine/cf_engine/cftype_unique_ref.h +3 -0
  419. data/src/core/lib/event_engine/cf_engine/dns_service_resolver.cc +15 -3
  420. data/src/core/lib/event_engine/cf_engine/dns_service_resolver.h +3 -0
  421. data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.cc +1 -1
  422. data/src/core/lib/event_engine/thread_pool/thread_count.h +15 -0
  423. data/src/core/lib/event_engine/thread_pool/thread_pool_factory.cc +3 -15
  424. data/src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.cc +10 -4
  425. data/src/core/lib/experiments/config.cc +9 -1
  426. data/src/core/lib/experiments/experiments.cc +144 -60
  427. data/src/core/lib/experiments/experiments.h +146 -41
  428. data/src/core/lib/gprpp/fork.h +1 -1
  429. data/src/core/lib/gprpp/manual_constructor.h +1 -2
  430. data/src/core/lib/gprpp/no_destruct.h +1 -1
  431. data/src/core/lib/gprpp/per_cpu.cc +2 -0
  432. data/src/core/lib/gprpp/per_cpu.h +36 -7
  433. data/src/core/lib/gprpp/ref_counted_ptr.h +63 -0
  434. data/src/core/lib/gprpp/work_serializer.cc +297 -25
  435. data/src/core/lib/gprpp/work_serializer.h +25 -9
  436. data/src/core/lib/iomgr/combiner.cc +54 -15
  437. data/src/core/lib/iomgr/combiner.h +8 -3
  438. data/src/core/lib/iomgr/event_engine_shims/endpoint.cc +2 -4
  439. data/src/core/lib/iomgr/exec_ctx.cc +12 -0
  440. data/src/core/lib/iomgr/exec_ctx.h +55 -19
  441. data/src/core/lib/iomgr/polling_entity.cc +10 -0
  442. data/src/core/lib/iomgr/polling_entity.h +2 -0
  443. data/src/core/lib/iomgr/port.h +14 -0
  444. data/src/core/lib/iomgr/tcp_posix.cc +17 -14
  445. data/src/core/lib/load_balancing/lb_policy.h +10 -9
  446. data/src/core/lib/promise/arena_promise.h +5 -1
  447. data/src/core/lib/promise/detail/seq_state.h +418 -0
  448. data/src/core/lib/promise/latch.h +1 -0
  449. data/src/core/lib/promise/loop.h +8 -5
  450. data/src/core/lib/promise/pipe.h +24 -24
  451. data/src/core/lib/promise/poll.h +4 -6
  452. data/src/core/lib/resolver/server_address.h +1 -0
  453. data/src/core/lib/resource_quota/memory_quota.cc +58 -2
  454. data/src/core/lib/resource_quota/memory_quota.h +4 -1
  455. data/src/core/lib/security/credentials/ssl/ssl_credentials.cc +115 -9
  456. data/src/core/lib/security/credentials/ssl/ssl_credentials.h +14 -0
  457. data/src/core/lib/security/credentials/tls/grpc_tls_certificate_match.cc +86 -0
  458. data/src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc +0 -59
  459. data/src/core/lib/security/credentials/tls/grpc_tls_certificate_verifier.h +2 -0
  460. data/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc +7 -57
  461. data/src/core/lib/security/security_connector/ssl/ssl_security_connector.h +1 -1
  462. data/src/core/lib/security/security_connector/tls/tls_security_connector.cc +2 -14
  463. data/src/core/lib/slice/slice.h +6 -0
  464. data/src/core/lib/slice/slice_buffer.cc +15 -0
  465. data/src/core/lib/slice/slice_buffer.h +16 -4
  466. data/src/core/lib/slice/slice_refcount.h +1 -1
  467. data/src/core/lib/surface/call.cc +92 -34
  468. data/src/core/lib/surface/call.h +4 -0
  469. data/src/core/lib/surface/channel.cc +7 -4
  470. data/src/core/lib/surface/channel_init.h +3 -2
  471. data/src/core/lib/surface/server.cc +45 -5
  472. data/src/core/lib/surface/server.h +18 -6
  473. data/src/core/lib/surface/version.cc +2 -2
  474. data/src/core/lib/transport/batch_builder.cc +3 -5
  475. data/src/core/lib/transport/metadata_batch.cc +6 -0
  476. data/src/core/lib/transport/metadata_batch.h +20 -1
  477. data/src/core/lib/transport/parsed_metadata.h +2 -4
  478. data/src/core/lib/transport/simple_slice_based_metadata.h +1 -2
  479. data/src/core/lib/transport/transport.h +21 -11
  480. data/src/core/tsi/ssl_transport_security.cc +7 -0
  481. data/src/core/tsi/ssl_transport_security.h +4 -0
  482. data/src/ruby/ext/grpc/extconf.rb +1 -1
  483. data/src/ruby/ext/grpc/rb_channel_args.c +6 -4
  484. data/src/ruby/lib/grpc/version.rb +1 -1
  485. data/src/ruby/pb/src/proto/grpc/testing/messages_pb.rb +4 -1
  486. data/third_party/abseil-cpp/absl/random/bit_gen_ref.h +185 -0
  487. data/third_party/upb/upb/collections/array.c +6 -0
  488. data/third_party/upb/upb/collections/array.h +6 -0
  489. data/third_party/upb/upb/collections/map.c +7 -0
  490. data/third_party/upb/upb/collections/map.h +5 -0
  491. data/third_party/upb/upb/collections/map_sorter_internal.h +1 -1
  492. data/third_party/upb/upb/collections/message_value.h +8 -1
  493. data/third_party/upb/upb/generated_code_support.h +54 -0
  494. data/third_party/upb/upb/hash/common.c +5 -0
  495. data/third_party/upb/upb/hash/common.h +1 -0
  496. data/third_party/upb/upb/hash/str_table.h +1 -0
  497. data/third_party/upb/upb/message/accessors.c +25 -1
  498. data/third_party/upb/upb/message/accessors.h +46 -25
  499. data/third_party/upb/upb/message/accessors_internal.h +69 -3
  500. data/third_party/upb/upb/message/extension_internal.h +1 -1
  501. data/third_party/upb/upb/message/internal/map_entry.h +64 -0
  502. data/third_party/upb/upb/message/internal.h +2 -6
  503. data/third_party/upb/upb/message/message.c +0 -6
  504. data/third_party/upb/upb/message/message.h +1 -1
  505. data/third_party/upb/upb/message/tagged_ptr.h +89 -0
  506. data/third_party/upb/upb/mini_descriptor/build_enum.c +150 -0
  507. data/third_party/upb/upb/mini_descriptor/build_enum.h +63 -0
  508. data/third_party/upb/upb/{mini_table → mini_descriptor}/decode.c +122 -374
  509. data/third_party/upb/upb/{mini_table → mini_descriptor}/decode.h +11 -50
  510. data/third_party/upb/upb/mini_descriptor/internal/base92.c +46 -0
  511. data/third_party/upb/upb/mini_descriptor/internal/base92.h +81 -0
  512. data/third_party/upb/upb/mini_descriptor/internal/decoder.h +73 -0
  513. data/third_party/upb/upb/{mini_table → mini_descriptor/internal}/encode.c +58 -32
  514. data/third_party/upb/upb/{mini_table/encode_internal.h → mini_descriptor/internal/encode.h} +3 -4
  515. data/third_party/upb/upb/{mini_table/encode_internal.hpp → mini_descriptor/internal/encode.hpp} +1 -1
  516. data/third_party/upb/upb/mini_descriptor/internal/modifiers.h +50 -0
  517. data/third_party/upb/upb/{mini_table/common_internal.h → mini_descriptor/internal/wire_constants.h} +3 -23
  518. data/third_party/upb/upb/mini_descriptor/link.c +142 -0
  519. data/third_party/upb/upb/mini_descriptor/link.h +104 -0
  520. data/third_party/upb/upb/mini_table/{types.h → enum.h} +19 -9
  521. data/third_party/upb/upb/mini_table/extension.h +40 -0
  522. data/third_party/upb/upb/mini_table/extension_registry.c +1 -1
  523. data/third_party/upb/upb/mini_table/extension_registry.h +2 -1
  524. data/third_party/upb/upb/mini_table/field.h +118 -0
  525. data/third_party/upb/upb/{json_decode.h → mini_table/file.h} +5 -6
  526. data/third_party/upb/upb/mini_table/{enum_internal.h → internal/enum.h} +7 -19
  527. data/third_party/upb/upb/mini_table/{extension_internal.h → internal/extension.h} +8 -8
  528. data/third_party/upb/upb/mini_table/{field_internal.h → internal/field.h} +10 -66
  529. data/third_party/upb/upb/mini_table/{file_internal.h → internal/file.h} +6 -4
  530. data/third_party/upb/upb/mini_table/internal/message.c +39 -0
  531. data/third_party/upb/upb/mini_table/{message_internal.h → internal/message.h} +14 -37
  532. data/third_party/upb/upb/mini_table/{sub_internal.h → internal/sub.h} +7 -6
  533. data/third_party/upb/upb/mini_table/{common.c → message.c} +2 -33
  534. data/third_party/upb/upb/mini_table/{common.h → message.h} +12 -77
  535. data/third_party/upb/upb/{json_encode.h → mini_table/sub.h} +5 -6
  536. data/third_party/upb/upb/reflection/def.hpp +16 -4
  537. data/third_party/upb/upb/reflection/def_pool_internal.h +1 -1
  538. data/third_party/upb/upb/reflection/desc_state_internal.h +1 -1
  539. data/third_party/upb/upb/reflection/enum_def.c +1 -1
  540. data/third_party/upb/upb/reflection/field_def.c +2 -1
  541. data/third_party/upb/upb/reflection/message.c +2 -2
  542. data/third_party/upb/upb/reflection/message_def.c +3 -1
  543. data/third_party/upb/upb/wire/decode.c +68 -29
  544. data/third_party/upb/upb/wire/decode.h +40 -0
  545. data/third_party/upb/upb/wire/encode.c +23 -13
  546. metadata +43 -27
  547. data/src/core/lib/event_engine/thread_pool/original_thread_pool.cc +0 -256
  548. data/src/core/lib/event_engine/thread_pool/original_thread_pool.h +0 -137
@@ -23,6 +23,7 @@
23
23
 
24
24
  #include <algorithm>
25
25
  #include <cmath>
26
+ #include <map>
26
27
  #include <memory>
27
28
  #include <string>
28
29
  #include <utility>
@@ -37,20 +38,21 @@
37
38
  #include "absl/strings/string_view.h"
38
39
  #include "absl/types/optional.h"
39
40
 
40
- #include <grpc/impl/channel_arg_names.h>
41
-
42
41
  #define XXH_INLINE_ALL
43
42
  #include "xxhash.h"
44
43
 
44
+ #include <grpc/impl/channel_arg_names.h>
45
45
  #include <grpc/impl/connectivity_state.h>
46
+ #include <grpc/support/json.h>
46
47
  #include <grpc/support/log.h>
47
48
 
48
49
  #include "src/core/ext/filters/client_channel/client_channel_internal.h"
49
- #include "src/core/ext/filters/client_channel/lb_policy/subchannel_list.h"
50
+ #include "src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.h"
50
51
  #include "src/core/lib/address_utils/sockaddr_utils.h"
51
52
  #include "src/core/lib/channel/channel_args.h"
52
53
  #include "src/core/lib/config/core_configuration.h"
53
54
  #include "src/core/lib/debug/trace.h"
55
+ #include "src/core/lib/gprpp/crash.h"
54
56
  #include "src/core/lib/gprpp/debug_location.h"
55
57
  #include "src/core/lib/gprpp/orphanable.h"
56
58
  #include "src/core/lib/gprpp/ref_counted.h"
@@ -60,10 +62,12 @@
60
62
  #include "src/core/lib/iomgr/closure.h"
61
63
  #include "src/core/lib/iomgr/error.h"
62
64
  #include "src/core/lib/iomgr/exec_ctx.h"
65
+ #include "src/core/lib/iomgr/pollset_set.h"
63
66
  #include "src/core/lib/json/json.h"
67
+ #include "src/core/lib/load_balancing/delegating_helper.h"
64
68
  #include "src/core/lib/load_balancing/lb_policy.h"
65
69
  #include "src/core/lib/load_balancing/lb_policy_factory.h"
66
- #include "src/core/lib/load_balancing/subchannel_interface.h"
70
+ #include "src/core/lib/load_balancing/lb_policy_registry.h"
67
71
  #include "src/core/lib/resolver/server_address.h"
68
72
  #include "src/core/lib/transport/connectivity_state.h"
69
73
 
@@ -141,201 +145,155 @@ class RingHash : public LoadBalancingPolicy {
141
145
  void ResetBackoffLocked() override;
142
146
 
143
147
  private:
144
- // Forward declaration.
145
- class RingHashSubchannelList;
146
-
147
- // Data for a particular subchannel in a subchannel list.
148
- // This subclass adds the following functionality:
149
- // - Tracks the previous connectivity state of the subchannel, so that
150
- // we know how many subchannels are in each state.
151
- class RingHashSubchannelData
152
- : public SubchannelData<RingHashSubchannelList, RingHashSubchannelData> {
148
+ // A ring computed based on a config and address list.
149
+ class Ring : public RefCounted<Ring> {
153
150
  public:
154
- RingHashSubchannelData(
155
- SubchannelList<RingHashSubchannelList, RingHashSubchannelData>*
156
- subchannel_list,
157
- const ServerAddress& address,
158
- RefCountedPtr<SubchannelInterface> subchannel)
159
- : SubchannelData(subchannel_list, address, std::move(subchannel)),
160
- address_(address) {}
161
-
162
- const ServerAddress& address() const { return address_; }
163
-
164
- grpc_connectivity_state logical_connectivity_state() const {
165
- return logical_connectivity_state_;
166
- }
167
- const absl::Status& logical_connectivity_status() const {
168
- return logical_connectivity_status_;
169
- }
151
+ struct RingEntry {
152
+ uint64_t hash;
153
+ size_t endpoint_index; // Index into RingHash::addresses_.
154
+ };
155
+
156
+ Ring(RingHash* ring_hash, RingHashLbConfig* config);
157
+
158
+ const std::vector<RingEntry>& ring() const { return ring_; }
170
159
 
171
160
  private:
172
- // Performs connectivity state updates that need to be done only
173
- // after we have started watching.
174
- void ProcessConnectivityChangeLocked(
175
- absl::optional<grpc_connectivity_state> old_state,
176
- grpc_connectivity_state new_state) override;
177
-
178
- ServerAddress address_;
179
-
180
- // Last logical connectivity state seen.
181
- // Note that this may differ from the state actually reported by the
182
- // subchannel in some cases; for example, once this is set to
183
- // TRANSIENT_FAILURE, we do not change it again until we get READY,
184
- // so we skip any interim stops in CONNECTING.
185
- grpc_connectivity_state logical_connectivity_state_ = GRPC_CHANNEL_IDLE;
186
- absl::Status logical_connectivity_status_;
161
+ std::vector<RingEntry> ring_;
187
162
  };
188
163
 
189
- // A list of subchannels and the ring containing those subchannels.
190
- class RingHashSubchannelList
191
- : public SubchannelList<RingHashSubchannelList, RingHashSubchannelData> {
164
+ // State for a particular endpoint. Delegates to a pick_first child policy.
165
+ class RingHashEndpoint : public InternallyRefCounted<RingHashEndpoint> {
192
166
  public:
193
- class Ring : public RefCounted<Ring> {
194
- public:
195
- struct RingEntry {
196
- uint64_t hash;
197
- size_t subchannel_index;
198
- };
167
+ // index is the index into RingHash::addresses_ of this endpoint.
168
+ RingHashEndpoint(RefCountedPtr<RingHash> ring_hash, size_t index)
169
+ : ring_hash_(std::move(ring_hash)), index_(index) {}
199
170
 
200
- Ring(RingHashLbConfig* config, RingHashSubchannelList* subchannel_list,
201
- const ChannelArgs& args);
171
+ void Orphan() override;
202
172
 
203
- const std::vector<RingEntry>& ring() const { return ring_; }
173
+ size_t index() const { return index_; }
204
174
 
205
- private:
206
- std::vector<RingEntry> ring_;
207
- };
175
+ void UpdateLocked(size_t index);
208
176
 
209
- RingHashSubchannelList(RingHash* policy, ServerAddressList addresses,
210
- const ChannelArgs& args);
177
+ grpc_connectivity_state connectivity_state() const {
178
+ return connectivity_state_;
179
+ }
211
180
 
212
- ~RingHashSubchannelList() override {
213
- RingHash* p = static_cast<RingHash*>(policy());
214
- p->Unref(DEBUG_LOCATION, "subchannel_list");
181
+ // Returns info about the endpoint to be stored in the picker.
182
+ struct EndpointInfo {
183
+ RefCountedPtr<RingHashEndpoint> endpoint;
184
+ RefCountedPtr<SubchannelPicker> picker;
185
+ grpc_connectivity_state state;
186
+ absl::Status status;
187
+ };
188
+ EndpointInfo GetInfoForPicker() {
189
+ return {Ref(), picker_, connectivity_state_, status_};
215
190
  }
216
191
 
217
- RefCountedPtr<Ring> ring() { return ring_; }
218
-
219
- // Updates the counters of subchannels in each state when a
220
- // subchannel transitions from old_state to new_state.
221
- void UpdateStateCountersLocked(grpc_connectivity_state old_state,
222
- grpc_connectivity_state new_state);
223
-
224
- // Updates the RH policy's connectivity state based on the
225
- // subchannel list's state counters, creating new picker and new ring.
226
- // The index parameter indicates the index into the list of the subchannel
227
- // whose status report triggered the call to
228
- // UpdateRingHashConnectivityStateLocked().
229
- // connection_attempt_complete is true if the subchannel just
230
- // finished a connection attempt.
231
- void UpdateRingHashConnectivityStateLocked(size_t index,
232
- bool connection_attempt_complete,
233
- absl::Status status);
192
+ void ResetBackoffLocked();
193
+
194
+ // If the child policy does not yet exist, creates it; otherwise,
195
+ // asks the child to exit IDLE.
196
+ void RequestConnectionLocked();
234
197
 
235
198
  private:
236
- std::shared_ptr<WorkSerializer> work_serializer() const override {
237
- return static_cast<RingHash*>(policy())->work_serializer();
238
- }
199
+ class Helper;
239
200
 
240
- size_t num_idle_;
241
- size_t num_ready_ = 0;
242
- size_t num_connecting_ = 0;
243
- size_t num_transient_failure_ = 0;
201
+ void CreateChildPolicy();
202
+ void UpdateChildPolicyLocked();
244
203
 
245
- RefCountedPtr<Ring> ring_;
204
+ // Called when the child policy reports a connectivity state update.
205
+ void OnStateUpdate(grpc_connectivity_state new_state,
206
+ const absl::Status& status,
207
+ RefCountedPtr<SubchannelPicker> picker);
208
+
209
+ // Ref to our parent.
210
+ RefCountedPtr<RingHash> ring_hash_;
211
+ size_t index_; // Index into RingHash::addresses_ of this endpoint.
246
212
 
247
- // The index of the subchannel currently doing an internally
248
- // triggered connection attempt, if any.
249
- absl::optional<size_t> internally_triggered_connection_index_;
213
+ // The pick_first child policy.
214
+ OrphanablePtr<LoadBalancingPolicy> child_policy_;
250
215
 
251
- // TODO(roth): If we ever change the helper UpdateState() API to not
252
- // need the status reported for TRANSIENT_FAILURE state (because
253
- // it's not currently actually used for anything outside of the picker),
254
- // then we will no longer need this data member.
255
- absl::Status last_failure_;
216
+ grpc_connectivity_state connectivity_state_ = GRPC_CHANNEL_IDLE;
217
+ absl::Status status_;
218
+ RefCountedPtr<SubchannelPicker> picker_;
256
219
  };
257
220
 
258
221
  class Picker : public SubchannelPicker {
259
222
  public:
260
- Picker(RefCountedPtr<RingHash> ring_hash_lb,
261
- RingHashSubchannelList* subchannel_list)
262
- : ring_hash_lb_(std::move(ring_hash_lb)),
263
- ring_(subchannel_list->ring()) {
264
- subchannels_.reserve(subchannel_list->num_subchannels());
265
- for (size_t i = 0; i < subchannel_list->num_subchannels(); ++i) {
266
- RingHashSubchannelData* subchannel_data =
267
- subchannel_list->subchannel(i);
268
- subchannels_.emplace_back(
269
- SubchannelInfo{subchannel_data->subchannel()->Ref(),
270
- subchannel_data->logical_connectivity_state(),
271
- subchannel_data->logical_connectivity_status()});
223
+ explicit Picker(RefCountedPtr<RingHash> ring_hash)
224
+ : ring_hash_(std::move(ring_hash)),
225
+ ring_(ring_hash_->ring_),
226
+ endpoints_(ring_hash_->addresses_.size()) {
227
+ for (const auto& p : ring_hash_->endpoint_map_) {
228
+ endpoints_[p.second->index()] = p.second->GetInfoForPicker();
272
229
  }
273
230
  }
274
231
 
275
232
  PickResult Pick(PickArgs args) override;
276
233
 
277
234
  private:
278
- // A fire-and-forget class that schedules subchannel connection attempts
235
+ // A fire-and-forget class that schedules endpoint connection attempts
279
236
  // on the control plane WorkSerializer.
280
- class SubchannelConnectionAttempter : public Orphanable {
237
+ class EndpointConnectionAttempter {
281
238
  public:
282
- explicit SubchannelConnectionAttempter(
283
- RefCountedPtr<RingHash> ring_hash_lb)
284
- : ring_hash_lb_(std::move(ring_hash_lb)) {
285
- GRPC_CLOSURE_INIT(&closure_, RunInExecCtx, this, nullptr);
286
- }
287
-
288
- void Orphan() override {
239
+ EndpointConnectionAttempter(RefCountedPtr<RingHash> ring_hash,
240
+ RefCountedPtr<RingHashEndpoint> endpoint)
241
+ : ring_hash_(std::move(ring_hash)), endpoint_(std::move(endpoint)) {
289
242
  // Hop into ExecCtx, so that we're not holding the data plane mutex
290
243
  // while we run control-plane code.
244
+ GRPC_CLOSURE_INIT(&closure_, RunInExecCtx, this, nullptr);
291
245
  ExecCtx::Run(DEBUG_LOCATION, &closure_, absl::OkStatus());
292
246
  }
293
247
 
294
- void AddSubchannel(RefCountedPtr<SubchannelInterface> subchannel) {
295
- subchannels_.push_back(std::move(subchannel));
296
- }
297
-
298
248
  private:
299
249
  static void RunInExecCtx(void* arg, grpc_error_handle /*error*/) {
300
- auto* self = static_cast<SubchannelConnectionAttempter*>(arg);
301
- self->ring_hash_lb_->work_serializer()->Run(
250
+ auto* self = static_cast<EndpointConnectionAttempter*>(arg);
251
+ self->ring_hash_->work_serializer()->Run(
302
252
  [self]() {
303
- if (!self->ring_hash_lb_->shutdown_) {
304
- for (auto& subchannel : self->subchannels_) {
305
- subchannel->RequestConnection();
306
- }
253
+ if (!self->ring_hash_->shutdown_) {
254
+ self->endpoint_->RequestConnectionLocked();
307
255
  }
308
256
  delete self;
309
257
  },
310
258
  DEBUG_LOCATION);
311
259
  }
312
260
 
313
- RefCountedPtr<RingHash> ring_hash_lb_;
261
+ RefCountedPtr<RingHash> ring_hash_;
262
+ RefCountedPtr<RingHashEndpoint> endpoint_;
314
263
  grpc_closure closure_;
315
- std::vector<RefCountedPtr<SubchannelInterface>> subchannels_;
316
264
  };
317
265
 
318
- struct SubchannelInfo {
319
- RefCountedPtr<SubchannelInterface> subchannel;
320
- grpc_connectivity_state state;
321
- absl::Status status;
322
- };
323
-
324
- RefCountedPtr<RingHash> ring_hash_lb_;
325
- RefCountedPtr<RingHashSubchannelList::Ring> ring_;
326
- std::vector<SubchannelInfo> subchannels_;
266
+ RefCountedPtr<RingHash> ring_hash_;
267
+ RefCountedPtr<Ring> ring_;
268
+ std::vector<RingHashEndpoint::EndpointInfo> endpoints_;
327
269
  };
328
270
 
329
271
  ~RingHash() override;
330
272
 
331
273
  void ShutdownLocked() override;
332
274
 
333
- // Current config from resolver.
334
- RefCountedPtr<RingHashLbConfig> config_;
275
+ // Updates the aggregate policy's connectivity state based on the
276
+ // endpoint list's state counters, creating a new picker.
277
+ // entered_transient_failure is true if the endpoint has just
278
+ // entered TRANSIENT_FAILURE state.
279
+ // If the call to this method is triggered by an endpoint entering
280
+ // TRANSIENT_FAILURE, then status is the status reported by the endpoint.
281
+ void UpdateAggregatedConnectivityStateLocked(bool entered_transient_failure,
282
+ absl::Status status);
283
+
284
+ // Current address list, channel args, and ring.
285
+ ServerAddressList addresses_;
286
+ ChannelArgs args_;
287
+ RefCountedPtr<Ring> ring_;
288
+
289
+ std::map<ServerAddress, OrphanablePtr<RingHashEndpoint>> endpoint_map_;
290
+
291
+ // TODO(roth): If we ever change the helper UpdateState() API to not
292
+ // need the status reported for TRANSIENT_FAILURE state (because
293
+ // it's not currently actually used for anything outside of the picker),
294
+ // then we will no longer need this data member.
295
+ absl::Status last_failure_;
335
296
 
336
- // list of subchannels.
337
- RefCountedPtr<RingHashSubchannelList> subchannel_list_;
338
- RefCountedPtr<RingHashSubchannelList> latest_pending_subchannel_list_;
339
297
  // indicating if we are shutting down.
340
298
  bool shutdown_ = false;
341
299
  };
@@ -358,106 +316,62 @@ RingHash::PickResult RingHash::Picker::Pick(PickArgs args) {
358
316
  absl::InternalError("ring hash value is not a number"));
359
317
  }
360
318
  const auto& ring = ring_->ring();
319
+ // Find the index in the ring to use for this RPC.
361
320
  // Ported from https://github.com/RJ/ketama/blob/master/libketama/ketama.c
362
321
  // (ketama_get_server) NOTE: The algorithm depends on using signed integers
363
- // for lowp, highp, and first_index. Do not change them!
322
+ // for lowp, highp, and index. Do not change them!
364
323
  int64_t lowp = 0;
365
324
  int64_t highp = ring.size();
366
- int64_t first_index = 0;
325
+ int64_t index = 0;
367
326
  while (true) {
368
- first_index = (lowp + highp) / 2;
369
- if (first_index == static_cast<int64_t>(ring.size())) {
370
- first_index = 0;
327
+ index = (lowp + highp) / 2;
328
+ if (index == static_cast<int64_t>(ring.size())) {
329
+ index = 0;
371
330
  break;
372
331
  }
373
- uint64_t midval = ring[first_index].hash;
374
- uint64_t midval1 = first_index == 0 ? 0 : ring[first_index - 1].hash;
332
+ uint64_t midval = ring[index].hash;
333
+ uint64_t midval1 = index == 0 ? 0 : ring[index - 1].hash;
375
334
  if (h <= midval && h > midval1) {
376
335
  break;
377
336
  }
378
337
  if (midval < h) {
379
- lowp = first_index + 1;
338
+ lowp = index + 1;
380
339
  } else {
381
- highp = first_index - 1;
340
+ highp = index - 1;
382
341
  }
383
342
  if (lowp > highp) {
384
- first_index = 0;
343
+ index = 0;
385
344
  break;
386
345
  }
387
346
  }
388
- OrphanablePtr<SubchannelConnectionAttempter> subchannel_connection_attempter;
389
- auto ScheduleSubchannelConnectionAttempt =
390
- [&](RefCountedPtr<SubchannelInterface> subchannel) {
391
- if (subchannel_connection_attempter == nullptr) {
392
- subchannel_connection_attempter =
393
- MakeOrphanable<SubchannelConnectionAttempter>(ring_hash_lb_->Ref(
394
- DEBUG_LOCATION, "SubchannelConnectionAttempter"));
395
- }
396
- subchannel_connection_attempter->AddSubchannel(std::move(subchannel));
397
- };
398
- SubchannelInfo& first_subchannel =
399
- subchannels_[ring[first_index].subchannel_index];
400
- switch (first_subchannel.state) {
401
- case GRPC_CHANNEL_READY:
402
- return PickResult::Complete(first_subchannel.subchannel);
403
- case GRPC_CHANNEL_IDLE:
404
- ScheduleSubchannelConnectionAttempt(first_subchannel.subchannel);
405
- ABSL_FALLTHROUGH_INTENDED;
406
- case GRPC_CHANNEL_CONNECTING:
407
- return PickResult::Queue();
408
- default: // GRPC_CHANNEL_TRANSIENT_FAILURE
409
- break;
410
- }
411
- ScheduleSubchannelConnectionAttempt(first_subchannel.subchannel);
412
- // Loop through remaining subchannels to find one in READY.
413
- // On the way, we make sure the right set of connection attempts
414
- // will happen.
415
- bool found_second_subchannel = false;
416
- bool found_first_non_failed = false;
417
- for (size_t i = 1; i < ring.size(); ++i) {
418
- const auto& entry = ring[(first_index + i) % ring.size()];
419
- if (entry.subchannel_index == ring[first_index].subchannel_index) {
420
- continue;
421
- }
422
- SubchannelInfo& subchannel_info = subchannels_[entry.subchannel_index];
423
- if (subchannel_info.state == GRPC_CHANNEL_READY) {
424
- return PickResult::Complete(subchannel_info.subchannel);
425
- }
426
- if (!found_second_subchannel) {
427
- switch (subchannel_info.state) {
428
- case GRPC_CHANNEL_IDLE:
429
- ScheduleSubchannelConnectionAttempt(subchannel_info.subchannel);
430
- ABSL_FALLTHROUGH_INTENDED;
431
- case GRPC_CHANNEL_CONNECTING:
432
- return PickResult::Queue();
433
- default:
434
- break;
435
- }
436
- found_second_subchannel = true;
437
- }
438
- if (!found_first_non_failed) {
439
- if (subchannel_info.state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
440
- ScheduleSubchannelConnectionAttempt(subchannel_info.subchannel);
441
- } else {
442
- if (subchannel_info.state == GRPC_CHANNEL_IDLE) {
443
- ScheduleSubchannelConnectionAttempt(subchannel_info.subchannel);
444
- }
445
- found_first_non_failed = true;
446
- }
347
+ // Find the first endpoint we can use from the selected index.
348
+ for (size_t i = 0; i < ring.size(); ++i) {
349
+ const auto& entry = ring[(index + i) % ring.size()];
350
+ const auto& endpoint_info = endpoints_[entry.endpoint_index];
351
+ switch (endpoint_info.state) {
352
+ case GRPC_CHANNEL_READY:
353
+ return endpoint_info.picker->Pick(args);
354
+ case GRPC_CHANNEL_IDLE:
355
+ new EndpointConnectionAttempter(
356
+ ring_hash_->Ref(DEBUG_LOCATION, "EndpointConnectionAttempter"),
357
+ endpoint_info.endpoint);
358
+ ABSL_FALLTHROUGH_INTENDED;
359
+ case GRPC_CHANNEL_CONNECTING:
360
+ return PickResult::Queue();
361
+ default:
362
+ break;
447
363
  }
448
364
  }
449
365
  return PickResult::Fail(absl::UnavailableError(absl::StrCat(
450
- "ring hash cannot find a connected subchannel; first failure: ",
451
- first_subchannel.status.ToString())));
366
+ "ring hash cannot find a connected endpoint; first failure: ",
367
+ endpoints_[ring[index].endpoint_index].status.message())));
452
368
  }
453
369
 
454
370
  //
455
- // RingHash::RingHashSubchannelList::Ring
371
+ // RingHash::Ring
456
372
  //
457
373
 
458
- RingHash::RingHashSubchannelList::Ring::Ring(
459
- RingHashLbConfig* config, RingHashSubchannelList* subchannel_list,
460
- const ChannelArgs& args) {
374
+ RingHash::Ring::Ring(RingHash* ring_hash, RingHashLbConfig* config) {
461
375
  // Store the weights while finding the sum.
462
376
  struct AddressWeight {
463
377
  std::string address;
@@ -468,15 +382,15 @@ RingHash::RingHashSubchannelList::Ring::Ring(
468
382
  };
469
383
  std::vector<AddressWeight> address_weights;
470
384
  size_t sum = 0;
471
- address_weights.reserve(subchannel_list->num_subchannels());
472
- for (size_t i = 0; i < subchannel_list->num_subchannels(); ++i) {
473
- RingHashSubchannelData* sd = subchannel_list->subchannel(i);
474
- auto weight_arg = sd->address().args().GetInt(GRPC_ARG_ADDRESS_WEIGHT);
385
+ const ServerAddressList& addresses = ring_hash->addresses_;
386
+ address_weights.reserve(addresses.size());
387
+ for (const auto& address : addresses) {
475
388
  AddressWeight address_weight;
476
389
  address_weight.address =
477
- grpc_sockaddr_to_string(&sd->address().address(), false).value();
390
+ grpc_sockaddr_to_string(&address.address(), false).value();
478
391
  // Weight should never be zero, but ignore it just in case, since
479
392
  // that value would screw up the ring-building algorithm.
393
+ auto weight_arg = address.args().GetInt(GRPC_ARG_ADDRESS_WEIGHT);
480
394
  if (weight_arg.value_or(0) > 0) {
481
395
  address_weight.weight = *weight_arg;
482
396
  }
@@ -500,8 +414,9 @@ RingHash::RingHashSubchannelList::Ring::Ring(
500
414
  // weights aren't provided, all hosts should get an equal number of hashes. In
501
415
  // the case where this number exceeds the max_ring_size, it's scaled back down
502
416
  // to fit.
503
- const size_t ring_size_cap = args.GetInt(GRPC_ARG_RING_HASH_LB_RING_SIZE_CAP)
504
- .value_or(kRingSizeCapDefault);
417
+ const size_t ring_size_cap =
418
+ ring_hash->args_.GetInt(GRPC_ARG_RING_HASH_LB_RING_SIZE_CAP)
419
+ .value_or(kRingSizeCapDefault);
505
420
  const size_t min_ring_size = std::min(config->min_ring_size(), ring_size_cap);
506
421
  const size_t max_ring_size = std::min(config->max_ring_size(), ring_size_cap);
507
422
  const double scale = std::min(
@@ -520,7 +435,7 @@ RingHash::RingHashSubchannelList::Ring::Ring(
520
435
  double target_hashes = 0.0;
521
436
  uint64_t min_hashes_per_host = ring_size;
522
437
  uint64_t max_hashes_per_host = 0;
523
- for (size_t i = 0; i < subchannel_list->num_subchannels(); ++i) {
438
+ for (size_t i = 0; i < addresses.size(); ++i) {
524
439
  const std::string& address_string = address_weights[i].address;
525
440
  hash_key_buffer.assign(address_string.begin(), address_string.end());
526
441
  hash_key_buffer.emplace_back('_');
@@ -550,210 +465,133 @@ RingHash::RingHashSubchannelList::Ring::Ring(
550
465
  }
551
466
 
552
467
  //
553
- // RingHash::RingHashSubchannelList
468
+ // RingHash::RingHashEndpoint::Helper
554
469
  //
555
470
 
556
- RingHash::RingHashSubchannelList::RingHashSubchannelList(
557
- RingHash* policy, ServerAddressList addresses, const ChannelArgs& args)
558
- : SubchannelList(policy,
559
- (GRPC_TRACE_FLAG_ENABLED(grpc_lb_ring_hash_trace)
560
- ? "RingHashSubchannelList"
561
- : nullptr),
562
- std::move(addresses), policy->channel_control_helper(),
563
- args),
564
- num_idle_(num_subchannels()) {
565
- // Need to maintain a ref to the LB policy as long as we maintain
566
- // any references to subchannels, since the subchannels'
567
- // pollset_sets will include the LB policy's pollset_set.
568
- policy->Ref(DEBUG_LOCATION, "subchannel_list").release();
569
- // Construct the ring.
570
- ring_ = MakeRefCounted<Ring>(policy->config_.get(), this, args);
571
- if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_ring_hash_trace)) {
572
- gpr_log(GPR_INFO,
573
- "[RH %p] created subchannel list %p with %" PRIuPTR " ring entries",
574
- policy, this, ring_->ring().size());
471
+ class RingHash::RingHashEndpoint::Helper
472
+ : public LoadBalancingPolicy::DelegatingChannelControlHelper {
473
+ public:
474
+ explicit Helper(RefCountedPtr<RingHashEndpoint> endpoint)
475
+ : endpoint_(std::move(endpoint)) {}
476
+
477
+ ~Helper() override { endpoint_.reset(DEBUG_LOCATION, "Helper"); }
478
+
479
+ void UpdateState(
480
+ grpc_connectivity_state state, const absl::Status& status,
481
+ RefCountedPtr<LoadBalancingPolicy::SubchannelPicker> picker) override {
482
+ endpoint_->OnStateUpdate(state, status, std::move(picker));
575
483
  }
576
- }
577
484
 
578
- void RingHash::RingHashSubchannelList::UpdateStateCountersLocked(
579
- grpc_connectivity_state old_state, grpc_connectivity_state new_state) {
580
- if (old_state == GRPC_CHANNEL_IDLE) {
581
- GPR_ASSERT(num_idle_ > 0);
582
- --num_idle_;
583
- } else if (old_state == GRPC_CHANNEL_READY) {
584
- GPR_ASSERT(num_ready_ > 0);
585
- --num_ready_;
586
- } else if (old_state == GRPC_CHANNEL_CONNECTING) {
587
- GPR_ASSERT(num_connecting_ > 0);
588
- --num_connecting_;
589
- } else if (old_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
590
- GPR_ASSERT(num_transient_failure_ > 0);
591
- --num_transient_failure_;
485
+ private:
486
+ LoadBalancingPolicy::ChannelControlHelper* parent_helper() const override {
487
+ return endpoint_->ring_hash_->channel_control_helper();
592
488
  }
593
- GPR_ASSERT(new_state != GRPC_CHANNEL_SHUTDOWN);
594
- if (new_state == GRPC_CHANNEL_IDLE) {
595
- ++num_idle_;
596
- } else if (new_state == GRPC_CHANNEL_READY) {
597
- ++num_ready_;
598
- } else if (new_state == GRPC_CHANNEL_CONNECTING) {
599
- ++num_connecting_;
600
- } else if (new_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
601
- ++num_transient_failure_;
489
+
490
+ RefCountedPtr<RingHashEndpoint> endpoint_;
491
+ };
492
+
493
+ //
494
+ // RingHash::RingHashEndpoint
495
+ //
496
+
497
+ void RingHash::RingHashEndpoint::Orphan() {
498
+ if (child_policy_ != nullptr) {
499
+ // Remove pollset_set linkage.
500
+ grpc_pollset_set_del_pollset_set(child_policy_->interested_parties(),
501
+ ring_hash_->interested_parties());
502
+ child_policy_.reset();
503
+ picker_.reset();
602
504
  }
505
+ Unref();
603
506
  }
604
507
 
605
- void RingHash::RingHashSubchannelList::UpdateRingHashConnectivityStateLocked(
606
- size_t index, bool connection_attempt_complete, absl::Status status) {
607
- RingHash* p = static_cast<RingHash*>(policy());
608
- // If this is latest_pending_subchannel_list_, then swap it into
609
- // subchannel_list_ as soon as we get the initial connectivity state
610
- // report for every subchannel in the list.
611
- if (p->latest_pending_subchannel_list_.get() == this &&
612
- AllSubchannelsSeenInitialState()) {
613
- if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_ring_hash_trace)) {
614
- gpr_log(GPR_INFO, "[RH %p] replacing subchannel list %p with %p", p,
615
- p->subchannel_list_.get(), this);
616
- }
617
- p->subchannel_list_ = std::move(p->latest_pending_subchannel_list_);
618
- }
619
- // Only set connectivity state if this is the current subchannel list.
620
- if (p->subchannel_list_.get() != this) return;
621
- // The overall aggregation rules here are:
622
- // 1. If there is at least one subchannel in READY state, report READY.
623
- // 2. If there are 2 or more subchannels in TRANSIENT_FAILURE state, report
624
- // TRANSIENT_FAILURE.
625
- // 3. If there is at least one subchannel in CONNECTING state, report
626
- // CONNECTING.
627
- // 4. If there is one subchannel in TRANSIENT_FAILURE state and there is
628
- // more than one subchannel, report CONNECTING.
629
- // 5. If there is at least one subchannel in IDLE state, report IDLE.
630
- // 6. Otherwise, report TRANSIENT_FAILURE.
631
- //
632
- // We set start_connection_attempt to true if we match rules 2, 3, or 6.
633
- grpc_connectivity_state state;
634
- bool start_connection_attempt = false;
635
- if (num_ready_ > 0) {
636
- state = GRPC_CHANNEL_READY;
637
- } else if (num_transient_failure_ >= 2) {
638
- state = GRPC_CHANNEL_TRANSIENT_FAILURE;
639
- start_connection_attempt = true;
640
- } else if (num_connecting_ > 0) {
641
- state = GRPC_CHANNEL_CONNECTING;
642
- } else if (num_transient_failure_ == 1 && num_subchannels() > 1) {
643
- state = GRPC_CHANNEL_CONNECTING;
644
- start_connection_attempt = true;
645
- } else if (num_idle_ > 0) {
646
- state = GRPC_CHANNEL_IDLE;
508
+ void RingHash::RingHashEndpoint::UpdateLocked(size_t index) {
509
+ index_ = index;
510
+ if (child_policy_ != nullptr) UpdateChildPolicyLocked();
511
+ }
512
+
513
+ void RingHash::RingHashEndpoint::ResetBackoffLocked() {
514
+ if (child_policy_ != nullptr) child_policy_->ResetBackoffLocked();
515
+ }
516
+
517
+ void RingHash::RingHashEndpoint::RequestConnectionLocked() {
518
+ if (child_policy_ == nullptr) {
519
+ CreateChildPolicy();
647
520
  } else {
648
- state = GRPC_CHANNEL_TRANSIENT_FAILURE;
649
- start_connection_attempt = true;
521
+ child_policy_->ExitIdleLocked();
650
522
  }
651
- // In TRANSIENT_FAILURE, report the last reported failure.
652
- // Otherwise, report OK.
653
- if (state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
654
- if (!status.ok()) {
655
- last_failure_ = absl::UnavailableError(absl::StrCat(
656
- "no reachable subchannels; last error: ", status.ToString()));
657
- }
658
- status = last_failure_;
659
- } else {
660
- status = absl::OkStatus();
661
- }
662
- // Generate new picker and return it to the channel.
663
- // Note that we use our own picker regardless of connectivity state.
664
- p->channel_control_helper()->UpdateState(
665
- state, status,
666
- MakeRefCounted<Picker>(p->Ref(DEBUG_LOCATION, "RingHashPicker"), this));
667
- // While the ring_hash policy is reporting TRANSIENT_FAILURE, it will
668
- // not be getting any pick requests from the priority policy.
669
- // However, because the ring_hash policy does not attempt to
670
- // reconnect to subchannels unless it is getting pick requests,
671
- // it will need special handling to ensure that it will eventually
672
- // recover from TRANSIENT_FAILURE state once the problem is resolved.
673
- // Specifically, it will make sure that it is attempting to connect to
674
- // at least one subchannel at any given time. After a given subchannel
675
- // fails a connection attempt, it will move on to the next subchannel
676
- // in the ring. It will keep doing this until one of the subchannels
677
- // successfully connects, at which point it will report READY and stop
678
- // proactively trying to connect. The policy will remain in
679
- // TRANSIENT_FAILURE until at least one subchannel becomes connected,
680
- // even if subchannels are in state CONNECTING during that time.
681
- //
682
- // Note that we do the same thing when the policy is in state
683
- // CONNECTING, just to ensure that we don't remain in CONNECTING state
684
- // indefinitely if there are no new picks coming in.
685
- if (internally_triggered_connection_index_.has_value() &&
686
- *internally_triggered_connection_index_ == index &&
687
- connection_attempt_complete) {
688
- internally_triggered_connection_index_.reset();
689
- }
690
- if (start_connection_attempt &&
691
- !internally_triggered_connection_index_.has_value()) {
692
- size_t next_index = (index + 1) % num_subchannels();
693
- if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_ring_hash_trace)) {
694
- gpr_log(GPR_INFO,
695
- "[RH %p] triggering internal connection attempt for subchannel "
696
- "%p, subchannel_list %p (index %" PRIuPTR " of %" PRIuPTR ")",
697
- p, subchannel(next_index)->subchannel(), this, next_index,
698
- num_subchannels());
699
- }
700
- internally_triggered_connection_index_ = next_index;
701
- subchannel(next_index)->subchannel()->RequestConnection();
523
+ }
524
+
525
+ void RingHash::RingHashEndpoint::CreateChildPolicy() {
526
+ GPR_ASSERT(child_policy_ == nullptr);
527
+ LoadBalancingPolicy::Args lb_policy_args;
528
+ lb_policy_args.work_serializer = ring_hash_->work_serializer();
529
+ lb_policy_args.args =
530
+ ring_hash_->args_
531
+ .Set(GRPC_ARG_INTERNAL_PICK_FIRST_ENABLE_HEALTH_CHECKING, true)
532
+ .Set(GRPC_ARG_INTERNAL_PICK_FIRST_OMIT_STATUS_MESSAGE_PREFIX, true);
533
+ lb_policy_args.channel_control_helper =
534
+ std::make_unique<Helper>(Ref(DEBUG_LOCATION, "Helper"));
535
+ child_policy_ =
536
+ CoreConfiguration::Get().lb_policy_registry().CreateLoadBalancingPolicy(
537
+ "pick_first", std::move(lb_policy_args));
538
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_ring_hash_trace)) {
539
+ const ServerAddress& address = ring_hash_->addresses_[index_];
540
+ gpr_log(GPR_INFO,
541
+ "[RH %p] endpoint %p (index %" PRIuPTR " of %" PRIuPTR
542
+ ", %s): created child policy %p",
543
+ ring_hash_.get(), this, index_, ring_hash_->addresses_.size(),
544
+ address.ToString().c_str(), child_policy_.get());
702
545
  }
546
+ // Add our interested_parties pollset_set to that of the newly created
547
+ // child policy. This will make the child policy progress upon activity on
548
+ // this policy, which in turn is tied to the application's call.
549
+ grpc_pollset_set_add_pollset_set(child_policy_->interested_parties(),
550
+ ring_hash_->interested_parties());
551
+ UpdateChildPolicyLocked();
703
552
  }
704
553
 
705
- //
706
- // RingHash::RingHashSubchannelData
707
- //
554
+ void RingHash::RingHashEndpoint::UpdateChildPolicyLocked() {
555
+ // Construct pick_first config.
556
+ auto config =
557
+ CoreConfiguration::Get().lb_policy_registry().ParseLoadBalancingConfig(
558
+ Json::FromArray(
559
+ {Json::FromObject({{"pick_first", Json::FromObject({})}})}));
560
+ GPR_ASSERT(config.ok());
561
+ // Update child policy.
562
+ LoadBalancingPolicy::UpdateArgs update_args;
563
+ update_args.addresses.emplace().emplace_back(ring_hash_->addresses_[index_]);
564
+ update_args.args = ring_hash_->args_;
565
+ update_args.config = std::move(*config);
566
+ // TODO(roth): If the child reports a non-OK status with the update,
567
+ // we need to propagate that back to the resolver somehow.
568
+ (void)child_policy_->UpdateLocked(std::move(update_args));
569
+ }
708
570
 
709
- void RingHash::RingHashSubchannelData::ProcessConnectivityChangeLocked(
710
- absl::optional<grpc_connectivity_state> old_state,
711
- grpc_connectivity_state new_state) {
712
- RingHash* p = static_cast<RingHash*>(subchannel_list()->policy());
571
+ void RingHash::RingHashEndpoint::OnStateUpdate(
572
+ grpc_connectivity_state new_state, const absl::Status& status,
573
+ RefCountedPtr<SubchannelPicker> picker) {
713
574
  if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_ring_hash_trace)) {
714
575
  gpr_log(
715
576
  GPR_INFO,
716
- "[RH %p] connectivity changed for subchannel %p, subchannel_list %p "
717
- "(index %" PRIuPTR " of %" PRIuPTR "): prev_state=%s new_state=%s",
718
- p, subchannel(), subchannel_list(), Index(),
719
- subchannel_list()->num_subchannels(),
720
- ConnectivityStateName(logical_connectivity_state_),
721
- ConnectivityStateName(new_state));
722
- }
723
- GPR_ASSERT(subchannel() != nullptr);
724
- // If this is not the initial state notification and the new state is
725
- // TRANSIENT_FAILURE or IDLE, re-resolve.
726
- // Note that we don't want to do this on the initial state notification,
727
- // because that would result in an endless loop of re-resolution.
728
- if (old_state.has_value() && (new_state == GRPC_CHANNEL_TRANSIENT_FAILURE ||
729
- new_state == GRPC_CHANNEL_IDLE)) {
730
- if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_ring_hash_trace)) {
731
- gpr_log(GPR_INFO,
732
- "[RH %p] Subchannel %p reported %s; requesting re-resolution", p,
733
- subchannel(), ConnectivityStateName(new_state));
734
- }
735
- p->channel_control_helper()->RequestReresolution();
736
- }
737
- const bool connection_attempt_complete = new_state != GRPC_CHANNEL_CONNECTING;
738
- // Decide what state to report for the purposes of aggregation and
739
- // picker behavior.
740
- // If the last recorded state was TRANSIENT_FAILURE, ignore the change
741
- // unless the new state is READY (or TF again, in which case we need
742
- // to update the status).
743
- if (logical_connectivity_state_ != GRPC_CHANNEL_TRANSIENT_FAILURE ||
744
- new_state == GRPC_CHANNEL_READY ||
745
- new_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
746
- // Update state counters used for aggregation.
747
- subchannel_list()->UpdateStateCountersLocked(logical_connectivity_state_,
748
- new_state);
749
- // Update logical state.
750
- logical_connectivity_state_ = new_state;
751
- logical_connectivity_status_ = connectivity_status();
577
+ "[RH %p] connectivity changed for endpoint %p (%s, child_policy=%p): "
578
+ "prev_state=%s new_state=%s (%s)",
579
+ ring_hash_.get(), this,
580
+ ring_hash_->addresses_[index_].ToString().c_str(), child_policy_.get(),
581
+ ConnectivityStateName(connectivity_state_),
582
+ ConnectivityStateName(new_state), status.ToString().c_str());
752
583
  }
753
- // Update the RH policy's connectivity state, creating new picker and new
754
- // ring.
755
- subchannel_list()->UpdateRingHashConnectivityStateLocked(
756
- Index(), connection_attempt_complete, logical_connectivity_status_);
584
+ if (child_policy_ == nullptr) return; // Already orphaned.
585
+ // Update state.
586
+ const bool entered_transient_failure =
587
+ connectivity_state_ != GRPC_CHANNEL_TRANSIENT_FAILURE &&
588
+ new_state == GRPC_CHANNEL_TRANSIENT_FAILURE;
589
+ connectivity_state_ = new_state;
590
+ status_ = status;
591
+ picker_ = std::move(picker);
592
+ // Update the aggregated connectivity state.
593
+ ring_hash_->UpdateAggregatedConnectivityStateLocked(entered_transient_failure,
594
+ status);
757
595
  }
758
596
 
759
597
  //
@@ -770,8 +608,6 @@ RingHash::~RingHash() {
770
608
  if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_ring_hash_trace)) {
771
609
  gpr_log(GPR_INFO, "[RH %p] Destroying Ring Hash policy", this);
772
610
  }
773
- GPR_ASSERT(subchannel_list_ == nullptr);
774
- GPR_ASSERT(latest_pending_subchannel_list_ == nullptr);
775
611
  }
776
612
 
777
613
  void RingHash::ShutdownLocked() {
@@ -779,73 +615,212 @@ void RingHash::ShutdownLocked() {
779
615
  gpr_log(GPR_INFO, "[RH %p] Shutting down", this);
780
616
  }
781
617
  shutdown_ = true;
782
- subchannel_list_.reset();
783
- latest_pending_subchannel_list_.reset();
618
+ endpoint_map_.clear();
784
619
  }
785
620
 
786
621
  void RingHash::ResetBackoffLocked() {
787
- subchannel_list_->ResetBackoffLocked();
788
- if (latest_pending_subchannel_list_ != nullptr) {
789
- latest_pending_subchannel_list_->ResetBackoffLocked();
622
+ for (const auto& p : endpoint_map_) {
623
+ p.second->ResetBackoffLocked();
790
624
  }
791
625
  }
792
626
 
793
627
  absl::Status RingHash::UpdateLocked(UpdateArgs args) {
794
- config_ = std::move(args.config);
795
- ServerAddressList addresses;
628
+ // Check address list.
796
629
  if (args.addresses.ok()) {
797
630
  if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_ring_hash_trace)) {
798
631
  gpr_log(GPR_INFO, "[RH %p] received update with %" PRIuPTR " addresses",
799
632
  this, args.addresses->size());
800
633
  }
801
- addresses = *std::move(args.addresses);
634
+ addresses_ = *std::move(args.addresses);
802
635
  } else {
803
636
  if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_ring_hash_trace)) {
804
637
  gpr_log(GPR_INFO, "[RH %p] received update with addresses error: %s",
805
638
  this, args.addresses.status().ToString().c_str());
806
639
  }
807
- // If we already have a subchannel list, then keep using the existing
640
+ // If we already have an endpoint list, then keep using the existing
808
641
  // list, but still report back that the update was not accepted.
809
- if (subchannel_list_ != nullptr) return args.addresses.status();
642
+ if (!addresses_.empty()) return args.addresses.status();
643
+ }
644
+ // Save channel args.
645
+ args_ = std::move(args.args);
646
+ // Build new ring.
647
+ ring_ = MakeRefCounted<Ring>(
648
+ this, static_cast<RingHashLbConfig*>(args.config.get()));
649
+ // Update endpoint map.
650
+ std::map<ServerAddress, OrphanablePtr<RingHashEndpoint>> endpoint_map;
651
+ for (size_t i = 0; i < addresses_.size(); ++i) {
652
+ const ServerAddress& address = addresses_[i];
653
+ // If present in old map, retain it; otherwise, create a new one.
654
+ auto it = endpoint_map_.find(address);
655
+ if (it != endpoint_map_.end()) {
656
+ it->second->UpdateLocked(i);
657
+ endpoint_map.emplace(address, std::move(it->second));
658
+ } else {
659
+ endpoint_map.emplace(address, MakeOrphanable<RingHashEndpoint>(Ref(), i));
660
+ }
661
+ }
662
+ endpoint_map_ = std::move(endpoint_map);
663
+ // If the address list is empty, report TRANSIENT_FAILURE.
664
+ // TODO(roth): As part of adding dualstack backend support, we need to
665
+ // also handle the case where the list of addresses for a given
666
+ // endpoint is empty.
667
+ if (addresses_.empty()) {
668
+ absl::Status status =
669
+ args.addresses.ok() ? absl::UnavailableError(absl::StrCat(
670
+ "empty address list: ", args.resolution_note))
671
+ : args.addresses.status();
672
+ channel_control_helper()->UpdateState(
673
+ GRPC_CHANNEL_TRANSIENT_FAILURE, status,
674
+ MakeRefCounted<TransientFailurePicker>(status));
675
+ return status;
676
+ }
677
+ // Return a new picker.
678
+ UpdateAggregatedConnectivityStateLocked(/*entered_transient_failure=*/false,
679
+ absl::OkStatus());
680
+ return absl::OkStatus();
681
+ }
682
+
683
+ void RingHash::UpdateAggregatedConnectivityStateLocked(
684
+ bool entered_transient_failure, absl::Status status) {
685
+ // Count the number of endpoints in each state.
686
+ size_t num_idle = 0;
687
+ size_t num_connecting = 0;
688
+ size_t num_ready = 0;
689
+ size_t num_transient_failure = 0;
690
+ for (const auto& p : endpoint_map_) {
691
+ switch (p.second->connectivity_state()) {
692
+ case GRPC_CHANNEL_READY:
693
+ ++num_ready;
694
+ break;
695
+ case GRPC_CHANNEL_IDLE:
696
+ ++num_idle;
697
+ break;
698
+ case GRPC_CHANNEL_CONNECTING:
699
+ ++num_connecting;
700
+ break;
701
+ case GRPC_CHANNEL_TRANSIENT_FAILURE:
702
+ ++num_transient_failure;
703
+ break;
704
+ default:
705
+ Crash("child policy should never report SHUTDOWN");
706
+ }
707
+ }
708
+ // The overall aggregation rules here are:
709
+ // 1. If there is at least one endpoint in READY state, report READY.
710
+ // 2. If there are 2 or more endpoints in TRANSIENT_FAILURE state, report
711
+ // TRANSIENT_FAILURE.
712
+ // 3. If there is at least one endpoint in CONNECTING state, report
713
+ // CONNECTING.
714
+ // 4. If there is one endpoint in TRANSIENT_FAILURE state and there is
715
+ // more than one endpoint, report CONNECTING.
716
+ // 5. If there is at least one endpoint in IDLE state, report IDLE.
717
+ // 6. Otherwise, report TRANSIENT_FAILURE.
718
+ //
719
+ // We set start_connection_attempt to true if we match rules 2, 4, or 6.
720
+ grpc_connectivity_state state;
721
+ bool start_connection_attempt = false;
722
+ if (num_ready > 0) {
723
+ state = GRPC_CHANNEL_READY;
724
+ } else if (num_transient_failure >= 2) {
725
+ state = GRPC_CHANNEL_TRANSIENT_FAILURE;
726
+ start_connection_attempt = true;
727
+ } else if (num_connecting > 0) {
728
+ state = GRPC_CHANNEL_CONNECTING;
729
+ } else if (num_transient_failure == 1 && addresses_.size() > 1) {
730
+ state = GRPC_CHANNEL_CONNECTING;
731
+ start_connection_attempt = true;
732
+ } else if (num_idle > 0) {
733
+ state = GRPC_CHANNEL_IDLE;
734
+ } else {
735
+ state = GRPC_CHANNEL_TRANSIENT_FAILURE;
736
+ start_connection_attempt = true;
810
737
  }
811
- if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_ring_hash_trace) &&
812
- latest_pending_subchannel_list_ != nullptr) {
813
- gpr_log(GPR_INFO, "[RH %p] replacing latest pending subchannel list %p",
814
- this, latest_pending_subchannel_list_.get());
738
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_ring_hash_trace)) {
739
+ gpr_log(GPR_INFO,
740
+ "[RH %p] setting connectivity state to %s (num_idle=%" PRIuPTR
741
+ ", num_connecting=%" PRIuPTR ", num_ready=%" PRIuPTR
742
+ ", num_transient_failure=%" PRIuPTR ", size=%" PRIuPTR
743
+ ") -- start_connection_attempt=%d",
744
+ this, ConnectivityStateName(state), num_idle, num_connecting,
745
+ num_ready, num_transient_failure, addresses_.size(),
746
+ start_connection_attempt);
815
747
  }
816
- latest_pending_subchannel_list_ = MakeRefCounted<RingHashSubchannelList>(
817
- this, std::move(addresses), args.args);
818
- latest_pending_subchannel_list_->StartWatchingLocked(args.args);
819
- // If we have no existing list or the new list is empty, immediately
820
- // promote the new list.
821
- // Otherwise, do nothing; the new list will be promoted when the
822
- // initial subchannel states are reported.
823
- if (subchannel_list_ == nullptr ||
824
- latest_pending_subchannel_list_->num_subchannels() == 0) {
825
- if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_ring_hash_trace) &&
826
- subchannel_list_ != nullptr) {
827
- gpr_log(GPR_INFO,
828
- "[RH %p] empty address list, replacing subchannel list %p", this,
829
- subchannel_list_.get());
748
+ // In TRANSIENT_FAILURE, report the last reported failure.
749
+ // Otherwise, report OK.
750
+ if (state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
751
+ if (!status.ok()) {
752
+ last_failure_ = absl::UnavailableError(absl::StrCat(
753
+ "no reachable endpoints; last error: ", status.message()));
830
754
  }
831
- subchannel_list_ = std::move(latest_pending_subchannel_list_);
832
- // If the new list is empty, report TRANSIENT_FAILURE.
833
- if (subchannel_list_->num_subchannels() == 0) {
834
- absl::Status status =
835
- args.addresses.ok()
836
- ? absl::UnavailableError(
837
- absl::StrCat("empty address list: ", args.resolution_note))
838
- : args.addresses.status();
839
- channel_control_helper()->UpdateState(
840
- GRPC_CHANNEL_TRANSIENT_FAILURE, status,
841
- MakeRefCounted<TransientFailurePicker>(status));
842
- return status;
755
+ status = last_failure_;
756
+ } else {
757
+ status = absl::OkStatus();
758
+ }
759
+ // Generate new picker and return it to the channel.
760
+ // Note that we use our own picker regardless of connectivity state.
761
+ channel_control_helper()->UpdateState(
762
+ state, status,
763
+ MakeRefCounted<Picker>(Ref(DEBUG_LOCATION, "RingHashPicker")));
764
+ // While the ring_hash policy is reporting TRANSIENT_FAILURE, it will
765
+ // not be getting any pick requests from the priority policy.
766
+ // However, because the ring_hash policy does not attempt to
767
+ // reconnect to endpoints unless it is getting pick requests,
768
+ // it will need special handling to ensure that it will eventually
769
+ // recover from TRANSIENT_FAILURE state once the problem is resolved.
770
+ // Specifically, it will make sure that it is attempting to connect to
771
+ // at least one endpoint at any given time. But we don't want to just
772
+ // try to connect to only one endpoint, because if that particular
773
+ // endpoint happens to be down but the rest are reachable, we would
774
+ // incorrectly fail to recover.
775
+ //
776
+ // So, to handle this, whenever an endpoint initially enters
777
+ // TRANSIENT_FAILURE state (i.e., its initial connection attempt has
778
+ // failed), if there are no endpoints currently in CONNECTING state
779
+ // (i.e., they are still trying their initial connection attempt),
780
+ // then we will trigger a connection attempt for the first endpoint
781
+ // that is currently in state IDLE, if any.
782
+ //
783
+ // Note that once an endpoint enters TRANSIENT_FAILURE state, it will
784
+ // stay in that state and automatically retry after appropriate backoff,
785
+ // never stopping until it establishes a connection. This means that
786
+ // if we stay in TRANSIENT_FAILURE for a long period of time, we will
787
+ // eventually be trying *all* endpoints, which probably isn't ideal.
788
+ // But it's no different than what can happen if ring_hash is the root
789
+ // LB policy and we keep getting picks, so it's not really a new
790
+ // problem. If/when it becomes an issue, we can figure out how to
791
+ // address it.
792
+ //
793
+ // Note that we do the same thing when the policy is in state
794
+ // CONNECTING, just to ensure that we don't remain in CONNECTING state
795
+ // indefinitely if there are no new picks coming in.
796
+ if (start_connection_attempt && entered_transient_failure) {
797
+ size_t first_idle_index = addresses_.size();
798
+ for (size_t i = 0; i < addresses_.size(); ++i) {
799
+ auto it = endpoint_map_.find(addresses_[i]);
800
+ GPR_ASSERT(it != endpoint_map_.end());
801
+ if (it->second->connectivity_state() == GRPC_CHANNEL_CONNECTING) {
802
+ first_idle_index = addresses_.size();
803
+ break;
804
+ }
805
+ if (first_idle_index == addresses_.size() &&
806
+ it->second->connectivity_state() == GRPC_CHANNEL_IDLE) {
807
+ first_idle_index = i;
808
+ }
809
+ }
810
+ if (first_idle_index != addresses_.size()) {
811
+ auto it = endpoint_map_.find(addresses_[first_idle_index]);
812
+ GPR_ASSERT(it != endpoint_map_.end());
813
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_ring_hash_trace)) {
814
+ gpr_log(GPR_INFO,
815
+ "[RH %p] triggering internal connection attempt for endpoint "
816
+ "%p (%s) (index %" PRIuPTR " of %" PRIuPTR ")",
817
+ this, it->second.get(),
818
+ addresses_[first_idle_index].ToString().c_str(),
819
+ first_idle_index, addresses_.size());
820
+ }
821
+ it->second->RequestConnectionLocked();
843
822
  }
844
- // Otherwise, report IDLE.
845
- subchannel_list_->UpdateRingHashConnectivityStateLocked(
846
- /*index=*/0, /*connection_attempt_complete=*/false, absl::OkStatus());
847
823
  }
848
- return absl::OkStatus();
849
824
  }
850
825
 
851
826
  //