grpc 1.49.0.pre1-x86_64-linux → 1.50.0.pre1-x86_64-linux

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of grpc might be problematic. Click here for more details.

Files changed (277) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +54 -153
  3. data/include/grpc/event_engine/endpoint_config.h +11 -5
  4. data/include/grpc/event_engine/event_engine.h +1 -1
  5. data/include/grpc/impl/codegen/atm_gcc_atomic.h +19 -28
  6. data/include/grpc/impl/codegen/atm_gcc_sync.h +0 -2
  7. data/include/grpc/impl/codegen/atm_windows.h +0 -2
  8. data/include/grpc/impl/codegen/grpc_types.h +6 -0
  9. data/src/core/ext/filters/channel_idle/channel_idle_filter.cc +3 -3
  10. data/src/core/ext/filters/client_channel/backup_poller.cc +4 -6
  11. data/src/core/ext/filters/client_channel/client_channel.cc +41 -22
  12. data/src/core/ext/filters/client_channel/client_channel.h +1 -1
  13. data/src/core/ext/filters/client_channel/client_channel_plugin.cc +0 -16
  14. data/src/core/ext/filters/client_channel/http_proxy.cc +12 -19
  15. data/src/core/ext/filters/client_channel/http_proxy.h +3 -2
  16. data/src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc +6 -4
  17. data/src/core/ext/filters/client_channel/lb_policy/child_policy_handler.h +5 -4
  18. data/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc +0 -2
  19. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +114 -103
  20. data/src/core/ext/filters/client_channel/lb_policy/oob_backend_metric.cc +20 -11
  21. data/src/core/ext/filters/client_channel/lb_policy/outlier_detection/outlier_detection.cc +106 -108
  22. data/src/core/ext/filters/client_channel/lb_policy/outlier_detection/outlier_detection.h +16 -0
  23. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +20 -13
  24. data/src/core/ext/filters/client_channel/lb_policy/priority/priority.cc +165 -257
  25. data/src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.cc +218 -231
  26. data/src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.h +10 -6
  27. data/src/core/ext/filters/client_channel/lb_policy/rls/rls.cc +389 -444
  28. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +16 -16
  29. data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +8 -13
  30. data/src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc +87 -96
  31. data/src/core/ext/filters/client_channel/lb_policy/xds/cds.cc +38 -37
  32. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc +106 -186
  33. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc +106 -93
  34. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc +170 -218
  35. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +2 -2
  36. data/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +1 -1
  37. data/src/core/ext/filters/client_channel/resolver/google_c2p/google_c2p_resolver.cc +38 -18
  38. data/src/core/ext/filters/client_channel/resolver/polling_resolver.cc +84 -37
  39. data/src/core/ext/filters/client_channel/resolver/polling_resolver.h +11 -0
  40. data/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc +1 -0
  41. data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc +5 -3
  42. data/src/core/ext/filters/client_channel/resolver_result_parsing.cc +5 -4
  43. data/src/core/ext/filters/client_channel/retry_filter.cc +25 -29
  44. data/src/core/ext/filters/client_channel/subchannel.cc +38 -33
  45. data/src/core/ext/filters/client_channel/subchannel.h +12 -3
  46. data/src/core/ext/filters/client_channel/subchannel_stream_client.cc +1 -2
  47. data/src/core/ext/filters/fault_injection/fault_injection_filter.cc +23 -16
  48. data/src/core/ext/filters/fault_injection/fault_injection_filter.h +8 -0
  49. data/src/core/ext/filters/http/client/http_client_filter.cc +1 -2
  50. data/src/core/ext/filters/http/message_compress/message_compress_filter.cc +2 -4
  51. data/src/core/ext/filters/http/message_compress/message_decompress_filter.cc +0 -2
  52. data/src/core/ext/filters/http/server/http_server_filter.cc +1 -2
  53. data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +12 -8
  54. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +32 -26
  55. data/src/core/ext/transport/chttp2/transport/bin_encoder.cc +1 -1
  56. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +25 -130
  57. data/src/core/ext/transport/chttp2/transport/decode_huff.cc +287 -0
  58. data/src/core/ext/transport/chttp2/transport/decode_huff.h +1018 -0
  59. data/src/core/ext/transport/chttp2/transport/flow_control.cc +83 -51
  60. data/src/core/ext/transport/chttp2/transport/flow_control.h +11 -6
  61. data/src/core/ext/transport/chttp2/transport/frame_ping.cc +1 -2
  62. data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +2 -20
  63. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +28 -28
  64. data/src/core/ext/transport/chttp2/transport/hpack_parser_table.cc +1 -10
  65. data/src/core/ext/transport/chttp2/transport/hpack_parser_table.h +11 -6
  66. data/src/core/ext/transport/chttp2/transport/internal.h +2 -0
  67. data/src/core/ext/transport/chttp2/transport/parsing.cc +44 -0
  68. data/src/core/ext/transport/chttp2/transport/writing.cc +3 -14
  69. data/src/core/ext/transport/inproc/inproc_transport.cc +1 -3
  70. data/src/core/ext/xds/certificate_provider_store.cc +63 -3
  71. data/src/core/ext/xds/certificate_provider_store.h +9 -1
  72. data/src/core/ext/xds/file_watcher_certificate_provider_factory.cc +5 -5
  73. data/src/core/ext/xds/file_watcher_certificate_provider_factory.h +1 -1
  74. data/src/core/ext/xds/xds_api.cc +21 -17
  75. data/src/core/ext/xds/xds_api.h +7 -0
  76. data/src/core/ext/xds/xds_bootstrap.cc +5 -537
  77. data/src/core/ext/xds/xds_bootstrap.h +39 -111
  78. data/src/core/ext/xds/xds_bootstrap_grpc.cc +370 -0
  79. data/src/core/ext/xds/xds_bootstrap_grpc.h +169 -0
  80. data/src/core/ext/xds/xds_client.cc +219 -145
  81. data/src/core/ext/xds/xds_client.h +19 -17
  82. data/src/core/ext/xds/xds_client_grpc.cc +18 -80
  83. data/src/core/ext/xds/xds_client_grpc.h +2 -25
  84. data/src/core/ext/xds/xds_client_stats.cc +4 -4
  85. data/src/core/ext/xds/xds_cluster.cc +87 -79
  86. data/src/core/ext/xds/xds_cluster.h +5 -5
  87. data/src/core/ext/xds/xds_cluster_specifier_plugin.cc +3 -1
  88. data/src/core/ext/xds/xds_common_types.cc +13 -5
  89. data/src/core/ext/xds/xds_endpoint.cc +8 -6
  90. data/src/core/ext/xds/xds_endpoint.h +3 -4
  91. data/src/core/ext/xds/xds_lb_policy_registry.cc +4 -2
  92. data/src/core/ext/xds/xds_listener.cc +25 -20
  93. data/src/core/ext/xds/xds_listener.h +3 -4
  94. data/src/core/ext/xds/xds_resource_type.h +11 -8
  95. data/src/core/ext/xds/xds_route_config.cc +15 -16
  96. data/src/core/ext/xds/xds_route_config.h +3 -3
  97. data/src/core/ext/xds/xds_server_config_fetcher.cc +7 -5
  98. data/src/core/ext/xds/xds_transport_grpc.cc +15 -7
  99. data/src/core/lib/backoff/backoff.cc +2 -4
  100. data/src/core/lib/channel/call_finalization.h +1 -3
  101. data/src/core/lib/channel/channel_args.h +114 -14
  102. data/src/core/lib/channel/channel_trace.cc +3 -4
  103. data/src/core/lib/channel/promise_based_filter.cc +18 -19
  104. data/src/core/lib/channel/status_util.cc +27 -0
  105. data/src/core/lib/channel/status_util.h +10 -0
  106. data/src/core/lib/config/core_configuration.cc +5 -1
  107. data/src/core/lib/config/core_configuration.h +33 -0
  108. data/src/core/lib/debug/stats.cc +26 -30
  109. data/src/core/lib/debug/stats.h +2 -12
  110. data/src/core/lib/debug/stats_data.cc +118 -614
  111. data/src/core/lib/debug/stats_data.h +67 -465
  112. data/src/core/lib/debug/trace.cc +0 -2
  113. data/src/core/lib/event_engine/channel_args_endpoint_config.cc +12 -20
  114. data/src/core/lib/event_engine/channel_args_endpoint_config.h +13 -7
  115. data/src/core/lib/event_engine/forkable.cc +19 -16
  116. data/src/core/lib/event_engine/poller.h +14 -12
  117. data/src/core/lib/event_engine/posix_engine/timer_manager.cc +53 -32
  118. data/src/core/lib/event_engine/posix_engine/timer_manager.h +23 -1
  119. data/src/core/lib/event_engine/thread_pool.cc +131 -94
  120. data/src/core/lib/event_engine/thread_pool.h +56 -23
  121. data/src/core/lib/event_engine/time_util.cc +30 -0
  122. data/src/core/lib/event_engine/time_util.h +32 -0
  123. data/src/core/lib/event_engine/utils.cc +0 -5
  124. data/src/core/lib/event_engine/utils.h +0 -4
  125. data/src/core/lib/event_engine/windows/iocp.cc +13 -7
  126. data/src/core/lib/event_engine/windows/iocp.h +2 -1
  127. data/src/core/lib/event_engine/windows/win_socket.cc +1 -1
  128. data/src/core/lib/experiments/config.cc +146 -0
  129. data/src/core/lib/experiments/config.h +43 -0
  130. data/src/core/lib/experiments/experiments.cc +75 -0
  131. data/src/core/lib/experiments/experiments.h +56 -0
  132. data/src/core/lib/gpr/alloc.cc +1 -9
  133. data/src/core/lib/gpr/log_windows.cc +0 -1
  134. data/src/core/lib/gpr/string_util_windows.cc +3 -30
  135. data/src/core/lib/gpr/sync_abseil.cc +0 -14
  136. data/src/core/lib/gpr/sync_posix.cc +0 -14
  137. data/src/core/lib/gpr/time_posix.cc +0 -6
  138. data/src/core/lib/gpr/time_precise.h +1 -1
  139. data/src/core/lib/gpr/tmpfile_windows.cc +5 -7
  140. data/src/core/lib/gpr/useful.h +11 -0
  141. data/src/core/lib/{gpr → gprpp}/env.h +25 -12
  142. data/src/core/lib/{gpr → gprpp}/env_linux.cc +20 -15
  143. data/src/core/lib/{gpr → gprpp}/env_posix.cc +11 -10
  144. data/src/core/lib/gprpp/env_windows.cc +56 -0
  145. data/src/core/lib/gprpp/fork.cc +14 -22
  146. data/src/core/lib/gprpp/fork.h +0 -8
  147. data/src/core/lib/gprpp/global_config_env.cc +7 -6
  148. data/src/core/lib/gprpp/notification.h +67 -0
  149. data/src/core/lib/gprpp/packed_table.h +40 -0
  150. data/src/core/lib/gprpp/ref_counted_ptr.h +20 -33
  151. data/src/core/lib/gprpp/sorted_pack.h +98 -0
  152. data/src/core/lib/gprpp/status_helper.h +6 -0
  153. data/src/core/lib/gprpp/table.h +9 -1
  154. data/src/core/lib/gprpp/tchar.cc +49 -0
  155. data/src/core/lib/gprpp/tchar.h +33 -0
  156. data/src/core/lib/gprpp/time.cc +21 -0
  157. data/src/core/lib/gprpp/time.h +55 -0
  158. data/src/core/lib/gprpp/validation_errors.cc +61 -0
  159. data/src/core/lib/gprpp/validation_errors.h +110 -0
  160. data/src/core/{ext/filters/client_channel → lib/handshaker}/proxy_mapper.h +3 -3
  161. data/src/core/{ext/filters/client_channel → lib/handshaker}/proxy_mapper_registry.cc +14 -36
  162. data/src/core/lib/handshaker/proxy_mapper_registry.h +75 -0
  163. data/src/core/lib/iomgr/call_combiner.cc +0 -8
  164. data/src/core/lib/iomgr/closure.h +0 -1
  165. data/src/core/lib/iomgr/endpoint_pair_posix.cc +14 -10
  166. data/src/core/lib/iomgr/endpoint_pair_windows.cc +2 -2
  167. data/src/core/lib/iomgr/ev_epoll1_linux.cc +1 -38
  168. data/src/core/lib/iomgr/ev_poll_posix.cc +2 -17
  169. data/src/core/lib/iomgr/exec_ctx.cc +0 -10
  170. data/src/core/lib/iomgr/exec_ctx.h +7 -31
  171. data/src/core/lib/iomgr/iocp_windows.cc +1 -2
  172. data/src/core/lib/iomgr/iomgr.cc +6 -8
  173. data/src/core/lib/iomgr/iomgr_fwd.h +1 -0
  174. data/src/core/lib/iomgr/pollset.h +1 -1
  175. data/src/core/lib/iomgr/pollset_set.h +0 -1
  176. data/src/core/lib/iomgr/resolve_address.h +1 -0
  177. data/src/core/lib/iomgr/resolve_address_impl.h +1 -0
  178. data/src/core/lib/iomgr/resolve_address_posix.cc +5 -0
  179. data/src/core/lib/iomgr/resolve_address_windows.cc +5 -0
  180. data/src/core/lib/iomgr/sockaddr_utils_posix.cc +2 -1
  181. data/src/core/lib/iomgr/socket_utils_common_posix.cc +12 -34
  182. data/src/core/lib/iomgr/socket_utils_posix.cc +83 -1
  183. data/src/core/lib/iomgr/socket_utils_posix.h +98 -6
  184. data/src/core/lib/iomgr/tcp_client.cc +6 -7
  185. data/src/core/lib/iomgr/tcp_client.h +11 -11
  186. data/src/core/lib/iomgr/tcp_client_cfstream.cc +6 -6
  187. data/src/core/lib/iomgr/tcp_client_posix.cc +33 -29
  188. data/src/core/lib/iomgr/tcp_client_posix.h +12 -9
  189. data/src/core/lib/iomgr/tcp_client_windows.cc +6 -6
  190. data/src/core/lib/iomgr/tcp_posix.cc +131 -114
  191. data/src/core/lib/iomgr/tcp_posix.h +3 -1
  192. data/src/core/lib/iomgr/tcp_server.cc +5 -4
  193. data/src/core/lib/iomgr/tcp_server.h +9 -6
  194. data/src/core/lib/iomgr/tcp_server_posix.cc +17 -28
  195. data/src/core/lib/iomgr/tcp_server_utils_posix.h +2 -2
  196. data/src/core/lib/iomgr/tcp_server_utils_posix_common.cc +3 -3
  197. data/src/core/lib/iomgr/tcp_server_windows.cc +6 -7
  198. data/src/core/lib/iomgr/tcp_windows.cc +0 -1
  199. data/src/core/lib/iomgr/tcp_windows.h +0 -1
  200. data/src/core/lib/iomgr/timer_generic.cc +4 -4
  201. data/src/core/lib/iomgr/timer_manager.cc +1 -2
  202. data/src/core/lib/iomgr/wakeup_fd_eventfd.cc +0 -2
  203. data/src/core/lib/json/json_object_loader.cc +21 -52
  204. data/src/core/lib/json/json_object_loader.h +56 -76
  205. data/src/core/lib/json/json_util.cc +2 -1
  206. data/src/core/lib/load_balancing/lb_policy.h +5 -5
  207. data/src/core/lib/load_balancing/lb_policy_registry.cc +29 -55
  208. data/src/core/lib/load_balancing/lb_policy_registry.h +23 -11
  209. data/src/core/lib/promise/activity.h +2 -3
  210. data/src/core/lib/promise/context.h +1 -1
  211. data/src/core/lib/promise/sleep.cc +16 -4
  212. data/src/core/lib/promise/sleep.h +8 -2
  213. data/src/core/lib/resolver/resolver.h +13 -3
  214. data/src/core/lib/resource_quota/api.cc +9 -0
  215. data/src/core/lib/resource_quota/api.h +6 -0
  216. data/src/core/lib/resource_quota/arena.cc +1 -3
  217. data/src/core/lib/resource_quota/memory_quota.cc +8 -24
  218. data/src/core/lib/resource_quota/memory_quota.h +6 -19
  219. data/src/core/lib/resource_quota/periodic_update.cc +2 -3
  220. data/src/core/{ext/xds → lib/security/certificate_provider}/certificate_provider_factory.h +3 -3
  221. data/src/core/lib/security/certificate_provider/certificate_provider_registry.cc +60 -0
  222. data/src/core/lib/security/certificate_provider/certificate_provider_registry.h +70 -0
  223. data/src/core/lib/security/credentials/channel_creds_registry_init.cc +1 -0
  224. data/src/core/lib/security/credentials/external/aws_external_account_credentials.cc +15 -16
  225. data/src/core/lib/security/credentials/external/external_account_credentials.cc +2 -1
  226. data/src/core/lib/security/credentials/google_default/credentials_generic.cc +5 -8
  227. data/src/core/lib/security/credentials/google_default/google_default_credentials.cc +6 -6
  228. data/src/core/lib/security/credentials/jwt/jwt_verifier.cc +3 -2
  229. data/src/core/lib/security/credentials/jwt/jwt_verifier.h +1 -1
  230. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +1 -2
  231. data/src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc +4 -3
  232. data/src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h +4 -2
  233. data/src/core/lib/security/credentials/tls/tls_utils.cc +3 -1
  234. data/src/core/lib/security/transport/client_auth_filter.cc +12 -1
  235. data/src/core/lib/security/transport/secure_endpoint.cc +0 -4
  236. data/src/core/lib/surface/call.cc +1 -11
  237. data/src/core/lib/surface/channel.cc +3 -2
  238. data/src/core/lib/surface/completion_queue.cc +16 -28
  239. data/src/core/lib/surface/completion_queue.h +1 -1
  240. data/src/core/lib/surface/completion_queue_factory.cc +5 -0
  241. data/src/core/lib/surface/init.cc +16 -11
  242. data/src/core/lib/surface/init_internally.cc +24 -0
  243. data/src/core/lib/surface/init_internally.h +28 -0
  244. data/src/core/lib/surface/server.cc +1 -7
  245. data/src/core/lib/surface/server.h +4 -6
  246. data/src/core/lib/surface/version.cc +2 -2
  247. data/src/core/lib/transport/bdp_estimator.cc +1 -3
  248. data/src/core/lib/transport/metadata_batch.cc +2 -3
  249. data/src/core/lib/transport/metadata_batch.h +9 -7
  250. data/src/core/lib/transport/parsed_metadata.h +4 -2
  251. data/src/core/lib/transport/status_conversion.cc +1 -3
  252. data/src/core/lib/transport/tcp_connect_handshaker.cc +9 -5
  253. data/src/core/lib/transport/transport.h +0 -1
  254. data/src/core/lib/transport/transport_impl.h +0 -1
  255. data/src/core/plugin_registry/grpc_plugin_registry.cc +23 -46
  256. data/src/core/plugin_registry/grpc_plugin_registry_extra.cc +13 -25
  257. data/src/ruby/ext/grpc/extconf.rb +1 -1
  258. data/src/ruby/lib/grpc/2.6/grpc_c.so +0 -0
  259. data/src/ruby/lib/grpc/2.7/grpc_c.so +0 -0
  260. data/src/ruby/lib/grpc/3.0/grpc_c.so +0 -0
  261. data/src/ruby/lib/grpc/3.1/grpc_c.so +0 -0
  262. data/src/ruby/lib/grpc/grpc_c.so +0 -0
  263. data/src/ruby/lib/grpc/version.rb +1 -1
  264. data/src/ruby/spec/channel_spec.rb +5 -0
  265. data/src/ruby/spec/generic/server_interceptors_spec.rb +1 -1
  266. data/src/ruby/spec/user_agent_spec.rb +1 -1
  267. metadata +32 -19
  268. data/src/core/ext/filters/client_channel/proxy_mapper_registry.h +0 -56
  269. data/src/core/ext/xds/certificate_provider_registry.cc +0 -103
  270. data/src/core/ext/xds/certificate_provider_registry.h +0 -59
  271. data/src/core/lib/event_engine/promise.h +0 -78
  272. data/src/core/lib/gpr/env_windows.cc +0 -74
  273. data/src/core/lib/gpr/string_windows.h +0 -32
  274. data/src/core/lib/profiling/basic_timers.cc +0 -295
  275. data/src/core/lib/profiling/stap_timers.cc +0 -50
  276. data/src/core/lib/profiling/timers.h +0 -94
  277. data/src/ruby/lib/grpc/2.5/grpc_c.so +0 -0
