grpc-flamingo 1.11.0 → 1.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (452) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +1150 -176
  3. data/etc/roots.pem +40 -196
  4. data/include/grpc/grpc.h +49 -8
  5. data/include/grpc/grpc_security.h +123 -2
  6. data/include/grpc/grpc_security_constants.h +6 -0
  7. data/include/grpc/impl/codegen/fork.h +4 -4
  8. data/include/grpc/impl/codegen/grpc_types.h +26 -5
  9. data/include/grpc/impl/codegen/log.h +112 -0
  10. data/include/grpc/impl/codegen/port_platform.h +55 -4
  11. data/include/grpc/module.modulemap +2 -0
  12. data/include/grpc/support/log.h +2 -80
  13. data/include/grpc/support/string_util.h +2 -0
  14. data/include/grpc/support/sync.h +0 -16
  15. data/src/boringssl/err_data.c +602 -588
  16. data/src/core/ext/{census → filters/census}/grpc_context.cc +0 -0
  17. data/src/core/ext/filters/client_channel/channel_connectivity.cc +1 -1
  18. data/src/core/ext/filters/client_channel/client_channel.cc +1234 -1070
  19. data/src/core/ext/filters/client_channel/client_channel.h +5 -0
  20. data/src/core/ext/filters/client_channel/client_channel_channelz.cc +113 -0
  21. data/src/core/ext/filters/client_channel/client_channel_channelz.h +71 -0
  22. data/src/core/ext/filters/client_channel/client_channel_plugin.cc +9 -0
  23. data/src/core/ext/filters/client_channel/http_connect_handshaker.cc +1 -1
  24. data/src/core/ext/filters/client_channel/http_proxy.cc +22 -5
  25. data/src/core/ext/filters/client_channel/lb_policy.cc +2 -2
  26. data/src/core/ext/filters/client_channel/lb_policy.h +30 -10
  27. data/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc +11 -9
  28. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +120 -127
  29. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h +36 -0
  30. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc +36 -102
  31. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h +37 -32
  32. data/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc +25 -22
  33. data/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h +4 -2
  34. data/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c +19 -0
  35. data/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h +54 -0
  36. data/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c +19 -0
  37. data/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h +54 -0
  38. data/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c +4 -17
  39. data/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h +37 -63
  40. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +306 -239
  41. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +444 -392
  42. data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +538 -98
  43. data/src/core/ext/filters/client_channel/lb_policy_factory.cc +8 -0
  44. data/src/core/ext/filters/client_channel/lb_policy_factory.h +4 -0
  45. data/src/core/ext/filters/client_channel/method_params.h +4 -0
  46. data/src/core/ext/filters/client_channel/resolver.h +10 -0
  47. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +36 -19
  48. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc +320 -0
  49. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h +62 -9
  50. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc +49 -294
  51. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +537 -0
  52. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +112 -87
  53. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h +17 -2
  54. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc +6 -5
  55. data/src/core/ext/filters/{load_reporting/server_load_reporting_filter.h → client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc} +7 -8
  56. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc +29 -0
  57. data/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +32 -15
  58. data/src/core/ext/filters/client_channel/retry_throttle.h +4 -0
  59. data/src/core/ext/filters/client_channel/subchannel.cc +58 -15
  60. data/src/core/ext/filters/client_channel/subchannel.h +11 -0
  61. data/src/core/ext/filters/deadline/deadline_filter.cc +18 -15
  62. data/src/core/ext/filters/deadline/deadline_filter.h +5 -5
  63. data/src/core/ext/filters/http/client/http_client_filter.cc +10 -9
  64. data/src/core/ext/filters/http/client_authority_filter.cc +6 -5
  65. data/src/core/ext/filters/http/message_compress/message_compress_filter.cc +6 -6
  66. data/src/core/ext/filters/http/server/http_server_filter.cc +123 -131
  67. data/src/core/ext/filters/http/server/http_server_filter.h +1 -1
  68. data/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc +1 -1
  69. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +1 -1
  70. data/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc +3 -2
  71. data/src/core/ext/transport/chttp2/transport/bin_decoder.cc +9 -8
  72. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +97 -48
  73. data/src/core/ext/transport/chttp2/transport/flow_control.cc +10 -7
  74. data/src/core/ext/transport/chttp2/transport/frame_settings.cc +3 -3
  75. data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +12 -8
  76. data/src/core/ext/transport/chttp2/transport/hpack_encoder.h +4 -3
  77. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +2 -2
  78. data/src/core/ext/transport/chttp2/transport/hpack_table.cc +2 -2
  79. data/src/core/ext/transport/chttp2/transport/parsing.cc +14 -12
  80. data/src/core/ext/transport/chttp2/transport/stream_lists.cc +3 -3
  81. data/src/core/ext/transport/chttp2/transport/writing.cc +32 -27
  82. data/src/core/ext/transport/inproc/inproc_transport.cc +87 -49
  83. data/src/core/lib/channel/channel_args.cc +28 -0
  84. data/src/core/lib/channel/channel_args.h +4 -0
  85. data/src/core/lib/channel/channel_stack.cc +22 -29
  86. data/src/core/lib/channel/channel_stack.h +2 -2
  87. data/src/core/lib/channel/channel_stack_builder.cc +0 -3
  88. data/src/core/lib/channel/channel_stack_builder.h +0 -2
  89. data/src/core/lib/channel/channel_trace.cc +28 -63
  90. data/src/core/lib/channel/channel_trace.h +13 -17
  91. data/src/core/lib/channel/channelz.cc +153 -0
  92. data/src/core/lib/channel/channelz.h +133 -0
  93. data/src/core/lib/channel/channelz_registry.cc +145 -0
  94. data/src/core/lib/channel/channelz_registry.h +120 -0
  95. data/src/core/lib/channel/connected_channel.cc +8 -1
  96. data/src/core/lib/channel/handshaker.cc +71 -0
  97. data/src/core/lib/channel/handshaker.h +4 -0
  98. data/src/core/lib/debug/stats.h +7 -0
  99. data/src/core/lib/debug/stats_data.cc +5 -0
  100. data/src/core/lib/debug/stats_data.h +120 -0
  101. data/src/core/lib/debug/trace.cc +2 -1
  102. data/src/core/lib/debug/trace.h +12 -1
  103. data/src/core/lib/gpr/alloc.h +28 -0
  104. data/src/core/lib/gpr/arena.cc +38 -45
  105. data/src/core/lib/gpr/log.cc +8 -2
  106. data/src/core/lib/gpr/log_android.cc +4 -0
  107. data/src/core/lib/gpr/log_linux.cc +4 -0
  108. data/src/core/lib/gpr/log_posix.cc +4 -0
  109. data/src/core/lib/gpr/log_windows.cc +5 -0
  110. data/src/core/lib/gpr/string.cc +28 -0
  111. data/src/core/lib/gpr/string.h +10 -0
  112. data/src/core/lib/gprpp/abstract.h +5 -2
  113. data/src/core/lib/gprpp/fork.cc +268 -0
  114. data/src/core/lib/gprpp/fork.h +88 -0
  115. data/src/core/lib/gprpp/inlined_vector.h +87 -37
  116. data/src/core/lib/gprpp/memory.h +12 -0
  117. data/src/core/lib/gprpp/mutex_lock.h +42 -0
  118. data/src/core/lib/gprpp/orphanable.h +10 -12
  119. data/src/core/lib/gprpp/ref_counted.h +10 -12
  120. data/src/core/lib/gprpp/ref_counted_ptr.h +65 -8
  121. data/src/core/lib/gprpp/thd.h +0 -3
  122. data/src/core/lib/gprpp/thd_posix.cc +5 -54
  123. data/src/core/lib/gprpp/thd_windows.cc +0 -7
  124. data/src/core/lib/http/httpcli_security_connector.cc +1 -3
  125. data/src/core/lib/iomgr/call_combiner.cc +13 -13
  126. data/src/core/lib/iomgr/call_combiner.h +84 -1
  127. data/src/core/lib/iomgr/closure.h +6 -5
  128. data/src/core/lib/iomgr/combiner.cc +30 -13
  129. data/src/core/lib/iomgr/combiner.h +1 -1
  130. data/src/core/lib/iomgr/endpoint_pair_posix.cc +2 -2
  131. data/src/core/lib/iomgr/error.cc +12 -0
  132. data/src/core/lib/iomgr/error.h +5 -0
  133. data/src/core/lib/iomgr/ev_epoll1_linux.cc +138 -51
  134. data/src/core/lib/iomgr/ev_epollex_linux.cc +276 -93
  135. data/src/core/lib/iomgr/ev_epollsig_linux.cc +58 -50
  136. data/src/core/lib/iomgr/ev_poll_posix.cc +163 -42
  137. data/src/core/lib/iomgr/ev_posix.cc +88 -24
  138. data/src/core/lib/iomgr/ev_posix.h +48 -12
  139. data/src/core/lib/iomgr/exec_ctx.cc +15 -9
  140. data/src/core/lib/iomgr/exec_ctx.h +48 -20
  141. data/src/core/lib/iomgr/executor.cc +274 -142
  142. data/src/core/lib/iomgr/executor.h +82 -16
  143. data/src/core/lib/iomgr/fork_posix.cc +42 -19
  144. data/src/core/lib/iomgr/iocp_windows.cc +9 -4
  145. data/src/core/lib/iomgr/iomgr.cc +2 -0
  146. data/src/core/lib/iomgr/iomgr.h +5 -0
  147. data/src/core/lib/iomgr/iomgr_posix.cc +2 -2
  148. data/src/core/lib/iomgr/is_epollexclusive_available.cc +1 -0
  149. data/src/core/lib/iomgr/lockfree_event.cc +5 -1
  150. data/src/core/lib/iomgr/polling_entity.cc +11 -2
  151. data/src/core/lib/iomgr/pollset_custom.cc +2 -2
  152. data/src/core/lib/iomgr/port.h +51 -1
  153. data/src/core/lib/iomgr/resolve_address.h +1 -1
  154. data/src/core/lib/iomgr/resolve_address_posix.cc +4 -3
  155. data/src/core/lib/iomgr/resolve_address_windows.cc +3 -2
  156. data/src/core/lib/iomgr/resource_quota.cc +89 -12
  157. data/src/core/lib/iomgr/resource_quota.h +16 -0
  158. data/src/core/lib/iomgr/sockaddr_posix.h +1 -1
  159. data/src/core/lib/iomgr/socket_factory_posix.cc +1 -1
  160. data/src/core/lib/iomgr/socket_mutator.cc +1 -1
  161. data/src/core/lib/iomgr/socket_mutator.h +1 -1
  162. data/src/core/lib/iomgr/socket_utils.h +9 -0
  163. data/src/core/lib/iomgr/socket_utils_common_posix.cc +29 -1
  164. data/src/core/lib/iomgr/socket_utils_linux.cc +0 -1
  165. data/src/core/lib/iomgr/socket_utils_posix.cc +2 -3
  166. data/src/core/lib/iomgr/socket_utils_posix.h +3 -0
  167. data/src/core/lib/iomgr/socket_utils_uv.cc +4 -0
  168. data/src/core/lib/iomgr/socket_utils_windows.cc +4 -0
  169. data/src/core/lib/iomgr/socket_windows.cc +33 -0
  170. data/src/core/lib/iomgr/socket_windows.h +6 -0
  171. data/src/core/lib/iomgr/tcp_client_custom.cc +5 -5
  172. data/src/core/lib/iomgr/tcp_client_posix.cc +10 -11
  173. data/src/core/lib/iomgr/tcp_custom.cc +11 -11
  174. data/src/core/lib/iomgr/tcp_posix.cc +49 -36
  175. data/src/core/lib/iomgr/tcp_server_custom.cc +5 -5
  176. data/src/core/lib/iomgr/tcp_server_posix.cc +16 -36
  177. data/src/core/lib/iomgr/tcp_server_utils_posix.h +1 -1
  178. data/src/core/lib/iomgr/tcp_server_utils_posix_common.cc +17 -5
  179. data/src/core/lib/iomgr/tcp_server_windows.cc +1 -0
  180. data/src/core/lib/iomgr/tcp_uv.cc +3 -0
  181. data/src/core/lib/iomgr/tcp_windows.cc +18 -2
  182. data/src/core/lib/iomgr/tcp_windows.h +2 -0
  183. data/src/core/lib/iomgr/timer.h +4 -3
  184. data/src/core/lib/iomgr/timer_generic.cc +133 -51
  185. data/src/core/lib/iomgr/timer_manager.cc +12 -14
  186. data/src/core/lib/iomgr/timer_uv.cc +3 -0
  187. data/src/core/lib/iomgr/udp_server.cc +106 -52
  188. data/src/core/lib/iomgr/udp_server.h +8 -4
  189. data/src/core/lib/json/json.cc +12 -1
  190. data/src/core/lib/json/json.h +5 -0
  191. data/src/core/lib/profiling/basic_timers.cc +1 -0
  192. data/src/core/lib/security/context/security_context.cc +8 -8
  193. data/src/core/lib/security/context/security_context.h +6 -2
  194. data/src/core/lib/security/credentials/alts/alts_credentials.h +0 -20
  195. data/src/core/lib/security/credentials/alts/check_gcp_environment_linux.cc +3 -2
  196. data/src/core/lib/security/credentials/alts/grpc_alts_credentials_client_options.cc +7 -7
  197. data/src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h +1 -38
  198. data/src/core/lib/security/credentials/credentials.h +1 -0
  199. data/src/core/lib/security/credentials/google_default/google_default_credentials.cc +89 -115
  200. data/src/core/lib/security/credentials/google_default/google_default_credentials.h +16 -0
  201. data/src/core/lib/security/credentials/jwt/json_token.h +2 -0
  202. data/src/core/lib/security/credentials/jwt/jwt_verifier.cc +2 -0
  203. data/src/core/lib/security/credentials/local/local_credentials.cc +77 -0
  204. data/src/core/lib/security/credentials/local/local_credentials.h +40 -0
  205. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +11 -7
  206. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.h +1 -1
  207. data/src/core/lib/security/credentials/ssl/ssl_credentials.cc +17 -3
  208. data/src/core/lib/security/security_connector/alts_security_connector.cc +2 -1
  209. data/src/core/lib/security/security_connector/load_system_roots.h +29 -0
  210. data/src/core/lib/{gpr/fork.h → security/security_connector/load_system_roots_fallback.cc} +10 -13
  211. data/src/core/lib/security/security_connector/load_system_roots_linux.cc +165 -0
  212. data/src/core/lib/security/security_connector/load_system_roots_linux.h +44 -0
  213. data/src/core/lib/security/security_connector/local_security_connector.cc +245 -0
  214. data/src/core/lib/security/security_connector/local_security_connector.h +58 -0
  215. data/src/core/lib/security/security_connector/security_connector.cc +79 -32
  216. data/src/core/lib/security/security_connector/security_connector.h +5 -3
  217. data/src/core/lib/security/transport/client_auth_filter.cc +5 -5
  218. data/src/core/lib/security/transport/secure_endpoint.cc +2 -2
  219. data/src/core/lib/security/transport/security_handshaker.cc +7 -2
  220. data/src/core/lib/security/transport/server_auth_filter.cc +4 -7
  221. data/src/core/lib/security/util/json_util.cc +4 -0
  222. data/src/core/lib/slice/slice.cc +6 -2
  223. data/src/core/lib/slice/slice_buffer.cc +27 -7
  224. data/src/core/lib/slice/slice_hash_table.h +4 -0
  225. data/src/core/lib/slice/slice_weak_hash_table.h +4 -0
  226. data/src/core/lib/surface/call.cc +119 -58
  227. data/src/core/lib/surface/call.h +7 -0
  228. data/src/core/lib/surface/channel.cc +50 -18
  229. data/src/core/lib/surface/channel.h +4 -0
  230. data/src/core/lib/surface/completion_queue.cc +153 -18
  231. data/src/core/lib/surface/completion_queue.h +20 -2
  232. data/src/core/lib/surface/completion_queue_factory.cc +13 -4
  233. data/src/core/lib/surface/init.cc +7 -8
  234. data/src/core/lib/surface/init.h +0 -1
  235. data/src/core/lib/surface/server.cc +16 -0
  236. data/src/core/lib/surface/version.cc +1 -1
  237. data/src/core/lib/transport/bdp_estimator.cc +3 -3
  238. data/src/core/lib/transport/bdp_estimator.h +2 -2
  239. data/src/core/lib/transport/byte_stream.cc +1 -1
  240. data/src/core/lib/transport/connectivity_state.cc +6 -7
  241. data/src/core/lib/transport/service_config.cc +2 -2
  242. data/src/core/lib/transport/service_config.h +3 -3
  243. data/src/core/lib/transport/transport.cc +22 -10
  244. data/src/core/lib/transport/transport.h +18 -18
  245. data/src/core/lib/transport/transport_op_string.cc +1 -8
  246. data/src/core/plugin_registry/grpc_plugin_registry.cc +0 -4
  247. data/src/core/tsi/alts/crypt/aes_gcm.cc +2 -0
  248. data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +19 -7
  249. data/src/core/tsi/alts/handshaker/alts_handshaker_client.h +10 -0
  250. data/src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.h +2 -2
  251. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +38 -3
  252. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker_private.h +3 -0
  253. data/src/core/tsi/alts/handshaker/altscontext.pb.c +0 -1
  254. data/src/core/tsi/alts/handshaker/altscontext.pb.h +1 -2
  255. data/src/core/tsi/alts/handshaker/handshaker.pb.c +0 -1
  256. data/src/core/tsi/alts/handshaker/handshaker.pb.h +1 -2
  257. data/src/core/tsi/alts/handshaker/transport_security_common.pb.c +0 -1
  258. data/src/core/tsi/alts/handshaker/transport_security_common.pb.h +1 -1
  259. data/src/core/tsi/alts/handshaker/transport_security_common_api.h +2 -2
  260. data/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.cc +47 -1
  261. data/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.h +3 -1
  262. data/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc +12 -11
  263. data/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.h +7 -2
  264. data/src/core/tsi/fake_transport_security.cc +1 -0
  265. data/src/core/tsi/grpc_shadow_boringssl.h +3006 -0
  266. data/src/core/tsi/local_transport_security.cc +209 -0
  267. data/src/core/tsi/local_transport_security.h +51 -0
  268. data/src/core/tsi/ssl/session_cache/ssl_session.h +2 -0
  269. data/src/core/tsi/ssl/session_cache/ssl_session_cache.cc +5 -5
  270. data/src/core/tsi/ssl/session_cache/ssl_session_cache.h +6 -0
  271. data/src/core/tsi/ssl_transport_security.cc +245 -116
  272. data/src/core/tsi/ssl_types.h +2 -0
  273. data/src/core/tsi/transport_security.cc +14 -0
  274. data/src/core/tsi/transport_security.h +2 -0
  275. data/src/core/tsi/transport_security_interface.h +11 -1
  276. data/src/ruby/bin/math_client.rb +17 -9
  277. data/src/ruby/ext/grpc/extconf.rb +1 -26
  278. data/src/ruby/ext/grpc/rb_channel_credentials.c +3 -3
  279. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +42 -16
  280. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +65 -26
  281. data/src/ruby/lib/grpc/generic/active_call.rb +19 -23
  282. data/src/ruby/lib/grpc/generic/rpc_server.rb +2 -1
  283. data/src/ruby/lib/grpc/version.rb +1 -1
  284. data/src/ruby/pb/generate_proto_ruby.sh +7 -1
  285. data/src/ruby/pb/grpc/health/v1/health_services_pb.rb +4 -1
  286. data/src/ruby/spec/call_credentials_spec.rb +1 -1
  287. data/src/ruby/spec/call_spec.rb +1 -1
  288. data/src/ruby/spec/channel_credentials_spec.rb +1 -1
  289. data/src/ruby/spec/channel_spec.rb +1 -1
  290. data/src/ruby/spec/client_auth_spec.rb +1 -12
  291. data/src/ruby/spec/client_server_spec.rb +1 -1
  292. data/src/ruby/spec/compression_options_spec.rb +1 -1
  293. data/src/ruby/spec/error_sanity_spec.rb +1 -1
  294. data/src/ruby/spec/generic/client_stub_spec.rb +16 -4
  295. data/src/ruby/spec/generic/rpc_desc_spec.rb +1 -1
  296. data/src/ruby/spec/generic/rpc_server_pool_spec.rb +1 -1
  297. data/src/ruby/spec/generic/service_spec.rb +1 -1
  298. data/src/ruby/spec/google_rpc_status_utils_spec.rb +1 -12
  299. data/src/ruby/spec/pb/duplicate/codegen_spec.rb +1 -0
  300. data/src/ruby/spec/pb/health/checker_spec.rb +1 -1
  301. data/src/ruby/spec/server_credentials_spec.rb +1 -1
  302. data/src/ruby/spec/server_spec.rb +1 -1
  303. data/src/ruby/spec/spec_helper.rb +1 -0
  304. data/src/ruby/spec/support/services.rb +1 -1
  305. data/src/ruby/spec/time_consts_spec.rb +1 -1
  306. data/third_party/address_sorting/address_sorting.c +17 -11
  307. data/third_party/address_sorting/address_sorting_windows.c +43 -3
  308. data/third_party/address_sorting/include/address_sorting/address_sorting.h +3 -0
  309. data/third_party/boringssl/crypto/asn1/a_int.c +33 -28
  310. data/third_party/boringssl/crypto/asn1/a_mbstr.c +24 -22
  311. data/third_party/boringssl/crypto/asn1/a_utf8.c +13 -11
  312. data/third_party/boringssl/crypto/asn1/asn1_locl.h +3 -0
  313. data/third_party/boringssl/crypto/asn1/tasn_dec.c +40 -19
  314. data/third_party/boringssl/crypto/bio/fd.c +1 -0
  315. data/third_party/boringssl/crypto/bio/file.c +2 -0
  316. data/third_party/boringssl/crypto/bn_extra/convert.c +6 -5
  317. data/third_party/boringssl/crypto/bytestring/ber.c +1 -4
  318. data/third_party/boringssl/crypto/bytestring/cbb.c +116 -16
  319. data/third_party/boringssl/crypto/bytestring/cbs.c +151 -20
  320. data/third_party/boringssl/crypto/cipher_extra/e_aesccm.c +203 -0
  321. data/third_party/boringssl/crypto/cipher_extra/e_rc2.c +2 -0
  322. data/third_party/boringssl/crypto/cipher_extra/e_tls.c +1 -2
  323. data/third_party/boringssl/crypto/cpu-aarch64-fuchsia.c +55 -0
  324. data/third_party/boringssl/crypto/cpu-aarch64-linux.c +2 -1
  325. data/third_party/boringssl/crypto/dsa/dsa.c +16 -54
  326. data/third_party/boringssl/crypto/ec_extra/ec_asn1.c +9 -10
  327. data/third_party/boringssl/crypto/ecdh/ecdh.c +4 -3
  328. data/third_party/boringssl/crypto/fipsmodule/bcm.c +11 -542
  329. data/third_party/boringssl/crypto/fipsmodule/bn/add.c +57 -112
  330. data/third_party/boringssl/crypto/fipsmodule/bn/asm/x86_64-gcc.c +4 -3
  331. data/third_party/boringssl/crypto/fipsmodule/bn/bn.c +128 -70
  332. data/third_party/boringssl/crypto/fipsmodule/bn/bytes.c +32 -71
  333. data/third_party/boringssl/crypto/fipsmodule/bn/cmp.c +64 -118
  334. data/third_party/boringssl/crypto/fipsmodule/bn/div.c +284 -122
  335. data/third_party/boringssl/crypto/fipsmodule/bn/exponentiation.c +31 -65
  336. data/third_party/boringssl/crypto/fipsmodule/bn/gcd.c +274 -218
  337. data/third_party/boringssl/crypto/fipsmodule/bn/generic.c +2 -1
  338. data/third_party/boringssl/crypto/fipsmodule/bn/internal.h +187 -27
  339. data/third_party/boringssl/crypto/fipsmodule/bn/jacobi.c +1 -1
  340. data/third_party/boringssl/crypto/fipsmodule/bn/montgomery.c +124 -81
  341. data/third_party/boringssl/crypto/fipsmodule/bn/montgomery_inv.c +8 -30
  342. data/third_party/boringssl/crypto/fipsmodule/bn/mul.c +321 -347
  343. data/third_party/boringssl/crypto/fipsmodule/bn/prime.c +326 -66
  344. data/third_party/boringssl/crypto/fipsmodule/bn/random.c +77 -25
  345. data/third_party/boringssl/crypto/fipsmodule/bn/rsaz_exp.c +199 -222
  346. data/third_party/boringssl/crypto/fipsmodule/bn/rsaz_exp.h +27 -47
  347. data/third_party/boringssl/crypto/fipsmodule/bn/shift.c +155 -96
  348. data/third_party/boringssl/crypto/fipsmodule/bn/sqrt.c +1 -1
  349. data/third_party/boringssl/crypto/fipsmodule/cipher/e_aes.c +10 -10
  350. data/third_party/boringssl/crypto/fipsmodule/des/internal.h +2 -0
  351. data/third_party/boringssl/crypto/fipsmodule/ec/ec.c +78 -47
  352. data/third_party/boringssl/crypto/fipsmodule/ec/ec_key.c +99 -163
  353. data/third_party/boringssl/crypto/fipsmodule/ec/ec_montgomery.c +3 -10
  354. data/third_party/boringssl/crypto/fipsmodule/ec/internal.h +44 -23
  355. data/third_party/boringssl/crypto/fipsmodule/ec/oct.c +59 -90
  356. data/third_party/boringssl/crypto/fipsmodule/ec/p224-64.c +38 -65
  357. data/third_party/boringssl/crypto/fipsmodule/ec/p256-x86_64-table.h +5378 -5418
  358. data/third_party/boringssl/crypto/fipsmodule/ec/p256-x86_64.c +17 -26
  359. data/third_party/boringssl/crypto/fipsmodule/ec/p256-x86_64.h +15 -11
  360. data/third_party/boringssl/crypto/fipsmodule/ec/simple.c +45 -51
  361. data/third_party/boringssl/crypto/fipsmodule/ec/{util-64.c → util.c} +0 -5
  362. data/third_party/boringssl/crypto/fipsmodule/ec/wnaf.c +144 -264
  363. data/third_party/boringssl/crypto/fipsmodule/ecdsa/ecdsa.c +78 -62
  364. data/third_party/boringssl/crypto/fipsmodule/modes/ccm.c +256 -0
  365. data/third_party/boringssl/crypto/fipsmodule/modes/internal.h +36 -32
  366. data/third_party/boringssl/crypto/fipsmodule/rand/ctrdrbg.c +9 -7
  367. data/third_party/boringssl/crypto/fipsmodule/rsa/blinding.c +16 -40
  368. data/third_party/boringssl/crypto/fipsmodule/rsa/internal.h +1 -6
  369. data/third_party/boringssl/crypto/fipsmodule/rsa/rsa.c +57 -39
  370. data/third_party/boringssl/crypto/fipsmodule/rsa/rsa_impl.c +309 -142
  371. data/third_party/boringssl/crypto/fipsmodule/self_check/self_check.c +581 -0
  372. data/third_party/boringssl/crypto/fipsmodule/tls/internal.h +39 -0
  373. data/third_party/boringssl/crypto/fipsmodule/tls/kdf.c +165 -0
  374. data/third_party/boringssl/crypto/internal.h +65 -2
  375. data/third_party/boringssl/crypto/mem.c +0 -2
  376. data/third_party/boringssl/crypto/obj/obj.c +6 -73
  377. data/third_party/boringssl/crypto/thread_pthread.c +35 -5
  378. data/third_party/boringssl/crypto/x509/a_strex.c +11 -11
  379. data/third_party/boringssl/crypto/x509/vpm_int.h +1 -0
  380. data/third_party/boringssl/crypto/x509/x509_vfy.c +4 -0
  381. data/third_party/boringssl/crypto/x509/x509_vpm.c +44 -22
  382. data/third_party/boringssl/crypto/x509/x_name.c +13 -0
  383. data/third_party/boringssl/include/openssl/aead.h +10 -0
  384. data/third_party/boringssl/include/openssl/asn1.h +2 -3
  385. data/third_party/boringssl/include/openssl/base.h +5 -14
  386. data/third_party/boringssl/include/openssl/bio.h +1 -1
  387. data/third_party/boringssl/include/openssl/bn.h +62 -18
  388. data/third_party/boringssl/include/openssl/bytestring.h +53 -28
  389. data/third_party/boringssl/include/openssl/crypto.h +4 -0
  390. data/third_party/boringssl/include/openssl/ec.h +10 -4
  391. data/third_party/boringssl/include/openssl/ec_key.h +7 -6
  392. data/third_party/boringssl/include/openssl/err.h +9 -9
  393. data/third_party/boringssl/include/openssl/evp.h +1 -1
  394. data/third_party/boringssl/include/openssl/rsa.h +35 -10
  395. data/third_party/boringssl/include/openssl/ssl.h +167 -19
  396. data/third_party/boringssl/include/openssl/ssl3.h +0 -1
  397. data/third_party/boringssl/include/openssl/stack.h +1 -1
  398. data/third_party/boringssl/include/openssl/tls1.h +10 -2
  399. data/third_party/boringssl/include/openssl/x509.h +4 -0
  400. data/third_party/boringssl/include/openssl/x509v3.h +1 -0
  401. data/third_party/boringssl/ssl/d1_both.cc +16 -2
  402. data/third_party/boringssl/ssl/dtls_method.cc +1 -1
  403. data/third_party/boringssl/ssl/handoff.cc +285 -0
  404. data/third_party/boringssl/ssl/handshake.cc +26 -12
  405. data/third_party/boringssl/ssl/handshake_client.cc +101 -95
  406. data/third_party/boringssl/ssl/handshake_server.cc +14 -2
  407. data/third_party/boringssl/ssl/internal.h +132 -79
  408. data/third_party/boringssl/ssl/s3_both.cc +2 -2
  409. data/third_party/boringssl/ssl/s3_lib.cc +3 -1
  410. data/third_party/boringssl/ssl/s3_pkt.cc +0 -18
  411. data/third_party/boringssl/ssl/ssl_aead_ctx.cc +1 -4
  412. data/third_party/boringssl/ssl/ssl_asn1.cc +47 -43
  413. data/third_party/boringssl/ssl/ssl_cipher.cc +12 -8
  414. data/third_party/boringssl/ssl/ssl_key_share.cc +3 -1
  415. data/third_party/boringssl/ssl/ssl_lib.cc +83 -14
  416. data/third_party/boringssl/ssl/ssl_privkey.cc +6 -0
  417. data/third_party/boringssl/ssl/ssl_stat.cc +6 -6
  418. data/third_party/boringssl/ssl/ssl_versions.cc +12 -85
  419. data/third_party/boringssl/ssl/ssl_x509.cc +59 -61
  420. data/third_party/boringssl/ssl/t1_enc.cc +73 -124
  421. data/third_party/boringssl/ssl/t1_lib.cc +367 -41
  422. data/third_party/boringssl/ssl/tls13_both.cc +8 -0
  423. data/third_party/boringssl/ssl/tls13_client.cc +98 -184
  424. data/third_party/boringssl/ssl/tls13_enc.cc +88 -158
  425. data/third_party/boringssl/ssl/tls13_server.cc +91 -137
  426. data/third_party/boringssl/ssl/tls_method.cc +0 -17
  427. data/third_party/boringssl/ssl/tls_record.cc +1 -10
  428. data/third_party/boringssl/third_party/fiat/curve25519.c +921 -2753
  429. data/third_party/boringssl/third_party/fiat/curve25519_tables.h +7880 -0
  430. data/third_party/boringssl/third_party/fiat/internal.h +32 -20
  431. data/third_party/boringssl/third_party/fiat/p256.c +1824 -0
  432. metadata +86 -71
  433. data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc +0 -253
  434. data/src/core/ext/filters/load_reporting/server_load_reporting_filter.cc +0 -222
  435. data/src/core/ext/filters/load_reporting/server_load_reporting_plugin.cc +0 -71
  436. data/src/core/ext/filters/load_reporting/server_load_reporting_plugin.h +0 -61
  437. data/src/core/lib/channel/channel_trace_registry.cc +0 -80
  438. data/src/core/lib/channel/channel_trace_registry.h +0 -43
  439. data/src/core/lib/gpr/fork.cc +0 -78
  440. data/src/core/tsi/transport_security_adapter.cc +0 -235
  441. data/src/core/tsi/transport_security_adapter.h +0 -41
  442. data/src/ruby/bin/apis/google/protobuf/empty.rb +0 -29
  443. data/src/ruby/bin/apis/pubsub_demo.rb +0 -241
  444. data/src/ruby/bin/apis/tech/pubsub/proto/pubsub.rb +0 -159
  445. data/src/ruby/bin/apis/tech/pubsub/proto/pubsub_services.rb +0 -88
  446. data/src/ruby/pb/test/client.rb +0 -764
  447. data/src/ruby/pb/test/server.rb +0 -252
  448. data/src/ruby/spec/pb/package_with_underscore/checker_spec.rb +0 -54
  449. data/src/ruby/spec/pb/package_with_underscore/data.proto +0 -23
  450. data/src/ruby/spec/pb/package_with_underscore/service.proto +0 -23
  451. data/third_party/boringssl/crypto/curve25519/x25519-x86_64.c +0 -247
  452. data/third_party/boringssl/crypto/fipsmodule/ec/p256-64.c +0 -1674