@@ -24,7 +24,6 @@
24
24
  #include <algorithm>
25
25
  #include <atomic>
26
26
  #include <cmath>
27
- #include <map>
28
27
  #include <memory>
29
28
  #include <string>
30
29
  #include <utility>
@@ -38,7 +37,6 @@
38
37
  #include "absl/status/statusor.h"
39
38
  #include "absl/strings/numbers.h"
40
39
  #include "absl/strings/str_cat.h"
41
- #include "absl/strings/str_join.h"
42
40
  #include "absl/strings/string_view.h"
43
41
  #include "absl/types/optional.h"
44
42
 
@@ -52,11 +50,10 @@
52
50
  #include "src/core/ext/filters/client_channel/lb_policy/subchannel_list.h"
53
51
  #include "src/core/lib/address_utils/sockaddr_utils.h"
54
52
  #include "src/core/lib/channel/channel_args.h"
53
+ #include "src/core/lib/config/core_configuration.h"
55
54
  #include "src/core/lib/debug/trace.h"
56
- #include "src/core/lib/gpr/string.h"
57
55
  #include "src/core/lib/gprpp/debug_location.h"
58
56
  #include "src/core/lib/gprpp/orphanable.h"
59
- #include "src/core/lib/gprpp/ref_counted.h"
60
57
  #include "src/core/lib/gprpp/ref_counted_ptr.h"