@@ -36,6 +36,7 @@
36
36
  #include "src/core/ext/filters/client_channel/subchannel_index.h"
37
37
  #include "src/core/lib/channel/channel_args.h"
38
38
  #include "src/core/lib/debug/trace.h"
39
+ #include "src/core/lib/gprpp/mutex_lock.h"
39
40
  #include "src/core/lib/gprpp/ref_counted_ptr.h"
40
41
  #include "src/core/lib/iomgr/combiner.h"
41
42
  #include "src/core/lib/iomgr/sockaddr_utils.h"
@@ -57,7 +58,7 @@ class RoundRobin : public LoadBalancingPolicy {
57
58
  explicit RoundRobin(const Args& args);
58
59
 
59
60
  void UpdateLocked(const grpc_channel_args& args) override;
60
- bool PickLocked(PickState* pick) override;
61
+ bool PickLocked(PickState* pick, grpc_error** error) override;
61
62
  void CancelPickLocked(PickState* pick, grpc_error* error) override;
62
63
  void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask,
63
64
  uint32_t initial_metadata_flags_eq,
@@ -67,29 +68,149 @@ class RoundRobin : public LoadBalancingPolicy {
67
68
  grpc_connectivity_state CheckConnectivityLocked(
68
69
  grpc_error** connectivity_error) override;
69
70
  void HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) override;
70
- void PingOneLocked(grpc_closure* on_initiate, grpc_closure* on_ack) override;
71
71
  void ExitIdleLocked() override;
72
+ void ResetBackoffLocked() override;
73
+ void FillChildRefsForChannelz(ChildRefsList* child_subchannels,
74
+ ChildRefsList* ignored) override;
72
75
 
73
76
  private:
74
77
  ~RoundRobin();
75
78
 
76
- void ShutdownLocked() override;
79
+ // Forward declaration.
80
+ class RoundRobinSubchannelList;
81
+
82
+ // Data for a particular subchannel in a subchannel list.
83
+ // This subclass adds the following functionality:
84
+ // - Tracks user_data associated with each address, which will be
85
+ // returned along with picks that select the subchannel.
86
+ // - Tracks the previous connectivity state of the subchannel, so that
87
+ // we know how many subchannels are in each state.
88
+ class RoundRobinSubchannelData
89
+ : public SubchannelData<RoundRobinSubchannelList,
90
+ RoundRobinSubchannelData> {
91
+ public:
92
+ RoundRobinSubchannelData(RoundRobinSubchannelList* subchannel_list,
93
+ const grpc_lb_user_data_vtable* user_data_vtable,
94
+ const grpc_lb_address& address,
95
+ grpc_subchannel* subchannel,
96
+ grpc_combiner* combiner)
97
+ : SubchannelData(subchannel_list, user_data_vtable, address, subchannel,
98
+ combiner),
99
+ user_data_vtable_(user_data_vtable),
100
+ user_data_(user_data_vtable_ != nullptr
101
+ ? user_data_vtable_->copy(address.user_data)
102
+ : nullptr) {}
103
+
104
+ void UnrefSubchannelLocked(const char* reason) override {
105
+ SubchannelData::UnrefSubchannelLocked(reason);
106
+ if (user_data_ != nullptr) {
107
+ GPR_ASSERT(user_data_vtable_ != nullptr);
108
+ user_data_vtable_->destroy(user_data_);
109
+ user_data_ = nullptr;
110
+ }
111
+ }
77
112
 
78
- void StartPickingLocked();
79
- size_t GetNextReadySubchannelIndexLocked();
80
- void UpdateLastReadySubchannelIndexLocked(size_t last_ready_index);
81
- void UpdateConnectivityStatusLocked(grpc_lb_subchannel_data* sd,
82
- grpc_error* error);
113
+ void* user_data() const { return user_data_; }
114
+
115
+ grpc_connectivity_state connectivity_state() const {
116
+ return last_connectivity_state_;
117
+ }
118
+
119
+ void UpdateConnectivityStateLocked(
120
+ grpc_connectivity_state connectivity_state, grpc_error* error);
121
+
122
+ private:
123
+ void ProcessConnectivityChangeLocked(
124
+ grpc_connectivity_state connectivity_state, grpc_error* error) override;
125
+
126
+ const grpc_lb_user_data_vtable* user_data_vtable_;
127
+ void* user_data_ = nullptr;
128
+ grpc_connectivity_state last_connectivity_state_ = GRPC_CHANNEL_IDLE;
129
+ };
130
+
131
+ // A list of subchannels.
132
+ class RoundRobinSubchannelList
133
+ : public SubchannelList<RoundRobinSubchannelList,
134
+ RoundRobinSubchannelData> {
135
+ public:
136
+ RoundRobinSubchannelList(
137
+ RoundRobin* policy, TraceFlag* tracer,
138
+ const grpc_lb_addresses* addresses, grpc_combiner* combiner,
139
+ grpc_client_channel_factory* client_channel_factory,
140
+ const grpc_channel_args& args)
141
+ : SubchannelList(policy, tracer, addresses, combiner,
142
+ client_channel_factory, args),
143
+ last_ready_index_(num_subchannels() - 1) {
144
+ // Need to maintain a ref to the LB policy as long as we maintain
145
+ // any references to subchannels, since the subchannels'
146
+ // pollset_sets will include the LB policy's pollset_set.
147
+ policy->Ref(DEBUG_LOCATION, "subchannel_list").release();
148
+ }
149
+
150
+ ~RoundRobinSubchannelList() {
151
+ GRPC_ERROR_UNREF(last_transient_failure_error_);
152
+ RoundRobin* p = static_cast<RoundRobin*>(policy());
153
+ p->Unref(DEBUG_LOCATION, "subchannel_list");
154
+ }
155
+
156
+ // Starts watching the subchannels in this list.
157
+ void StartWatchingLocked();
158
+
159
+ // Updates the counters of subchannels in each state when a
160
+ // subchannel transitions from old_state to new_state.
161
+ // transient_failure_error is the error that is reported when
162
+ // new_state is TRANSIENT_FAILURE.
163
+ void UpdateStateCountersLocked(grpc_connectivity_state old_state,
164
+ grpc_connectivity_state new_state,
165
+ grpc_error* transient_failure_error);
166
+
167
+ // If this subchannel list is the RR policy's current subchannel
168
+ // list, updates the RR policy's connectivity state based on the
169
+ // subchannel list's state counters.
170
+ void MaybeUpdateRoundRobinConnectivityStateLocked();
171
+
172
+ // Updates the RR policy's overall state based on the counters of
173
+ // subchannels in each state.
174
+ void UpdateRoundRobinStateFromSubchannelStateCountsLocked();
175
+
176
+ size_t GetNextReadySubchannelIndexLocked();
177
+ void UpdateLastReadySubchannelIndexLocked(size_t last_ready_index);
178
+
179
+ private:
180
+ size_t num_ready_ = 0;
181
+ size_t num_connecting_ = 0;
182
+ size_t num_transient_failure_ = 0;
183
+ grpc_error* last_transient_failure_error_ = GRPC_ERROR_NONE;
184
+ size_t last_ready_index_; // Index into list of last pick.
185
+ };
186
+
187
+ // Helper class to ensure that any function that modifies the child refs
188
+ // data structures will update the channelz snapshot data structures before
189
+ // returning.
190
+ class AutoChildRefsUpdater {
191
+ public:
192
+ explicit AutoChildRefsUpdater(RoundRobin* rr) : rr_(rr) {}
193
+ ~AutoChildRefsUpdater() { rr_->UpdateChildRefsLocked(); }
194
+
195
+ private:
196
+ RoundRobin* rr_;
197
+ };
83
198
 
84
- static void OnConnectivityChangedLocked(void* arg, grpc_error* error);
199
+ void ShutdownLocked() override;
85
200
 
86
- void SubchannelListRefForConnectivityWatch(
87
- grpc_lb_subchannel_list* subchannel_list, const char* reason);
88
- void SubchannelListUnrefForConnectivityWatch(
89
- grpc_lb_subchannel_list* subchannel_list, const char* reason);
201
+ void StartPickingLocked();
202
+ bool DoPickLocked(PickState* pick);
203
+ void DrainPendingPicksLocked();
204
+ void UpdateChildRefsLocked();
90
205
 
91
206
  /** list of subchannels */
92
- grpc_lb_subchannel_list* subchannel_list_ = nullptr;
207
+ OrphanablePtr<RoundRobinSubchannelList> subchannel_list_;
208
+ /** Latest version of the subchannel list.
209
+ * Subchannel connectivity callbacks will only promote updated subchannel
210
+ * lists if they equal \a latest_pending_subchannel_list. In other words,
211
+ * racing callbacks that reference outdated subchannel lists won't perform any
212
+ * update. */
213
+ OrphanablePtr<RoundRobinSubchannelList> latest_pending_subchannel_list_;
93
214
  /** have we started picking? */
94
215
  bool started_picking_ = false;
95
216
  /** are we shutting down? */
@@ -98,32 +219,31 @@ class RoundRobin : public LoadBalancingPolicy {
98
219
  PickState* pending_picks_ = nullptr;
99
220
  /** our connectivity state tracker */
100
221
  grpc_connectivity_state_tracker state_tracker_;
101
- /** Index into subchannels for last pick. */
102
- size_t last_ready_subchannel_index_ = 0;
103
- /** Latest version of the subchannel list.
104
- * Subchannel connectivity callbacks will only promote updated subchannel
105
- * lists if they equal \a latest_pending_subchannel_list. In other words,
106
- * racing callbacks that reference outdated subchannel lists won't perform any
107
- * update. */
108
- grpc_lb_subchannel_list* latest_pending_subchannel_list_ = nullptr;
222
+ /// Lock and data used to capture snapshots of this channel's child
223
+ /// channels and subchannels. This data is consumed by channelz.
224
+ gpr_mu child_refs_mu_;
225
+ ChildRefsList child_subchannels_;
226
+ ChildRefsList child_channels_;
109
227
  };
110
228
 
111
229
  RoundRobin::RoundRobin(const Args& args) : LoadBalancingPolicy(args) {
112
230
  GPR_ASSERT(args.client_channel_factory != nullptr);
231
+ gpr_mu_init(&child_refs_mu_);
113
232
  grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE,
114
233
  "round_robin");
115
234
  UpdateLocked(*args.args);
116
235
  if (grpc_lb_round_robin_trace.enabled()) {
117
- gpr_log(GPR_DEBUG, "[RR %p] Created with %" PRIuPTR " subchannels", this,
118
- subchannel_list_->num_subchannels);
236
+ gpr_log(GPR_INFO, "[RR %p] Created with %" PRIuPTR " subchannels", this,
237
+ subchannel_list_->num_subchannels());
119
238
  }
120
239
  grpc_subchannel_index_ref();
121
240
  }