61
58
  #include "src/core/lib/gprpp/sync.h"
62
59
  #include "src/core/lib/gprpp/unique_type_name.h"
@@ -82,49 +79,35 @@ UniqueTypeName RequestHashAttributeName() {
82
79
  }
83
80
 
84
81
  // Helper Parser method
85
- absl::StatusOr<RingHashConfig> ParseRingHashLbConfig(const Json& json) {
86
- if (json.type() != Json::Type::OBJECT) {
87
- return absl::InvalidArgumentError(
88
- "ring_hash_experimental should be of type object");
89
- }
90
- RingHashConfig config;
91
- std::vector<std::string> errors;
92
- const Json::Object& ring_hash = json.object_value();
93
- auto ring_hash_it = ring_hash.find("min_ring_size");
94
- if (ring_hash_it != ring_hash.end()) {
95
- if (ring_hash_it->second.type() != Json::Type::NUMBER) {
96
- errors.emplace_back(
97
- "field:min_ring_size error: should be of type number");
98
- } else {
99
- config.min_ring_size = gpr_parse_nonnegative_int(
100
- ring_hash_it->second.string_value().c_str());
82
+
83
+ const JsonLoaderInterface* RingHashConfig::JsonLoader(const JsonArgs&) {
84
+ static const auto* loader =
85
+ JsonObjectLoader<RingHashConfig>()
86
+ .OptionalField("min_ring_size", &RingHashConfig::min_ring_size)
87
+ .OptionalField("max_ring_size", &RingHashConfig::max_ring_size)
88
+ .Finish();
89
+ return loader;
90
+ }
91
+
92
+ void RingHashConfig::JsonPostLoad(const Json&, const JsonArgs&,
93
+ ValidationErrors* errors) {
94
+ {
95
+ ValidationErrors::ScopedField field(errors, ".min_ring_size");
96
+ if (!errors->FieldHasErrors() &&
97
+ (min_ring_size == 0 || min_ring_size > 8388608)) {
98
+ errors->AddError("must be in the range [1, 8388608]");
101
99
  }
102
100
  }
103
- ring_hash_it = ring_hash.find("max_ring_size");
104
- if (ring_hash_it != ring_hash.end()) {
105
- if (ring_hash_it->second.type() != Json::Type::NUMBER) {
106
- errors.emplace_back(
107
- "field:max_ring_size error: should be of type number");
108
- } else {
109
- config.max_ring_size = gpr_parse_nonnegative_int(
110
- ring_hash_it->second.string_value().c_str());
101
+ {
102
+ ValidationErrors::ScopedField field(errors, ".max_ring_size");
103
+ if (!errors->FieldHasErrors() &&
104
+ (max_ring_size == 0 || max_ring_size > 8388608)) {
105
+ errors->AddError("must be in the range [1, 8388608]");
111
106
  }
112
107
  }
113
- if (config.min_ring_size == 0 || config.min_ring_size > 8388608 ||
114
- config.max_ring_size == 0 || config.max_ring_size > 8388608 ||
115
- config.min_ring_size > config.max_ring_size) {
116
- errors.emplace_back(
117
- "field:max_ring_size and or min_ring_size error: "
118
- "values need to be in the range of 1 to 8388608 "
119
- "and max_ring_size cannot be smaller than "
120
- "min_ring_size");
108
+ if (min_ring_size > max_ring_size) {
109
+ errors->AddError("max_ring_size cannot be smaller than min_ring_size");
121
110
  }
122
- if (!errors.empty()) {
123
- return absl::InvalidArgumentError(
124
- absl::StrCat("errors parsing ring hash LB config: [",
125
- absl::StrJoin(errors, "; "), "]"));
126
- }
127
- return config;
128
111
  }
129
112
 
130
113
  namespace {
@@ -154,15 +137,14 @@ class RingHash : public LoadBalancingPolicy {
154
137
 
155
138
  absl::string_view name() const override { return kRingHash; }
156
139
 
157
- void UpdateLocked(UpdateArgs args) override;
140
+ absl::Status UpdateLocked(UpdateArgs args) override;
158
141
  void ResetBackoffLocked() override;
159
142
 
160
143
  private:
161
144
  ~RingHash() override;
162
145
 
163
- // Forward declarations.
146
+ // Forward declaration.
164
147
  class RingHashSubchannelList;
165
- class Ring;
166
148
 
167
149
  // Data for a particular subchannel in a subchannel list.
168
150
  // This subclass adds the following functionality:
@@ -211,32 +193,25 @@ class RingHash : public LoadBalancingPolicy {
211
193
  absl::Status connectivity_status_ ABSL_GUARDED_BY(&mu_);
212
194
  };
213
195
 
214
- // A list of subchannels.
196
+ // A list of subchannels and the ring containing those subchannels.
215
197
  class RingHashSubchannelList
216
198
  : public SubchannelList<RingHashSubchannelList, RingHashSubchannelData> {
217
199
  public:
200
+ struct RingEntry {
201
+ uint64_t hash;
202
+ RingHashSubchannelData* subchannel;
203
+ };
204
+
218
205
  RingHashSubchannelList(RingHash* policy, ServerAddressList addresses,
219
- const ChannelArgs& args)
220
- : SubchannelList(policy,
221
- (GRPC_TRACE_FLAG_ENABLED(grpc_lb_ring_hash_trace)
222
- ? "RingHashSubchannelList"
223
- : nullptr),
224
- std::move(addresses), policy->channel_control_helper(),
225
- args),
226
- num_idle_(num_subchannels()),
227
- ring_(MakeRefCounted<Ring>(policy, Ref(DEBUG_LOCATION, "Ring"))) {
228
- // Need to maintain a ref to the LB policy as long as we maintain
229
- // any references to subchannels, since the subchannels'
230
- // pollset_sets will include the LB policy's pollset_set.
231
- policy->Ref(DEBUG_LOCATION, "subchannel_list").release();
232
- }
206
+ const ChannelArgs& args);
233
207
 
234
208
  ~RingHashSubchannelList() override {
235
- ring_.reset(DEBUG_LOCATION, "~RingHashSubchannelList");
236
209
  RingHash* p = static_cast<RingHash*>(policy());
237
210
  p->Unref(DEBUG_LOCATION, "subchannel_list");
238
211
  }
239
212
 
213
+ const std::vector<RingEntry>& ring() const { return ring_; }
214
+
240
215
  // Updates the counters of subchannels in each state when a
241
216
  // subchannel transitions from old_state to new_state.
242
217
  void UpdateStateCountersLocked(grpc_connectivity_state old_state,
@@ -261,17 +236,12 @@ class RingHash : public LoadBalancingPolicy {
261
236
  return true;
262
237
  }
263
238
 
264
- void ShutdownLocked() override {
265
- ring_.reset(DEBUG_LOCATION, "RingHashSubchannelList::ShutdownLocked()");
266
- SubchannelList::ShutdownLocked();
267
- }
268
-
269
239
  size_t num_idle_;
270
240
  size_t num_ready_ = 0;
271
241
  size_t num_connecting_ = 0;
272
242
  size_t num_transient_failure_ = 0;
273
243
 
274
- RefCountedPtr<Ring> ring_;
244
+ std::vector<RingEntry> ring_;
275
245
 
276
246
  // The index of the subchannel currently doing an internally
277
247
  // triggered connection attempt, if any.
@@ -284,73 +254,83 @@ class RingHash : public LoadBalancingPolicy {
284
254
  absl::Status last_failure_;
285
255
  };
286
256
 
287
- class Ring : public RefCounted<Ring> {
288
- public:
289
- struct Entry {
290
- uint64_t hash;
291
- RingHashSubchannelData* subchannel;
292
- };
293
-
294
- Ring(RingHash* parent,
295
- RefCountedPtr<RingHashSubchannelList> subchannel_list);
296
-
297
- const std::vector<Entry>& ring() const { return ring_; }
298
-
299
- private:
300
- RefCountedPtr<RingHashSubchannelList> subchannel_list_;
301
- std::vector<Entry> ring_;
302
- };
303
-
304
257
  class Picker : public SubchannelPicker {
305
258
  public:
306
- Picker(RefCountedPtr<RingHash> parent, RefCountedPtr<Ring> ring)
307
- : parent_(std::move(parent)), ring_(std::move(ring)) {}
259
+ explicit Picker(RefCountedPtr<RingHashSubchannelList> subchannel_list)
260
+ : subchannel_list_(std::move(subchannel_list)) {}
261
+
262
+ ~Picker() override {
263
+ // Hop into WorkSerializer to unref the subchannel list, since that may
264
+ // trigger the unreffing of the underlying subchannels.
265
+ MakeOrphanable<WorkSerializerRunner>(std::move(subchannel_list_));
266
+ }
308
267
 
309
268
  PickResult Pick(PickArgs args) override;
310
269
 
311
270
  private:
312
- // A fire-and-forget class that schedules subchannel connection attempts
313
- // on the control plane WorkSerializer.
314
- class SubchannelConnectionAttempter : public Orphanable {
271
+ // An interface for running a callback in the control plane WorkSerializer.
272
+ class WorkSerializerRunner : public Orphanable {
315
273
  public:
316
- explicit SubchannelConnectionAttempter(
317
- RefCountedPtr<RingHash> ring_hash_lb)
318
- : ring_hash_lb_(std::move(ring_hash_lb)) {
274
+ explicit WorkSerializerRunner(
275
+ RefCountedPtr<RingHashSubchannelList> subchannel_list)
276
+ : subchannel_list_(std::move(subchannel_list)) {
319
277
  GRPC_CLOSURE_INIT(&closure_, RunInExecCtx, this, nullptr);
320
278
  }
321
279
 
322
- void AddSubchannel(RefCountedPtr<SubchannelInterface> subchannel) {
323
- subchannels_.push_back(std::move(subchannel));
324
- }
325
-
326
280
  void Orphan() override {
327
281
  // Hop into ExecCtx, so that we're not holding the data plane mutex
328
282
  // while we run control-plane code.
329
283
  ExecCtx::Run(DEBUG_LOCATION, &closure_, GRPC_ERROR_NONE);
330
284
  }
331
285
 
286
+ // Will be invoked inside of the WorkSerializer.
287
+ virtual void Run() {}
288
+
289
+ protected:
290
+ RingHash* ring_hash_lb() const {
291
+ return static_cast<RingHash*>(subchannel_list_->policy());
292
+ }
293
+
332
294
  private:
333
295
  static void RunInExecCtx(void* arg, grpc_error_handle /*error*/) {
334
296
  auto* self = static_cast<SubchannelConnectionAttempter*>(arg);
335
- self->ring_hash_lb_->work_serializer()->Run(
297
+ self->ring_hash_lb()->work_serializer()->Run(
336
298
  [self]() {
337
- if (!self->ring_hash_lb_->shutdown_) {
338
- for (auto& subchannel : self->subchannels_) {
339
- subchannel->RequestConnection();
340
- }
341
- }
299
+ self->Run();
342
300
  delete self;
343
301
  },
344
302
  DEBUG_LOCATION);
345
303
  }
346
304
 
347
- RefCountedPtr<RingHash> ring_hash_lb_;
305
+ RefCountedPtr<RingHashSubchannelList> subchannel_list_;
348
306
  grpc_closure closure_;
307
+ };
308
+
309
+ // A fire-and-forget class that schedules subchannel connection attempts
310
+ // on the control plane WorkSerializer.
311
+ class SubchannelConnectionAttempter : public WorkSerializerRunner {
312
+ public:
313
+ explicit SubchannelConnectionAttempter(
314
+ RefCountedPtr<RingHashSubchannelList> subchannel_list)
315
+ : WorkSerializerRunner(std::move(subchannel_list)) {}
316
+
317
+ void AddSubchannel(RefCountedPtr<SubchannelInterface> subchannel) {
318
+ subchannels_.push_back(std::move(subchannel));
319
+ }
320
+
321
+ void Run() override {
322
+ if (!ring_hash_lb()->shutdown_) {
323
+ for (auto& subchannel : subchannels_) {
324
+ subchannel->RequestConnection();
325
+ }
326
+ }
327
+ }
328
+
329
+ private:
349
330
  std::vector<RefCountedPtr<SubchannelInterface>> subchannels_;
350
331
  };
351
332
 
352
- RefCountedPtr<RingHash> parent_;
353
- RefCountedPtr<Ring> ring_;
333
+ RefCountedPtr<RingHashSubchannelList> subchannel_list_;
354
334
  };
355
335
 
356
336
  void ShutdownLocked() override;
@@ -359,117 +339,12 @@ class RingHash : public LoadBalancingPolicy {
359
339
  RefCountedPtr<RingHashLbConfig> config_;
360
340
 
361
341
  // list of subchannels.
362
- OrphanablePtr<RingHashSubchannelList> subchannel_list_;
363
- OrphanablePtr<RingHashSubchannelList> latest_pending_subchannel_list_;
342
+ RefCountedPtr<RingHashSubchannelList> subchannel_list_;
343
+ RefCountedPtr<RingHashSubchannelList> latest_pending_subchannel_list_;
364
344
  // indicating if we are shutting down.
365
345
  bool shutdown_ = false;
366
346
  };
367
347
 
368
- //
369
- // RingHash::Ring
370
- //
371
-
372
- RingHash::Ring::Ring(RingHash* parent,
373
- RefCountedPtr<RingHashSubchannelList> subchannel_list)
374
- : subchannel_list_(std::move(subchannel_list)) {
375
- size_t num_subchannels = subchannel_list_->num_subchannels();
376
- // Store the weights while finding the sum.
377
- struct AddressWeight {
378
- std::string address;
379
- // Default weight is 1 for the cases where a weight is not provided,
380
- // each occurrence of the address will be counted a weight value of 1.
381
- uint32_t weight = 1;
382
- double normalized_weight;
383
- };
384
- std::vector<AddressWeight> address_weights;
385
- size_t sum = 0;
386
- address_weights.reserve(num_subchannels);
387
- for (size_t i = 0; i < num_subchannels; ++i) {
388
- RingHashSubchannelData* sd = subchannel_list_->subchannel(i);
389
- const ServerAddressWeightAttribute* weight_attribute = static_cast<
390
- const ServerAddressWeightAttribute*>(sd->address().GetAttribute(
391
- ServerAddressWeightAttribute::kServerAddressWeightAttributeKey));
392
- AddressWeight address_weight;
393
- address_weight.address =
394
- grpc_sockaddr_to_string(&sd->address().address(), false).value();
395
- // Weight should never be zero, but ignore it just in case, since
396
- // that value would screw up the ring-building algorithm.
397
- if (weight_attribute != nullptr && weight_attribute->weight() > 0) {
398
- address_weight.weight = weight_attribute->weight();
399
- }
400
- sum += address_weight.weight;
401
- address_weights.push_back(std::move(address_weight));
402
- }
403
- // Calculating normalized weights and find min and max.
404
- double min_normalized_weight = 1.0;
405
- double max_normalized_weight = 0.0;
406
- for (auto& address : address_weights) {
407
- address.normalized_weight = static_cast<double>(address.weight) / sum;
408
- min_normalized_weight =
409
- std::min(address.normalized_weight, min_normalized_weight);
410
- max_normalized_weight =
411
- std::max(address.normalized_weight, max_normalized_weight);
412
- }
413
- // Scale up the number of hashes per host such that the least-weighted host
414
- // gets a whole number of hashes on the ring. Other hosts might not end up
415
- // with whole numbers, and that's fine (the ring-building algorithm below can
416
- // handle this). This preserves the original implementation's behavior: when
417
- // weights aren't provided, all hosts should get an equal number of hashes. In
418
- // the case where this number exceeds the max_ring_size, it's scaled back down
419
- // to fit.
420
- const size_t min_ring_size = parent->config_->min_ring_size();
421
- const size_t max_ring_size = parent->config_->max_ring_size();
422
- const double scale = std::min(
423
- std::ceil(min_normalized_weight * min_ring_size) / min_normalized_weight,
424
- static_cast<double>(max_ring_size));
425
- // Reserve memory for the entire ring up front.
426
- const size_t ring_size = std::ceil(scale);
427
- ring_.reserve(ring_size);
428
- // Populate the hash ring by walking through the (host, weight) pairs in
429
- // normalized_host_weights, and generating (scale * weight) hashes for each
430
- // host. Since these aren't necessarily whole numbers, we maintain running
431
- // sums -- current_hashes and target_hashes -- which allows us to populate the
432
- // ring in a mostly stable way.
433
- absl::InlinedVector<char, 196> hash_key_buffer;
434
- double current_hashes = 0.0;
435
- double target_hashes = 0.0;
436
- uint64_t min_hashes_per_host = ring_size;
437
- uint64_t max_hashes_per_host = 0;
438
- for (size_t i = 0; i < num_subchannels; ++i) {
439
- const std::string& address_string = address_weights[i].address;
440
- hash_key_buffer.assign(address_string.begin(), address_string.end());
441
- hash_key_buffer.emplace_back('_');
442
- auto offset_start = hash_key_buffer.end();
443
- target_hashes += scale * address_weights[i].normalized_weight;
444
- size_t count = 0;
445
- while (current_hashes < target_hashes) {
446
- const std::string count_str = absl::StrCat(count);
447
- hash_key_buffer.insert(offset_start, count_str.begin(), count_str.end());
448
- absl::string_view hash_key(hash_key_buffer.data(),
449
- hash_key_buffer.size());
450
- const uint64_t hash = XXH64(hash_key.data(), hash_key.size(), 0);
451
- ring_.push_back({hash, subchannel_list_->subchannel(i)});
452
- ++count;
453
- ++current_hashes;
454
- hash_key_buffer.erase(offset_start, hash_key_buffer.end());
455
- }
456
- min_hashes_per_host =
457
- std::min(static_cast<uint64_t>(i), min_hashes_per_host);
458
- max_hashes_per_host =
459
- std::max(static_cast<uint64_t>(i), max_hashes_per_host);
460
- }
461
- std::sort(ring_.begin(), ring_.end(),
462
- [](const Entry& lhs, const Entry& rhs) -> bool {
463
- return lhs.hash < rhs.hash;
464
- });
465
- if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_ring_hash_trace)) {
466
- gpr_log(GPR_INFO,
467
- "[RH %p picker %p] created ring from subchannel_list=%p "
468
- "with %" PRIuPTR " ring entries",
469
- parent, this, subchannel_list_.get(), ring_.size());
470
- }
471
- }
472
-
473
348
  //
474
349
  // RingHash::Picker
475
350
  //
@@ -483,7 +358,7 @@ RingHash::PickResult RingHash::Picker::Pick(PickArgs args) {
483
358
  return PickResult::Fail(
484
359
  absl::InternalError("ring hash value is not a number"));
485
360
  }
486
- const std::vector<Ring::Entry>& ring = ring_->ring();
361
+ const auto& ring = subchannel_list_->ring();
487
362
  // Ported from https://github.com/RJ/ketama/blob/master/libketama/ketama.c
488
363
  // (ketama_get_server) NOTE: The algorithm depends on using signed integers
489
364
  // for lowp, highp, and first_index. Do not change them!
@@ -516,7 +391,9 @@ RingHash::PickResult RingHash::Picker::Pick(PickArgs args) {
516
391
  [&](RefCountedPtr<SubchannelInterface> subchannel) {
517
392
  if (subchannel_connection_attempter == nullptr) {
518
393
  subchannel_connection_attempter =
519
- MakeOrphanable<SubchannelConnectionAttempter>(parent_);
394
+ MakeOrphanable<SubchannelConnectionAttempter>(
395
+ subchannel_list_->Ref(DEBUG_LOCATION,
396
+ "SubchannelConnectionAttempter"));
520
397
  }
521
398
  subchannel_connection_attempter->AddSubchannel(std::move(subchannel));
522
399
  };
@@ -541,7 +418,7 @@ RingHash::PickResult RingHash::Picker::Pick(PickArgs args) {
541
418
  bool found_second_subchannel = false;
542
419
  bool found_first_non_failed = false;
543
420
  for (size_t i = 1; i < ring.size(); ++i) {
544
- const Ring::Entry& entry = ring[(first_index + i) % ring.size()];
421
+ const auto& entry = ring[(first_index + i) % ring.size()];
545
422
  if (entry.subchannel == ring[first_index].subchannel) {
546
423
  continue;
547
424
  }
@@ -585,6 +462,117 @@ RingHash::PickResult RingHash::Picker::Pick(PickArgs args) {
585
462
  // RingHash::RingHashSubchannelList
586
463
  //
587
464
 
465
+ RingHash::RingHashSubchannelList::RingHashSubchannelList(
466
+ RingHash* policy, ServerAddressList addresses, const ChannelArgs& args)
467
+ : SubchannelList(policy,
468
+ (GRPC_TRACE_FLAG_ENABLED(grpc_lb_ring_hash_trace)
469
+ ? "RingHashSubchannelList"
470
+ : nullptr),
471
+ std::move(addresses), policy->channel_control_helper(),
472
+ args),
473
+ num_idle_(num_subchannels()) {
474
+ // Need to maintain a ref to the LB policy as long as we maintain
475
+ // any references to subchannels, since the subchannels'
476
+ // pollset_sets will include the LB policy's pollset_set.
477
+ policy->Ref(DEBUG_LOCATION, "subchannel_list").release();
478
+ // Construct the ring.
479
+ // Store the weights while finding the sum.
480
+ struct AddressWeight {
481
+ std::string address;
482
+ // Default weight is 1 for the cases where a weight is not provided,
483
+ // each occurrence of the address will be counted a weight value of 1.
484
+ uint32_t weight = 1;
485
+ double normalized_weight;
486
+ };
487
+ std::vector<AddressWeight> address_weights;
488
+ size_t sum = 0;
489
+ address_weights.reserve(num_subchannels());
490
+ for (size_t i = 0; i < num_subchannels(); ++i) {
491
+ RingHashSubchannelData* sd = subchannel(i);
492
+ const ServerAddressWeightAttribute* weight_attribute = static_cast<
493
+ const ServerAddressWeightAttribute*>(sd->address().GetAttribute(
494
+ ServerAddressWeightAttribute::kServerAddressWeightAttributeKey));
495
+ AddressWeight address_weight;
496
+ address_weight.address =
497
+ grpc_sockaddr_to_string(&sd->address().address(), false).value();
498
+ // Weight should never be zero, but ignore it just in case, since
499
+ // that value would screw up the ring-building algorithm.
500
+ if (weight_attribute != nullptr && weight_attribute->weight() > 0) {
501
+ address_weight.weight = weight_attribute->weight();
502
+ }
503
+ sum += address_weight.weight;
504
+ address_weights.push_back(std::move(address_weight));
505
+ }
506
+ // Calculating normalized weights and find min and max.
507
+ double min_normalized_weight = 1.0;
508
+ double max_normalized_weight = 0.0;
509
+ for (auto& address : address_weights) {
510
+ address.normalized_weight = static_cast<double>(address.weight) / sum;
511
+ min_normalized_weight =
512
+ std::min(address.normalized_weight, min_normalized_weight);
513
+ max_normalized_weight =
514
+ std::max(address.normalized_weight, max_normalized_weight);
515
+ }
516
+ // Scale up the number of hashes per host such that the least-weighted host
517
+ // gets a whole number of hashes on the ring. Other hosts might not end up
518
+ // with whole numbers, and that's fine (the ring-building algorithm below can
519
+ // handle this). This preserves the original implementation's behavior: when
520
+ // weights aren't provided, all hosts should get an equal number of hashes. In
521
+ // the case where this number exceeds the max_ring_size, it's scaled back down
522
+ // to fit.
523
+ const size_t min_ring_size = policy->config_->min_ring_size();
524
+ const size_t max_ring_size = policy->config_->max_ring_size();
525
+ const double scale = std::min(
526
+ std::ceil(min_normalized_weight * min_ring_size) / min_normalized_weight,
527
+ static_cast<double>(max_ring_size));
528
+ // Reserve memory for the entire ring up front.
529
+ const size_t ring_size = std::ceil(scale);
530
+ ring_.reserve(ring_size);
531
+ // Populate the hash ring by walking through the (host, weight) pairs in
532
+ // normalized_host_weights, and generating (scale * weight) hashes for each
533
+ // host. Since these aren't necessarily whole numbers, we maintain running
534
+ // sums -- current_hashes and target_hashes -- which allows us to populate the
535
+ // ring in a mostly stable way.
536
+ absl::InlinedVector<char, 196> hash_key_buffer;
537
+ double current_hashes = 0.0;
538
+ double target_hashes = 0.0;
539
+ uint64_t min_hashes_per_host = ring_size;
540
+ uint64_t max_hashes_per_host = 0;
541
+ for (size_t i = 0; i < num_subchannels(); ++i) {
542
+ const std::string& address_string = address_weights[i].address;
543
+ hash_key_buffer.assign(address_string.begin(), address_string.end());
544
+ hash_key_buffer.emplace_back('_');
545
+ auto offset_start = hash_key_buffer.end();
546
+ target_hashes += scale * address_weights[i].normalized_weight;
547
+ size_t count = 0;
548
+ while (current_hashes < target_hashes) {
549
+ const std::string count_str = absl::StrCat(count);
550
+ hash_key_buffer.insert(offset_start, count_str.begin(), count_str.end());
551
+ absl::string_view hash_key(hash_key_buffer.data(),
552
+ hash_key_buffer.size());
553
+ const uint64_t hash = XXH64(hash_key.data(), hash_key.size(), 0);
554
+ ring_.push_back({hash, subchannel(i)});
555
+ ++count;
556
+ ++current_hashes;
557
+ hash_key_buffer.erase(offset_start, hash_key_buffer.end());
558
+ }
559
+ min_hashes_per_host =
560
+ std::min(static_cast<uint64_t>(i), min_hashes_per_host);
561
+ max_hashes_per_host =
562
+ std::max(static_cast<uint64_t>(i), max_hashes_per_host);
563
+ }
564
+ std::sort(ring_.begin(), ring_.end(),
565
+ [](const RingHashSubchannelList::RingEntry& lhs,
566
+ const RingHashSubchannelList::RingEntry& rhs) -> bool {
567
+ return lhs.hash < rhs.hash;
568
+ });
569
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_ring_hash_trace)) {
570
+ gpr_log(GPR_INFO,
571
+ "[RH %p] created subchannel list %p with %" PRIuPTR " ring entries",
572
+ policy, this, ring_.size());
573
+ }
574
+ }
575
+
588
576
  void RingHash::RingHashSubchannelList::UpdateStateCountersLocked(
589
577
  grpc_connectivity_state old_state, grpc_connectivity_state new_state) {
590
578
  if (old_state == GRPC_CHANNEL_IDLE) {
@@ -673,8 +661,7 @@ void RingHash::RingHashSubchannelList::UpdateRingHashConnectivityStateLocked(
673
661
  // Note that we use our own picker regardless of connectivity state.
674
662
  p->channel_control_helper()->UpdateState(
675
663
  state, status,
676
- absl::make_unique<Picker>(p->Ref(DEBUG_LOCATION, "RingHashPicker"),
677
- ring_));
664
+ absl::make_unique<Picker>(Ref(DEBUG_LOCATION, "RingHashPicker")));
678
665
  // While the ring_hash policy is reporting TRANSIENT_FAILURE, it will
679
666
  // not be getting any pick requests from the priority policy.
680
667
  // However, because the ring_hash policy does not attempt to
@@ -813,7 +800,7 @@ void RingHash::ResetBackoffLocked() {
813
800
  }
814
801
  }
815
802
 
816
- void RingHash::UpdateLocked(UpdateArgs args) {
803
+ absl::Status RingHash::UpdateLocked(UpdateArgs args) {
817
804
  config_ = std::move(args.config);
818
805
  ServerAddressList addresses;
819
806
  if (args.addresses.ok()) {
@@ -827,16 +814,16 @@ void RingHash::UpdateLocked(UpdateArgs args) {
827
814
  gpr_log(GPR_INFO, "[RH %p] received update with addresses error: %s",
828
815
  this, args.addresses.status().ToString().c_str());
829
816
  }
830
- // If we already have a subchannel list, then ignore the resolver
831
- // failure and keep using the existing list.
832
- if (subchannel_list_ != nullptr) return;
817
+ // If we already have a subchannel list, then keep using the existing
818
+ // list, but still report back that the update was not accepted.
819
+ if (subchannel_list_ != nullptr) return args.addresses.status();
833
820
  }
834
821
  if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_ring_hash_trace) &&
835
822
  latest_pending_subchannel_list_ != nullptr) {
836
823
  gpr_log(GPR_INFO, "[RH %p] replacing latest pending subchannel list %p",
837
824
  this, latest_pending_subchannel_list_.get());
838
825
  }
839
- latest_pending_subchannel_list_ = MakeOrphanable<RingHashSubchannelList>(
826
+ latest_pending_subchannel_list_ = MakeRefCounted<RingHashSubchannelList>(
840
827
  this, std::move(addresses), args.args);
841
828
  latest_pending_subchannel_list_->StartWatchingLocked();
842
829
  // If we have no existing list or the new list is empty, immediately
@@ -862,12 +849,13 @@ void RingHash::UpdateLocked(UpdateArgs args) {
862
849
  channel_control_helper()->UpdateState(
863
850
  GRPC_CHANNEL_TRANSIENT_FAILURE, status,
864
851
  absl::make_unique<TransientFailurePicker>(status));
865
- } else {
866
- // Otherwise, report IDLE.
867
- subchannel_list_->UpdateRingHashConnectivityStateLocked(
868
- /*index=*/0, /*connection_attempt_complete=*/false, absl::OkStatus());
852
+ return status;
869
853
  }
854
+ // Otherwise, report IDLE.
855
+ subchannel_list_->UpdateRingHashConnectivityStateLocked(
856
+ /*index=*/0, /*connection_attempt_complete=*/false, absl::OkStatus());
870
857
  }
858
+ return absl::OkStatus();
871
859
  }
872
860
 
873
861
  //
@@ -885,7 +873,8 @@ class RingHashFactory : public LoadBalancingPolicyFactory {
885
873
 
886
874
  absl::StatusOr<RefCountedPtr<LoadBalancingPolicy::Config>>
887
875
  ParseLoadBalancingConfig(const Json& json) const override {
888
- auto config = ParseRingHashLbConfig(json);
876
+ auto config = LoadFromJson<RingHashConfig>(
877
+ json, JsonArgs(), "errors validating ring_hash LB policy config");
889
878
  if (!config.ok()) return config.status();
890
879
  return MakeRefCounted<RingHashLbConfig>(config->min_ring_size,
891
880
  config->max_ring_size);
@@ -894,11 +883,9 @@ class RingHashFactory : public LoadBalancingPolicyFactory {
894
883
 
895
884
  } // namespace
896
885
 
897
- void GrpcLbPolicyRingHashInit() {
898
- LoadBalancingPolicyRegistry::Builder::RegisterLoadBalancingPolicyFactory(
886
+ void RegisterRingHashLbPolicy(CoreConfiguration::Builder* builder) {
887
+ builder->lb_policy_registry()->RegisterLoadBalancingPolicyFactory(
899
888
  absl::make_unique<RingHashFactory>());
900
889
  }
901
890
 
902
- void GrpcLbPolicyRingHashShutdown() {}
903
-
904
891
  } // namespace grpc_core
@@ -19,12 +19,13 @@
19
19
 
20
20
  #include <grpc/support/port_platform.h>
21
21
 
22
- #include <stdlib.h>
23
-
24
- #include "absl/status/statusor.h"
22
+ #include <stdint.h>
25
23
 
26
24
  #include "src/core/lib/gprpp/unique_type_name.h"
25
+ #include "src/core/lib/gprpp/validation_errors.h"
27
26
  #include "src/core/lib/json/json.h"
27
+ #include "src/core/lib/json/json_args.h"
28
+ #include "src/core/lib/json/json_object_loader.h"
28
29
 
29
30
  namespace grpc_core {
30
31
 
@@ -33,10 +34,13 @@ UniqueTypeName RequestHashAttributeName();
33
34
  // Helper Parsing method to parse ring hash policy configs; for example, ring
34
35
  // hash size validity.
35
36
  struct RingHashConfig {
36
- size_t min_ring_size = 1024;
37
- size_t max_ring_size = 8388608;
37
+ uint64_t min_ring_size = 1024;
38
+ uint64_t max_ring_size = 8388608;
39
+
40
+ static const JsonLoaderInterface* JsonLoader(const JsonArgs&);
41
+ void JsonPostLoad(const Json& json, const JsonArgs&,
42
+ ValidationErrors* errors);
38
43
  };
39
- absl::StatusOr<RingHashConfig> ParseRingHashLbConfig(const Json& json);
40
44
 
41
45
  } // namespace grpc_core
42
46