122
241
 
123
242
  RoundRobin::~RoundRobin() {
124
243
  if (grpc_lb_round_robin_trace.enabled()) {
125
- gpr_log(GPR_DEBUG, "[RR %p] Destroying Round Robin policy", this);
244
+ gpr_log(GPR_INFO, "[RR %p] Destroying Round Robin policy", this);
126
245
  }
246
+ gpr_mu_destroy(&child_refs_mu_);
127
247
  GPR_ASSERT(subchannel_list_ == nullptr);
128
248
  GPR_ASSERT(latest_pending_subchannel_list_ == nullptr);
129
249
  GPR_ASSERT(pending_picks_ == nullptr);
@@ -131,83 +251,23 @@ RoundRobin::~RoundRobin() {
131
251
  grpc_subchannel_index_unref();
132
252
  }
133
253
 
134
- /** Returns the index into p->subchannel_list->subchannels of the next
135
- * subchannel in READY state, or p->subchannel_list->num_subchannels if no
136
- * subchannel is READY.
137
- *
138
- * Note that this function does *not* update p->last_ready_subchannel_index.
139
- * The caller must do that if it returns a pick. */
140
- size_t RoundRobin::GetNextReadySubchannelIndexLocked() {
141
- GPR_ASSERT(subchannel_list_ != nullptr);
142
- if (grpc_lb_round_robin_trace.enabled()) {
143
- gpr_log(GPR_INFO,
144
- "[RR %p] getting next ready subchannel (out of %" PRIuPTR
145
- "), "
146
- "last_ready_subchannel_index=%" PRIuPTR,
147
- this, subchannel_list_->num_subchannels,
148
- last_ready_subchannel_index_);
149
- }
150
- for (size_t i = 0; i < subchannel_list_->num_subchannels; ++i) {
151
- const size_t index = (i + last_ready_subchannel_index_ + 1) %
152
- subchannel_list_->num_subchannels;
153
- if (grpc_lb_round_robin_trace.enabled()) {
154
- gpr_log(
155
- GPR_DEBUG,
156
- "[RR %p] checking subchannel %p, subchannel_list %p, index %" PRIuPTR
157
- ": state=%s",
158
- this, subchannel_list_->subchannels[index].subchannel,
159
- subchannel_list_, index,
160
- grpc_connectivity_state_name(
161
- subchannel_list_->subchannels[index].curr_connectivity_state));
162
- }
163
- if (subchannel_list_->subchannels[index].curr_connectivity_state ==
164
- GRPC_CHANNEL_READY) {
165
- if (grpc_lb_round_robin_trace.enabled()) {
166
- gpr_log(GPR_DEBUG,
167
- "[RR %p] found next ready subchannel (%p) at index %" PRIuPTR
168
- " of subchannel_list %p",
169
- this, subchannel_list_->subchannels[index].subchannel, index,
170
- subchannel_list_);
171
- }
172
- return index;
173
- }
174
- }
175
- if (grpc_lb_round_robin_trace.enabled()) {
176
- gpr_log(GPR_DEBUG, "[RR %p] no subchannels in ready state", this);
177
- }
178
- return subchannel_list_->num_subchannels;
179
- }
180
-
181
- // Sets last_ready_subchannel_index_ to last_ready_index.
182
- void RoundRobin::UpdateLastReadySubchannelIndexLocked(size_t last_ready_index) {
183
- GPR_ASSERT(last_ready_index < subchannel_list_->num_subchannels);
184
- last_ready_subchannel_index_ = last_ready_index;
185
- if (grpc_lb_round_robin_trace.enabled()) {
186
- gpr_log(GPR_DEBUG,
187
- "[RR %p] setting last_ready_subchannel_index=%" PRIuPTR
188
- " (SC %p, CSC %p)",
189
- this, last_ready_index,
190
- subchannel_list_->subchannels[last_ready_index].subchannel,
191
- subchannel_list_->subchannels[last_ready_index]
192
- .connected_subchannel.get());
193
- }
194
- }
195
-
196
254
  void RoundRobin::HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) {
197
255
  PickState* pick;
198
256
  while ((pick = pending_picks_) != nullptr) {
199
257
  pending_picks_ = pick->next;
200
- if (new_policy->PickLocked(pick)) {
258
+ grpc_error* error = GRPC_ERROR_NONE;
259
+ if (new_policy->PickLocked(pick, &error)) {
201
260
  // Synchronous return, schedule closure.
202
- GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_NONE);
261
+ GRPC_CLOSURE_SCHED(pick->on_complete, error);
203
262
  }
204
263
  }
205
264
  }
206
265
 
207
266
  void RoundRobin::ShutdownLocked() {
267
+ AutoChildRefsUpdater guard(this);
208
268
  grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel shutdown");
209
269
  if (grpc_lb_round_robin_trace.enabled()) {
210
- gpr_log(GPR_DEBUG, "[RR %p] Shutting down", this);
270
+ gpr_log(GPR_INFO, "[RR %p] Shutting down", this);
211
271
  }
212
272
  shutdown_ = true;
213
273
  PickState* pick;
@@ -218,16 +278,8 @@ void RoundRobin::ShutdownLocked() {
218
278
  }
219
279
  grpc_connectivity_state_set(&state_tracker_, GRPC_CHANNEL_SHUTDOWN,
220
280
  GRPC_ERROR_REF(error), "rr_shutdown");
221
- if (subchannel_list_ != nullptr) {
222
- grpc_lb_subchannel_list_shutdown_and_unref(subchannel_list_,
223
- "sl_shutdown_rr_shutdown");
224
- subchannel_list_ = nullptr;
225
- }
226
- if (latest_pending_subchannel_list_ != nullptr) {
227
- grpc_lb_subchannel_list_shutdown_and_unref(
228
- latest_pending_subchannel_list_, "sl_shutdown_pending_rr_shutdown");
229
- latest_pending_subchannel_list_ = nullptr;
230
- }
281
+ subchannel_list_.reset();
282
+ latest_pending_subchannel_list_.reset();
231
283
  TryReresolutionLocked(&grpc_lb_round_robin_trace, GRPC_ERROR_CANCELLED);
232
284
  GRPC_ERROR_UNREF(error);
233
285
  }
@@ -273,110 +325,170 @@ void RoundRobin::CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask,
273
325
  GRPC_ERROR_UNREF(error);
274
326
  }
275
327
 
276
- void RoundRobin::SubchannelListRefForConnectivityWatch(
277
- grpc_lb_subchannel_list* subchannel_list, const char* reason) {
278
- // TODO(roth): We currently track this ref manually. Once the new
279
- // ClosureRef API is ready and the subchannel_list code has been
280
- // converted to a C++ API, find a way to hold the RefCountedPtr<>
281
- // somewhere (maybe in the subchannel_data object) instead of doing
282
- // this manually.
283
- auto self = Ref(DEBUG_LOCATION, reason);
284
- self.release();
285
- grpc_lb_subchannel_list_ref(subchannel_list, reason);
328
+ void RoundRobin::StartPickingLocked() {
329
+ started_picking_ = true;
330
+ subchannel_list_->StartWatchingLocked();
331
+ }
332
+
333
+ void RoundRobin::ExitIdleLocked() {
334
+ if (!started_picking_) {
335
+ StartPickingLocked();
336
+ }
286
337
  }
287
338
 
288
- void RoundRobin::SubchannelListUnrefForConnectivityWatch(
289
- grpc_lb_subchannel_list* subchannel_list, const char* reason) {
290
- Unref(DEBUG_LOCATION, reason);
291
- grpc_lb_subchannel_list_unref(subchannel_list, reason);
339
+ void RoundRobin::ResetBackoffLocked() {
340
+ subchannel_list_->ResetBackoffLocked();
341
+ if (latest_pending_subchannel_list_ != nullptr) {
342
+ latest_pending_subchannel_list_->ResetBackoffLocked();
343
+ }
292
344
  }
293
345
 
294
- void RoundRobin::StartPickingLocked() {
295
- started_picking_ = true;
296
- for (size_t i = 0; i < subchannel_list_->num_subchannels; i++) {
297
- if (subchannel_list_->subchannels[i].subchannel != nullptr) {
298
- SubchannelListRefForConnectivityWatch(subchannel_list_,
299
- "connectivity_watch");
300
- grpc_lb_subchannel_data_start_connectivity_watch(
301
- &subchannel_list_->subchannels[i]);
346
+ bool RoundRobin::DoPickLocked(PickState* pick) {
347
+ const size_t next_ready_index =
348
+ subchannel_list_->GetNextReadySubchannelIndexLocked();
349
+ if (next_ready_index < subchannel_list_->num_subchannels()) {
350
+ /* readily available, report right away */
351
+ RoundRobinSubchannelData* sd =
352
+ subchannel_list_->subchannel(next_ready_index);
353
+ GPR_ASSERT(sd->connected_subchannel() != nullptr);
354
+ pick->connected_subchannel = sd->connected_subchannel()->Ref();
355
+ if (pick->user_data != nullptr) {
356
+ *pick->user_data = sd->user_data();
357
+ }
358
+ if (grpc_lb_round_robin_trace.enabled()) {
359
+ gpr_log(GPR_INFO,
360
+ "[RR %p] Picked target <-- Subchannel %p (connected %p) (sl %p, "
361
+ "index %" PRIuPTR ")",
362
+ this, sd->subchannel(), pick->connected_subchannel.get(),
363
+ sd->subchannel_list(), next_ready_index);
302
364
  }
365
+ /* only advance the last picked pointer if the selection was used */
366
+ subchannel_list_->UpdateLastReadySubchannelIndexLocked(next_ready_index);
367
+ return true;
303
368
  }
369
+ return false;
304
370
  }
305
371
 
306
- void RoundRobin::ExitIdleLocked() {
307
- if (!started_picking_) {
308
- StartPickingLocked();
372
+ void RoundRobin::DrainPendingPicksLocked() {
373
+ PickState* pick;
374
+ while ((pick = pending_picks_)) {
375
+ pending_picks_ = pick->next;
376
+ GPR_ASSERT(DoPickLocked(pick));
377
+ GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_NONE);
309
378
  }
310
379
  }
311
380
 
312
- bool RoundRobin::PickLocked(PickState* pick) {
381
+ bool RoundRobin::PickLocked(PickState* pick, grpc_error** error) {
313
382
  if (grpc_lb_round_robin_trace.enabled()) {
314
- gpr_log(GPR_DEBUG, "[RR %p] Trying to pick (shutdown: %d)", this,
315
- shutdown_);
383
+ gpr_log(GPR_INFO, "[RR %p] Trying to pick (shutdown: %d)", this, shutdown_);
316
384
  }
317
385
  GPR_ASSERT(!shutdown_);
318
386
  if (subchannel_list_ != nullptr) {
319
- const size_t next_ready_index = GetNextReadySubchannelIndexLocked();
320
- if (next_ready_index < subchannel_list_->num_subchannels) {
321
- /* readily available, report right away */
322
- grpc_lb_subchannel_data* sd =
323
- &subchannel_list_->subchannels[next_ready_index];
324
- pick->connected_subchannel = sd->connected_subchannel;
325
- if (pick->user_data != nullptr) {
326
- *pick->user_data = sd->user_data;
327
- }
328
- if (grpc_lb_round_robin_trace.enabled()) {
329
- gpr_log(
330
- GPR_DEBUG,
331
- "[RR %p] Picked target <-- Subchannel %p (connected %p) (sl %p, "
332
- "index %" PRIuPTR ")",
333
- this, sd->subchannel, pick->connected_subchannel.get(),
334
- sd->subchannel_list, next_ready_index);
335
- }
336
- /* only advance the last picked pointer if the selection was used */
337
- UpdateLastReadySubchannelIndexLocked(next_ready_index);
338
- return true;
339
- }
387
+ if (DoPickLocked(pick)) return true;
388
+ }
389
+ if (pick->on_complete == nullptr) {
390
+ *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
391
+ "No pick result available but synchronous result required.");
392
+ return true;
340
393
  }
341
394
  /* no pick currently available. Save for later in list of pending picks */
395
+ pick->next = pending_picks_;
396
+ pending_picks_ = pick;
342
397
  if (!started_picking_) {
343
398
  StartPickingLocked();
344
399
  }
345
- pick->next = pending_picks_;
346
- pending_picks_ = pick;
347
400
  return false;
348
401
  }
349
402
 
350
- void UpdateStateCountersLocked(grpc_lb_subchannel_data* sd) {
351
- grpc_lb_subchannel_list* subchannel_list = sd->subchannel_list;
352
- GPR_ASSERT(sd->prev_connectivity_state != GRPC_CHANNEL_SHUTDOWN);
353
- GPR_ASSERT(sd->curr_connectivity_state != GRPC_CHANNEL_SHUTDOWN);
354
- if (sd->prev_connectivity_state == GRPC_CHANNEL_READY) {
355
- GPR_ASSERT(subchannel_list->num_ready > 0);
356
- --subchannel_list->num_ready;
357
- } else if (sd->prev_connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
358
- GPR_ASSERT(subchannel_list->num_transient_failures > 0);
359
- --subchannel_list->num_transient_failures;
360
- } else if (sd->prev_connectivity_state == GRPC_CHANNEL_IDLE) {
361
- GPR_ASSERT(subchannel_list->num_idle > 0);
362
- --subchannel_list->num_idle;
363
- }
364
- sd->prev_connectivity_state = sd->curr_connectivity_state;
365
- if (sd->curr_connectivity_state == GRPC_CHANNEL_READY) {
366
- ++subchannel_list->num_ready;
367
- } else if (sd->curr_connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
368
- ++subchannel_list->num_transient_failures;
369
- } else if (sd->curr_connectivity_state == GRPC_CHANNEL_IDLE) {
370
- ++subchannel_list->num_idle;
403
+ void RoundRobin::FillChildRefsForChannelz(
404
+ ChildRefsList* child_subchannels_to_fill, ChildRefsList* ignored) {
405
+ MutexLock lock(&child_refs_mu_);
406
+ for (size_t i = 0; i < child_subchannels_.size(); ++i) {
407
+ // TODO(ncteisen): implement a de dup loop that is not O(n^2). Might
408
+ // have to implement lightweight set. For now, we don't care about
409
+ // performance when channelz requests are made.
410
+ bool found = false;
411
+ for (size_t j = 0; j < child_subchannels_to_fill->size(); ++j) {
412
+ if ((*child_subchannels_to_fill)[j] == child_subchannels_[i]) {
413
+ found = true;
414
+ break;
415
+ }
416
+ }
417
+ if (!found) {
418
+ child_subchannels_to_fill->push_back(child_subchannels_[i]);
419
+ }
420
+ }
421
+ }
422
+
423
+ void RoundRobin::UpdateChildRefsLocked() {
424
+ ChildRefsList cs;
425
+ if (subchannel_list_ != nullptr) {
426
+ subchannel_list_->PopulateChildRefsList(&cs);
427
+ }
428
+ if (latest_pending_subchannel_list_ != nullptr) {
429
+ latest_pending_subchannel_list_->PopulateChildRefsList(&cs);
430
+ }
431
+ // atomically update the data that channelz will actually be looking at.
432
+ MutexLock lock(&child_refs_mu_);
433
+ child_subchannels_ = std::move(cs);
434
+ }
435
+
436
+ void RoundRobin::RoundRobinSubchannelList::StartWatchingLocked() {
437
+ if (num_subchannels() == 0) return;
438
+ // Check current state of each subchannel synchronously, since any
439
+ // subchannel already used by some other channel may have a non-IDLE
440
+ // state.
441
+ for (size_t i = 0; i < num_subchannels(); ++i) {
442
+ grpc_error* error = GRPC_ERROR_NONE;
443
+ grpc_connectivity_state state =
444
+ subchannel(i)->CheckConnectivityStateLocked(&error);
445
+ if (state != GRPC_CHANNEL_IDLE) {
446
+ subchannel(i)->UpdateConnectivityStateLocked(state, error);
447
+ }
371
448
  }
449
+ // Now set the LB policy's state based on the subchannels' states.
450
+ UpdateRoundRobinStateFromSubchannelStateCountsLocked();
451
+ // Start connectivity watch for each subchannel.
452
+ for (size_t i = 0; i < num_subchannels(); i++) {
453
+ if (subchannel(i)->subchannel() != nullptr) {
454
+ subchannel(i)->StartConnectivityWatchLocked();
455
+ }
456
+ }
457
+ }
458
+
459
+ void RoundRobin::RoundRobinSubchannelList::UpdateStateCountersLocked(
460
+ grpc_connectivity_state old_state, grpc_connectivity_state new_state,
461
+ grpc_error* transient_failure_error) {
462
+ GPR_ASSERT(old_state != GRPC_CHANNEL_SHUTDOWN);
463
+ GPR_ASSERT(new_state != GRPC_CHANNEL_SHUTDOWN);
464
+ if (old_state == GRPC_CHANNEL_READY) {
465
+ GPR_ASSERT(num_ready_ > 0);
466
+ --num_ready_;
467
+ } else if (old_state == GRPC_CHANNEL_CONNECTING) {
468
+ GPR_ASSERT(num_connecting_ > 0);
469
+ --num_connecting_;
470
+ } else if (old_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
471
+ GPR_ASSERT(num_transient_failure_ > 0);
472
+ --num_transient_failure_;
473
+ }
474
+ if (new_state == GRPC_CHANNEL_READY) {
475
+ ++num_ready_;
476
+ } else if (new_state == GRPC_CHANNEL_CONNECTING) {
477
+ ++num_connecting_;
478
+ } else if (new_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
479
+ ++num_transient_failure_;
480
+ }
481
+ GRPC_ERROR_UNREF(last_transient_failure_error_);
482
+ last_transient_failure_error_ = transient_failure_error;
372
483
  }
373
484
 
374
- /** Sets the policy's connectivity status based on that of the passed-in \a sd
375
- * (the grpc_lb_subchannel_data associated with the updated subchannel) and the
376
- * subchannel list \a sd belongs to (sd->subchannel_list). \a error will be used
377
- * only if the policy transitions to state TRANSIENT_FAILURE. */
378
- void RoundRobin::UpdateConnectivityStatusLocked(grpc_lb_subchannel_data* sd,
379
- grpc_error* error) {
485
+ // Sets the RR policy's connectivity state based on the current
486
+ // subchannel list.
487
+ void RoundRobin::RoundRobinSubchannelList::
488
+ MaybeUpdateRoundRobinConnectivityStateLocked() {
489
+ RoundRobin* p = static_cast<RoundRobin*>(policy());
490
+ // Only set connectivity state if this is the current subchannel list.
491
+ if (p->subchannel_list_.get() != this) return;
380
492
  /* In priority order. The first rule to match terminates the search (ie, if we
381
493
  * are on rule n, all previous rules were unfulfilled).
382
494
  *
@@ -391,155 +503,152 @@ void RoundRobin::UpdateConnectivityStatusLocked(grpc_lb_subchannel_data* sd,
391
503
  * CHECK: subchannel_list->num_transient_failures ==
392
504
  * subchannel_list->num_subchannels.
393
505
  */
394
- grpc_lb_subchannel_list* subchannel_list = sd->subchannel_list;
395
- GPR_ASSERT(sd->curr_connectivity_state != GRPC_CHANNEL_IDLE);
396
- if (subchannel_list->num_ready > 0) {
506
+ if (num_ready_ > 0) {
397
507
  /* 1) READY */
398
- grpc_connectivity_state_set(&state_tracker_, GRPC_CHANNEL_READY,
508
+ grpc_connectivity_state_set(&p->state_tracker_, GRPC_CHANNEL_READY,
399
509
  GRPC_ERROR_NONE, "rr_ready");
400
- } else if (sd->curr_connectivity_state == GRPC_CHANNEL_CONNECTING) {
510
+ } else if (num_connecting_ > 0) {
401
511
  /* 2) CONNECTING */
402
- grpc_connectivity_state_set(&state_tracker_, GRPC_CHANNEL_CONNECTING,
512
+ grpc_connectivity_state_set(&p->state_tracker_, GRPC_CHANNEL_CONNECTING,
403
513
  GRPC_ERROR_NONE, "rr_connecting");
404
- } else if (subchannel_list->num_transient_failures ==
405
- subchannel_list->num_subchannels) {
514
+ } else if (num_transient_failure_ == num_subchannels()) {
406
515
  /* 3) TRANSIENT_FAILURE */
407
- grpc_connectivity_state_set(&state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE,
408
- GRPC_ERROR_REF(error),
516
+ grpc_connectivity_state_set(&p->state_tracker_,
517
+ GRPC_CHANNEL_TRANSIENT_FAILURE,
518
+ GRPC_ERROR_REF(last_transient_failure_error_),
409
519
  "rr_exhausted_subchannels");
410
520
  }
411
- GRPC_ERROR_UNREF(error);
412
521
  }
413
522
 
414
- void RoundRobin::OnConnectivityChangedLocked(void* arg, grpc_error* error) {
415
- grpc_lb_subchannel_data* sd = static_cast<grpc_lb_subchannel_data*>(arg);
416
- RoundRobin* p = static_cast<RoundRobin*>(sd->subchannel_list->policy);
523
+ void RoundRobin::RoundRobinSubchannelList::
524
+ UpdateRoundRobinStateFromSubchannelStateCountsLocked() {
525
+ RoundRobin* p = static_cast<RoundRobin*>(policy());
526
+ AutoChildRefsUpdater guard(p);
527
+ if (num_ready_ > 0) {
528
+ if (p->subchannel_list_.get() != this) {
529
+ // Promote this list to p->subchannel_list_.
530
+ // This list must be p->latest_pending_subchannel_list_, because
531
+ // any previous update would have been shut down already and
532
+ // therefore we would not be receiving a notification for them.
533
+ GPR_ASSERT(p->latest_pending_subchannel_list_.get() == this);
534
+ GPR_ASSERT(!shutting_down());
535
+ if (grpc_lb_round_robin_trace.enabled()) {
536
+ const size_t old_num_subchannels =
537
+ p->subchannel_list_ != nullptr
538
+ ? p->subchannel_list_->num_subchannels()
539
+ : 0;
540
+ gpr_log(GPR_INFO,
541
+ "[RR %p] phasing out subchannel list %p (size %" PRIuPTR
542
+ ") in favor of %p (size %" PRIuPTR ")",
543
+ p, p->subchannel_list_.get(), old_num_subchannels, this,
544
+ num_subchannels());
545
+ }
546
+ p->subchannel_list_ = std::move(p->latest_pending_subchannel_list_);
547
+ }
548
+ // Drain pending picks.
549
+ p->DrainPendingPicksLocked();
550
+ }
551
+ // Update the RR policy's connectivity state if needed.
552
+ MaybeUpdateRoundRobinConnectivityStateLocked();
553
+ }
554
+
555
+ void RoundRobin::RoundRobinSubchannelData::UpdateConnectivityStateLocked(
556
+ grpc_connectivity_state connectivity_state, grpc_error* error) {
557
+ RoundRobin* p = static_cast<RoundRobin*>(subchannel_list()->policy());
417
558
  if (grpc_lb_round_robin_trace.enabled()) {
418
559
  gpr_log(
419
- GPR_DEBUG,
420
- "[RR %p] connectivity changed for subchannel %p, subchannel_list %p: "
421
- "prev_state=%s new_state=%s p->shutdown=%d "
422
- "sd->subchannel_list->shutting_down=%d error=%s",
423
- p, sd->subchannel, sd->subchannel_list,
424
- grpc_connectivity_state_name(sd->prev_connectivity_state),
425
- grpc_connectivity_state_name(sd->pending_connectivity_state_unsafe),
426
- p->shutdown_, sd->subchannel_list->shutting_down,
427
- grpc_error_string(error));
428
- }
429
- GPR_ASSERT(sd->subchannel != nullptr);
430
- // If the policy is shutting down, unref and return.
431
- if (p->shutdown_) {
432
- grpc_lb_subchannel_data_stop_connectivity_watch(sd);
433
- grpc_lb_subchannel_data_unref_subchannel(sd, "rr_shutdown");
434
- p->SubchannelListUnrefForConnectivityWatch(sd->subchannel_list,
435
- "rr_shutdown");
436
- return;
560
+ GPR_INFO,
561
+ "[RR %p] connectivity changed for subchannel %p, subchannel_list %p "
562
+ "(index %" PRIuPTR " of %" PRIuPTR "): prev_state=%s new_state=%s",
563
+ p, subchannel(), subchannel_list(), Index(),
564
+ subchannel_list()->num_subchannels(),
565
+ grpc_connectivity_state_name(last_connectivity_state_),
566
+ grpc_connectivity_state_name(connectivity_state));
567
+ }
568
+ subchannel_list()->UpdateStateCountersLocked(last_connectivity_state_,
569
+ connectivity_state, error);
570
+ last_connectivity_state_ = connectivity_state;
571
+ }
572
+
573
+ void RoundRobin::RoundRobinSubchannelData::ProcessConnectivityChangeLocked(
574
+ grpc_connectivity_state connectivity_state, grpc_error* error) {
575
+ RoundRobin* p = static_cast<RoundRobin*>(subchannel_list()->policy());
576
+ GPR_ASSERT(subchannel() != nullptr);
577
+ // If the new state is TRANSIENT_FAILURE, re-resolve.
578
+ // Only do this if we've started watching, not at startup time.
579
+ // Otherwise, if the subchannel was already in state TRANSIENT_FAILURE
580
+ // when the subchannel list was created, we'd wind up in a constant
581
+ // loop of re-resolution.
582
+ if (connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
583
+ if (grpc_lb_round_robin_trace.enabled()) {
584
+ gpr_log(GPR_INFO,
585
+ "[RR %p] Subchannel %p has gone into TRANSIENT_FAILURE. "
586
+ "Requesting re-resolution",
587
+ p, subchannel());
588
+ }
589
+ p->TryReresolutionLocked(&grpc_lb_round_robin_trace, GRPC_ERROR_NONE);
437
590
  }
438
- // If the subchannel list is shutting down, stop watching.
439
- if (sd->subchannel_list->shutting_down || error == GRPC_ERROR_CANCELLED) {
440
- grpc_lb_subchannel_data_stop_connectivity_watch(sd);
441
- grpc_lb_subchannel_data_unref_subchannel(sd, "rr_sl_shutdown");
442
- p->SubchannelListUnrefForConnectivityWatch(sd->subchannel_list,
443
- "rr_sl_shutdown");
444
- return;
591
+ // Update state counters.
592
+ UpdateConnectivityStateLocked(connectivity_state, error);
593
+ // Update overall state and renew notification.
594
+ subchannel_list()->UpdateRoundRobinStateFromSubchannelStateCountsLocked();
595
+ RenewConnectivityWatchLocked();
596
+ }
597
+
598
+ /** Returns the index into p->subchannel_list->subchannels of the next
599
+ * subchannel in READY state, or p->subchannel_list->num_subchannels if no
600
+ * subchannel is READY.
601
+ *
602
+ * Note that this function does *not* update p->last_ready_subchannel_index.
603
+ * The caller must do that if it returns a pick. */
604
+ size_t
605
+ RoundRobin::RoundRobinSubchannelList::GetNextReadySubchannelIndexLocked() {
606
+ if (grpc_lb_round_robin_trace.enabled()) {
607
+ gpr_log(GPR_INFO,
608
+ "[RR %p] getting next ready subchannel (out of %" PRIuPTR
609
+ "), last_ready_index=%" PRIuPTR,
610
+ policy(), num_subchannels(), last_ready_index_);
445
611
  }
446
- // If we're still here, the notification must be for a subchannel in
447
- // either the current or latest pending subchannel lists.
448
- GPR_ASSERT(sd->subchannel_list == p->subchannel_list_ ||
449
- sd->subchannel_list == p->latest_pending_subchannel_list_);
450
- GPR_ASSERT(sd->pending_connectivity_state_unsafe != GRPC_CHANNEL_SHUTDOWN);
451
- // Now that we're inside the combiner, copy the pending connectivity
452
- // state (which was set by the connectivity state watcher) to
453
- // curr_connectivity_state, which is what we use inside of the combiner.
454
- sd->curr_connectivity_state = sd->pending_connectivity_state_unsafe;
455
- // If the sd's new state is TRANSIENT_FAILURE, unref the *connected*
456
- // subchannel, if any.
457
- switch (sd->curr_connectivity_state) {
458
- case GRPC_CHANNEL_TRANSIENT_FAILURE: {
459
- sd->connected_subchannel.reset();
460
- if (grpc_lb_round_robin_trace.enabled()) {
461
- gpr_log(GPR_DEBUG,
462
- "[RR %p] Subchannel %p has gone into TRANSIENT_FAILURE. "
463
- "Requesting re-resolution",
464
- p, sd->subchannel);
465
- }
466
- p->TryReresolutionLocked(&grpc_lb_round_robin_trace, GRPC_ERROR_NONE);
467
- break;
612
+ for (size_t i = 0; i < num_subchannels(); ++i) {
613
+ const size_t index = (i + last_ready_index_ + 1) % num_subchannels();
614
+ if (grpc_lb_round_robin_trace.enabled()) {
615
+ gpr_log(
616
+ GPR_INFO,
617
+ "[RR %p] checking subchannel %p, subchannel_list %p, index %" PRIuPTR
618
+ ": state=%s",
619
+ policy(), subchannel(index)->subchannel(), this, index,
620
+ grpc_connectivity_state_name(
621
+ subchannel(index)->connectivity_state()));
468
622
  }
469
- case GRPC_CHANNEL_READY: {
470
- if (sd->connected_subchannel == nullptr) {
471
- sd->connected_subchannel =
472
- grpc_subchannel_get_connected_subchannel(sd->subchannel);
473
- }
474
- if (sd->subchannel_list != p->subchannel_list_) {
475
- // promote sd->subchannel_list to p->subchannel_list_.
476
- // sd->subchannel_list must be equal to
477
- // p->latest_pending_subchannel_list_ because we have already filtered
478
- // for sds belonging to outdated subchannel lists.
479
- GPR_ASSERT(sd->subchannel_list == p->latest_pending_subchannel_list_);
480
- GPR_ASSERT(!sd->subchannel_list->shutting_down);
481
- if (grpc_lb_round_robin_trace.enabled()) {
482
- const size_t num_subchannels =
483
- p->subchannel_list_ != nullptr
484
- ? p->subchannel_list_->num_subchannels
485
- : 0;
486
- gpr_log(GPR_DEBUG,
487
- "[RR %p] phasing out subchannel list %p (size %" PRIuPTR
488
- ") in favor of %p (size %" PRIuPTR ")",
489
- p, p->subchannel_list_, num_subchannels, sd->subchannel_list,
490
- num_subchannels);
491
- }
492
- if (p->subchannel_list_ != nullptr) {
493
- // dispose of the current subchannel_list
494
- grpc_lb_subchannel_list_shutdown_and_unref(p->subchannel_list_,
495
- "sl_phase_out_shutdown");
496
- }
497
- p->subchannel_list_ = p->latest_pending_subchannel_list_;
498
- p->latest_pending_subchannel_list_ = nullptr;
499
- }
500
- /* at this point we know there's at least one suitable subchannel. Go
501
- * ahead and pick one and notify the pending suitors in
502
- * p->pending_picks. This preemptively replicates rr_pick()'s actions. */
503
- const size_t next_ready_index = p->GetNextReadySubchannelIndexLocked();
504
- GPR_ASSERT(next_ready_index < p->subchannel_list_->num_subchannels);
505
- grpc_lb_subchannel_data* selected =
506
- &p->subchannel_list_->subchannels[next_ready_index];
507
- if (p->pending_picks_ != nullptr) {
508
- // if the selected subchannel is going to be used for the pending
509
- // picks, update the last picked pointer
510
- p->UpdateLastReadySubchannelIndexLocked(next_ready_index);
511
- }
512
- PickState* pick;
513
- while ((pick = p->pending_picks_)) {
514
- p->pending_picks_ = pick->next;
515
- pick->connected_subchannel = selected->connected_subchannel;
516
- if (pick->user_data != nullptr) {
517
- *pick->user_data = selected->user_data;
518
- }
519
- if (grpc_lb_round_robin_trace.enabled()) {
520
- gpr_log(GPR_DEBUG,
521
- "[RR %p] Fulfilling pending pick. Target <-- subchannel %p "
522
- "(subchannel_list %p, index %" PRIuPTR ")",
523
- p, selected->subchannel, p->subchannel_list_,
524
- next_ready_index);
525
- }
526
- GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_NONE);
623
+ if (subchannel(index)->connectivity_state() == GRPC_CHANNEL_READY) {
624
+ if (grpc_lb_round_robin_trace.enabled()) {
625
+ gpr_log(GPR_INFO,
626
+ "[RR %p] found next ready subchannel (%p) at index %" PRIuPTR
627
+ " of subchannel_list %p",
628
+ policy(), subchannel(index)->subchannel(), index, this);
527
629
  }
528
- break;
630
+ return index;
529
631
  }
530
- case GRPC_CHANNEL_SHUTDOWN:
531
- GPR_UNREACHABLE_CODE(return );
532
- case GRPC_CHANNEL_CONNECTING:
533
- case GRPC_CHANNEL_IDLE:; // fallthrough
534
632
  }
535
- // Update state counters.
536
- UpdateStateCountersLocked(sd);
537
- // Only update connectivity based on the selected subchannel list.
538
- if (sd->subchannel_list == p->subchannel_list_) {
539
- p->UpdateConnectivityStatusLocked(sd, GRPC_ERROR_REF(error));
633
+ if (grpc_lb_round_robin_trace.enabled()) {
634
+ gpr_log(GPR_INFO, "[RR %p] no subchannels in ready state", this);
635
+ }
636
+ return num_subchannels();
637
+ }
638
+
639
+ // Sets last_ready_index_ to last_ready_index.
640
+ void RoundRobin::RoundRobinSubchannelList::UpdateLastReadySubchannelIndexLocked(
641
+ size_t last_ready_index) {
642
+ GPR_ASSERT(last_ready_index < num_subchannels());
643
+ last_ready_index_ = last_ready_index;
644
+ if (grpc_lb_round_robin_trace.enabled()) {
645
+ gpr_log(GPR_INFO,
646
+ "[RR %p] setting last_ready_subchannel_index=%" PRIuPTR
647
+ " (SC %p, CSC %p)",
648
+ policy(), last_ready_index,
649
+ subchannel(last_ready_index)->subchannel(),
650
+ subchannel(last_ready_index)->connected_subchannel());
540
651
  }
541
- // Renew notification.
542
- grpc_lb_subchannel_data_start_connectivity_watch(sd);
543
652
  }
544
653
 
545
654
  grpc_connectivity_state RoundRobin::CheckConnectivityLocked(
@@ -553,24 +662,10 @@ void RoundRobin::NotifyOnStateChangeLocked(grpc_connectivity_state* current,
553
662
  notify);
554
663
  }
555
664
 
556
- void RoundRobin::PingOneLocked(grpc_closure* on_initiate,
557
- grpc_closure* on_ack) {
558
- const size_t next_ready_index = GetNextReadySubchannelIndexLocked();
559
- if (next_ready_index < subchannel_list_->num_subchannels) {
560
- grpc_lb_subchannel_data* selected =
561
- &subchannel_list_->subchannels[next_ready_index];
562
- selected->connected_subchannel->Ping(on_initiate, on_ack);
563
- } else {
564
- GRPC_CLOSURE_SCHED(on_initiate, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
565
- "Round Robin not connected"));
566
- GRPC_CLOSURE_SCHED(on_ack, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
567
- "Round Robin not connected"));
568
- }
569
- }
570
-
571
665
  void RoundRobin::UpdateLocked(const grpc_channel_args& args) {
572
666
  const grpc_arg* arg = grpc_channel_args_find(&args, GRPC_ARG_LB_ADDRESSES);
573
- if (arg == nullptr || arg->type != GRPC_ARG_POINTER) {
667
+ AutoChildRefsUpdater guard(this);
668
+ if (GPR_UNLIKELY(arg == nullptr || arg->type != GRPC_ARG_POINTER)) {
574
669
  gpr_log(GPR_ERROR, "[RR %p] update provided no addresses; ignoring", this);
575
670
  // If we don't have a current subchannel list, go into TRANSIENT_FAILURE.
576
671
  // Otherwise, keep using the current subchannel list (ignore this update).
@@ -582,80 +677,37 @@ void RoundRobin::UpdateLocked(const grpc_channel_args& args) {
582
677
  }
583
678
  return;
584
679
  }
585
- grpc_lb_addresses* addresses = (grpc_lb_addresses*)arg->value.pointer.p;
680
+ grpc_lb_addresses* addresses =
681
+ static_cast<grpc_lb_addresses*>(arg->value.pointer.p);
586
682
  if (grpc_lb_round_robin_trace.enabled()) {
587
- gpr_log(GPR_DEBUG, "[RR %p] received update with %" PRIuPTR " addresses",
683
+ gpr_log(GPR_INFO, "[RR %p] received update with %" PRIuPTR " addresses",
588
684
  this, addresses->num_addresses);
589
685
  }
590
- grpc_lb_subchannel_list* subchannel_list = grpc_lb_subchannel_list_create(
591
- this, &grpc_lb_round_robin_trace, addresses, combiner(),
592
- client_channel_factory(), args, &RoundRobin::OnConnectivityChangedLocked);
593
- if (subchannel_list->num_subchannels == 0) {
594
- grpc_connectivity_state_set(
595
- &state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE,
596
- GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"),
597
- "rr_update_empty");
598
- if (subchannel_list_ != nullptr) {
599
- grpc_lb_subchannel_list_shutdown_and_unref(subchannel_list_,
600
- "sl_shutdown_empty_update");
686
+ // Replace latest_pending_subchannel_list_.
687
+ if (latest_pending_subchannel_list_ != nullptr) {
688
+ if (grpc_lb_round_robin_trace.enabled()) {
689
+ gpr_log(GPR_INFO,
690
+ "[RR %p] Shutting down previous pending subchannel list %p", this,
691
+ latest_pending_subchannel_list_.get());
601
692
  }
602
- subchannel_list_ = subchannel_list; // empty list
603
- return;
604
693
  }
605
- if (started_picking_) {
606
- for (size_t i = 0; i < subchannel_list->num_subchannels; ++i) {
607
- const grpc_connectivity_state subchannel_state =
608
- grpc_subchannel_check_connectivity(
609
- subchannel_list->subchannels[i].subchannel, nullptr);
610
- // Override the default setting of IDLE for connectivity notification
611
- // purposes if the subchannel is already in transient failure. Otherwise
612
- // we'd be immediately notified of the IDLE-TRANSIENT_FAILURE
613
- // discrepancy, attempt to re-resolve and end up here again.
614
- // TODO(roth): As part of C++-ifying the subchannel_list API, design a
615
- // better API for notifying the LB policy of subchannel states, which can
616
- // be used both for the subchannel's initial state and for subsequent
617
- // state changes. This will allow us to handle this more generally instead
618
- // of special-casing TRANSIENT_FAILURE (e.g., we can also distribute any
619
- // pending picks across all READY subchannels rather than sending them all
620
- // to the first one).
621
- if (subchannel_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
622
- subchannel_list->subchannels[i].pending_connectivity_state_unsafe =
623
- subchannel_list->subchannels[i].curr_connectivity_state =
624
- subchannel_list->subchannels[i].prev_connectivity_state =
625
- subchannel_state;
626
- --subchannel_list->num_idle;
627
- ++subchannel_list->num_transient_failures;
628
- }
629
- }
630
- if (latest_pending_subchannel_list_ != nullptr) {
631
- if (grpc_lb_round_robin_trace.enabled()) {
632
- gpr_log(GPR_DEBUG,
633
- "[RR %p] Shutting down latest pending subchannel list %p, "
634
- "about to be replaced by newer latest %p",
635
- this, latest_pending_subchannel_list_, subchannel_list);
636
- }
637
- grpc_lb_subchannel_list_shutdown_and_unref(
638
- latest_pending_subchannel_list_, "sl_outdated");
639
- }
640
- latest_pending_subchannel_list_ = subchannel_list;
641
- for (size_t i = 0; i < subchannel_list->num_subchannels; ++i) {
642
- /* Watch every new subchannel. A subchannel list becomes active the
643
- * moment one of its subchannels is READY. At that moment, we swap
644
- * p->subchannel_list for sd->subchannel_list, provided the subchannel
645
- * list is still valid (ie, isn't shutting down) */
646
- SubchannelListRefForConnectivityWatch(subchannel_list,
647
- "connectivity_watch");
648
- grpc_lb_subchannel_data_start_connectivity_watch(
649
- &subchannel_list->subchannels[i]);
694
+ latest_pending_subchannel_list_ = MakeOrphanable<RoundRobinSubchannelList>(
695
+ this, &grpc_lb_round_robin_trace, addresses, combiner(),
696
+ client_channel_factory(), args);
697
+ // If we haven't started picking yet or the new list is empty,
698
+ // immediately promote the new list to the current list.
699
+ if (!started_picking_ ||
700
+ latest_pending_subchannel_list_->num_subchannels() == 0) {
701
+ if (latest_pending_subchannel_list_->num_subchannels() == 0) {
702
+ grpc_connectivity_state_set(
703
+ &state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE,
704
+ GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"),
705
+ "rr_update_empty");
650
706
  }
707
+ subchannel_list_ = std::move(latest_pending_subchannel_list_);
651
708
  } else {
652
- // The policy isn't picking yet. Save the update for later, disposing of
653
- // previous version if any.
654
- if (subchannel_list_ != nullptr) {
655
- grpc_lb_subchannel_list_shutdown_and_unref(
656
- subchannel_list_, "rr_update_before_started_picking");
657
- }
658
- subchannel_list_ = subchannel_list;
709
+ // If we've started picking, start watching the new list.
710
+ latest_pending_subchannel_list_->StartWatchingLocked();
659
711
  }
660
712
  }
661
713