grpc 1.24.0 → 1.25.0

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 (505) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +306 -243
  3. data/etc/roots.pem +0 -100
  4. data/include/grpc/grpc_security.h +44 -18
  5. data/include/grpc/impl/codegen/grpc_types.h +15 -0
  6. data/include/grpc/impl/codegen/port_platform.h +27 -11
  7. data/include/grpc/impl/codegen/sync_generic.h +1 -1
  8. data/src/boringssl/err_data.c +695 -650
  9. data/src/core/ext/filters/client_channel/client_channel.cc +257 -179
  10. data/src/core/ext/filters/client_channel/client_channel.h +24 -0
  11. data/src/core/ext/filters/client_channel/client_channel_channelz.cc +2 -3
  12. data/src/core/ext/filters/client_channel/client_channel_factory.h +1 -5
  13. data/src/core/ext/filters/client_channel/health/health_check_client.cc +18 -45
  14. data/src/core/ext/filters/client_channel/health/health_check_client.h +5 -13
  15. data/src/core/ext/filters/client_channel/http_connect_handshaker.cc +1 -1
  16. data/src/core/ext/filters/client_channel/lb_policy.cc +2 -3
  17. data/src/core/ext/filters/client_channel/lb_policy.h +65 -55
  18. data/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc +14 -14
  19. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +113 -36
  20. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +14 -19
  21. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +36 -13
  22. data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +3 -10
  23. data/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +814 -1589
  24. data/src/core/ext/filters/client_channel/lb_policy/xds/xds.h +2 -5
  25. data/src/core/ext/filters/client_channel/lb_policy_factory.h +3 -6
  26. data/src/core/ext/filters/client_channel/resolver.cc +1 -2
  27. data/src/core/ext/filters/client_channel/resolver.h +8 -16
  28. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +25 -8
  29. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc +46 -12
  30. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h +10 -17
  31. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc +7 -8
  32. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc +4 -4
  33. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +111 -44
  34. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +22 -14
  35. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h +1 -1
  36. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc +2 -2
  37. data/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +29 -10
  38. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +27 -36
  39. data/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc +7 -10
  40. data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc +60 -16
  41. data/src/core/ext/filters/client_channel/resolver_factory.h +4 -8
  42. data/src/core/ext/filters/client_channel/resolver_registry.cc +1 -1
  43. data/src/core/ext/filters/client_channel/resolver_registry.h +1 -1
  44. data/src/core/ext/filters/client_channel/resolver_result_parsing.cc +7 -10
  45. data/src/core/ext/filters/client_channel/resolving_lb_policy.cc +7 -8
  46. data/src/core/ext/filters/client_channel/resolving_lb_policy.h +1 -1
  47. data/src/core/ext/filters/client_channel/retry_throttle.cc +5 -5
  48. data/src/core/ext/filters/client_channel/retry_throttle.h +1 -4
  49. data/src/core/ext/filters/client_channel/service_config.h +8 -8
  50. data/src/core/ext/filters/client_channel/subchannel.cc +53 -86
  51. data/src/core/ext/filters/client_channel/subchannel.h +7 -9
  52. data/src/core/ext/filters/client_channel/subchannel_interface.h +9 -13
  53. data/src/core/ext/filters/client_channel/subchannel_pool_interface.h +3 -6
  54. data/src/core/ext/filters/client_channel/{lb_policy/xds/xds_load_balancer_api.cc → xds/xds_api.cc} +169 -52
  55. data/src/core/ext/filters/client_channel/xds/xds_api.h +171 -0
  56. data/src/core/ext/filters/client_channel/xds/xds_bootstrap.cc +450 -0
  57. data/src/core/ext/filters/client_channel/xds/xds_bootstrap.h +99 -0
  58. data/src/core/ext/filters/client_channel/{lb_policy/xds → xds}/xds_channel.h +8 -6
  59. data/src/core/ext/filters/client_channel/xds/xds_channel_args.h +26 -0
  60. data/src/core/ext/filters/client_channel/{lb_policy/xds → xds}/xds_channel_secure.cc +28 -11
  61. data/src/core/ext/filters/client_channel/xds/xds_client.cc +1413 -0
  62. data/src/core/ext/filters/client_channel/xds/xds_client.h +221 -0
  63. data/src/core/ext/filters/client_channel/{lb_policy/xds → xds}/xds_client_stats.cc +1 -5
  64. data/src/core/ext/filters/client_channel/{lb_policy/xds → xds}/xds_client_stats.h +3 -4
  65. data/src/core/ext/filters/deadline/deadline_filter.cc +20 -20
  66. data/src/core/ext/filters/http/client/http_client_filter.cc +15 -15
  67. data/src/core/ext/filters/http/client_authority_filter.cc +14 -14
  68. data/src/core/ext/filters/http/message_compress/message_compress_filter.cc +12 -12
  69. data/src/core/ext/filters/max_age/max_age_filter.cc +59 -50
  70. data/src/core/ext/filters/message_size/message_size_filter.cc +18 -18
  71. data/src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc +15 -14
  72. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +233 -175
  73. data/src/core/ext/transport/chttp2/transport/flow_control.h +21 -24
  74. data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +253 -163
  75. data/src/core/ext/transport/chttp2/transport/hpack_encoder.h +24 -12
  76. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +2 -3
  77. data/src/core/ext/transport/chttp2/transport/internal.h +13 -15
  78. data/src/core/ext/transport/chttp2/transport/writing.cc +3 -0
  79. data/src/core/ext/transport/inproc/inproc_transport.cc +20 -13
  80. data/src/core/lib/channel/channel_args.cc +16 -0
  81. data/src/core/lib/channel/channel_args.h +22 -0
  82. data/src/core/lib/channel/channelz.cc +5 -6
  83. data/src/core/lib/channel/channelz.h +1 -1
  84. data/src/core/lib/channel/connected_channel.cc +20 -20
  85. data/src/core/lib/channel/handshaker.h +3 -4
  86. data/src/core/lib/channel/handshaker_factory.h +1 -3
  87. data/src/core/lib/debug/trace.h +3 -2
  88. data/src/core/lib/gprpp/arena.cc +3 -3
  89. data/src/core/lib/gprpp/arena.h +2 -3
  90. data/src/core/lib/gprpp/inlined_vector.h +9 -0
  91. data/src/core/lib/gprpp/map.h +3 -501
  92. data/src/core/lib/gprpp/memory.h +45 -41
  93. data/src/core/lib/gprpp/mpscq.cc +108 -0
  94. data/src/core/lib/gprpp/mpscq.h +98 -0
  95. data/src/core/lib/gprpp/orphanable.h +6 -11
  96. data/src/core/lib/gprpp/ref_counted.h +25 -19
  97. data/src/core/lib/gprpp/set.h +33 -0
  98. data/src/core/lib/gprpp/thd.h +2 -4
  99. data/src/core/lib/http/httpcli.cc +1 -1
  100. data/src/core/lib/http/httpcli_security_connector.cc +15 -11
  101. data/src/core/lib/http/parser.cc +1 -1
  102. data/src/core/lib/iomgr/buffer_list.cc +4 -5
  103. data/src/core/lib/iomgr/buffer_list.h +5 -6
  104. data/src/core/lib/iomgr/call_combiner.cc +4 -5
  105. data/src/core/lib/iomgr/call_combiner.h +2 -2
  106. data/src/core/lib/iomgr/cfstream_handle.h +3 -5
  107. data/src/core/lib/iomgr/closure.h +8 -3
  108. data/src/core/lib/iomgr/combiner.cc +45 -82
  109. data/src/core/lib/iomgr/combiner.h +32 -8
  110. data/src/core/lib/iomgr/endpoint_cfstream.cc +5 -3
  111. data/src/core/lib/iomgr/ev_epoll1_linux.cc +19 -15
  112. data/src/core/lib/iomgr/ev_poll_posix.cc +3 -1
  113. data/src/core/lib/iomgr/exec_ctx.h +4 -3
  114. data/src/core/lib/iomgr/executor.cc +4 -2
  115. data/src/core/lib/iomgr/executor.h +3 -0
  116. data/src/core/lib/iomgr/executor/mpmcqueue.h +3 -6
  117. data/src/core/lib/iomgr/executor/threadpool.cc +1 -2
  118. data/src/core/lib/iomgr/executor/threadpool.h +7 -11
  119. data/src/core/lib/iomgr/resource_quota.cc +55 -51
  120. data/src/core/lib/iomgr/resource_quota.h +13 -9
  121. data/src/core/lib/iomgr/socket_utils_common_posix.cc +13 -0
  122. data/src/core/lib/iomgr/socket_utils_posix.h +4 -0
  123. data/src/core/lib/iomgr/tcp_client_posix.cc +4 -11
  124. data/src/core/lib/iomgr/tcp_custom.cc +9 -7
  125. data/src/core/lib/iomgr/tcp_posix.cc +20 -16
  126. data/src/core/lib/iomgr/tcp_server.h +1 -4
  127. data/src/core/lib/iomgr/tcp_server_custom.cc +5 -5
  128. data/src/core/lib/iomgr/tcp_server_posix.cc +1 -1
  129. data/src/core/lib/iomgr/tcp_server_utils_posix_common.cc +2 -11
  130. data/src/core/lib/iomgr/timer_custom.cc +2 -2
  131. data/src/core/lib/iomgr/udp_server.cc +3 -2
  132. data/src/core/lib/iomgr/udp_server.h +6 -12
  133. data/src/core/lib/json/json.h +1 -1
  134. data/src/core/lib/json/json_string.cc +2 -2
  135. data/src/core/lib/profiling/basic_timers.cc +2 -2
  136. data/src/core/lib/security/credentials/alts/alts_credentials.cc +2 -2
  137. data/src/core/lib/security/credentials/alts/grpc_alts_credentials_server_options.cc +1 -1
  138. data/src/core/lib/security/credentials/credentials.h +4 -20
  139. data/src/core/lib/security/credentials/fake/fake_credentials.cc +4 -4
  140. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.h +1 -3
  141. data/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h +64 -0
  142. data/src/core/lib/security/security_connector/alts/alts_security_connector.cc +4 -4
  143. data/src/core/lib/security/security_connector/fake/fake_security_connector.cc +9 -7
  144. data/src/core/lib/security/security_connector/load_system_roots_linux.cc +2 -0
  145. data/src/core/lib/security/security_connector/local/local_security_connector.cc +4 -4
  146. data/src/core/lib/security/security_connector/security_connector.cc +1 -0
  147. data/src/core/lib/security/security_connector/security_connector.h +19 -17
  148. data/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc +8 -5
  149. data/src/core/lib/security/security_connector/ssl_utils.cc +2 -2
  150. data/src/core/lib/security/security_connector/ssl_utils.h +1 -1
  151. data/src/core/lib/security/security_connector/tls/spiffe_security_connector.cc +14 -6
  152. data/src/core/lib/security/security_connector/tls/spiffe_security_connector.h +4 -2
  153. data/src/core/lib/security/transport/client_auth_filter.cc +17 -17
  154. data/src/core/lib/security/transport/security_handshaker.cc +29 -13
  155. data/src/core/lib/security/transport/security_handshaker.h +4 -2
  156. data/src/core/lib/security/transport/server_auth_filter.cc +14 -14
  157. data/src/core/lib/slice/slice.cc +2 -10
  158. data/src/core/lib/slice/slice_hash_table.h +4 -6
  159. data/src/core/lib/slice/slice_intern.cc +42 -39
  160. data/src/core/lib/slice/slice_internal.h +3 -3
  161. data/src/core/lib/slice/slice_utils.h +21 -4
  162. data/src/core/lib/slice/slice_weak_hash_table.h +4 -6
  163. data/src/core/lib/surface/call.cc +3 -3
  164. data/src/core/lib/surface/channel.cc +7 -0
  165. data/src/core/lib/surface/completion_queue.cc +12 -11
  166. data/src/core/lib/surface/completion_queue.h +4 -2
  167. data/src/core/lib/surface/init.cc +1 -0
  168. data/src/core/lib/surface/lame_client.cc +33 -18
  169. data/src/core/lib/surface/server.cc +77 -76
  170. data/src/core/lib/surface/version.cc +1 -1
  171. data/src/core/lib/transport/byte_stream.h +3 -7
  172. data/src/core/lib/transport/connectivity_state.cc +112 -98
  173. data/src/core/lib/transport/connectivity_state.h +100 -50
  174. data/src/core/lib/transport/static_metadata.cc +276 -288
  175. data/src/core/lib/transport/static_metadata.h +73 -76
  176. data/src/core/lib/transport/status_conversion.cc +1 -1
  177. data/src/core/lib/transport/status_metadata.cc +1 -1
  178. data/src/core/lib/transport/transport.cc +2 -2
  179. data/src/core/lib/transport/transport.h +12 -4
  180. data/src/core/lib/transport/transport_op_string.cc +14 -11
  181. data/src/core/tsi/alts/frame_protector/alts_unseal_privacy_integrity_crypter.cc +1 -1
  182. data/src/core/tsi/alts/handshaker/alts_shared_resource.cc +1 -1
  183. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +5 -5
  184. data/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc +12 -2
  185. data/src/core/tsi/fake_transport_security.cc +7 -5
  186. data/src/core/tsi/grpc_shadow_boringssl.h +2918 -2627
  187. data/src/core/tsi/local_transport_security.cc +8 -6
  188. data/src/core/tsi/ssl/session_cache/ssl_session.h +1 -3
  189. data/src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc +1 -2
  190. data/src/core/tsi/ssl/session_cache/ssl_session_cache.cc +7 -5
  191. data/src/core/tsi/ssl/session_cache/ssl_session_cache.h +4 -6
  192. data/src/core/tsi/ssl/session_cache/ssl_session_openssl.cc +1 -2
  193. data/src/core/tsi/ssl_transport_security.cc +12 -12
  194. data/src/core/tsi/ssl_transport_security.h +2 -2
  195. data/src/core/tsi/transport_security_grpc.cc +7 -0
  196. data/src/core/tsi/transport_security_grpc.h +6 -0
  197. data/src/ruby/ext/grpc/extconf.rb +1 -0
  198. data/src/ruby/ext/grpc/rb_call.c +1 -1
  199. data/src/ruby/ext/grpc/rb_channel.c +1 -1
  200. data/src/ruby/lib/grpc/generic/bidi_call.rb +1 -1
  201. data/src/ruby/lib/grpc/generic/rpc_server.rb +1 -1
  202. data/src/ruby/lib/grpc/version.rb +1 -1
  203. data/src/ruby/spec/google_rpc_status_utils_spec.rb +2 -2
  204. data/third_party/boringssl/crypto/asn1/a_bool.c +18 -5
  205. data/third_party/boringssl/crypto/asn1/a_d2i_fp.c +17 -221
  206. data/third_party/boringssl/crypto/asn1/a_dup.c +0 -24
  207. data/third_party/boringssl/crypto/asn1/a_enum.c +2 -2
  208. data/third_party/boringssl/crypto/asn1/a_i2d_fp.c +10 -72
  209. data/third_party/boringssl/crypto/asn1/a_int.c +12 -71
  210. data/third_party/boringssl/crypto/asn1/a_mbstr.c +110 -216
  211. data/third_party/boringssl/crypto/asn1/a_object.c +16 -5
  212. data/third_party/boringssl/crypto/asn1/a_strnid.c +1 -0
  213. data/third_party/boringssl/crypto/asn1/asn1_lib.c +5 -1
  214. data/third_party/boringssl/crypto/asn1/tasn_enc.c +3 -1
  215. data/third_party/boringssl/crypto/base64/base64.c +2 -2
  216. data/third_party/boringssl/crypto/bio/bio.c +73 -9
  217. data/third_party/boringssl/crypto/bio/connect.c +4 -0
  218. data/third_party/boringssl/crypto/bio/fd.c +4 -0
  219. data/third_party/boringssl/crypto/bio/file.c +5 -2
  220. data/third_party/boringssl/crypto/bio/socket.c +4 -0
  221. data/third_party/boringssl/crypto/bio/socket_helper.c +4 -0
  222. data/third_party/boringssl/crypto/bn_extra/convert.c +11 -7
  223. data/third_party/boringssl/crypto/bytestring/ber.c +8 -4
  224. data/third_party/boringssl/crypto/bytestring/cbb.c +19 -7
  225. data/third_party/boringssl/crypto/bytestring/cbs.c +28 -15
  226. data/third_party/boringssl/crypto/bytestring/internal.h +28 -7
  227. data/third_party/boringssl/crypto/bytestring/unicode.c +155 -0
  228. data/third_party/boringssl/crypto/chacha/chacha.c +36 -19
  229. data/third_party/boringssl/crypto/chacha/internal.h +45 -0
  230. data/third_party/boringssl/crypto/cipher_extra/cipher_extra.c +29 -0
  231. data/third_party/boringssl/crypto/cipher_extra/e_aesccm.c +269 -25
  232. data/third_party/boringssl/crypto/cipher_extra/e_aesctrhmac.c +16 -14
  233. data/third_party/boringssl/crypto/cipher_extra/e_aesgcmsiv.c +54 -38
  234. data/third_party/boringssl/crypto/cipher_extra/e_chacha20poly1305.c +133 -41
  235. data/third_party/boringssl/crypto/cipher_extra/e_tls.c +23 -15
  236. data/third_party/boringssl/crypto/cipher_extra/tls_cbc.c +24 -15
  237. data/third_party/boringssl/crypto/cmac/cmac.c +62 -25
  238. data/third_party/boringssl/crypto/conf/conf.c +7 -0
  239. data/third_party/boringssl/crypto/cpu-arm-linux.c +4 -148
  240. data/third_party/boringssl/crypto/cpu-arm-linux.h +201 -0
  241. data/third_party/boringssl/crypto/cpu-intel.c +45 -51
  242. data/third_party/boringssl/crypto/crypto.c +39 -22
  243. data/third_party/boringssl/crypto/curve25519/spake25519.c +1 -1
  244. data/third_party/boringssl/crypto/dsa/dsa.c +77 -53
  245. data/third_party/boringssl/crypto/ec_extra/ec_asn1.c +20 -8
  246. data/third_party/boringssl/crypto/ec_extra/ec_derive.c +96 -0
  247. data/third_party/boringssl/crypto/{ecdh/ecdh.c → ecdh_extra/ecdh_extra.c} +20 -58
  248. data/third_party/boringssl/crypto/ecdsa_extra/ecdsa_asn1.c +1 -9
  249. data/third_party/boringssl/crypto/engine/engine.c +2 -1
  250. data/third_party/boringssl/crypto/err/err.c +2 -0
  251. data/third_party/boringssl/crypto/err/internal.h +2 -2
  252. data/third_party/boringssl/crypto/evp/evp.c +89 -8
  253. data/third_party/boringssl/crypto/evp/evp_asn1.c +56 -5
  254. data/third_party/boringssl/crypto/evp/evp_ctx.c +52 -14
  255. data/third_party/boringssl/crypto/evp/internal.h +18 -1
  256. data/third_party/boringssl/crypto/evp/p_dsa_asn1.c +5 -0
  257. data/third_party/boringssl/crypto/evp/p_ec.c +51 -3
  258. data/third_party/boringssl/crypto/evp/p_ec_asn1.c +6 -7
  259. data/third_party/boringssl/crypto/evp/p_ed25519.c +36 -3
  260. data/third_party/boringssl/crypto/evp/p_ed25519_asn1.c +76 -45
  261. data/third_party/boringssl/crypto/evp/p_rsa.c +3 -1
  262. data/third_party/boringssl/crypto/evp/p_rsa_asn1.c +5 -0
  263. data/third_party/boringssl/crypto/evp/p_x25519.c +110 -0
  264. data/third_party/boringssl/crypto/evp/p_x25519_asn1.c +249 -0
  265. data/third_party/boringssl/crypto/evp/scrypt.c +6 -2
  266. data/third_party/boringssl/crypto/fipsmodule/aes/aes.c +34 -274
  267. data/third_party/boringssl/crypto/fipsmodule/aes/internal.h +161 -21
  268. data/third_party/boringssl/crypto/fipsmodule/aes/key_wrap.c +111 -13
  269. data/third_party/boringssl/crypto/fipsmodule/aes/mode_wrappers.c +17 -21
  270. data/third_party/boringssl/crypto/fipsmodule/bcm.c +119 -7
  271. data/third_party/boringssl/crypto/fipsmodule/bn/bn.c +19 -2
  272. data/third_party/boringssl/crypto/fipsmodule/bn/cmp.c +2 -2
  273. data/third_party/boringssl/crypto/fipsmodule/bn/ctx.c +93 -160
  274. data/third_party/boringssl/crypto/fipsmodule/bn/div.c +48 -57
  275. data/third_party/boringssl/crypto/fipsmodule/bn/div_extra.c +87 -0
  276. data/third_party/boringssl/crypto/fipsmodule/bn/exponentiation.c +143 -211
  277. data/third_party/boringssl/crypto/fipsmodule/bn/gcd.c +0 -305
  278. data/third_party/boringssl/crypto/fipsmodule/bn/gcd_extra.c +325 -0
  279. data/third_party/boringssl/crypto/fipsmodule/bn/internal.h +168 -50
  280. data/third_party/boringssl/crypto/fipsmodule/bn/montgomery.c +68 -92
  281. data/third_party/boringssl/crypto/fipsmodule/bn/montgomery_inv.c +7 -6
  282. data/third_party/boringssl/crypto/fipsmodule/bn/mul.c +11 -14
  283. data/third_party/boringssl/crypto/fipsmodule/bn/prime.c +358 -443
  284. data/third_party/boringssl/crypto/fipsmodule/bn/random.c +25 -35
  285. data/third_party/boringssl/crypto/fipsmodule/bn/rsaz_exp.c +20 -25
  286. data/third_party/boringssl/crypto/fipsmodule/bn/rsaz_exp.h +76 -5
  287. data/third_party/boringssl/crypto/fipsmodule/bn/shift.c +14 -14
  288. data/third_party/boringssl/crypto/fipsmodule/cipher/cipher.c +7 -2
  289. data/third_party/boringssl/crypto/fipsmodule/cipher/e_aes.c +383 -516
  290. data/third_party/boringssl/crypto/fipsmodule/cipher/e_des.c +4 -0
  291. data/third_party/boringssl/crypto/fipsmodule/cipher/internal.h +3 -4
  292. data/third_party/boringssl/crypto/fipsmodule/delocate.h +3 -2
  293. data/third_party/boringssl/crypto/fipsmodule/digest/digest.c +32 -17
  294. data/third_party/boringssl/crypto/fipsmodule/digest/md32_common.h +3 -3
  295. data/third_party/boringssl/crypto/fipsmodule/ec/ec.c +228 -122
  296. data/third_party/boringssl/crypto/fipsmodule/ec/ec_key.c +34 -8
  297. data/third_party/boringssl/crypto/fipsmodule/ec/ec_montgomery.c +311 -98
  298. data/third_party/boringssl/crypto/fipsmodule/ec/felem.c +82 -0
  299. data/third_party/boringssl/crypto/fipsmodule/ec/internal.h +263 -97
  300. data/third_party/boringssl/crypto/fipsmodule/ec/oct.c +22 -59
  301. data/third_party/boringssl/crypto/fipsmodule/ec/p224-64.c +317 -234
  302. data/third_party/boringssl/crypto/fipsmodule/ec/p256-x86_64-table.h +9473 -9475
  303. data/third_party/boringssl/crypto/fipsmodule/ec/p256-x86_64.c +313 -109
  304. data/third_party/boringssl/crypto/fipsmodule/ec/p256-x86_64.h +36 -0
  305. data/third_party/boringssl/crypto/fipsmodule/ec/scalar.c +96 -0
  306. data/third_party/boringssl/crypto/fipsmodule/ec/simple.c +126 -792
  307. data/third_party/boringssl/crypto/fipsmodule/ec/simple_mul.c +84 -0
  308. data/third_party/boringssl/crypto/fipsmodule/ec/util.c +163 -12
  309. data/third_party/boringssl/crypto/fipsmodule/ec/wnaf.c +84 -211
  310. data/third_party/boringssl/crypto/fipsmodule/ecdh/ecdh.c +122 -0
  311. data/third_party/boringssl/crypto/fipsmodule/ecdsa/ecdsa.c +60 -205
  312. data/third_party/boringssl/crypto/fipsmodule/fips_shared_support.c +32 -0
  313. data/third_party/boringssl/crypto/fipsmodule/is_fips.c +2 -0
  314. data/third_party/boringssl/crypto/fipsmodule/md4/md4.c +3 -1
  315. data/third_party/boringssl/crypto/fipsmodule/md5/internal.h +37 -0
  316. data/third_party/boringssl/crypto/fipsmodule/md5/md5.c +11 -8
  317. data/third_party/boringssl/crypto/fipsmodule/modes/cbc.c +35 -79
  318. data/third_party/boringssl/crypto/fipsmodule/modes/cfb.c +7 -39
  319. data/third_party/boringssl/crypto/fipsmodule/modes/ctr.c +7 -27
  320. data/third_party/boringssl/crypto/fipsmodule/modes/gcm.c +123 -309
  321. data/third_party/boringssl/crypto/fipsmodule/modes/internal.h +189 -126
  322. data/third_party/boringssl/crypto/fipsmodule/modes/ofb.c +3 -2
  323. data/third_party/boringssl/crypto/fipsmodule/rand/ctrdrbg.c +2 -2
  324. data/third_party/boringssl/crypto/fipsmodule/rand/internal.h +35 -0
  325. data/third_party/boringssl/crypto/fipsmodule/rand/rand.c +24 -19
  326. data/third_party/boringssl/crypto/fipsmodule/rand/urandom.c +256 -77
  327. data/third_party/boringssl/crypto/fipsmodule/rsa/padding.c +10 -7
  328. data/third_party/boringssl/crypto/fipsmodule/rsa/rsa.c +5 -1
  329. data/third_party/boringssl/crypto/fipsmodule/rsa/rsa_impl.c +131 -14
  330. data/third_party/boringssl/crypto/fipsmodule/self_check/self_check.c +83 -10
  331. data/third_party/boringssl/crypto/fipsmodule/sha/internal.h +53 -0
  332. data/third_party/boringssl/crypto/fipsmodule/sha/sha1.c +9 -13
  333. data/third_party/boringssl/crypto/fipsmodule/sha/sha256.c +18 -12
  334. data/third_party/boringssl/crypto/fipsmodule/sha/sha512.c +95 -168
  335. data/third_party/boringssl/crypto/hrss/hrss.c +2201 -0
  336. data/third_party/boringssl/crypto/hrss/internal.h +62 -0
  337. data/third_party/boringssl/crypto/internal.h +95 -20
  338. data/third_party/boringssl/crypto/lhash/lhash.c +45 -33
  339. data/third_party/boringssl/crypto/mem.c +39 -2
  340. data/third_party/boringssl/crypto/obj/obj.c +4 -4
  341. data/third_party/boringssl/crypto/obj/obj_dat.h +6181 -875
  342. data/third_party/boringssl/crypto/pem/pem_all.c +2 -3
  343. data/third_party/boringssl/crypto/pem/pem_info.c +144 -162
  344. data/third_party/boringssl/crypto/pem/pem_lib.c +53 -52
  345. data/third_party/boringssl/crypto/pem/pem_pkey.c +13 -21
  346. data/third_party/boringssl/crypto/pkcs7/pkcs7.c +15 -22
  347. data/third_party/boringssl/crypto/pkcs7/pkcs7_x509.c +168 -16
  348. data/third_party/boringssl/crypto/pkcs8/internal.h +11 -0
  349. data/third_party/boringssl/crypto/pkcs8/p5_pbev2.c +24 -15
  350. data/third_party/boringssl/crypto/pkcs8/pkcs8.c +42 -25
  351. data/third_party/boringssl/crypto/pkcs8/pkcs8_x509.c +559 -43
  352. data/third_party/boringssl/crypto/pool/internal.h +1 -1
  353. data/third_party/boringssl/crypto/pool/pool.c +21 -0
  354. data/third_party/boringssl/crypto/rand_extra/deterministic.c +8 -0
  355. data/third_party/boringssl/crypto/rand_extra/fuchsia.c +1 -14
  356. data/third_party/boringssl/crypto/refcount_lock.c +2 -2
  357. data/third_party/boringssl/crypto/rsa_extra/rsa_print.c +22 -0
  358. data/third_party/boringssl/crypto/siphash/siphash.c +80 -0
  359. data/third_party/boringssl/crypto/stack/stack.c +83 -32
  360. data/third_party/boringssl/crypto/thread_none.c +2 -2
  361. data/third_party/boringssl/crypto/thread_pthread.c +2 -2
  362. data/third_party/boringssl/crypto/thread_win.c +38 -19
  363. data/third_party/boringssl/crypto/x509/a_strex.c +22 -2
  364. data/third_party/boringssl/crypto/x509/asn1_gen.c +2 -1
  365. data/third_party/boringssl/crypto/x509/by_dir.c +7 -0
  366. data/third_party/boringssl/crypto/x509/by_file.c +12 -10
  367. data/third_party/boringssl/crypto/x509/t_crl.c +5 -8
  368. data/third_party/boringssl/crypto/x509/t_req.c +1 -3
  369. data/third_party/boringssl/crypto/x509/t_x509.c +5 -8
  370. data/third_party/boringssl/crypto/x509/x509_cmp.c +1 -1
  371. data/third_party/boringssl/crypto/x509/x509_def.c +1 -1
  372. data/third_party/boringssl/crypto/x509/x509_lu.c +114 -5
  373. data/third_party/boringssl/crypto/x509/x509_req.c +20 -0
  374. data/third_party/boringssl/crypto/x509/x509_set.c +5 -0
  375. data/third_party/boringssl/crypto/x509/x509_trs.c +1 -0
  376. data/third_party/boringssl/crypto/x509/x509_txt.c +4 -5
  377. data/third_party/boringssl/crypto/x509/x509_vfy.c +145 -138
  378. data/third_party/boringssl/crypto/x509/x509_vpm.c +2 -0
  379. data/third_party/boringssl/crypto/x509/x509cset.c +40 -0
  380. data/third_party/boringssl/crypto/x509/x509name.c +2 -3
  381. data/third_party/boringssl/crypto/x509/x_all.c +109 -210
  382. data/third_party/boringssl/crypto/x509/x_x509.c +6 -0
  383. data/third_party/boringssl/crypto/x509v3/ext_dat.h +1 -3
  384. data/third_party/boringssl/crypto/x509v3/internal.h +56 -0
  385. data/third_party/boringssl/crypto/x509v3/pcy_cache.c +2 -0
  386. data/third_party/boringssl/crypto/x509v3/pcy_node.c +1 -0
  387. data/third_party/boringssl/crypto/x509v3/pcy_tree.c +4 -2
  388. data/third_party/boringssl/crypto/x509v3/v3_akey.c +5 -2
  389. data/third_party/boringssl/crypto/x509v3/v3_alt.c +19 -13
  390. data/third_party/boringssl/crypto/x509v3/v3_conf.c +2 -1
  391. data/third_party/boringssl/crypto/x509v3/v3_cpols.c +3 -2
  392. data/third_party/boringssl/crypto/x509v3/v3_genn.c +1 -6
  393. data/third_party/boringssl/crypto/x509v3/v3_lib.c +1 -0
  394. data/third_party/boringssl/crypto/x509v3/v3_ocsp.c +68 -0
  395. data/third_party/boringssl/crypto/x509v3/v3_pci.c +2 -1
  396. data/third_party/boringssl/crypto/x509v3/v3_purp.c +47 -69
  397. data/third_party/boringssl/crypto/x509v3/v3_skey.c +5 -2
  398. data/third_party/boringssl/crypto/x509v3/v3_utl.c +69 -25
  399. data/third_party/boringssl/include/openssl/aead.h +45 -19
  400. data/third_party/boringssl/include/openssl/aes.h +32 -7
  401. data/third_party/boringssl/include/openssl/asn1.h +7 -77
  402. data/third_party/boringssl/include/openssl/base.h +120 -6
  403. data/third_party/boringssl/include/openssl/base64.h +4 -1
  404. data/third_party/boringssl/include/openssl/bio.h +112 -81
  405. data/third_party/boringssl/include/openssl/blowfish.h +3 -3
  406. data/third_party/boringssl/include/openssl/bn.h +55 -29
  407. data/third_party/boringssl/include/openssl/buf.h +2 -2
  408. data/third_party/boringssl/include/openssl/bytestring.h +54 -32
  409. data/third_party/boringssl/include/openssl/cast.h +2 -2
  410. data/third_party/boringssl/include/openssl/cipher.h +46 -16
  411. data/third_party/boringssl/include/openssl/cmac.h +6 -2
  412. data/third_party/boringssl/include/openssl/conf.h +3 -6
  413. data/third_party/boringssl/include/openssl/cpu.h +25 -9
  414. data/third_party/boringssl/include/openssl/crypto.h +32 -10
  415. data/third_party/boringssl/include/openssl/curve25519.h +4 -4
  416. data/third_party/boringssl/include/openssl/dh.h +3 -2
  417. data/third_party/boringssl/include/openssl/digest.h +21 -7
  418. data/third_party/boringssl/include/openssl/dsa.h +8 -2
  419. data/third_party/boringssl/include/openssl/e_os2.h +18 -0
  420. data/third_party/boringssl/include/openssl/ec.h +25 -21
  421. data/third_party/boringssl/include/openssl/ec_key.h +36 -8
  422. data/third_party/boringssl/include/openssl/ecdh.h +17 -0
  423. data/third_party/boringssl/include/openssl/ecdsa.h +3 -3
  424. data/third_party/boringssl/include/openssl/engine.h +4 -4
  425. data/third_party/boringssl/include/openssl/err.h +3 -0
  426. data/third_party/boringssl/include/openssl/evp.h +199 -42
  427. data/third_party/boringssl/include/openssl/hmac.h +4 -4
  428. data/third_party/boringssl/include/openssl/hrss.h +100 -0
  429. data/third_party/boringssl/include/openssl/lhash.h +131 -23
  430. data/third_party/boringssl/include/openssl/md4.h +6 -4
  431. data/third_party/boringssl/include/openssl/md5.h +6 -4
  432. data/third_party/boringssl/include/openssl/mem.h +6 -2
  433. data/third_party/boringssl/include/openssl/nid.h +3 -0
  434. data/third_party/boringssl/include/openssl/obj.h +3 -0
  435. data/third_party/boringssl/include/openssl/pem.h +102 -64
  436. data/third_party/boringssl/include/openssl/pkcs7.h +136 -3
  437. data/third_party/boringssl/include/openssl/pkcs8.h +42 -3
  438. data/third_party/boringssl/include/openssl/pool.h +13 -2
  439. data/third_party/boringssl/include/openssl/ripemd.h +5 -4
  440. data/third_party/boringssl/include/openssl/rsa.h +46 -15
  441. data/third_party/boringssl/include/openssl/sha.h +40 -28
  442. data/third_party/boringssl/include/openssl/siphash.h +37 -0
  443. data/third_party/boringssl/include/openssl/span.h +17 -9
  444. data/third_party/boringssl/include/openssl/ssl.h +766 -393
  445. data/third_party/boringssl/include/openssl/ssl3.h +4 -3
  446. data/third_party/boringssl/include/openssl/stack.h +134 -77
  447. data/third_party/boringssl/include/openssl/thread.h +1 -1
  448. data/third_party/boringssl/include/openssl/tls1.h +25 -9
  449. data/third_party/boringssl/include/openssl/type_check.h +14 -15
  450. data/third_party/boringssl/include/openssl/x509.h +28 -3
  451. data/third_party/boringssl/include/openssl/x509_vfy.h +98 -32
  452. data/third_party/boringssl/include/openssl/x509v3.h +17 -13
  453. data/third_party/boringssl/ssl/d1_both.cc +9 -18
  454. data/third_party/boringssl/ssl/d1_lib.cc +4 -3
  455. data/third_party/boringssl/ssl/d1_pkt.cc +4 -4
  456. data/third_party/boringssl/ssl/d1_srtp.cc +15 -15
  457. data/third_party/boringssl/ssl/dtls_method.cc +0 -1
  458. data/third_party/boringssl/ssl/dtls_record.cc +28 -28
  459. data/third_party/boringssl/ssl/handoff.cc +295 -91
  460. data/third_party/boringssl/ssl/handshake.cc +133 -72
  461. data/third_party/boringssl/ssl/handshake_client.cc +218 -189
  462. data/third_party/boringssl/ssl/handshake_server.cc +399 -272
  463. data/third_party/boringssl/ssl/internal.h +1413 -928
  464. data/third_party/boringssl/ssl/s3_both.cc +175 -36
  465. data/third_party/boringssl/ssl/s3_lib.cc +9 -13
  466. data/third_party/boringssl/ssl/s3_pkt.cc +63 -29
  467. data/third_party/boringssl/ssl/ssl_aead_ctx.cc +55 -35
  468. data/third_party/boringssl/ssl/ssl_asn1.cc +57 -73
  469. data/third_party/boringssl/ssl/ssl_buffer.cc +13 -12
  470. data/third_party/boringssl/ssl/ssl_cert.cc +313 -210
  471. data/third_party/boringssl/ssl/ssl_cipher.cc +159 -221
  472. data/third_party/boringssl/ssl/ssl_file.cc +2 -0
  473. data/third_party/boringssl/ssl/ssl_key_share.cc +164 -19
  474. data/third_party/boringssl/ssl/ssl_lib.cc +847 -555
  475. data/third_party/boringssl/ssl/ssl_privkey.cc +441 -111
  476. data/third_party/boringssl/ssl/ssl_session.cc +230 -178
  477. data/third_party/boringssl/ssl/ssl_transcript.cc +21 -142
  478. data/third_party/boringssl/ssl/ssl_versions.cc +88 -93
  479. data/third_party/boringssl/ssl/ssl_x509.cc +279 -218
  480. data/third_party/boringssl/ssl/t1_enc.cc +5 -96
  481. data/third_party/boringssl/ssl/t1_lib.cc +931 -678
  482. data/third_party/boringssl/ssl/tls13_both.cc +251 -121
  483. data/third_party/boringssl/ssl/tls13_client.cc +129 -73
  484. data/third_party/boringssl/ssl/tls13_enc.cc +350 -282
  485. data/third_party/boringssl/ssl/tls13_server.cc +259 -192
  486. data/third_party/boringssl/ssl/tls_method.cc +26 -21
  487. data/third_party/boringssl/ssl/tls_record.cc +42 -47
  488. data/third_party/boringssl/third_party/fiat/curve25519.c +261 -1324
  489. data/third_party/boringssl/third_party/fiat/curve25519_32.h +911 -0
  490. data/third_party/boringssl/third_party/fiat/curve25519_64.h +559 -0
  491. data/third_party/boringssl/third_party/fiat/p256.c +238 -999
  492. data/third_party/boringssl/third_party/fiat/p256_32.h +3226 -0
  493. data/third_party/boringssl/third_party/fiat/p256_64.h +1217 -0
  494. data/third_party/upb/upb/port_def.inc +1 -1
  495. data/third_party/upb/upb/table.c +2 -1
  496. metadata +72 -44
  497. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h +0 -127
  498. data/src/core/lib/gpr/mpscq.cc +0 -117
  499. data/src/core/lib/gpr/mpscq.h +0 -88
  500. data/src/core/lib/gprpp/abstract.h +0 -47
  501. data/src/core/lib/gprpp/pair.h +0 -38
  502. data/third_party/boringssl/crypto/cipher_extra/e_ssl3.c +0 -460
  503. data/third_party/boringssl/crypto/fipsmodule/modes/ccm.c +0 -256
  504. data/third_party/boringssl/include/openssl/lhash_macros.h +0 -174
  505. data/third_party/boringssl/ssl/custom_extensions.cc +0 -265
@@ -88,14 +88,21 @@ class RoundRobin : public LoadBalancingPolicy {
88
88
  return last_connectivity_state_;
89
89
  }
90
90
 
91
+ bool seen_failure_since_ready() const { return seen_failure_since_ready_; }
92
+
93
+ // Performs connectivity state updates that need to be done both when we
94
+ // first start watching and when a watcher notification is received.
91
95
  void UpdateConnectivityStateLocked(
92
96
  grpc_connectivity_state connectivity_state);
93
97
 
94
98
  private:
99
+ // Performs connectivity state updates that need to be done only
100
+ // after we have started watching.
95
101
  void ProcessConnectivityChangeLocked(
96
102
  grpc_connectivity_state connectivity_state) override;
97
103
 
98
104
  grpc_connectivity_state last_connectivity_state_ = GRPC_CHANNEL_IDLE;
105
+ bool seen_failure_since_ready_ = false;
99
106
  };
100
107
 
101
108
  // A list of subchannels.
@@ -314,13 +321,13 @@ void RoundRobin::RoundRobinSubchannelList::
314
321
  */
315
322
  if (num_ready_ > 0) {
316
323
  /* 1) READY */
317
- p->channel_control_helper()->UpdateState(
318
- GRPC_CHANNEL_READY, UniquePtr<SubchannelPicker>(New<Picker>(p, this)));
324
+ p->channel_control_helper()->UpdateState(GRPC_CHANNEL_READY,
325
+ MakeUnique<Picker>(p, this));
319
326
  } else if (num_connecting_ > 0) {
320
327
  /* 2) CONNECTING */
321
328
  p->channel_control_helper()->UpdateState(
322
- GRPC_CHANNEL_CONNECTING, UniquePtr<SubchannelPicker>(New<QueuePicker>(
323
- p->Ref(DEBUG_LOCATION, "QueuePicker"))));
329
+ GRPC_CHANNEL_CONNECTING,
330
+ MakeUnique<QueuePicker>(p->Ref(DEBUG_LOCATION, "QueuePicker")));
324
331
  } else if (num_transient_failure_ == num_subchannels()) {
325
332
  /* 3) TRANSIENT_FAILURE */
326
333
  grpc_error* error =
@@ -329,7 +336,7 @@ void RoundRobin::RoundRobinSubchannelList::
329
336
  GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
330
337
  p->channel_control_helper()->UpdateState(
331
338
  GRPC_CHANNEL_TRANSIENT_FAILURE,
332
- UniquePtr<SubchannelPicker>(New<TransientFailurePicker>(error)));
339
+ MakeUnique<TransientFailurePicker>(error));
333
340
  }
334
341
  }
335
342
 
@@ -372,11 +379,28 @@ void RoundRobin::RoundRobinSubchannelData::UpdateConnectivityStateLocked(
372
379
  "(index %" PRIuPTR " of %" PRIuPTR "): prev_state=%s new_state=%s",
373
380
  p, subchannel(), subchannel_list(), Index(),
374
381
  subchannel_list()->num_subchannels(),
375
- grpc_connectivity_state_name(last_connectivity_state_),
376
- grpc_connectivity_state_name(connectivity_state));
382
+ ConnectivityStateName(last_connectivity_state_),
383
+ ConnectivityStateName(connectivity_state));
384
+ }
385
+ // Decide what state to report for aggregation purposes.
386
+ // If we haven't seen a failure since the last time we were in state
387
+ // READY, then we report the state change as-is. However, once we do see
388
+ // a failure, we report TRANSIENT_FAILURE and do not report any subsequent
389
+ // state changes until we go back into state READY.
390
+ if (!seen_failure_since_ready_) {
391
+ if (connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
392
+ seen_failure_since_ready_ = true;
393
+ }
394
+ subchannel_list()->UpdateStateCountersLocked(last_connectivity_state_,
395
+ connectivity_state);
396
+ } else {
397
+ if (connectivity_state == GRPC_CHANNEL_READY) {
398
+ seen_failure_since_ready_ = false;
399
+ subchannel_list()->UpdateStateCountersLocked(
400
+ GRPC_CHANNEL_TRANSIENT_FAILURE, connectivity_state);
401
+ }
377
402
  }
378
- subchannel_list()->UpdateStateCountersLocked(last_connectivity_state_,
379
- connectivity_state);
403
+ // Record last seen connectivity state.
380
404
  last_connectivity_state_ = connectivity_state;
381
405
  }
382
406
 
@@ -429,7 +453,7 @@ void RoundRobin::UpdateLocked(UpdateArgs args) {
429
453
  GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
430
454
  channel_control_helper()->UpdateState(
431
455
  GRPC_CHANNEL_TRANSIENT_FAILURE,
432
- UniquePtr<SubchannelPicker>(New<TransientFailurePicker>(error)));
456
+ MakeUnique<TransientFailurePicker>(error));
433
457
  subchannel_list_ = std::move(latest_pending_subchannel_list_);
434
458
  } else if (subchannel_list_ == nullptr) {
435
459
  // If there is no current list, immediately promote the new list to
@@ -456,7 +480,7 @@ class RoundRobinFactory : public LoadBalancingPolicyFactory {
456
480
  public:
457
481
  OrphanablePtr<LoadBalancingPolicy> CreateLoadBalancingPolicy(
458
482
  LoadBalancingPolicy::Args args) const override {
459
- return OrphanablePtr<LoadBalancingPolicy>(New<RoundRobin>(std::move(args)));
483
+ return MakeOrphanable<RoundRobin>(std::move(args));
460
484
  }
461
485
 
462
486
  const char* name() const override { return kRoundRobin; }
@@ -478,8 +502,7 @@ class RoundRobinFactory : public LoadBalancingPolicyFactory {
478
502
  void grpc_lb_policy_round_robin_init() {
479
503
  grpc_core::LoadBalancingPolicyRegistry::Builder::
480
504
  RegisterLoadBalancingPolicyFactory(
481
- grpc_core::UniquePtr<grpc_core::LoadBalancingPolicyFactory>(
482
- grpc_core::New<grpc_core::RoundRobinFactory>()));
505
+ grpc_core::MakeUnique<grpc_core::RoundRobinFactory>());
483
506
  }
484
507
 
485
508
  void grpc_lb_policy_round_robin_shutdown() {}
@@ -33,7 +33,6 @@
33
33
  #include "src/core/ext/filters/client_channel/subchannel_interface.h"
34
34
  #include "src/core/lib/channel/channel_args.h"
35
35
  #include "src/core/lib/debug/trace.h"
36
- #include "src/core/lib/gprpp/abstract.h"
37
36
  #include "src/core/lib/gprpp/inlined_vector.h"
38
37
  #include "src/core/lib/gprpp/orphanable.h"
39
38
  #include "src/core/lib/gprpp/ref_counted.h"
@@ -117,8 +116,6 @@ class SubchannelData {
117
116
  // Cancels any pending connectivity watch and unrefs the subchannel.
118
117
  void ShutdownLocked();
119
118
 
120
- GRPC_ABSTRACT_BASE_CLASS
121
-
122
119
  protected:
123
120
  SubchannelData(
124
121
  SubchannelList<SubchannelListType, SubchannelDataType>* subchannel_list,
@@ -131,7 +128,7 @@ class SubchannelData {
131
128
  // invoked whenever the subchannel's connectivity state changes.
132
129
  // To stop watching, use CancelConnectivityWatchLocked().
133
130
  virtual void ProcessConnectivityChangeLocked(
134
- grpc_connectivity_state connectivity_state) GRPC_ABSTRACT;
131
+ grpc_connectivity_state connectivity_state) = 0;
135
132
 
136
133
  private:
137
134
  // Watcher for subchannel connectivity state.
@@ -200,8 +197,6 @@ class SubchannelList : public InternallyRefCounted<SubchannelListType> {
200
197
  InternallyRefCounted<SubchannelListType>::Unref(DEBUG_LOCATION, "shutdown");
201
198
  }
202
199
 
203
- GRPC_ABSTRACT_BASE_CLASS
204
-
205
200
  protected:
206
201
  SubchannelList(LoadBalancingPolicy* policy, TraceFlag* tracer,
207
202
  const ServerAddressList& addresses,
@@ -254,8 +249,7 @@ void SubchannelData<SubchannelListType, SubchannelDataType>::Watcher::
254
249
  subchannel_list_.get(), subchannel_data_->Index(),
255
250
  subchannel_list_->num_subchannels(),
256
251
  subchannel_data_->subchannel_.get(),
257
- grpc_connectivity_state_name(new_state),
258
- subchannel_list_->shutting_down(),
252
+ ConnectivityStateName(new_state), subchannel_list_->shutting_down(),
259
253
  subchannel_data_->pending_watcher_);
260
254
  }
261
255
  if (!subchannel_list_->shutting_down() &&
@@ -318,8 +312,7 @@ void SubchannelData<SubchannelListType,
318
312
  " (subchannel %p): starting watch (from %s)",
319
313
  subchannel_list_->tracer()->name(), subchannel_list_->policy(),
320
314
  subchannel_list_, Index(), subchannel_list_->num_subchannels(),
321
- subchannel_.get(),
322
- grpc_connectivity_state_name(connectivity_state_));
315
+ subchannel_.get(), ConnectivityStateName(connectivity_state_));
323
316
  }
324
317
  GPR_ASSERT(pending_watcher_ == nullptr);
325
318
  pending_watcher_ =
@@ -16,43 +16,6 @@
16
16
  *
17
17
  */
18
18
 
19
- /// Implementation of the gRPC LB policy.
20
- ///
21
- /// This policy takes as input a list of resolved addresses, which must
22
- /// include at least one balancer address.
23
- ///
24
- /// An internal channel (\a lb_channel_) is created for the addresses
25
- /// from that are balancers. This channel behaves just like a regular
26
- /// channel that uses pick_first to select from the list of balancer
27
- /// addresses.
28
- ///
29
- /// When we get our initial update, we instantiate the internal *streaming*
30
- /// call to the LB server (whichever address pick_first chose). The call
31
- /// will be complete when either the balancer sends status or when we cancel
32
- /// the call (e.g., because we are shutting down). In needed, we retry the
33
- /// call. If we received at least one valid message from the server, a new
34
- /// call attempt will be made immediately; otherwise, we apply back-off
35
- /// delays between attempts.
36
- ///
37
- /// We maintain an internal child policy (round_robin) instance for distributing
38
- /// requests across backends. Whenever we receive a new serverlist from
39
- /// the balancer, we update the child policy with the new list of
40
- /// addresses.
41
- ///
42
- /// Once a child policy instance is in place (and getting updated as
43
- /// described), calls for a pick, or a cancellation will be serviced right away
44
- /// by forwarding them to the child policy instance. Any time there's no child
45
- /// policy available (i.e., right after the creation of the xDS policy), pick
46
- /// requests are added to a list of pending picks to be flushed and serviced
47
- /// when the child policy instance becomes available.
48
- ///
49
- /// \see https://github.com/grpc/grpc/blob/master/doc/load-balancing.md for the
50
- /// high level design and details.
51
-
52
- // With the addition of a libuv endpoint, sockaddr.h now includes uv.h when
53
- // using that endpoint. Because of various transitive includes in uv.h,
54
- // including windows.h on Windows, uv.h must be included before other system
55
- // headers. Therefore, sockaddr.h must always be included first.
56
19
  #include <grpc/support/port_platform.h>
57
20
 
58
21
  #include "src/core/lib/iomgr/sockaddr.h"
@@ -62,25 +25,21 @@
62
25
  #include <limits.h>
63
26
  #include <string.h>
64
27
 
65
- #include <grpc/byte_buffer_reader.h>
66
28
  #include <grpc/grpc.h>
67
29
  #include <grpc/support/alloc.h>
68
30
  #include <grpc/support/string_util.h>
69
31
  #include <grpc/support/time.h>
70
32
 
71
- #include "include/grpc/support/alloc.h"
72
33
  #include "src/core/ext/filters/client_channel/client_channel.h"
73
34
  #include "src/core/ext/filters/client_channel/lb_policy.h"
74
35
  #include "src/core/ext/filters/client_channel/lb_policy/xds/xds.h"
75
- #include "src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h"
76
- #include "src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h"
77
- #include "src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h"
78
36
  #include "src/core/ext/filters/client_channel/lb_policy_factory.h"
79
37
  #include "src/core/ext/filters/client_channel/lb_policy_registry.h"
80
38
  #include "src/core/ext/filters/client_channel/parse_address.h"
81
- #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h"
82
39
  #include "src/core/ext/filters/client_channel/server_address.h"
83
40
  #include "src/core/ext/filters/client_channel/service_config.h"
41
+ #include "src/core/ext/filters/client_channel/xds/xds_client.h"
42
+ #include "src/core/ext/filters/client_channel/xds/xds_client_stats.h"
84
43
  #include "src/core/lib/backoff/backoff.h"
85
44
  #include "src/core/lib/channel/channel_args.h"
86
45
  #include "src/core/lib/channel/channel_stack.h"
@@ -103,13 +62,9 @@
103
62
  #include "src/core/lib/surface/channel_init.h"
104
63
  #include "src/core/lib/transport/static_metadata.h"
105
64
 
106
- #define GRPC_XDS_INITIAL_CONNECT_BACKOFF_SECONDS 1
107
- #define GRPC_XDS_RECONNECT_BACKOFF_MULTIPLIER 1.6
108
- #define GRPC_XDS_RECONNECT_MAX_BACKOFF_SECONDS 120
109
- #define GRPC_XDS_RECONNECT_JITTER 0.2
110
65
  #define GRPC_XDS_DEFAULT_FALLBACK_TIMEOUT_MS 10000
111
- #define GRPC_XDS_MIN_CLIENT_LOAD_REPORTING_INTERVAL_MS 1000
112
66
  #define GRPC_XDS_DEFAULT_LOCALITY_RETENTION_INTERVAL_MS (15 * 60 * 1000)
67
+ #define GRPC_XDS_DEFAULT_FAILOVER_TIMEOUT_MS 10000
113
68
 
114
69
  namespace grpc_core {
115
70
 
@@ -121,17 +76,13 @@ constexpr char kXds[] = "xds_experimental";
121
76
 
122
77
  class ParsedXdsConfig : public LoadBalancingPolicy::Config {
123
78
  public:
124
- ParsedXdsConfig(const char* balancer_name,
125
- RefCountedPtr<LoadBalancingPolicy::Config> child_policy,
79
+ ParsedXdsConfig(RefCountedPtr<LoadBalancingPolicy::Config> child_policy,
126
80
  RefCountedPtr<LoadBalancingPolicy::Config> fallback_policy)
127
- : balancer_name_(balancer_name),
128
- child_policy_(std::move(child_policy)),
81
+ : child_policy_(std::move(child_policy)),
129
82
  fallback_policy_(std::move(fallback_policy)) {}
130
83
 
131
84
  const char* name() const override { return kXds; }
132
85
 
133
- const char* balancer_name() const { return balancer_name_; };
134
-
135
86
  RefCountedPtr<LoadBalancingPolicy::Config> child_policy() const {
136
87
  return child_policy_;
137
88
  }
@@ -141,7 +92,6 @@ class ParsedXdsConfig : public LoadBalancingPolicy::Config {
141
92
  }
142
93
 
143
94
  private:
144
- const char* balancer_name_ = nullptr;
145
95
  RefCountedPtr<LoadBalancingPolicy::Config> child_policy_;
146
96
  RefCountedPtr<LoadBalancingPolicy::Config> fallback_policy_;
147
97
  };
@@ -156,224 +106,12 @@ class XdsLb : public LoadBalancingPolicy {
156
106
  void ResetBackoffLocked() override;
157
107
 
158
108
  private:
159
- // Contains a channel to the LB server and all the data related to the
160
- // channel. Holds a ref to the xds policy.
161
- class LbChannelState : public InternallyRefCounted<LbChannelState> {
162
- public:
163
- // An LB call wrapper that can restart a call upon failure. Holds a ref to
164
- // the LB channel. The template parameter is the kind of wrapped LB call.
165
- template <typename T>
166
- class RetryableLbCall : public InternallyRefCounted<RetryableLbCall<T>> {
167
- public:
168
- explicit RetryableLbCall(RefCountedPtr<LbChannelState> lb_chand);
169
-
170
- void Orphan() override;
171
-
172
- void OnCallFinishedLocked();
173
-
174
- T* lb_calld() const { return lb_calld_.get(); }
175
- LbChannelState* lb_chand() const { return lb_chand_.get(); }
176
-
177
- private:
178
- void StartNewCallLocked();
179
- void StartRetryTimerLocked();
180
- static void OnRetryTimerLocked(void* arg, grpc_error* error);
181
-
182
- // The wrapped LB call that talks to the LB server. It's instantiated
183
- // every time we start a new call. It's null during call retry backoff.
184
- OrphanablePtr<T> lb_calld_;
185
- // The owing LB channel.
186
- RefCountedPtr<LbChannelState> lb_chand_;
187
-
188
- // Retry state.
189
- BackOff backoff_;
190
- grpc_timer retry_timer_;
191
- grpc_closure on_retry_timer_;
192
- bool retry_timer_callback_pending_ = false;
193
-
194
- bool shutting_down_ = false;
195
- };
196
-
197
- // Contains an EDS call to the LB server.
198
- class EdsCallState : public InternallyRefCounted<EdsCallState> {
199
- public:
200
- // The ctor and dtor should not be used directly.
201
- explicit EdsCallState(
202
- RefCountedPtr<RetryableLbCall<EdsCallState>> parent);
203
- ~EdsCallState() override;
204
-
205
- void Orphan() override;
206
-
207
- RetryableLbCall<EdsCallState>* parent() const { return parent_.get(); }
208
- LbChannelState* lb_chand() const { return parent_->lb_chand(); }
209
- XdsLb* xdslb_policy() const { return lb_chand()->xdslb_policy(); }
210
- bool seen_response() const { return seen_response_; }
211
-
212
- private:
213
- static void OnResponseReceivedLocked(void* arg, grpc_error* error);
214
- static void OnStatusReceivedLocked(void* arg, grpc_error* error);
215
-
216
- bool IsCurrentCallOnChannel() const;
217
-
218
- // The owning RetryableLbCall<>.
219
- RefCountedPtr<RetryableLbCall<EdsCallState>> parent_;
220
- bool seen_response_ = false;
221
-
222
- // Always non-NULL.
223
- grpc_call* lb_call_;
224
-
225
- // recv_initial_metadata
226
- grpc_metadata_array initial_metadata_recv_;
227
-
228
- // send_message
229
- grpc_byte_buffer* send_message_payload_ = nullptr;
230
-
231
- // recv_message
232
- grpc_byte_buffer* recv_message_payload_ = nullptr;
233
- grpc_closure on_response_received_;
234
-
235
- // recv_trailing_metadata
236
- grpc_metadata_array trailing_metadata_recv_;
237
- grpc_status_code status_code_;
238
- grpc_slice status_details_;
239
- grpc_closure on_status_received_;
240
- };
241
-
242
- // Contains an LRS call to the LB server.
243
- class LrsCallState : public InternallyRefCounted<LrsCallState> {
244
- public:
245
- // The ctor and dtor should not be used directly.
246
- explicit LrsCallState(
247
- RefCountedPtr<RetryableLbCall<LrsCallState>> parent);
248
- ~LrsCallState() override;
249
-
250
- void Orphan() override;
251
-
252
- void MaybeStartReportingLocked();
253
-
254
- RetryableLbCall<LrsCallState>* parent() { return parent_.get(); }
255
- LbChannelState* lb_chand() const { return parent_->lb_chand(); }
256
- XdsLb* xdslb_policy() const { return lb_chand()->xdslb_policy(); }
257
- bool seen_response() const { return seen_response_; }
258
-
259
- private:
260
- // Reports client-side load stats according to a fixed interval.
261
- class Reporter : public InternallyRefCounted<Reporter> {
262
- public:
263
- Reporter(RefCountedPtr<LrsCallState> parent,
264
- grpc_millis report_interval)
265
- : parent_(std::move(parent)), report_interval_(report_interval) {
266
- GRPC_CLOSURE_INIT(
267
- &on_next_report_timer_, OnNextReportTimerLocked, this,
268
- grpc_combiner_scheduler(xdslb_policy()->combiner()));
269
- GRPC_CLOSURE_INIT(
270
- &on_report_done_, OnReportDoneLocked, this,
271
- grpc_combiner_scheduler(xdslb_policy()->combiner()));
272
- ScheduleNextReportLocked();
273
- }
274
-
275
- void Orphan() override;
276
-
277
- private:
278
- void ScheduleNextReportLocked();
279
- static void OnNextReportTimerLocked(void* arg, grpc_error* error);
280
- void SendReportLocked();
281
- static void OnReportDoneLocked(void* arg, grpc_error* error);
282
-
283
- bool IsCurrentReporterOnCall() const {
284
- return this == parent_->reporter_.get();
285
- }
286
- XdsLb* xdslb_policy() const { return parent_->xdslb_policy(); }
287
-
288
- // The owning LRS call.
289
- RefCountedPtr<LrsCallState> parent_;
290
-
291
- // The load reporting state.
292
- const grpc_millis report_interval_;
293
- bool last_report_counters_were_zero_ = false;
294
- bool next_report_timer_callback_pending_ = false;
295
- grpc_timer next_report_timer_;
296
- grpc_closure on_next_report_timer_;
297
- grpc_closure on_report_done_;
298
- };
299
-
300
- static void OnInitialRequestSentLocked(void* arg, grpc_error* error);
301
- static void OnResponseReceivedLocked(void* arg, grpc_error* error);
302
- static void OnStatusReceivedLocked(void* arg, grpc_error* error);
303
-
304
- bool IsCurrentCallOnChannel() const;
305
-
306
- // The owning RetryableLbCall<>.
307
- RefCountedPtr<RetryableLbCall<LrsCallState>> parent_;
308
- bool seen_response_ = false;
309
-
310
- // Always non-NULL.
311
- grpc_call* lb_call_;
312
-
313
- // recv_initial_metadata
314
- grpc_metadata_array initial_metadata_recv_;
315
-
316
- // send_message
317
- grpc_byte_buffer* send_message_payload_ = nullptr;
318
- grpc_closure on_initial_request_sent_;
319
-
320
- // recv_message
321
- grpc_byte_buffer* recv_message_payload_ = nullptr;
322
- grpc_closure on_response_received_;
323
-
324
- // recv_trailing_metadata
325
- grpc_metadata_array trailing_metadata_recv_;
326
- grpc_status_code status_code_;
327
- grpc_slice status_details_;
328
- grpc_closure on_status_received_;
329
-
330
- // Load reporting state.
331
- grpc_millis load_reporting_interval_ = 0;
332
- OrphanablePtr<Reporter> reporter_;
333
- };
334
-
335
- LbChannelState(RefCountedPtr<XdsLb> xdslb_policy, const char* balancer_name,
336
- const grpc_channel_args& args);
337
- ~LbChannelState();
338
-
339
- void Orphan() override;
340
-
341
- grpc_channel* channel() const { return channel_; }
342
- XdsLb* xdslb_policy() const { return xdslb_policy_.get(); }
343
- EdsCallState* eds_calld() const { return eds_calld_->lb_calld(); }
344
- LrsCallState* lrs_calld() const { return lrs_calld_->lb_calld(); }
345
-
346
- bool IsCurrentChannel() const {
347
- return this == xdslb_policy_->lb_chand_.get();
348
- }
349
- bool IsPendingChannel() const {
350
- return this == xdslb_policy_->pending_lb_chand_.get();
351
- }
352
- bool HasActiveEdsCall() const { return eds_calld_->lb_calld() != nullptr; }
353
-
354
- void StartConnectivityWatchLocked();
355
- void CancelConnectivityWatchLocked();
356
- static void OnConnectivityChangedLocked(void* arg, grpc_error* error);
357
-
358
- private:
359
- // The owning LB policy.
360
- RefCountedPtr<XdsLb> xdslb_policy_;
361
-
362
- // The channel and its status.
363
- grpc_channel* channel_;
364
- bool shutting_down_ = false;
365
- grpc_connectivity_state connectivity_ = GRPC_CHANNEL_IDLE;
366
- grpc_closure on_connectivity_changed_;
367
-
368
- // The retryable XDS calls to the LB server.
369
- OrphanablePtr<RetryableLbCall<EdsCallState>> eds_calld_;
370
- OrphanablePtr<RetryableLbCall<LrsCallState>> lrs_calld_;
371
- };
109
+ class EndpointWatcher;
372
110
 
373
111
  // We need this wrapper for the following reasons:
374
112
  // 1. To process per-locality load reporting.
375
113
  // 2. Since pickers are UniquePtrs we use this RefCounted wrapper to control
376
- // references to it by the xds picker and the locality entry.
114
+ // references to it by the xds picker and the locality.
377
115
  class PickerWrapper : public RefCounted<PickerWrapper> {
378
116
  public:
379
117
  PickerWrapper(UniquePtr<SubchannelPicker> picker,
@@ -387,11 +125,6 @@ class XdsLb : public LoadBalancingPolicy {
387
125
  PickResult Pick(PickArgs args);
388
126
 
389
127
  private:
390
- static void RecordCallCompletion(
391
- void* arg, grpc_error* error,
392
- LoadBalancingPolicy::MetadataInterface* recv_trailing_metadata,
393
- LoadBalancingPolicy::CallState* call_state);
394
-
395
128
  UniquePtr<SubchannelPicker> picker_;
396
129
  RefCountedPtr<XdsClientStats::LocalityStats> locality_stats_;
397
130
  };
@@ -405,7 +138,7 @@ class XdsLb : public LoadBalancingPolicy {
405
138
  // proportional to the locality's weight. The start of the range is the
406
139
  // previous value in the vector and is 0 for the first element.
407
140
  using PickerList =
408
- InlinedVector<Pair<uint32_t, RefCountedPtr<PickerWrapper>>, 1>;
141
+ InlinedVector<std::pair<uint32_t, RefCountedPtr<PickerWrapper>>, 1>;
409
142
  Picker(RefCountedPtr<XdsLb> xds_policy, PickerList pickers)
410
143
  : xds_policy_(std::move(xds_policy)),
411
144
  pickers_(std::move(pickers)),
@@ -446,144 +179,235 @@ class XdsLb : public LoadBalancingPolicy {
446
179
  LoadBalancingPolicy* child_ = nullptr;
447
180
  };
448
181
 
449
- class LocalityMap {
182
+ // There is only one PriorityList instance, which has the same lifetime with
183
+ // the XdsLb instance.
184
+ class PriorityList {
450
185
  public:
451
- class LocalityEntry : public InternallyRefCounted<LocalityEntry> {
186
+ // Each LocalityMap holds a ref to the XdsLb.
187
+ class LocalityMap : public InternallyRefCounted<LocalityMap> {
452
188
  public:
453
- LocalityEntry(RefCountedPtr<XdsLb> parent,
454
- RefCountedPtr<XdsLocalityName> name);
455
- ~LocalityEntry();
456
-
457
- void UpdateLocked(uint32_t locality_weight, ServerAddressList serverlist,
458
- LoadBalancingPolicy::Config* child_policy_config,
459
- const grpc_channel_args* args);
460
- void ShutdownLocked();
189
+ // Each Locality holds a ref to the LocalityMap it is in.
190
+ class Locality : public InternallyRefCounted<Locality> {
191
+ public:
192
+ Locality(RefCountedPtr<LocalityMap> locality_map,
193
+ RefCountedPtr<XdsLocalityName> name);
194
+ ~Locality();
195
+
196
+ void UpdateLocked(uint32_t locality_weight,
197
+ ServerAddressList serverlist);
198
+ void ShutdownLocked();
199
+ void ResetBackoffLocked();
200
+ void DeactivateLocked();
201
+ void Orphan() override;
202
+
203
+ grpc_connectivity_state connectivity_state() const {
204
+ return connectivity_state_;
205
+ }
206
+ uint32_t weight() const { return weight_; }
207
+ RefCountedPtr<PickerWrapper> picker_wrapper() const {
208
+ return picker_wrapper_;
209
+ }
210
+
211
+ void set_locality_map(RefCountedPtr<LocalityMap> locality_map) {
212
+ locality_map_ = std::move(locality_map);
213
+ }
214
+
215
+ private:
216
+ class Helper : public ChannelControlHelper {
217
+ public:
218
+ explicit Helper(RefCountedPtr<Locality> locality)
219
+ : locality_(std::move(locality)) {}
220
+
221
+ ~Helper() { locality_.reset(DEBUG_LOCATION, "Helper"); }
222
+
223
+ RefCountedPtr<SubchannelInterface> CreateSubchannel(
224
+ const grpc_channel_args& args) override;
225
+ void UpdateState(grpc_connectivity_state state,
226
+ UniquePtr<SubchannelPicker> picker) override;
227
+ // This is a no-op, because we get the addresses from the xds
228
+ // client, which is a watch-based API.
229
+ void RequestReresolution() override {}
230
+ void AddTraceEvent(TraceSeverity severity,
231
+ StringView message) override;
232
+ void set_child(LoadBalancingPolicy* child) { child_ = child; }
233
+
234
+ private:
235
+ bool CalledByPendingChild() const;
236
+ bool CalledByCurrentChild() const;
237
+
238
+ RefCountedPtr<Locality> locality_;
239
+ LoadBalancingPolicy* child_ = nullptr;
240
+ };
241
+
242
+ // Methods for dealing with the child policy.
243
+ OrphanablePtr<LoadBalancingPolicy> CreateChildPolicyLocked(
244
+ const char* name, const grpc_channel_args* args);
245
+ grpc_channel_args* CreateChildPolicyArgsLocked(
246
+ const grpc_channel_args* args);
247
+
248
+ static void OnDelayedRemovalTimer(void* arg, grpc_error* error);
249
+ static void OnDelayedRemovalTimerLocked(void* arg, grpc_error* error);
250
+
251
+ XdsLb* xds_policy() const { return locality_map_->xds_policy(); }
252
+
253
+ // The owning locality map.
254
+ RefCountedPtr<LocalityMap> locality_map_;
255
+
256
+ RefCountedPtr<XdsLocalityName> name_;
257
+ OrphanablePtr<LoadBalancingPolicy> child_policy_;
258
+ OrphanablePtr<LoadBalancingPolicy> pending_child_policy_;
259
+ RefCountedPtr<PickerWrapper> picker_wrapper_;
260
+ grpc_connectivity_state connectivity_state_ = GRPC_CHANNEL_IDLE;
261
+ uint32_t weight_;
262
+
263
+ // States for delayed removal.
264
+ grpc_timer delayed_removal_timer_;
265
+ grpc_closure on_delayed_removal_timer_;
266
+ bool delayed_removal_timer_callback_pending_ = false;
267
+ bool shutdown_ = false;
268
+ };
269
+
270
+ LocalityMap(RefCountedPtr<XdsLb> xds_policy, uint32_t priority);
271
+
272
+ void UpdateLocked(
273
+ const XdsPriorityListUpdate::LocalityMap& locality_map_update);
461
274
  void ResetBackoffLocked();
275
+ void UpdateXdsPickerLocked();
276
+ OrphanablePtr<Locality> ExtractLocalityLocked(
277
+ const RefCountedPtr<XdsLocalityName>& name);
462
278
  void DeactivateLocked();
279
+ // Returns true if this locality map becomes the currently used one (i.e.,
280
+ // its priority is selected) after reactivation.
281
+ bool MaybeReactivateLocked();
282
+ void MaybeCancelFailoverTimerLocked();
283
+
463
284
  void Orphan() override;
464
285
 
286
+ XdsLb* xds_policy() const { return xds_policy_.get(); }
287
+ uint32_t priority() const { return priority_; }
465
288
  grpc_connectivity_state connectivity_state() const {
466
289
  return connectivity_state_;
467
290
  }
468
- uint32_t locality_weight() const { return locality_weight_; }
469
- RefCountedPtr<PickerWrapper> picker_wrapper() const {
470
- return picker_wrapper_;
291
+ bool failover_timer_callback_pending() const {
292
+ return failover_timer_callback_pending_;
471
293
  }
472
294
 
473
295
  private:
474
- class Helper : public ChannelControlHelper {
475
- public:
476
- explicit Helper(RefCountedPtr<LocalityEntry> entry)
477
- : entry_(std::move(entry)) {}
478
-
479
- ~Helper() { entry_.reset(DEBUG_LOCATION, "Helper"); }
480
-
481
- RefCountedPtr<SubchannelInterface> CreateSubchannel(
482
- const grpc_channel_args& args) override;
483
- void UpdateState(grpc_connectivity_state state,
484
- UniquePtr<SubchannelPicker> picker) override;
485
- void RequestReresolution() override;
486
- void AddTraceEvent(TraceSeverity severity, StringView message) override;
487
- void set_child(LoadBalancingPolicy* child) { child_ = child; }
488
-
489
- private:
490
- bool CalledByPendingChild() const;
491
- bool CalledByCurrentChild() const;
492
-
493
- RefCountedPtr<LocalityEntry> entry_;
494
- LoadBalancingPolicy* child_ = nullptr;
495
- };
296
+ void OnLocalityStateUpdateLocked();
297
+ void UpdateConnectivityStateLocked();
298
+ static void OnDelayedRemovalTimer(void* arg, grpc_error* error);
299
+ static void OnFailoverTimer(void* arg, grpc_error* error);
300
+ static void OnDelayedRemovalTimerLocked(void* arg, grpc_error* error);
301
+ static void OnFailoverTimerLocked(void* arg, grpc_error* error);
496
302
 
497
- // Methods for dealing with the child policy.
498
- OrphanablePtr<LoadBalancingPolicy> CreateChildPolicyLocked(
499
- const char* name, const grpc_channel_args* args);
500
- grpc_channel_args* CreateChildPolicyArgsLocked(
501
- const grpc_channel_args* args);
303
+ PriorityList* priority_list() const {
304
+ return &xds_policy_->priority_list_;
305
+ }
306
+ const XdsPriorityListUpdate& priority_list_update() const {
307
+ return xds_policy_->priority_list_update_;
308
+ }
309
+ const XdsPriorityListUpdate::LocalityMap* locality_map_update() const {
310
+ return xds_policy_->priority_list_update_.Find(priority_);
311
+ }
502
312
 
503
- static void OnDelayedRemovalTimerLocked(void* arg, grpc_error* error);
313
+ RefCountedPtr<XdsLb> xds_policy_;
504
314
 
505
- RefCountedPtr<XdsLb> parent_;
506
- RefCountedPtr<XdsLocalityName> name_;
507
- OrphanablePtr<LoadBalancingPolicy> child_policy_;
508
- OrphanablePtr<LoadBalancingPolicy> pending_child_policy_;
509
- RefCountedPtr<PickerWrapper> picker_wrapper_;
315
+ Map<RefCountedPtr<XdsLocalityName>, OrphanablePtr<Locality>,
316
+ XdsLocalityName::Less>
317
+ localities_;
318
+ const uint32_t priority_;
510
319
  grpc_connectivity_state connectivity_state_ = GRPC_CHANNEL_IDLE;
511
- uint32_t locality_weight_;
512
- grpc_closure on_delayed_removal_timer_;
320
+
321
+ // States for delayed removal.
513
322
  grpc_timer delayed_removal_timer_;
323
+ grpc_closure on_delayed_removal_timer_;
514
324
  bool delayed_removal_timer_callback_pending_ = false;
325
+
326
+ // States of failover.
327
+ grpc_timer failover_timer_;
328
+ grpc_closure on_failover_timer_;
329
+ bool failover_timer_callback_pending_ = false;
515
330
  };
516
331
 
517
- explicit LocalityMap(XdsLb* xds_policy) : xds_policy_(xds_policy) {}
332
+ explicit PriorityList(XdsLb* xds_policy) : xds_policy_(xds_policy) {}
518
333
 
519
- void UpdateLocked(const XdsLocalityList& locality_list,
520
- LoadBalancingPolicy::Config* child_policy_config,
521
- const grpc_channel_args* args, XdsLb* parent,
522
- bool is_initial_update = false);
523
- void UpdateXdsPickerLocked();
524
- void ShutdownLocked();
334
+ void UpdateLocked();
525
335
  void ResetBackoffLocked();
336
+ void ShutdownLocked();
337
+ void UpdateXdsPickerLocked();
338
+
339
+ const XdsPriorityListUpdate& priority_list_update() const {
340
+ return xds_policy_->priority_list_update_;
341
+ }
342
+ uint32_t current_priority() const { return current_priority_; }
526
343
 
527
344
  private:
345
+ void MaybeCreateLocalityMapLocked(uint32_t priority);
346
+ void FailoverOnConnectionFailureLocked();
347
+ void FailoverOnDisconnectionLocked(uint32_t failed_priority);
348
+ void SwitchToHigherPriorityLocked(uint32_t priority);
349
+ void DeactivatePrioritiesLowerThan(uint32_t priority);
350
+ OrphanablePtr<LocalityMap::Locality> ExtractLocalityLocked(
351
+ const RefCountedPtr<XdsLocalityName>& name, uint32_t exclude_priority);
352
+ // Callers should make sure the priority list is non-empty.
353
+ uint32_t LowestPriority() const {
354
+ return static_cast<uint32_t>(priorities_.size()) - 1;
355
+ }
356
+ bool Contains(uint32_t priority) { return priority < priorities_.size(); }
357
+
528
358
  XdsLb* xds_policy_;
529
- Map<RefCountedPtr<XdsLocalityName>, OrphanablePtr<LocalityEntry>,
530
- XdsLocalityName::Less>
531
- map_;
359
+
360
+ // The list of locality maps, indexed by priority. P0 is the highest
361
+ // priority.
362
+ InlinedVector<OrphanablePtr<LocalityMap>, 2> priorities_;
363
+ // The priority that is being used.
364
+ uint32_t current_priority_ = UINT32_MAX;
532
365
  };
533
366
 
534
367
  ~XdsLb();
535
368
 
536
369
  void ShutdownLocked() override;
537
370
 
538
- // Helper function used in UpdateLocked().
539
- void ProcessAddressesAndChannelArgsLocked(ServerAddressList addresses,
540
- const grpc_channel_args& args);
541
-
542
- // Parses the xds config given the JSON node of the first child of XdsConfig.
543
- // If parsing succeeds, updates \a balancer_name, and updates \a
544
- // child_policy_config_ and \a fallback_policy_config_ if they are also
545
- // found. Does nothing upon failure.
546
- void ParseLbConfig(const ParsedXdsConfig* xds_config);
547
-
548
- LbChannelState* LatestLbChannel() const {
549
- return pending_lb_chand_ != nullptr ? pending_lb_chand_.get()
550
- : lb_chand_.get();
551
- }
552
-
553
371
  // Methods for dealing with fallback state.
554
372
  void MaybeCancelFallbackAtStartupChecks();
373
+ static void OnFallbackTimer(void* arg, grpc_error* error);
555
374
  static void OnFallbackTimerLocked(void* arg, grpc_error* error);
556
375
  void UpdateFallbackPolicyLocked();
557
376
  OrphanablePtr<LoadBalancingPolicy> CreateFallbackPolicyLocked(
558
377
  const char* name, const grpc_channel_args* args);
559
378
  void MaybeExitFallbackMode();
560
379
 
380
+ XdsClient* xds_client() const {
381
+ return xds_client_from_channel_ != nullptr ? xds_client_from_channel_.get()
382
+ : xds_client_.get();
383
+ }
384
+
561
385
  // Name of the backend server to connect to.
562
386
  const char* server_name_ = nullptr;
563
387
 
564
- // Name of the balancer to connect to.
565
- UniquePtr<char> balancer_name_;
566
-
567
388
  // Current channel args from the resolver.
568
- grpc_channel_args* args_ = nullptr;
389
+ const grpc_channel_args* args_ = nullptr;
569
390
 
570
391
  // Internal state.
571
392
  bool shutting_down_ = false;
572
393
 
573
- // The channel for communicating with the LB server.
574
- OrphanablePtr<LbChannelState> lb_chand_;
575
- OrphanablePtr<LbChannelState> pending_lb_chand_;
576
-
577
- // Timeout in milliseconds for the LB call. 0 means no deadline.
578
- const grpc_millis lb_call_timeout_ms_;
394
+ // The xds client and endpoint watcher.
395
+ // If we get the XdsClient from the channel, we store it in
396
+ // xds_client_from_channel_; if we create it ourselves, we store it in
397
+ // xds_client_.
398
+ RefCountedPtr<XdsClient> xds_client_from_channel_;
399
+ OrphanablePtr<XdsClient> xds_client_;
400
+ // A pointer to the endpoint watcher, to be used when cancelling the watch.
401
+ // Note that this is not owned, so this pointer must never be derefernced.
402
+ EndpointWatcher* endpoint_watcher_ = nullptr;
579
403
 
580
404
  // Whether the checks for fallback at startup are ALL pending. There are
581
405
  // several cases where this can be reset:
582
406
  // 1. The fallback timer fires, we enter fallback mode.
583
- // 2. Before the fallback timer fires, the LB channel becomes
584
- // TRANSIENT_FAILURE or the LB call fails, we enter fallback mode.
407
+ // 2. Before the fallback timer fires, the endpoint watcher reports an
408
+ // error, we enter fallback mode.
585
409
  // 3. Before the fallback timer fires, if any child policy in the locality map
586
- // becomes READY, we cancel the fallback timer.
410
+ // becomes READY, we cancel the fallback timer.
587
411
  bool fallback_at_startup_checks_pending_ = false;
588
412
  // Timeout in milliseconds for before using fallback backend addresses.
589
413
  // 0 means not using fallback.
@@ -603,14 +427,11 @@ class XdsLb : public LoadBalancingPolicy {
603
427
  // The policy to use for the backends.
604
428
  RefCountedPtr<LoadBalancingPolicy::Config> child_policy_config_;
605
429
  const grpc_millis locality_retention_interval_ms_;
606
- // Map of policies to use in the backend
607
- LocalityMap locality_map_;
608
- // TODO(mhaidry) : Add support for multiple maps of localities
609
- // with different priorities
610
- XdsLocalityList locality_list_;
611
- // TODO(mhaidry) : Add a pending locality map that may be swapped with the
612
- // the current one when new localities in the pending map are ready
613
- // to accept connections
430
+ const grpc_millis locality_map_failover_timeout_ms_;
431
+ // A list of locality maps indexed by priority.
432
+ PriorityList priority_list_;
433
+ // The update for priority_list_.
434
+ XdsPriorityListUpdate priority_list_update_;
614
435
 
615
436
  // The config for dropping calls.
616
437
  RefCountedPtr<XdsDropConfig> drop_config_;
@@ -634,25 +455,20 @@ LoadBalancingPolicy::PickResult XdsLb::PickerWrapper::Pick(
634
455
  // Record a call started.
635
456
  locality_stats_->AddCallStarted();
636
457
  // Intercept the recv_trailing_metadata op to record call completion.
637
- result.recv_trailing_metadata_ready = RecordCallCompletion;
638
- result.recv_trailing_metadata_ready_user_data =
458
+ XdsClientStats::LocalityStats* locality_stats =
639
459
  locality_stats_->Ref(DEBUG_LOCATION, "LocalityStats+call").release();
460
+ result.recv_trailing_metadata_ready =
461
+ // Note: This callback does not run in either the control plane
462
+ // combiner or in the data plane mutex.
463
+ [locality_stats](grpc_error* error, MetadataInterface* metadata,
464
+ CallState* call_state) {
465
+ const bool call_failed = error != GRPC_ERROR_NONE;
466
+ locality_stats->AddCallFinished(call_failed);
467
+ locality_stats->Unref(DEBUG_LOCATION, "LocalityStats+call");
468
+ };
640
469
  return result;
641
470
  }
642
471
 
643
- // Note that the following callback does not run in either the control plane
644
- // combiner or the data plane combiner.
645
- void XdsLb::PickerWrapper::RecordCallCompletion(
646
- void* arg, grpc_error* error,
647
- LoadBalancingPolicy::MetadataInterface* recv_trailing_metadata,
648
- LoadBalancingPolicy::CallState* call_state) {
649
- XdsClientStats::LocalityStats* locality_stats =
650
- static_cast<XdsClientStats::LocalityStats*>(arg);
651
- const bool call_failed = error != GRPC_ERROR_NONE;
652
- locality_stats->AddCallFinished(call_failed);
653
- locality_stats->Unref(DEBUG_LOCATION, "LocalityStats+call");
654
- }
655
-
656
472
  //
657
473
  // XdsLb::Picker
658
474
  //
@@ -729,7 +545,7 @@ void XdsLb::FallbackHelper::UpdateState(grpc_connectivity_state state,
729
545
  GPR_INFO,
730
546
  "[xdslb %p helper %p] pending fallback policy %p reports state=%s",
731
547
  parent_.get(), this, parent_->pending_fallback_policy_.get(),
732
- grpc_connectivity_state_name(state));
548
+ ConnectivityStateName(state));
733
549
  }
734
550
  if (state != GRPC_CHANNEL_READY) return;
735
551
  grpc_pollset_set_del_pollset_set(
@@ -755,7 +571,6 @@ void XdsLb::FallbackHelper::RequestReresolution() {
755
571
  "[xdslb %p] Re-resolution requested from the fallback policy (%p).",
756
572
  parent_.get(), child_);
757
573
  }
758
- GPR_ASSERT(parent_->lb_chand_ != nullptr);
759
574
  parent_->channel_control_helper()->RequestReresolution();
760
575
  }
761
576
 
@@ -769,927 +584,79 @@ void XdsLb::FallbackHelper::AddTraceEvent(TraceSeverity severity,
769
584
  }
770
585
 
771
586
  //
772
- // XdsLb::LbChannelState
587
+ // XdsLb::EndpointWatcher
773
588
  //
774
589
 
775
- XdsLb::LbChannelState::LbChannelState(RefCountedPtr<XdsLb> xdslb_policy,
776
- const char* balancer_name,
777
- const grpc_channel_args& args)
778
- : InternallyRefCounted<LbChannelState>(&grpc_lb_xds_trace),
779
- xdslb_policy_(std::move(xdslb_policy)) {
780
- GRPC_CLOSURE_INIT(&on_connectivity_changed_, OnConnectivityChangedLocked,
781
- this, grpc_combiner_scheduler(xdslb_policy_->combiner()));
782
- channel_ = CreateXdsBalancerChannel(balancer_name, args);
783
- GPR_ASSERT(channel_ != nullptr);
784
- eds_calld_.reset(New<RetryableLbCall<EdsCallState>>(
785
- Ref(DEBUG_LOCATION, "LbChannelState+eds")));
786
- lrs_calld_.reset(New<RetryableLbCall<LrsCallState>>(
787
- Ref(DEBUG_LOCATION, "LbChannelState+lrs")));
788
- }
789
-
790
- XdsLb::LbChannelState::~LbChannelState() {
791
- if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) {
792
- gpr_log(GPR_INFO, "[xdslb %p] Destroying LB channel %p", xdslb_policy(),
793
- this);
794
- }
795
- grpc_channel_destroy(channel_);
796
- }
797
-
798
- void XdsLb::LbChannelState::Orphan() {
799
- shutting_down_ = true;
800
- eds_calld_.reset();
801
- lrs_calld_.reset();
802
- Unref(DEBUG_LOCATION, "LbChannelState+orphaned");
803
- }
804
-
805
- void XdsLb::LbChannelState::StartConnectivityWatchLocked() {
806
- grpc_channel_element* client_channel_elem =
807
- grpc_channel_stack_last_element(grpc_channel_get_channel_stack(channel_));
808
- GPR_ASSERT(client_channel_elem->filter == &grpc_client_channel_filter);
809
- // Ref held by callback.
810
- Ref(DEBUG_LOCATION, "LbChannelState+start_watch").release();
811
- grpc_client_channel_watch_connectivity_state(
812
- client_channel_elem,
813
- grpc_polling_entity_create_from_pollset_set(
814
- xdslb_policy_->interested_parties()),
815
- &connectivity_, &on_connectivity_changed_, nullptr);
816
- }
817
-
818
- void XdsLb::LbChannelState::CancelConnectivityWatchLocked() {
819
- grpc_channel_element* client_channel_elem =
820
- grpc_channel_stack_last_element(grpc_channel_get_channel_stack(channel_));
821
- GPR_ASSERT(client_channel_elem->filter == &grpc_client_channel_filter);
822
- grpc_client_channel_watch_connectivity_state(
823
- client_channel_elem,
824
- grpc_polling_entity_create_from_pollset_set(
825
- xdslb_policy_->interested_parties()),
826
- nullptr, &on_connectivity_changed_, nullptr);
827
- }
828
-
829
- void XdsLb::LbChannelState::OnConnectivityChangedLocked(void* arg,
830
- grpc_error* error) {
831
- LbChannelState* self = static_cast<LbChannelState*>(arg);
832
- if (!self->shutting_down_ &&
833
- self->xdslb_policy_->fallback_at_startup_checks_pending_) {
834
- if (self->connectivity_ != GRPC_CHANNEL_TRANSIENT_FAILURE) {
835
- // Not in TRANSIENT_FAILURE. Renew connectivity watch.
836
- grpc_channel_element* client_channel_elem =
837
- grpc_channel_stack_last_element(
838
- grpc_channel_get_channel_stack(self->channel_));
839
- GPR_ASSERT(client_channel_elem->filter == &grpc_client_channel_filter);
840
- grpc_client_channel_watch_connectivity_state(
841
- client_channel_elem,
842
- grpc_polling_entity_create_from_pollset_set(
843
- self->xdslb_policy_->interested_parties()),
844
- &self->connectivity_, &self->on_connectivity_changed_, nullptr);
845
- return; // Early out so we don't drop the ref below.
846
- }
847
- // In TRANSIENT_FAILURE. Cancel the fallback timer and go into
848
- // fallback mode immediately.
849
- gpr_log(GPR_INFO,
850
- "[xdslb %p] Balancer channel in state TRANSIENT_FAILURE; "
851
- "entering fallback mode",
852
- self);
853
- self->xdslb_policy_->fallback_at_startup_checks_pending_ = false;
854
- grpc_timer_cancel(&self->xdslb_policy_->lb_fallback_timer_);
855
- self->xdslb_policy_->UpdateFallbackPolicyLocked();
856
- }
857
- // Done watching connectivity state, so drop ref.
858
- self->Unref(DEBUG_LOCATION, "LbChannelState+watch_done");
859
- }
860
-
861
- //
862
- // XdsLb::LbChannelState::RetryableLbCall<>
863
- //
864
-
865
- template <typename T>
866
- XdsLb::LbChannelState::RetryableLbCall<T>::RetryableLbCall(
867
- RefCountedPtr<LbChannelState> lb_chand)
868
- : lb_chand_(std::move(lb_chand)),
869
- backoff_(
870
- BackOff::Options()
871
- .set_initial_backoff(GRPC_XDS_INITIAL_CONNECT_BACKOFF_SECONDS *
872
- 1000)
873
- .set_multiplier(GRPC_XDS_RECONNECT_BACKOFF_MULTIPLIER)
874
- .set_jitter(GRPC_XDS_RECONNECT_JITTER)
875
- .set_max_backoff(GRPC_XDS_RECONNECT_MAX_BACKOFF_SECONDS * 1000)) {
876
- GRPC_CLOSURE_INIT(
877
- &on_retry_timer_, OnRetryTimerLocked, this,
878
- grpc_combiner_scheduler(lb_chand_->xdslb_policy()->combiner()));
879
- StartNewCallLocked();
880
- }
881
-
882
- template <typename T>
883
- void XdsLb::LbChannelState::RetryableLbCall<T>::Orphan() {
884
- shutting_down_ = true;
885
- lb_calld_.reset();
886
- if (retry_timer_callback_pending_) grpc_timer_cancel(&retry_timer_);
887
- this->Unref(DEBUG_LOCATION, "RetryableLbCall+orphaned");
888
- }
889
-
890
- template <typename T>
891
- void XdsLb::LbChannelState::RetryableLbCall<T>::OnCallFinishedLocked() {
892
- const bool seen_response = lb_calld_->seen_response();
893
- lb_calld_.reset();
894
- if (seen_response) {
895
- // If we lost connection to the LB server, reset backoff and restart the LB
896
- // call immediately.
897
- backoff_.Reset();
898
- StartNewCallLocked();
899
- } else {
900
- // If we failed to connect to the LB server, retry later.
901
- StartRetryTimerLocked();
902
- }
903
- }
904
-
905
- template <typename T>
906
- void XdsLb::LbChannelState::RetryableLbCall<T>::StartNewCallLocked() {
907
- if (shutting_down_) return;
908
- GPR_ASSERT(lb_chand_->channel_ != nullptr);
909
- GPR_ASSERT(lb_calld_ == nullptr);
910
- if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) {
911
- gpr_log(GPR_INFO,
912
- "[xdslb %p] Start new call from retryable call (lb_chand: %p, "
913
- "retryable call: %p)",
914
- lb_chand()->xdslb_policy(), lb_chand(), this);
915
- }
916
- lb_calld_ = MakeOrphanable<T>(
917
- this->Ref(DEBUG_LOCATION, "RetryableLbCall+start_new_call"));
918
- }
919
-
920
- template <typename T>
921
- void XdsLb::LbChannelState::RetryableLbCall<T>::StartRetryTimerLocked() {
922
- if (shutting_down_) return;
923
- const grpc_millis next_attempt_time = backoff_.NextAttemptTime();
924
- if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) {
925
- grpc_millis timeout = GPR_MAX(next_attempt_time - ExecCtx::Get()->Now(), 0);
926
- gpr_log(GPR_INFO,
927
- "[xdslb %p] Failed to connect to LB server (lb_chand: %p) "
928
- "retry timer will fire in %" PRId64 "ms.",
929
- lb_chand()->xdslb_policy(), lb_chand(), timeout);
930
- }
931
- this->Ref(DEBUG_LOCATION, "RetryableLbCall+retry_timer_start").release();
932
- grpc_timer_init(&retry_timer_, next_attempt_time, &on_retry_timer_);
933
- retry_timer_callback_pending_ = true;
934
- }
935
-
936
- template <typename T>
937
- void XdsLb::LbChannelState::RetryableLbCall<T>::OnRetryTimerLocked(
938
- void* arg, grpc_error* error) {
939
- RetryableLbCall* lb_calld = static_cast<RetryableLbCall*>(arg);
940
- lb_calld->retry_timer_callback_pending_ = false;
941
- if (!lb_calld->shutting_down_ && error == GRPC_ERROR_NONE) {
942
- if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) {
943
- gpr_log(GPR_INFO,
944
- "[xdslb %p] Retry timer fires (lb_chand: %p, retryable call: %p)",
945
- lb_calld->lb_chand()->xdslb_policy(), lb_calld->lb_chand(),
946
- lb_calld);
947
- }
948
- lb_calld->StartNewCallLocked();
949
- }
950
- lb_calld->Unref(DEBUG_LOCATION, "RetryableLbCall+retry_timer_done");
951
- }
952
-
953
- //
954
- // XdsLb::LbChannelState::EdsCallState
955
- //
956
-
957
- XdsLb::LbChannelState::EdsCallState::EdsCallState(
958
- RefCountedPtr<RetryableLbCall<EdsCallState>> parent)
959
- : InternallyRefCounted<EdsCallState>(&grpc_lb_xds_trace),
960
- parent_(std::move(parent)) {
961
- // Init the LB call. Note that the LB call will progress every time there's
962
- // activity in xdslb_policy()->interested_parties(), which is comprised of
963
- // the polling entities from client_channel.
964
- GPR_ASSERT(xdslb_policy() != nullptr);
965
- GPR_ASSERT(xdslb_policy()->server_name_ != nullptr);
966
- GPR_ASSERT(xdslb_policy()->server_name_[0] != '\0');
967
- const grpc_millis deadline =
968
- xdslb_policy()->lb_call_timeout_ms_ == 0
969
- ? GRPC_MILLIS_INF_FUTURE
970
- : ExecCtx::Get()->Now() + xdslb_policy()->lb_call_timeout_ms_;
971
- // Create an LB call with the specified method name.
972
- lb_call_ = grpc_channel_create_pollset_set_call(
973
- lb_chand()->channel_, nullptr, GRPC_PROPAGATE_DEFAULTS,
974
- xdslb_policy()->interested_parties(),
975
- GRPC_MDSTR_SLASH_ENVOY_DOT_API_DOT_V2_DOT_ENDPOINTDISCOVERYSERVICE_SLASH_STREAMENDPOINTS,
976
- nullptr, deadline, nullptr);
977
- GPR_ASSERT(lb_call_ != nullptr);
978
- // Init the LB call request payload.
979
- grpc_slice request_payload_slice =
980
- XdsEdsRequestCreateAndEncode(xdslb_policy()->server_name_);
981
- send_message_payload_ =
982
- grpc_raw_byte_buffer_create(&request_payload_slice, 1);
983
- grpc_slice_unref_internal(request_payload_slice);
984
- // Init other data associated with the LB call.
985
- grpc_metadata_array_init(&initial_metadata_recv_);
986
- grpc_metadata_array_init(&trailing_metadata_recv_);
987
- GRPC_CLOSURE_INIT(&on_response_received_, OnResponseReceivedLocked, this,
988
- grpc_combiner_scheduler(xdslb_policy()->combiner()));
989
- GRPC_CLOSURE_INIT(&on_status_received_, OnStatusReceivedLocked, this,
990
- grpc_combiner_scheduler(xdslb_policy()->combiner()));
991
- // Start the call.
992
- if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) {
993
- gpr_log(GPR_INFO,
994
- "[xdslb %p] Starting EDS call (lb_chand: %p, lb_calld: %p, "
995
- "lb_call: %p)",
996
- xdslb_policy(), lb_chand(), this, lb_call_);
997
- }
998
- // Create the ops.
999
- grpc_call_error call_error;
1000
- grpc_op ops[3];
1001
- memset(ops, 0, sizeof(ops));
1002
- // Op: send initial metadata.
1003
- grpc_op* op = ops;
1004
- op->op = GRPC_OP_SEND_INITIAL_METADATA;
1005
- op->data.send_initial_metadata.count = 0;
1006
- op->flags = 0;
1007
- op->reserved = nullptr;
1008
- op++;
1009
- // Op: send request message.
1010
- GPR_ASSERT(send_message_payload_ != nullptr);
1011
- op->op = GRPC_OP_SEND_MESSAGE;
1012
- op->data.send_message.send_message = send_message_payload_;
1013
- op->flags = 0;
1014
- op->reserved = nullptr;
1015
- op++;
1016
- call_error = grpc_call_start_batch_and_execute(lb_call_, ops,
1017
- (size_t)(op - ops), nullptr);
1018
- GPR_ASSERT(GRPC_CALL_OK == call_error);
1019
- // Op: recv initial metadata.
1020
- op = ops;
1021
- op->op = GRPC_OP_RECV_INITIAL_METADATA;
1022
- op->data.recv_initial_metadata.recv_initial_metadata =
1023
- &initial_metadata_recv_;
1024
- op->flags = 0;
1025
- op->reserved = nullptr;
1026
- op++;
1027
- // Op: recv response.
1028
- op->op = GRPC_OP_RECV_MESSAGE;
1029
- op->data.recv_message.recv_message = &recv_message_payload_;
1030
- op->flags = 0;
1031
- op->reserved = nullptr;
1032
- op++;
1033
- Ref(DEBUG_LOCATION, "EDS+OnResponseReceivedLocked").release();
1034
- call_error = grpc_call_start_batch_and_execute(
1035
- lb_call_, ops, (size_t)(op - ops), &on_response_received_);
1036
- GPR_ASSERT(GRPC_CALL_OK == call_error);
1037
- // Op: recv server status.
1038
- op = ops;
1039
- op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
1040
- op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv_;
1041
- op->data.recv_status_on_client.status = &status_code_;
1042
- op->data.recv_status_on_client.status_details = &status_details_;
1043
- op->flags = 0;
1044
- op->reserved = nullptr;
1045
- op++;
1046
- // This callback signals the end of the LB call, so it relies on the initial
1047
- // ref instead of a new ref. When it's invoked, it's the initial ref that is
1048
- // unreffed.
1049
- call_error = grpc_call_start_batch_and_execute(
1050
- lb_call_, ops, (size_t)(op - ops), &on_status_received_);
1051
- GPR_ASSERT(GRPC_CALL_OK == call_error);
1052
- }
1053
-
1054
- XdsLb::LbChannelState::EdsCallState::~EdsCallState() {
1055
- grpc_metadata_array_destroy(&initial_metadata_recv_);
1056
- grpc_metadata_array_destroy(&trailing_metadata_recv_);
1057
- grpc_byte_buffer_destroy(send_message_payload_);
1058
- grpc_byte_buffer_destroy(recv_message_payload_);
1059
- grpc_slice_unref_internal(status_details_);
1060
- GPR_ASSERT(lb_call_ != nullptr);
1061
- grpc_call_unref(lb_call_);
1062
- }
1063
-
1064
- void XdsLb::LbChannelState::EdsCallState::Orphan() {
1065
- GPR_ASSERT(lb_call_ != nullptr);
1066
- // If we are here because xdslb_policy wants to cancel the call,
1067
- // on_status_received_ will complete the cancellation and clean up. Otherwise,
1068
- // we are here because xdslb_policy has to orphan a failed call, then the
1069
- // following cancellation will be a no-op.
1070
- grpc_call_cancel(lb_call_, nullptr);
1071
- // Note that the initial ref is hold by on_status_received_. So the
1072
- // corresponding unref happens in on_status_received_ instead of here.
1073
- }
590
+ class XdsLb::EndpointWatcher : public XdsClient::EndpointWatcherInterface {
591
+ public:
592
+ explicit EndpointWatcher(RefCountedPtr<XdsLb> xds_policy)
593
+ : xds_policy_(std::move(xds_policy)) {}
1074
594
 
1075
- void XdsLb::LbChannelState::EdsCallState::OnResponseReceivedLocked(
1076
- void* arg, grpc_error* error) {
1077
- EdsCallState* eds_calld = static_cast<EdsCallState*>(arg);
1078
- LbChannelState* lb_chand = eds_calld->lb_chand();
1079
- XdsLb* xdslb_policy = eds_calld->xdslb_policy();
1080
- // Empty payload means the LB call was cancelled.
1081
- if (!eds_calld->IsCurrentCallOnChannel() ||
1082
- eds_calld->recv_message_payload_ == nullptr) {
1083
- eds_calld->Unref(DEBUG_LOCATION, "EDS+OnResponseReceivedLocked");
1084
- return;
1085
- }
1086
- // Read the response.
1087
- grpc_byte_buffer_reader bbr;
1088
- grpc_byte_buffer_reader_init(&bbr, eds_calld->recv_message_payload_);
1089
- grpc_slice response_slice = grpc_byte_buffer_reader_readall(&bbr);
1090
- grpc_byte_buffer_reader_destroy(&bbr);
1091
- grpc_byte_buffer_destroy(eds_calld->recv_message_payload_);
1092
- eds_calld->recv_message_payload_ = nullptr;
1093
- // TODO(juanlishen): When we convert this to use the xds protocol, the
1094
- // balancer will send us a fallback timeout such that we should go into
1095
- // fallback mode if we have lost contact with the balancer after a certain
1096
- // period of time. We will need to save the timeout value here, and then
1097
- // when the balancer call ends, we will need to start a timer for the
1098
- // specified period of time, and if the timer fires, we go into fallback
1099
- // mode. We will also need to cancel the timer when we receive a serverlist
1100
- // from the balancer.
1101
- // This anonymous lambda is a hack to avoid the usage of goto.
1102
- [&]() {
1103
- // Parse the response.
1104
- XdsUpdate update;
1105
- grpc_error* parse_error =
1106
- XdsEdsResponseDecodeAndParse(response_slice, &update);
1107
- if (parse_error != GRPC_ERROR_NONE) {
1108
- gpr_log(GPR_ERROR, "[xdslb %p] EDS response parsing failed. error=%s",
1109
- xdslb_policy, grpc_error_string(parse_error));
1110
- GRPC_ERROR_UNREF(parse_error);
1111
- return;
1112
- }
1113
- if (update.locality_list.empty() && !update.drop_all) {
1114
- char* response_slice_str =
1115
- grpc_dump_slice(response_slice, GPR_DUMP_ASCII | GPR_DUMP_HEX);
1116
- gpr_log(GPR_ERROR,
1117
- "[xdslb %p] EDS response '%s' doesn't contain any valid locality "
1118
- "but doesn't require to drop all calls. Ignoring.",
1119
- xdslb_policy, response_slice_str);
1120
- gpr_free(response_slice_str);
1121
- return;
1122
- }
1123
- eds_calld->seen_response_ = true;
595
+ void OnEndpointChanged(EdsUpdate update) override {
1124
596
  if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) {
1125
- gpr_log(GPR_INFO,
1126
- "[xdslb %p] EDS response with %" PRIuPTR
1127
- " localities and %" PRIuPTR
1128
- " drop categories received (drop_all=%d)",
1129
- xdslb_policy, update.locality_list.size(),
1130
- update.drop_config->drop_category_list().size(), update.drop_all);
1131
- for (size_t i = 0; i < update.locality_list.size(); ++i) {
1132
- const XdsLocalityInfo& locality = update.locality_list[i];
1133
- gpr_log(GPR_INFO,
1134
- "[xdslb %p] Locality %" PRIuPTR " %s contains %" PRIuPTR
1135
- " server addresses",
1136
- xdslb_policy, i,
1137
- locality.locality_name->AsHumanReadableString(),
1138
- locality.serverlist.size());
1139
- for (size_t j = 0; j < locality.serverlist.size(); ++j) {
1140
- char* ipport;
1141
- grpc_sockaddr_to_string(&ipport, &locality.serverlist[j].address(),
1142
- false);
1143
- gpr_log(GPR_INFO,
1144
- "[xdslb %p] Locality %" PRIuPTR
1145
- " %s, server address %" PRIuPTR ": %s",
1146
- xdslb_policy, i,
1147
- locality.locality_name->AsHumanReadableString(), j, ipport);
1148
- gpr_free(ipport);
1149
- }
1150
- }
1151
- for (size_t i = 0; i < update.drop_config->drop_category_list().size();
1152
- ++i) {
1153
- const XdsDropConfig::DropCategory& drop_category =
1154
- update.drop_config->drop_category_list()[i];
1155
- gpr_log(GPR_INFO,
1156
- "[xdslb %p] Drop category %s has drop rate %d per million",
1157
- xdslb_policy, drop_category.name.get(),
1158
- drop_category.parts_per_million);
1159
- }
1160
- }
1161
- // Pending LB channel receives a response; promote it.
1162
- // Note that this call can't be on a discarded pending channel, because
1163
- // such channels don't have any current call but we have checked this call
1164
- // is a current call.
1165
- if (!lb_chand->IsCurrentChannel()) {
1166
- if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) {
1167
- gpr_log(GPR_INFO,
1168
- "[xdslb %p] Pending LB channel %p receives EDS response; "
1169
- "promoting it to replace current LB channel %p",
1170
- xdslb_policy, lb_chand, xdslb_policy->lb_chand_.get());
1171
- }
1172
- // TODO(juanlishen): Maybe promote the pending LB channel when the
1173
- // response results a READY locality map.
1174
- xdslb_policy->lb_chand_ = std::move(xdslb_policy->pending_lb_chand_);
597
+ gpr_log(GPR_INFO, "[xdslb %p] Received EDS update from xds client",
598
+ xds_policy_.get());
1175
599
  }
1176
- // At this point, lb_chand must be the current LB channel, so try to start
1177
- // load reporting.
1178
- LrsCallState* lrs_calld = lb_chand->lrs_calld_->lb_calld();
1179
- if (lrs_calld != nullptr) lrs_calld->MaybeStartReportingLocked();
1180
600
  // If the balancer tells us to drop all the calls, we should exit fallback
1181
601
  // mode immediately.
1182
- if (update.drop_all) xdslb_policy->MaybeExitFallbackMode();
602
+ if (update.drop_all) xds_policy_->MaybeExitFallbackMode();
1183
603
  // Update the drop config.
1184
604
  const bool drop_config_changed =
1185
- xdslb_policy->drop_config_ == nullptr ||
1186
- *xdslb_policy->drop_config_ != *update.drop_config;
1187
- xdslb_policy->drop_config_ = std::move(update.drop_config);
605
+ xds_policy_->drop_config_ == nullptr ||
606
+ *xds_policy_->drop_config_ != *update.drop_config;
607
+ xds_policy_->drop_config_ = std::move(update.drop_config);
1188
608
  // Ignore identical locality update.
1189
- if (xdslb_policy->locality_list_ == update.locality_list) {
609
+ if (xds_policy_->priority_list_update_ == update.priority_list_update) {
1190
610
  if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) {
1191
611
  gpr_log(GPR_INFO,
1192
- "[xdslb %p] Incoming locality list identical to current, "
612
+ "[xdslb %p] Incoming locality update identical to current, "
1193
613
  "ignoring. (drop_config_changed=%d)",
1194
- xdslb_policy, drop_config_changed);
614
+ xds_policy_.get(), drop_config_changed);
1195
615
  }
1196
616
  if (drop_config_changed) {
1197
- xdslb_policy->locality_map_.UpdateXdsPickerLocked();
617
+ xds_policy_->priority_list_.UpdateXdsPickerLocked();
1198
618
  }
1199
619
  return;
1200
620
  }
1201
- // Update the locality list.
1202
- xdslb_policy->locality_list_ = std::move(update.locality_list);
1203
- // Update the locality map.
1204
- xdslb_policy->locality_map_.UpdateLocked(
1205
- xdslb_policy->locality_list_, xdslb_policy->child_policy_config_.get(),
1206
- xdslb_policy->args_, xdslb_policy);
1207
- }();
1208
- grpc_slice_unref_internal(response_slice);
1209
- if (xdslb_policy->shutting_down_) {
1210
- eds_calld->Unref(DEBUG_LOCATION,
1211
- "EDS+OnResponseReceivedLocked+xds_shutdown");
1212
- return;
1213
- }
1214
- // Keep listening for serverlist updates.
1215
- grpc_op op;
1216
- memset(&op, 0, sizeof(op));
1217
- op.op = GRPC_OP_RECV_MESSAGE;
1218
- op.data.recv_message.recv_message = &eds_calld->recv_message_payload_;
1219
- op.flags = 0;
1220
- op.reserved = nullptr;
1221
- GPR_ASSERT(eds_calld->lb_call_ != nullptr);
1222
- // Reuse the "EDS+OnResponseReceivedLocked" ref taken in ctor.
1223
- const grpc_call_error call_error = grpc_call_start_batch_and_execute(
1224
- eds_calld->lb_call_, &op, 1, &eds_calld->on_response_received_);
1225
- GPR_ASSERT(GRPC_CALL_OK == call_error);
1226
- }
1227
-
1228
- void XdsLb::LbChannelState::EdsCallState::OnStatusReceivedLocked(
1229
- void* arg, grpc_error* error) {
1230
- EdsCallState* eds_calld = static_cast<EdsCallState*>(arg);
1231
- LbChannelState* lb_chand = eds_calld->lb_chand();
1232
- XdsLb* xdslb_policy = eds_calld->xdslb_policy();
1233
- if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) {
1234
- char* status_details = grpc_slice_to_c_string(eds_calld->status_details_);
1235
- gpr_log(GPR_INFO,
1236
- "[xdslb %p] EDS call status received. Status = %d, details "
1237
- "= '%s', (lb_chand: %p, eds_calld: %p, lb_call: %p), error '%s'",
1238
- xdslb_policy, eds_calld->status_code_, status_details, lb_chand,
1239
- eds_calld, eds_calld->lb_call_, grpc_error_string(error));
1240
- gpr_free(status_details);
1241
- }
1242
- // Ignore status from a stale call.
1243
- if (eds_calld->IsCurrentCallOnChannel()) {
1244
- // Because this call is the current one on the channel, the channel can't
1245
- // have been swapped out; otherwise, the call should have been reset.
1246
- GPR_ASSERT(lb_chand->IsCurrentChannel() || lb_chand->IsPendingChannel());
1247
- if (lb_chand != xdslb_policy->LatestLbChannel()) {
1248
- // This channel must be the current one and there is a pending one. Swap
1249
- // in the pending one and we are done.
1250
- if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) {
1251
- gpr_log(GPR_INFO,
1252
- "[xdslb %p] Promoting pending LB channel %p to replace "
1253
- "current LB channel %p",
1254
- xdslb_policy, lb_chand, xdslb_policy->lb_chand_.get());
1255
- }
1256
- xdslb_policy->lb_chand_ = std::move(xdslb_policy->pending_lb_chand_);
1257
- } else {
1258
- // This channel is the most recently created one. Try to restart the call
1259
- // and reresolve.
1260
- eds_calld->parent_->OnCallFinishedLocked();
1261
- xdslb_policy->channel_control_helper()->RequestReresolution();
1262
- // If the fallback-at-startup checks are pending, go into fallback mode
1263
- // immediately. This short-circuits the timeout for the
1264
- // fallback-at-startup case.
1265
- if (xdslb_policy->fallback_at_startup_checks_pending_) {
1266
- gpr_log(GPR_INFO,
1267
- "[xdslb %p] Balancer call finished; entering fallback mode",
1268
- xdslb_policy);
1269
- xdslb_policy->fallback_at_startup_checks_pending_ = false;
1270
- grpc_timer_cancel(&xdslb_policy->lb_fallback_timer_);
1271
- lb_chand->CancelConnectivityWatchLocked();
1272
- xdslb_policy->UpdateFallbackPolicyLocked();
1273
- }
1274
- }
1275
- }
1276
- eds_calld->Unref(DEBUG_LOCATION, "EDS+OnStatusReceivedLocked");
1277
- }
1278
-
1279
- bool XdsLb::LbChannelState::EdsCallState::IsCurrentCallOnChannel() const {
1280
- // If the retryable EDS call is null (which only happens when the LB channel
1281
- // is shutting down), all the EDS calls are stale.
1282
- if (lb_chand()->eds_calld_ == nullptr) return false;
1283
- return this == lb_chand()->eds_calld_->lb_calld();
1284
- }
1285
-
1286
- //
1287
- // XdsLb::LbChannelState::LrsCallState::Reporter
1288
- //
1289
-
1290
- void XdsLb::LbChannelState::LrsCallState::Reporter::Orphan() {
1291
- if (next_report_timer_callback_pending_) {
1292
- grpc_timer_cancel(&next_report_timer_);
1293
- }
1294
- }
1295
-
1296
- void XdsLb::LbChannelState::LrsCallState::Reporter::ScheduleNextReportLocked() {
1297
- const grpc_millis next_report_time = ExecCtx::Get()->Now() + report_interval_;
1298
- grpc_timer_init(&next_report_timer_, next_report_time,
1299
- &on_next_report_timer_);
1300
- next_report_timer_callback_pending_ = true;
1301
- }
1302
-
1303
- void XdsLb::LbChannelState::LrsCallState::Reporter::OnNextReportTimerLocked(
1304
- void* arg, grpc_error* error) {
1305
- Reporter* self = static_cast<Reporter*>(arg);
1306
- self->next_report_timer_callback_pending_ = false;
1307
- if (error != GRPC_ERROR_NONE || !self->IsCurrentReporterOnCall()) {
1308
- self->Unref(DEBUG_LOCATION, "Reporter+timer");
1309
- return;
621
+ // Update the priority list.
622
+ xds_policy_->priority_list_update_ = std::move(update.priority_list_update);
623
+ xds_policy_->priority_list_.UpdateLocked();
1310
624
  }
1311
- self->SendReportLocked();
1312
- }
1313
625
 
1314
- void XdsLb::LbChannelState::LrsCallState::Reporter::SendReportLocked() {
1315
- // Create a request that contains the load report.
1316
- grpc_slice request_payload_slice = XdsLrsRequestCreateAndEncode(
1317
- xdslb_policy()->server_name_, &xdslb_policy()->client_stats_);
1318
- // Skip client load report if the counters were all zero in the last
1319
- // report and they are still zero in this one.
1320
- const bool old_val = last_report_counters_were_zero_;
1321
- last_report_counters_were_zero_ = static_cast<bool>(
1322
- grpc_slice_eq(request_payload_slice, grpc_empty_slice()));
1323
- if (old_val && last_report_counters_were_zero_) {
1324
- ScheduleNextReportLocked();
1325
- return;
1326
- }
1327
- parent_->send_message_payload_ =
1328
- grpc_raw_byte_buffer_create(&request_payload_slice, 1);
1329
- grpc_slice_unref_internal(request_payload_slice);
1330
- // Send the report.
1331
- grpc_op op;
1332
- memset(&op, 0, sizeof(op));
1333
- op.op = GRPC_OP_SEND_MESSAGE;
1334
- op.data.send_message.send_message = parent_->send_message_payload_;
1335
- grpc_call_error call_error = grpc_call_start_batch_and_execute(
1336
- parent_->lb_call_, &op, 1, &on_report_done_);
1337
- if (GPR_UNLIKELY(call_error != GRPC_CALL_OK)) {
1338
- gpr_log(GPR_ERROR,
1339
- "[xdslb %p] lb_calld=%p call_error=%d sending client load report",
1340
- xdslb_policy(), this, call_error);
1341
- GPR_ASSERT(GRPC_CALL_OK == call_error);
1342
- }
1343
- }
1344
-
1345
- void XdsLb::LbChannelState::LrsCallState::Reporter::OnReportDoneLocked(
1346
- void* arg, grpc_error* error) {
1347
- Reporter* self = static_cast<Reporter*>(arg);
1348
- grpc_byte_buffer_destroy(self->parent_->send_message_payload_);
1349
- self->parent_->send_message_payload_ = nullptr;
1350
- if (error != GRPC_ERROR_NONE || !self->IsCurrentReporterOnCall()) {
1351
- // If this reporter is no longer the current one on the call, the reason
1352
- // might be that it was orphaned for a new one due to config update.
1353
- if (!self->IsCurrentReporterOnCall()) {
1354
- self->parent_->MaybeStartReportingLocked();
1355
- }
1356
- self->Unref(DEBUG_LOCATION, "Reporter+report_done");
1357
- return;
1358
- }
1359
- self->ScheduleNextReportLocked();
1360
- }
1361
-
1362
- //
1363
- // XdsLb::LbChannelState::LrsCallState
1364
- //
1365
-
1366
- XdsLb::LbChannelState::LrsCallState::LrsCallState(
1367
- RefCountedPtr<RetryableLbCall<LrsCallState>> parent)
1368
- : InternallyRefCounted<LrsCallState>(&grpc_lb_xds_trace),
1369
- parent_(std::move(parent)) {
1370
- // Init the LB call. Note that the LB call will progress every time there's
1371
- // activity in xdslb_policy()->interested_parties(), which is comprised of
1372
- // the polling entities from client_channel.
1373
- GPR_ASSERT(xdslb_policy() != nullptr);
1374
- GPR_ASSERT(xdslb_policy()->server_name_ != nullptr);
1375
- GPR_ASSERT(xdslb_policy()->server_name_[0] != '\0');
1376
- const grpc_millis deadline =
1377
- xdslb_policy()->lb_call_timeout_ms_ == 0
1378
- ? GRPC_MILLIS_INF_FUTURE
1379
- : ExecCtx::Get()->Now() + xdslb_policy()->lb_call_timeout_ms_;
1380
- lb_call_ = grpc_channel_create_pollset_set_call(
1381
- lb_chand()->channel_, nullptr, GRPC_PROPAGATE_DEFAULTS,
1382
- xdslb_policy()->interested_parties(),
1383
- GRPC_MDSTR_SLASH_ENVOY_DOT_SERVICE_DOT_LOAD_STATS_DOT_V2_DOT_LOADREPORTINGSERVICE_SLASH_STREAMLOADSTATS,
1384
- nullptr, deadline, nullptr);
1385
- GPR_ASSERT(lb_call_ != nullptr);
1386
- // Init the LB call request payload.
1387
- grpc_slice request_payload_slice =
1388
- XdsLrsRequestCreateAndEncode(xdslb_policy()->server_name_);
1389
- send_message_payload_ =
1390
- grpc_raw_byte_buffer_create(&request_payload_slice, 1);
1391
- grpc_slice_unref_internal(request_payload_slice);
1392
- // Init other data associated with the LRS call.
1393
- grpc_metadata_array_init(&initial_metadata_recv_);
1394
- grpc_metadata_array_init(&trailing_metadata_recv_);
1395
- GRPC_CLOSURE_INIT(&on_initial_request_sent_, OnInitialRequestSentLocked, this,
1396
- grpc_combiner_scheduler(xdslb_policy()->combiner()));
1397
- GRPC_CLOSURE_INIT(&on_response_received_, OnResponseReceivedLocked, this,
1398
- grpc_combiner_scheduler(xdslb_policy()->combiner()));
1399
- GRPC_CLOSURE_INIT(&on_status_received_, OnStatusReceivedLocked, this,
1400
- grpc_combiner_scheduler(xdslb_policy()->combiner()));
1401
- // Start the call.
1402
- if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) {
1403
- gpr_log(GPR_INFO,
1404
- "[xdslb %p] Starting LRS call (lb_chand: %p, lb_calld: %p, "
1405
- "lb_call: %p)",
1406
- xdslb_policy(), lb_chand(), this, lb_call_);
1407
- }
1408
- // Create the ops.
1409
- grpc_call_error call_error;
1410
- grpc_op ops[3];
1411
- memset(ops, 0, sizeof(ops));
1412
- // Op: send initial metadata.
1413
- grpc_op* op = ops;
1414
- op->op = GRPC_OP_SEND_INITIAL_METADATA;
1415
- op->data.send_initial_metadata.count = 0;
1416
- op->flags = 0;
1417
- op->reserved = nullptr;
1418
- op++;
1419
- // Op: send request message.
1420
- GPR_ASSERT(send_message_payload_ != nullptr);
1421
- op->op = GRPC_OP_SEND_MESSAGE;
1422
- op->data.send_message.send_message = send_message_payload_;
1423
- op->flags = 0;
1424
- op->reserved = nullptr;
1425
- op++;
1426
- Ref(DEBUG_LOCATION, "LRS+OnInitialRequestSentLocked").release();
1427
- call_error = grpc_call_start_batch_and_execute(
1428
- lb_call_, ops, (size_t)(op - ops), &on_initial_request_sent_);
1429
- GPR_ASSERT(GRPC_CALL_OK == call_error);
1430
- // Op: recv initial metadata.
1431
- op = ops;
1432
- op->op = GRPC_OP_RECV_INITIAL_METADATA;
1433
- op->data.recv_initial_metadata.recv_initial_metadata =
1434
- &initial_metadata_recv_;
1435
- op->flags = 0;
1436
- op->reserved = nullptr;
1437
- op++;
1438
- // Op: recv response.
1439
- op->op = GRPC_OP_RECV_MESSAGE;
1440
- op->data.recv_message.recv_message = &recv_message_payload_;
1441
- op->flags = 0;
1442
- op->reserved = nullptr;
1443
- op++;
1444
- Ref(DEBUG_LOCATION, "LRS+OnResponseReceivedLocked").release();
1445
- call_error = grpc_call_start_batch_and_execute(
1446
- lb_call_, ops, (size_t)(op - ops), &on_response_received_);
1447
- GPR_ASSERT(GRPC_CALL_OK == call_error);
1448
- // Op: recv server status.
1449
- op = ops;
1450
- op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
1451
- op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv_;
1452
- op->data.recv_status_on_client.status = &status_code_;
1453
- op->data.recv_status_on_client.status_details = &status_details_;
1454
- op->flags = 0;
1455
- op->reserved = nullptr;
1456
- op++;
1457
- // This callback signals the end of the LB call, so it relies on the initial
1458
- // ref instead of a new ref. When it's invoked, it's the initial ref that is
1459
- // unreffed.
1460
- call_error = grpc_call_start_batch_and_execute(
1461
- lb_call_, ops, (size_t)(op - ops), &on_status_received_);
1462
- GPR_ASSERT(GRPC_CALL_OK == call_error);
1463
- }
1464
-
1465
- XdsLb::LbChannelState::LrsCallState::~LrsCallState() {
1466
- grpc_metadata_array_destroy(&initial_metadata_recv_);
1467
- grpc_metadata_array_destroy(&trailing_metadata_recv_);
1468
- grpc_byte_buffer_destroy(send_message_payload_);
1469
- grpc_byte_buffer_destroy(recv_message_payload_);
1470
- grpc_slice_unref_internal(status_details_);
1471
- GPR_ASSERT(lb_call_ != nullptr);
1472
- grpc_call_unref(lb_call_);
1473
- }
1474
-
1475
- void XdsLb::LbChannelState::LrsCallState::Orphan() {
1476
- reporter_.reset();
1477
- GPR_ASSERT(lb_call_ != nullptr);
1478
- // If we are here because xdslb_policy wants to cancel the call,
1479
- // on_status_received_ will complete the cancellation and clean up. Otherwise,
1480
- // we are here because xdslb_policy has to orphan a failed call, then the
1481
- // following cancellation will be a no-op.
1482
- grpc_call_cancel(lb_call_, nullptr);
1483
- // Note that the initial ref is hold by on_status_received_. So the
1484
- // corresponding unref happens in on_status_received_ instead of here.
1485
- }
1486
-
1487
- void XdsLb::LbChannelState::LrsCallState::MaybeStartReportingLocked() {
1488
- // Don't start if this is not the current call on the current channel.
1489
- if (!IsCurrentCallOnChannel() || !lb_chand()->IsCurrentChannel()) return;
1490
- // Don't start again if already started.
1491
- if (reporter_ != nullptr) return;
1492
- // Don't start if the previous send_message op (of the initial request or the
1493
- // last report of the previous reporter) hasn't completed.
1494
- if (send_message_payload_ != nullptr) return;
1495
- // Don't start if no LRS response has arrived.
1496
- if (!seen_response()) return;
1497
- // Don't start if the EDS call hasn't received any valid response. Note that
1498
- // this must be the first channel because it is the current channel but its
1499
- // EDS call hasn't seen any response.
1500
- EdsCallState* eds_calld = lb_chand()->eds_calld_->lb_calld();
1501
- if (eds_calld == nullptr || !eds_calld->seen_response()) return;
1502
- // Start reporting.
1503
- lb_chand()->xdslb_policy_->client_stats_.MaybeInitLastReportTime();
1504
- reporter_ = MakeOrphanable<Reporter>(
1505
- Ref(DEBUG_LOCATION, "LRS+load_report+start"), load_reporting_interval_);
1506
- }
1507
-
1508
- void XdsLb::LbChannelState::LrsCallState::OnInitialRequestSentLocked(
1509
- void* arg, grpc_error* error) {
1510
- LrsCallState* lrs_calld = static_cast<LrsCallState*>(arg);
1511
- // Clear the send_message_payload_.
1512
- grpc_byte_buffer_destroy(lrs_calld->send_message_payload_);
1513
- lrs_calld->send_message_payload_ = nullptr;
1514
- lrs_calld->MaybeStartReportingLocked();
1515
- lrs_calld->Unref(DEBUG_LOCATION, "LRS+OnInitialRequestSentLocked");
1516
- }
1517
-
1518
- void XdsLb::LbChannelState::LrsCallState::OnResponseReceivedLocked(
1519
- void* arg, grpc_error* error) {
1520
- LrsCallState* lrs_calld = static_cast<LrsCallState*>(arg);
1521
- XdsLb* xdslb_policy = lrs_calld->xdslb_policy();
1522
- // Empty payload means the LB call was cancelled.
1523
- if (!lrs_calld->IsCurrentCallOnChannel() ||
1524
- lrs_calld->recv_message_payload_ == nullptr) {
1525
- lrs_calld->Unref(DEBUG_LOCATION, "LRS+OnResponseReceivedLocked");
1526
- return;
1527
- }
1528
- // Read the response.
1529
- grpc_byte_buffer_reader bbr;
1530
- grpc_byte_buffer_reader_init(&bbr, lrs_calld->recv_message_payload_);
1531
- grpc_slice response_slice = grpc_byte_buffer_reader_readall(&bbr);
1532
- grpc_byte_buffer_reader_destroy(&bbr);
1533
- grpc_byte_buffer_destroy(lrs_calld->recv_message_payload_);
1534
- lrs_calld->recv_message_payload_ = nullptr;
1535
- // This anonymous lambda is a hack to avoid the usage of goto.
1536
- [&]() {
1537
- // Parse the response.
1538
- grpc_millis new_load_reporting_interval;
1539
- grpc_error* parse_error = XdsLrsResponseDecodeAndParse(
1540
- response_slice, &new_load_reporting_interval,
1541
- xdslb_policy->server_name_);
1542
- if (parse_error != GRPC_ERROR_NONE) {
1543
- gpr_log(GPR_ERROR, "[xdslb %p] LRS response parsing failed. error=%s",
1544
- xdslb_policy, grpc_error_string(parse_error));
1545
- GRPC_ERROR_UNREF(parse_error);
1546
- return;
1547
- }
1548
- lrs_calld->seen_response_ = true;
1549
- if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) {
626
+ void OnError(grpc_error* error) override {
627
+ // If the fallback-at-startup checks are pending, go into fallback mode
628
+ // immediately. This short-circuits the timeout for the
629
+ // fallback-at-startup case.
630
+ if (xds_policy_->fallback_at_startup_checks_pending_) {
1550
631
  gpr_log(GPR_INFO,
1551
- "[xdslb %p] LRS response received, load_report_interval=%" PRId64
1552
- "ms",
1553
- xdslb_policy, new_load_reporting_interval);
1554
- }
1555
- if (new_load_reporting_interval <
1556
- GRPC_XDS_MIN_CLIENT_LOAD_REPORTING_INTERVAL_MS) {
1557
- new_load_reporting_interval =
1558
- GRPC_XDS_MIN_CLIENT_LOAD_REPORTING_INTERVAL_MS;
1559
- if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) {
1560
- gpr_log(
1561
- GPR_INFO,
1562
- "[xdslb %p] Increased load_report_interval to minimum value %dms",
1563
- xdslb_policy, GRPC_XDS_MIN_CLIENT_LOAD_REPORTING_INTERVAL_MS);
1564
- }
1565
- }
1566
- // Ignore identical update.
1567
- if (lrs_calld->load_reporting_interval_ == new_load_reporting_interval) {
1568
- if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) {
1569
- gpr_log(GPR_INFO,
1570
- "[xdslb %p] Incoming LRS response identical to current, "
1571
- "ignoring.",
1572
- xdslb_policy);
632
+ "[xdslb %p] xds watcher reported error; entering fallback "
633
+ "mode: %s",
634
+ xds_policy_.get(), grpc_error_string(error));
635
+ xds_policy_->fallback_at_startup_checks_pending_ = false;
636
+ grpc_timer_cancel(&xds_policy_->lb_fallback_timer_);
637
+ xds_policy_->UpdateFallbackPolicyLocked();
638
+ // If the xds call failed, request re-resolution.
639
+ // TODO(roth): We check the error string contents here to
640
+ // differentiate between the xds call failing and the xds channel
641
+ // going into TRANSIENT_FAILURE. This is a pretty ugly hack,
642
+ // but it's okay for now, since we're not yet sure whether we will
643
+ // continue to support the current fallback functionality. If we
644
+ // decide to keep the fallback approach, then we should either
645
+ // find a cleaner way to expose the difference between these two
646
+ // cases or decide that we're okay re-resolving in both cases.
647
+ // Note that even if we do keep the current fallback functionality,
648
+ // this re-resolution will only be necessary if we are going to be
649
+ // using this LB policy with resolvers other than the xds resolver.
650
+ if (strstr(grpc_error_string(error), "xds call failed")) {
651
+ xds_policy_->channel_control_helper()->RequestReresolution();
1573
652
  }
1574
- return;
1575
- }
1576
- // Stop current load reporting (if any) to adopt the new reporting interval.
1577
- lrs_calld->reporter_.reset();
1578
- // Record the new config.
1579
- lrs_calld->load_reporting_interval_ = new_load_reporting_interval;
1580
- // Try starting sending load report.
1581
- lrs_calld->MaybeStartReportingLocked();
1582
- }();
1583
- grpc_slice_unref_internal(response_slice);
1584
- if (xdslb_policy->shutting_down_) {
1585
- lrs_calld->Unref(DEBUG_LOCATION,
1586
- "LRS+OnResponseReceivedLocked+xds_shutdown");
1587
- return;
1588
- }
1589
- // Keep listening for LRS config updates.
1590
- grpc_op op;
1591
- memset(&op, 0, sizeof(op));
1592
- op.op = GRPC_OP_RECV_MESSAGE;
1593
- op.data.recv_message.recv_message = &lrs_calld->recv_message_payload_;
1594
- op.flags = 0;
1595
- op.reserved = nullptr;
1596
- GPR_ASSERT(lrs_calld->lb_call_ != nullptr);
1597
- // Reuse the "OnResponseReceivedLocked" ref taken in ctor.
1598
- const grpc_call_error call_error = grpc_call_start_batch_and_execute(
1599
- lrs_calld->lb_call_, &op, 1, &lrs_calld->on_response_received_);
1600
- GPR_ASSERT(GRPC_CALL_OK == call_error);
1601
- }
1602
-
1603
- void XdsLb::LbChannelState::LrsCallState::OnStatusReceivedLocked(
1604
- void* arg, grpc_error* error) {
1605
- LrsCallState* lrs_calld = static_cast<LrsCallState*>(arg);
1606
- XdsLb* xdslb_policy = lrs_calld->xdslb_policy();
1607
- LbChannelState* lb_chand = lrs_calld->lb_chand();
1608
- GPR_ASSERT(lrs_calld->lb_call_ != nullptr);
1609
- if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) {
1610
- char* status_details = grpc_slice_to_c_string(lrs_calld->status_details_);
1611
- gpr_log(GPR_INFO,
1612
- "[xdslb %p] LRS call status received. Status = %d, details "
1613
- "= '%s', (lb_chand: %p, lb_calld: %p, lb_call: %p), error '%s'",
1614
- xdslb_policy, lrs_calld->status_code_, status_details, lb_chand,
1615
- lrs_calld, lrs_calld->lb_call_, grpc_error_string(error));
1616
- gpr_free(status_details);
1617
- }
1618
- // Ignore status from a stale call.
1619
- if (lrs_calld->IsCurrentCallOnChannel()) {
1620
- // Because this call is the current one on the channel, the channel can't
1621
- // have been swapped out; otherwise, the call should have been reset.
1622
- GPR_ASSERT(lb_chand->IsCurrentChannel() || lb_chand->IsPendingChannel());
1623
- GPR_ASSERT(!xdslb_policy->shutting_down_);
1624
- if (lb_chand == xdslb_policy->LatestLbChannel()) {
1625
- // This channel is the most recently created one. Try to restart the call
1626
- // and reresolve.
1627
- lrs_calld->parent_->OnCallFinishedLocked();
1628
- xdslb_policy->channel_control_helper()->RequestReresolution();
1629
653
  }
654
+ GRPC_ERROR_UNREF(error);
1630
655
  }
1631
- lrs_calld->Unref(DEBUG_LOCATION, "LRS+OnStatusReceivedLocked");
1632
- }
1633
-
1634
- bool XdsLb::LbChannelState::LrsCallState::IsCurrentCallOnChannel() const {
1635
- // If the retryable LRS call is null (which only happens when the LB channel
1636
- // is shutting down), all the LRS calls are stale.
1637
- if (lb_chand()->lrs_calld_ == nullptr) return false;
1638
- return this == lb_chand()->lrs_calld_->lb_calld();
1639
- }
1640
-
1641
- //
1642
- // helper code for creating balancer channel
1643
- //
1644
656
 
1645
- // Returns the channel args for the LB channel, used to create a bidirectional
1646
- // stream for the reception of load balancing updates.
1647
- grpc_channel_args* BuildBalancerChannelArgs(const grpc_channel_args* args) {
1648
- static const char* args_to_remove[] = {
1649
- // LB policy name, since we want to use the default (pick_first) in
1650
- // the LB channel.
1651
- GRPC_ARG_LB_POLICY_NAME,
1652
- // The service config that contains the LB config. We don't want to
1653
- // recursively use xds in the LB channel.
1654
- GRPC_ARG_SERVICE_CONFIG,
1655
- // The channel arg for the server URI, since that will be different for
1656
- // the LB channel than for the parent channel. The client channel
1657
- // factory will re-add this arg with the right value.
1658
- GRPC_ARG_SERVER_URI,
1659
- // The LB channel should use the authority indicated by the target
1660
- // authority table (see \a ModifyXdsBalancerChannelArgs),
1661
- // as opposed to the authority from the parent channel.
1662
- GRPC_ARG_DEFAULT_AUTHORITY,
1663
- // Just as for \a GRPC_ARG_DEFAULT_AUTHORITY, the LB channel should be
1664
- // treated as a stand-alone channel and not inherit this argument from the
1665
- // args of the parent channel.
1666
- GRPC_SSL_TARGET_NAME_OVERRIDE_ARG,
1667
- // Don't want to pass down channelz node from parent; the balancer
1668
- // channel will get its own.
1669
- GRPC_ARG_CHANNELZ_CHANNEL_NODE,
1670
- };
1671
- // Channel args to add.
1672
- InlinedVector<grpc_arg, 2> args_to_add;
1673
- // A channel arg indicating the target is a xds load balancer.
1674
- args_to_add.emplace_back(grpc_channel_arg_integer_create(
1675
- const_cast<char*>(GRPC_ARG_ADDRESS_IS_XDS_LOAD_BALANCER), 1));
1676
- // The parent channel's channelz uuid.
1677
- channelz::ChannelNode* channelz_node = nullptr;
1678
- const grpc_arg* arg =
1679
- grpc_channel_args_find(args, GRPC_ARG_CHANNELZ_CHANNEL_NODE);
1680
- if (arg != nullptr && arg->type == GRPC_ARG_POINTER &&
1681
- arg->value.pointer.p != nullptr) {
1682
- channelz_node = static_cast<channelz::ChannelNode*>(arg->value.pointer.p);
1683
- args_to_add.emplace_back(
1684
- channelz::MakeParentUuidArg(channelz_node->uuid()));
1685
- }
1686
- // Construct channel args.
1687
- grpc_channel_args* new_args = grpc_channel_args_copy_and_add_and_remove(
1688
- args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), args_to_add.data(),
1689
- args_to_add.size());
1690
- // Make any necessary modifications for security.
1691
- return ModifyXdsBalancerChannelArgs(new_args);
1692
- }
657
+ private:
658
+ RefCountedPtr<XdsLb> xds_policy_;
659
+ };
1693
660
 
1694
661
  //
1695
662
  // ctor and dtor
@@ -1697,15 +664,22 @@ grpc_channel_args* BuildBalancerChannelArgs(const grpc_channel_args* args) {
1697
664
 
1698
665
  XdsLb::XdsLb(Args args)
1699
666
  : LoadBalancingPolicy(std::move(args)),
1700
- lb_call_timeout_ms_(grpc_channel_args_find_integer(
1701
- args.args, GRPC_ARG_GRPCLB_CALL_TIMEOUT_MS, {0, 0, INT_MAX})),
667
+ xds_client_from_channel_(XdsClient::GetFromChannelArgs(*args.args)),
1702
668
  lb_fallback_timeout_ms_(grpc_channel_args_find_integer(
1703
669
  args.args, GRPC_ARG_XDS_FALLBACK_TIMEOUT_MS,
1704
670
  {GRPC_XDS_DEFAULT_FALLBACK_TIMEOUT_MS, 0, INT_MAX})),
1705
671
  locality_retention_interval_ms_(grpc_channel_args_find_integer(
1706
672
  args.args, GRPC_ARG_LOCALITY_RETENTION_INTERVAL_MS,
1707
673
  {GRPC_XDS_DEFAULT_LOCALITY_RETENTION_INTERVAL_MS, 0, INT_MAX})),
1708
- locality_map_(this) {
674
+ locality_map_failover_timeout_ms_(grpc_channel_args_find_integer(
675
+ args.args, GRPC_ARG_XDS_FAILOVER_TIMEOUT_MS,
676
+ {GRPC_XDS_DEFAULT_FAILOVER_TIMEOUT_MS, 0, INT_MAX})),
677
+ priority_list_(this) {
678
+ if (xds_client_from_channel_ != nullptr &&
679
+ GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) {
680
+ gpr_log(GPR_INFO, "[xdslb %p] Using xds client %p from channel", this,
681
+ xds_client_from_channel_.get());
682
+ }
1709
683
  // Record server name.
1710
684
  const grpc_arg* arg = grpc_channel_args_find(args.args, GRPC_ARG_SERVER_URI);
1711
685
  const char* server_uri = grpc_channel_arg_get_string(arg);
@@ -1727,7 +701,6 @@ XdsLb::~XdsLb() {
1727
701
  }
1728
702
  gpr_free((void*)server_name_);
1729
703
  grpc_channel_args_destroy(args_);
1730
- locality_list_.clear();
1731
704
  }
1732
705
 
1733
706
  void XdsLb::ShutdownLocked() {
@@ -1735,10 +708,8 @@ void XdsLb::ShutdownLocked() {
1735
708
  gpr_log(GPR_INFO, "[xdslb %p] shutting down", this);
1736
709
  }
1737
710
  shutting_down_ = true;
1738
- if (fallback_at_startup_checks_pending_) {
1739
- grpc_timer_cancel(&lb_fallback_timer_);
1740
- }
1741
- locality_map_.ShutdownLocked();
711
+ MaybeCancelFallbackAtStartupChecks();
712
+ priority_list_.ShutdownLocked();
1742
713
  if (fallback_policy_ != nullptr) {
1743
714
  grpc_pollset_set_del_pollset_set(fallback_policy_->interested_parties(),
1744
715
  interested_parties());
@@ -1749,10 +720,13 @@ void XdsLb::ShutdownLocked() {
1749
720
  }
1750
721
  fallback_policy_.reset();
1751
722
  pending_fallback_policy_.reset();
1752
- // We reset the LB channels here instead of in our destructor because they
1753
- // hold refs to XdsLb.
1754
- lb_chand_.reset();
1755
- pending_lb_chand_.reset();
723
+ // Cancel the endpoint watch here instead of in our dtor, because the
724
+ // watcher holds a ref to us.
725
+ xds_client()->CancelEndpointDataWatch(StringView(server_name_),
726
+ endpoint_watcher_);
727
+ xds_client()->RemoveClientStats(StringView(server_name_), &client_stats_);
728
+ xds_client_from_channel_.reset();
729
+ xds_client_.reset();
1756
730
  }
1757
731
 
1758
732
  //
@@ -1760,13 +734,11 @@ void XdsLb::ShutdownLocked() {
1760
734
  //
1761
735
 
1762
736
  void XdsLb::ResetBackoffLocked() {
1763
- if (lb_chand_ != nullptr) {
1764
- grpc_channel_reset_connect_backoff(lb_chand_->channel());
1765
- }
1766
- if (pending_lb_chand_ != nullptr) {
1767
- grpc_channel_reset_connect_backoff(pending_lb_chand_->channel());
1768
- }
1769
- locality_map_.ResetBackoffLocked();
737
+ // When the XdsClient is instantiated in the resolver instead of in this
738
+ // LB policy, this is done via the resolver, so we don't need to do it
739
+ // for xds_client_from_channel_ here.
740
+ if (xds_client_ != nullptr) xds_client_->ResetBackoff();
741
+ priority_list_.ResetBackoffLocked();
1770
742
  if (fallback_policy_ != nullptr) {
1771
743
  fallback_policy_->ResetBackoffLocked();
1772
744
  }
@@ -1775,79 +747,53 @@ void XdsLb::ResetBackoffLocked() {
1775
747
  }
1776
748
  }
1777
749
 
1778
- void XdsLb::ProcessAddressesAndChannelArgsLocked(
1779
- ServerAddressList addresses, const grpc_channel_args& args) {
1780
- // Update fallback address list.
1781
- fallback_backend_addresses_ = std::move(addresses);
1782
- // Make sure that GRPC_ARG_LB_POLICY_NAME is set in channel args,
1783
- // since we use this to trigger the client_load_reporting filter.
1784
- static const char* args_to_remove[] = {GRPC_ARG_LB_POLICY_NAME};
1785
- grpc_arg new_arg = grpc_channel_arg_string_create(
1786
- (char*)GRPC_ARG_LB_POLICY_NAME, (char*)"xds");
1787
- grpc_channel_args_destroy(args_);
1788
- args_ = grpc_channel_args_copy_and_add_and_remove(
1789
- &args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), &new_arg, 1);
1790
- // Construct args for balancer channel.
1791
- grpc_channel_args* lb_channel_args = BuildBalancerChannelArgs(&args);
1792
- // Create an LB channel if we don't have one yet or the balancer name has
1793
- // changed from the last received one.
1794
- bool create_lb_channel = lb_chand_ == nullptr;
1795
- if (lb_chand_ != nullptr) {
1796
- UniquePtr<char> last_balancer_name(
1797
- grpc_channel_get_target(LatestLbChannel()->channel()));
1798
- create_lb_channel =
1799
- strcmp(last_balancer_name.get(), balancer_name_.get()) != 0;
1800
- }
1801
- if (create_lb_channel) {
1802
- OrphanablePtr<LbChannelState> lb_chand = MakeOrphanable<LbChannelState>(
1803
- Ref(DEBUG_LOCATION, "XdsLb+LbChannelState"), balancer_name_.get(),
1804
- *lb_channel_args);
1805
- if (lb_chand_ == nullptr || !lb_chand_->HasActiveEdsCall()) {
1806
- GPR_ASSERT(pending_lb_chand_ == nullptr);
1807
- // If we do not have a working LB channel yet, use the newly created one.
1808
- lb_chand_ = std::move(lb_chand);
1809
- } else {
1810
- // Otherwise, wait until the new LB channel to be ready to swap it in.
1811
- pending_lb_chand_ = std::move(lb_chand);
1812
- }
750
+ void XdsLb::UpdateLocked(UpdateArgs args) {
751
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) {
752
+ gpr_log(GPR_INFO, "[xdslb %p] Received update", this);
1813
753
  }
1814
- grpc_channel_args_destroy(lb_channel_args);
1815
- }
1816
-
1817
- void XdsLb::ParseLbConfig(const ParsedXdsConfig* xds_config) {
1818
- if (xds_config == nullptr || xds_config->balancer_name() == nullptr) return;
1819
- // TODO(yashykt) : does this need to be a gpr_strdup
1820
- // TODO(juanlishen): Read balancer name from bootstrap file.
1821
- balancer_name_ = UniquePtr<char>(gpr_strdup(xds_config->balancer_name()));
754
+ const bool is_initial_update = args_ == nullptr;
755
+ // Update config.
756
+ auto* xds_config = static_cast<const ParsedXdsConfig*>(args.config.get());
1822
757
  child_policy_config_ = xds_config->child_policy();
1823
758
  fallback_policy_config_ = xds_config->fallback_policy();
1824
- }
1825
-
1826
- void XdsLb::UpdateLocked(UpdateArgs args) {
1827
- const bool is_initial_update = lb_chand_ == nullptr;
1828
- ParseLbConfig(static_cast<const ParsedXdsConfig*>(args.config.get()));
1829
- if (balancer_name_ == nullptr) {
1830
- gpr_log(GPR_ERROR, "[xdslb %p] LB config parsing fails.", this);
1831
- return;
1832
- }
1833
- ProcessAddressesAndChannelArgsLocked(std::move(args.addresses), *args.args);
1834
- locality_map_.UpdateLocked(locality_list_, child_policy_config_.get(), args_,
1835
- this, is_initial_update);
759
+ // Update fallback address list.
760
+ fallback_backend_addresses_ = std::move(args.addresses);
761
+ // Update args.
762
+ grpc_channel_args_destroy(args_);
763
+ args_ = args.args;
764
+ args.args = nullptr;
765
+ // Update priority list.
766
+ priority_list_.UpdateLocked();
1836
767
  // Update the existing fallback policy. The fallback policy config and/or the
1837
768
  // fallback addresses may be new.
1838
769
  if (fallback_policy_ != nullptr) UpdateFallbackPolicyLocked();
1839
- // If this is the initial update, start the fallback-at-startup checks.
1840
770
  if (is_initial_update) {
771
+ // Initialize XdsClient.
772
+ if (xds_client_from_channel_ == nullptr) {
773
+ grpc_error* error = GRPC_ERROR_NONE;
774
+ xds_client_ = MakeOrphanable<XdsClient>(
775
+ combiner(), interested_parties(), StringView(server_name_),
776
+ nullptr /* service config watcher */, *args_, &error);
777
+ // TODO(roth): If we decide that we care about fallback mode, add
778
+ // proper error handling here.
779
+ GPR_ASSERT(error == GRPC_ERROR_NONE);
780
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) {
781
+ gpr_log(GPR_INFO, "[xdslb %p] Created xds client %p", this,
782
+ xds_client_.get());
783
+ }
784
+ }
785
+ auto watcher = MakeUnique<EndpointWatcher>(Ref());
786
+ endpoint_watcher_ = watcher.get();
787
+ xds_client()->WatchEndpointData(StringView(server_name_),
788
+ std::move(watcher));
789
+ xds_client()->AddClientStats(StringView(server_name_), &client_stats_);
790
+ // Start fallback-at-startup checks.
1841
791
  grpc_millis deadline = ExecCtx::Get()->Now() + lb_fallback_timeout_ms_;
1842
792
  Ref(DEBUG_LOCATION, "on_fallback_timer").release(); // Held by closure
1843
- GRPC_CLOSURE_INIT(&lb_on_fallback_, &XdsLb::OnFallbackTimerLocked, this,
1844
- grpc_combiner_scheduler(combiner()));
793
+ GRPC_CLOSURE_INIT(&lb_on_fallback_, &XdsLb::OnFallbackTimer, this,
794
+ grpc_schedule_on_exec_ctx);
1845
795
  fallback_at_startup_checks_pending_ = true;
1846
796
  grpc_timer_init(&lb_fallback_timer_, deadline, &lb_on_fallback_);
1847
- // Start watching the channel's connectivity state. If the channel
1848
- // goes into state TRANSIENT_FAILURE, we go into fallback mode even if
1849
- // the fallback timeout has not elapsed.
1850
- lb_chand_->StartConnectivityWatchLocked();
1851
797
  }
1852
798
  }
1853
799
 
@@ -1857,30 +803,33 @@ void XdsLb::UpdateLocked(UpdateArgs args) {
1857
803
 
1858
804
  void XdsLb::MaybeCancelFallbackAtStartupChecks() {
1859
805
  if (!fallback_at_startup_checks_pending_) return;
1860
- gpr_log(GPR_INFO,
1861
- "[xdslb %p] Cancelling fallback timer and LB channel connectivity "
1862
- "watch",
1863
- this);
806
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) {
807
+ gpr_log(GPR_INFO, "[xdslb %p] Cancelling fallback timer", this);
808
+ }
1864
809
  grpc_timer_cancel(&lb_fallback_timer_);
1865
- lb_chand_->CancelConnectivityWatchLocked();
1866
810
  fallback_at_startup_checks_pending_ = false;
1867
811
  }
1868
812
 
813
+ void XdsLb::OnFallbackTimer(void* arg, grpc_error* error) {
814
+ XdsLb* xdslb_policy = static_cast<XdsLb*>(arg);
815
+ xdslb_policy->combiner()->Run(
816
+ GRPC_CLOSURE_INIT(&xdslb_policy->lb_on_fallback_,
817
+ &XdsLb::OnFallbackTimerLocked, xdslb_policy, nullptr),
818
+ GRPC_ERROR_REF(error));
819
+ }
820
+
1869
821
  void XdsLb::OnFallbackTimerLocked(void* arg, grpc_error* error) {
1870
822
  XdsLb* xdslb_policy = static_cast<XdsLb*>(arg);
1871
823
  // If some fallback-at-startup check is done after the timer fires but before
1872
824
  // this callback actually runs, don't fall back.
1873
825
  if (xdslb_policy->fallback_at_startup_checks_pending_ &&
1874
826
  !xdslb_policy->shutting_down_ && error == GRPC_ERROR_NONE) {
1875
- if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) {
1876
- gpr_log(GPR_INFO,
1877
- "[xdslb %p] Child policy not ready after fallback timeout; "
1878
- "entering fallback mode",
1879
- xdslb_policy);
1880
- }
827
+ gpr_log(GPR_INFO,
828
+ "[xdslb %p] Child policy not ready after fallback timeout; "
829
+ "entering fallback mode",
830
+ xdslb_policy);
1881
831
  xdslb_policy->fallback_at_startup_checks_pending_ = false;
1882
832
  xdslb_policy->UpdateFallbackPolicyLocked();
1883
- xdslb_policy->lb_chand_->CancelConnectivityWatchLocked();
1884
833
  }
1885
834
  xdslb_policy->Unref(DEBUG_LOCATION, "on_fallback_timer");
1886
835
  }
@@ -2027,150 +976,460 @@ void XdsLb::MaybeExitFallbackMode() {
2027
976
  }
2028
977
 
2029
978
  //
2030
- // XdsLb::LocalityMap
979
+ // XdsLb::PriorityList
2031
980
  //
2032
981
 
2033
- void XdsLb::LocalityMap::UpdateLocked(
2034
- const XdsLocalityList& locality_list,
2035
- LoadBalancingPolicy::Config* child_policy_config,
2036
- const grpc_channel_args* args, XdsLb* parent, bool is_initial_update) {
2037
- if (parent->shutting_down_) return;
2038
- // Add or update the localities in locality_list.
2039
- for (size_t i = 0; i < locality_list.size(); i++) {
2040
- auto& locality_name = locality_list[i].locality_name;
2041
- auto iter = map_.find(locality_name);
2042
- // Add a new entry in the locality map if a new locality is received in the
2043
- // locality list.
2044
- if (iter == map_.end()) {
2045
- OrphanablePtr<LocalityEntry> new_entry = MakeOrphanable<LocalityEntry>(
2046
- parent->Ref(DEBUG_LOCATION, "LocalityEntry"), locality_name);
2047
- iter = map_.emplace(locality_name, std::move(new_entry)).first;
982
+ void XdsLb::PriorityList::UpdateLocked() {
983
+ const auto& priority_list_update = xds_policy_->priority_list_update_;
984
+ // 1. Remove from the priority list the priorities that are not in the update.
985
+ DeactivatePrioritiesLowerThan(priority_list_update.LowestPriority());
986
+ // 2. Update all the existing priorities.
987
+ for (uint32_t priority = 0; priority < priorities_.size(); ++priority) {
988
+ LocalityMap* locality_map = priorities_[priority].get();
989
+ const auto* locality_map_update = priority_list_update.Find(priority);
990
+ // Propagate locality_map_update.
991
+ // TODO(juanlishen): Find a clean way to skip duplicate update for a
992
+ // priority.
993
+ locality_map->UpdateLocked(*locality_map_update);
994
+ }
995
+ // 3. Only create a new locality map if all the existing ones have failed.
996
+ if (priorities_.empty() ||
997
+ !priorities_[priorities_.size() - 1]->failover_timer_callback_pending()) {
998
+ const uint32_t new_priority = static_cast<uint32_t>(priorities_.size());
999
+ // Create a new locality map. Note that in some rare cases (e.g., the
1000
+ // locality map reports TRANSIENT_FAILURE synchronously due to subchannel
1001
+ // sharing), the following invocation may result in multiple locality maps
1002
+ // to be created.
1003
+ MaybeCreateLocalityMapLocked(new_priority);
1004
+ }
1005
+ }
1006
+
1007
+ void XdsLb::PriorityList::ResetBackoffLocked() {
1008
+ for (size_t i = 0; i < priorities_.size(); ++i) {
1009
+ priorities_[i]->ResetBackoffLocked();
1010
+ }
1011
+ }
1012
+
1013
+ void XdsLb::PriorityList::ShutdownLocked() { priorities_.clear(); }
1014
+
1015
+ void XdsLb::PriorityList::UpdateXdsPickerLocked() {
1016
+ // If we are in fallback mode, don't generate an xds picker from localities.
1017
+ if (xds_policy_->fallback_policy_ != nullptr) return;
1018
+ if (current_priority() == UINT32_MAX) {
1019
+ grpc_error* error = grpc_error_set_int(
1020
+ GRPC_ERROR_CREATE_FROM_STATIC_STRING("no ready locality map"),
1021
+ GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
1022
+ xds_policy_->channel_control_helper()->UpdateState(
1023
+ GRPC_CHANNEL_TRANSIENT_FAILURE,
1024
+ MakeUnique<TransientFailurePicker>(error));
1025
+ return;
1026
+ }
1027
+ priorities_[current_priority_]->UpdateXdsPickerLocked();
1028
+ }
1029
+
1030
+ void XdsLb::PriorityList::MaybeCreateLocalityMapLocked(uint32_t priority) {
1031
+ // Exhausted priorities in the update.
1032
+ if (!priority_list_update().Contains(priority)) return;
1033
+ auto new_locality_map = New<LocalityMap>(
1034
+ xds_policy_->Ref(DEBUG_LOCATION, "XdsLb+LocalityMap"), priority);
1035
+ priorities_.emplace_back(OrphanablePtr<LocalityMap>(new_locality_map));
1036
+ new_locality_map->UpdateLocked(*priority_list_update().Find(priority));
1037
+ }
1038
+
1039
+ void XdsLb::PriorityList::FailoverOnConnectionFailureLocked() {
1040
+ const uint32_t failed_priority = LowestPriority();
1041
+ // If we're failing over from the lowest priority, report TRANSIENT_FAILURE.
1042
+ if (failed_priority == priority_list_update().LowestPriority()) {
1043
+ UpdateXdsPickerLocked();
1044
+ }
1045
+ MaybeCreateLocalityMapLocked(failed_priority + 1);
1046
+ }
1047
+
1048
+ void XdsLb::PriorityList::FailoverOnDisconnectionLocked(
1049
+ uint32_t failed_priority) {
1050
+ current_priority_ = UINT32_MAX;
1051
+ for (uint32_t next_priority = failed_priority + 1;
1052
+ next_priority <= priority_list_update().LowestPriority();
1053
+ ++next_priority) {
1054
+ if (!Contains(next_priority)) {
1055
+ MaybeCreateLocalityMapLocked(next_priority);
1056
+ return;
2048
1057
  }
2049
- // Keep a copy of serverlist in locality_list_ so that we can compare it
2050
- // with the future ones.
2051
- iter->second->UpdateLocked(locality_list[i].lb_weight,
2052
- locality_list[i].serverlist, child_policy_config,
2053
- args);
2054
- }
2055
- // Remove (later) the localities not in locality_list.
2056
- for (auto& p : map_) {
2057
- const XdsLocalityName* locality_name = p.first.get();
2058
- LocalityEntry* locality_entry = p.second.get();
2059
- bool in_locality_list = false;
2060
- for (size_t i = 0; i < locality_list.size(); ++i) {
2061
- if (*locality_list[i].locality_name == *locality_name) {
2062
- in_locality_list = true;
2063
- break;
1058
+ if (priorities_[next_priority]->MaybeReactivateLocked()) return;
1059
+ }
1060
+ }
1061
+
1062
+ void XdsLb::PriorityList::SwitchToHigherPriorityLocked(uint32_t priority) {
1063
+ current_priority_ = priority;
1064
+ DeactivatePrioritiesLowerThan(current_priority_);
1065
+ UpdateXdsPickerLocked();
1066
+ }
1067
+
1068
+ void XdsLb::PriorityList::DeactivatePrioritiesLowerThan(uint32_t priority) {
1069
+ if (priorities_.empty()) return;
1070
+ // Deactivate the locality maps from the lowest priority.
1071
+ for (uint32_t p = LowestPriority(); p > priority; --p) {
1072
+ if (xds_policy_->locality_retention_interval_ms_ == 0) {
1073
+ priorities_.pop_back();
1074
+ } else {
1075
+ priorities_[p]->DeactivateLocked();
1076
+ }
1077
+ }
1078
+ }
1079
+
1080
+ OrphanablePtr<XdsLb::PriorityList::LocalityMap::Locality>
1081
+ XdsLb::PriorityList::ExtractLocalityLocked(
1082
+ const RefCountedPtr<XdsLocalityName>& name, uint32_t exclude_priority) {
1083
+ for (uint32_t priority = 0; priority < priorities_.size(); ++priority) {
1084
+ if (priority == exclude_priority) continue;
1085
+ LocalityMap* locality_map = priorities_[priority].get();
1086
+ auto locality = locality_map->ExtractLocalityLocked(name);
1087
+ if (locality != nullptr) return locality;
1088
+ }
1089
+ return nullptr;
1090
+ }
1091
+
1092
+ //
1093
+ // XdsLb::PriorityList::LocalityMap
1094
+ //
1095
+
1096
+ XdsLb::PriorityList::LocalityMap::LocalityMap(RefCountedPtr<XdsLb> xds_policy,
1097
+ uint32_t priority)
1098
+ : xds_policy_(std::move(xds_policy)), priority_(priority) {
1099
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) {
1100
+ gpr_log(GPR_INFO, "[xdslb %p] Creating priority %" PRIu32,
1101
+ xds_policy_.get(), priority_);
1102
+ }
1103
+
1104
+ GRPC_CLOSURE_INIT(&on_failover_timer_, OnFailoverTimer, this,
1105
+ grpc_schedule_on_exec_ctx);
1106
+ // Start the failover timer.
1107
+ Ref(DEBUG_LOCATION, "LocalityMap+OnFailoverTimerLocked").release();
1108
+ grpc_timer_init(
1109
+ &failover_timer_,
1110
+ ExecCtx::Get()->Now() + xds_policy_->locality_map_failover_timeout_ms_,
1111
+ &on_failover_timer_);
1112
+ failover_timer_callback_pending_ = true;
1113
+ // This is the first locality map ever created, report CONNECTING.
1114
+ if (priority_ == 0) {
1115
+ xds_policy_->channel_control_helper()->UpdateState(
1116
+ GRPC_CHANNEL_CONNECTING, MakeUnique<QueuePicker>(xds_policy_->Ref(
1117
+ DEBUG_LOCATION, "QueuePicker")));
1118
+ }
1119
+ }
1120
+
1121
+ void XdsLb::PriorityList::LocalityMap::UpdateLocked(
1122
+ const XdsPriorityListUpdate::LocalityMap& locality_map_update) {
1123
+ if (xds_policy_->shutting_down_) return;
1124
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) {
1125
+ gpr_log(GPR_INFO, "[xdslb %p] Start Updating priority %" PRIu32,
1126
+ xds_policy(), priority_);
1127
+ }
1128
+ // Maybe reactivate the locality map in case all the active locality maps have
1129
+ // failed.
1130
+ MaybeReactivateLocked();
1131
+ // Remove (later) the localities not in locality_map_update.
1132
+ for (auto iter = localities_.begin(); iter != localities_.end();) {
1133
+ const auto& name = iter->first;
1134
+ Locality* locality = iter->second.get();
1135
+ if (locality_map_update.Contains(name)) {
1136
+ ++iter;
1137
+ continue;
1138
+ }
1139
+ if (xds_policy()->locality_retention_interval_ms_ == 0) {
1140
+ iter = localities_.erase(iter);
1141
+ } else {
1142
+ locality->DeactivateLocked();
1143
+ ++iter;
1144
+ }
1145
+ }
1146
+ // Add or update the localities in locality_map_update.
1147
+ for (const auto& p : locality_map_update.localities) {
1148
+ const auto& name = p.first;
1149
+ const auto& locality_update = p.second;
1150
+ OrphanablePtr<Locality>& locality = localities_[name];
1151
+ if (locality == nullptr) {
1152
+ // Move from another locality map if possible.
1153
+ locality = priority_list()->ExtractLocalityLocked(name, priority_);
1154
+ if (locality != nullptr) {
1155
+ locality->set_locality_map(
1156
+ Ref(DEBUG_LOCATION, "LocalityMap+Locality_move"));
1157
+ } else {
1158
+ locality = MakeOrphanable<Locality>(
1159
+ Ref(DEBUG_LOCATION, "LocalityMap+Locality"), name);
2064
1160
  }
2065
1161
  }
2066
- if (!in_locality_list) locality_entry->DeactivateLocked();
1162
+ // Keep a copy of serverlist in the update so that we can compare it
1163
+ // with the future ones.
1164
+ locality->UpdateLocked(locality_update.lb_weight,
1165
+ locality_update.serverlist);
2067
1166
  }
2068
- // Generate a new xds picker immediately.
2069
- if (!is_initial_update) UpdateXdsPickerLocked();
2070
1167
  }
2071
1168
 
2072
- void XdsLb::LocalityMap::UpdateXdsPickerLocked() {
2073
- // If we are in fallback mode, don't generate an xds picker from localities.
2074
- if (xds_policy_->fallback_policy_ != nullptr) return;
1169
+ void XdsLb::PriorityList::LocalityMap::ResetBackoffLocked() {
1170
+ for (auto& p : localities_) p.second->ResetBackoffLocked();
1171
+ }
1172
+
1173
+ void XdsLb::PriorityList::LocalityMap::UpdateXdsPickerLocked() {
2075
1174
  // Construct a new xds picker which maintains a map of all locality pickers
2076
1175
  // that are ready. Each locality is represented by a portion of the range
2077
1176
  // proportional to its weight, such that the total range is the sum of the
2078
1177
  // weights of all localities.
1178
+ Picker::PickerList picker_list;
2079
1179
  uint32_t end = 0;
1180
+ for (const auto& p : localities_) {
1181
+ const auto& locality_name = p.first;
1182
+ const Locality* locality = p.second.get();
1183
+ // Skip the localities that are not in the latest locality map update.
1184
+ if (!locality_map_update()->Contains(locality_name)) continue;
1185
+ if (locality->connectivity_state() != GRPC_CHANNEL_READY) continue;
1186
+ end += locality->weight();
1187
+ picker_list.push_back(std::make_pair(end, locality->picker_wrapper()));
1188
+ }
1189
+ xds_policy()->channel_control_helper()->UpdateState(
1190
+ GRPC_CHANNEL_READY,
1191
+ MakeUnique<Picker>(xds_policy_->Ref(DEBUG_LOCATION, "XdsLb+Picker"),
1192
+ std::move(picker_list)));
1193
+ }
1194
+
1195
+ OrphanablePtr<XdsLb::PriorityList::LocalityMap::Locality>
1196
+ XdsLb::PriorityList::LocalityMap::ExtractLocalityLocked(
1197
+ const RefCountedPtr<XdsLocalityName>& name) {
1198
+ for (auto iter = localities_.begin(); iter != localities_.end(); ++iter) {
1199
+ const auto& name_in_map = iter->first;
1200
+ if (*name_in_map == *name) {
1201
+ auto locality = std::move(iter->second);
1202
+ localities_.erase(iter);
1203
+ return locality;
1204
+ }
1205
+ }
1206
+ return nullptr;
1207
+ }
1208
+
1209
+ void XdsLb::PriorityList::LocalityMap::DeactivateLocked() {
1210
+ // If already deactivated, don't do it again.
1211
+ if (delayed_removal_timer_callback_pending_) return;
1212
+ MaybeCancelFailoverTimerLocked();
1213
+ // Start a timer to delete the locality.
1214
+ Ref(DEBUG_LOCATION, "LocalityMap+timer").release();
1215
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) {
1216
+ gpr_log(GPR_INFO,
1217
+ "[xdslb %p] Will remove priority %" PRIu32 " in %" PRId64 " ms.",
1218
+ xds_policy(), priority_,
1219
+ xds_policy()->locality_retention_interval_ms_);
1220
+ }
1221
+ GRPC_CLOSURE_INIT(&on_delayed_removal_timer_, OnDelayedRemovalTimer, this,
1222
+ grpc_schedule_on_exec_ctx);
1223
+ grpc_timer_init(
1224
+ &delayed_removal_timer_,
1225
+ ExecCtx::Get()->Now() + xds_policy()->locality_retention_interval_ms_,
1226
+ &on_delayed_removal_timer_);
1227
+ delayed_removal_timer_callback_pending_ = true;
1228
+ }
1229
+
1230
+ bool XdsLb::PriorityList::LocalityMap::MaybeReactivateLocked() {
1231
+ // Don't reactivate a priority that is not higher than the current one.
1232
+ if (priority_ >= priority_list()->current_priority()) return false;
1233
+ // Reactivate this priority by cancelling deletion timer.
1234
+ if (delayed_removal_timer_callback_pending_) {
1235
+ grpc_timer_cancel(&delayed_removal_timer_);
1236
+ }
1237
+ // Switch to this higher priority if it's READY.
1238
+ if (connectivity_state_ != GRPC_CHANNEL_READY) return false;
1239
+ priority_list()->SwitchToHigherPriorityLocked(priority_);
1240
+ return true;
1241
+ }
1242
+
1243
+ void XdsLb::PriorityList::LocalityMap::MaybeCancelFailoverTimerLocked() {
1244
+ if (failover_timer_callback_pending_) grpc_timer_cancel(&failover_timer_);
1245
+ }
1246
+
1247
+ void XdsLb::PriorityList::LocalityMap::Orphan() {
1248
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) {
1249
+ gpr_log(GPR_INFO, "[xdslb %p] Priority %" PRIu32 " orphaned.", xds_policy(),
1250
+ priority_);
1251
+ }
1252
+ MaybeCancelFailoverTimerLocked();
1253
+ if (delayed_removal_timer_callback_pending_) {
1254
+ grpc_timer_cancel(&delayed_removal_timer_);
1255
+ }
1256
+ localities_.clear();
1257
+ Unref(DEBUG_LOCATION, "LocalityMap+Orphan");
1258
+ }
1259
+
1260
+ void XdsLb::PriorityList::LocalityMap::OnLocalityStateUpdateLocked() {
1261
+ UpdateConnectivityStateLocked();
1262
+ // Ignore priorities not in priority_list_update.
1263
+ if (!priority_list_update().Contains(priority_)) return;
1264
+ const uint32_t current_priority = priority_list()->current_priority();
1265
+ // Ignore lower-than-current priorities.
1266
+ if (priority_ > current_priority) return;
1267
+ // Maybe update fallback state.
1268
+ if (connectivity_state_ == GRPC_CHANNEL_READY) {
1269
+ xds_policy_->MaybeCancelFallbackAtStartupChecks();
1270
+ xds_policy_->MaybeExitFallbackMode();
1271
+ }
1272
+ // Update is for a higher-than-current priority. (Special case: update is for
1273
+ // any active priority if there is no current priority.)
1274
+ if (priority_ < current_priority) {
1275
+ if (connectivity_state_ == GRPC_CHANNEL_READY) {
1276
+ MaybeCancelFailoverTimerLocked();
1277
+ // If a higher-than-current priority becomes READY, switch to use it.
1278
+ priority_list()->SwitchToHigherPriorityLocked(priority_);
1279
+ } else if (connectivity_state_ == GRPC_CHANNEL_TRANSIENT_FAILURE) {
1280
+ // If a higher-than-current priority becomes TRANSIENT_FAILURE, only
1281
+ // handle it if it's the priority that is still in failover timeout.
1282
+ if (failover_timer_callback_pending_) {
1283
+ MaybeCancelFailoverTimerLocked();
1284
+ priority_list()->FailoverOnConnectionFailureLocked();
1285
+ }
1286
+ }
1287
+ return;
1288
+ }
1289
+ // Update is for current priority.
1290
+ if (connectivity_state_ != GRPC_CHANNEL_READY) {
1291
+ // Fail over if it's no longer READY.
1292
+ priority_list()->FailoverOnDisconnectionLocked(priority_);
1293
+ }
1294
+ // At this point, one of the following things has happened to the current
1295
+ // priority.
1296
+ // 1. It remained the same (but received picker update from its localities).
1297
+ // 2. It changed to a lower priority due to failover.
1298
+ // 3. It became invalid because failover didn't yield a READY priority.
1299
+ // In any case, update the xds picker.
1300
+ priority_list()->UpdateXdsPickerLocked();
1301
+ }
1302
+
1303
+ void XdsLb::PriorityList::LocalityMap::UpdateConnectivityStateLocked() {
1304
+ size_t num_ready = 0;
2080
1305
  size_t num_connecting = 0;
2081
1306
  size_t num_idle = 0;
2082
1307
  size_t num_transient_failures = 0;
2083
- Picker::PickerList pickers;
2084
- for (auto& p : map_) {
2085
- const LocalityEntry* entry = p.second.get();
2086
- if (entry->locality_weight() == 0) continue;
2087
- switch (entry->connectivity_state()) {
1308
+ for (const auto& p : localities_) {
1309
+ const auto& locality_name = p.first;
1310
+ const Locality* locality = p.second.get();
1311
+ // Skip the localities that are not in the latest locality map update.
1312
+ if (!locality_map_update()->Contains(locality_name)) continue;
1313
+ switch (locality->connectivity_state()) {
2088
1314
  case GRPC_CHANNEL_READY: {
2089
- end += entry->locality_weight();
2090
- pickers.push_back(MakePair(end, entry->picker_wrapper()));
1315
+ ++num_ready;
2091
1316
  break;
2092
1317
  }
2093
1318
  case GRPC_CHANNEL_CONNECTING: {
2094
- num_connecting++;
1319
+ ++num_connecting;
2095
1320
  break;
2096
1321
  }
2097
1322
  case GRPC_CHANNEL_IDLE: {
2098
- num_idle++;
1323
+ ++num_idle;
2099
1324
  break;
2100
1325
  }
2101
1326
  case GRPC_CHANNEL_TRANSIENT_FAILURE: {
2102
- num_transient_failures++;
1327
+ ++num_transient_failures;
2103
1328
  break;
2104
1329
  }
2105
1330
  default:
2106
1331
  GPR_UNREACHABLE_CODE(return );
2107
1332
  }
2108
1333
  }
2109
- // Pass on the constructed xds picker if it has any ready pickers in their map
2110
- // otherwise pass a QueuePicker if any of the locality pickers are in a
2111
- // connecting or idle state, finally return a transient failure picker if all
2112
- // locality pickers are in transient failure.
2113
- if (!pickers.empty()) {
2114
- xds_policy_->channel_control_helper()->UpdateState(
2115
- GRPC_CHANNEL_READY,
2116
- UniquePtr<LoadBalancingPolicy::SubchannelPicker>(
2117
- New<Picker>(xds_policy_->Ref(DEBUG_LOCATION, "XdsLb+Picker"),
2118
- std::move(pickers))));
1334
+ if (num_ready > 0) {
1335
+ connectivity_state_ = GRPC_CHANNEL_READY;
2119
1336
  } else if (num_connecting > 0) {
2120
- xds_policy_->channel_control_helper()->UpdateState(
2121
- GRPC_CHANNEL_CONNECTING,
2122
- UniquePtr<SubchannelPicker>(
2123
- New<QueuePicker>(xds_policy_->Ref(DEBUG_LOCATION, "QueuePicker"))));
1337
+ connectivity_state_ = GRPC_CHANNEL_CONNECTING;
2124
1338
  } else if (num_idle > 0) {
2125
- xds_policy_->channel_control_helper()->UpdateState(
2126
- GRPC_CHANNEL_IDLE,
2127
- UniquePtr<SubchannelPicker>(
2128
- New<QueuePicker>(xds_policy_->Ref(DEBUG_LOCATION, "QueuePicker"))));
1339
+ connectivity_state_ = GRPC_CHANNEL_IDLE;
2129
1340
  } else {
2130
- grpc_error* error =
2131
- grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
2132
- "connections to all active localities failing"),
2133
- GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
2134
- xds_policy_->channel_control_helper()->UpdateState(
2135
- GRPC_CHANNEL_TRANSIENT_FAILURE,
2136
- UniquePtr<SubchannelPicker>(New<TransientFailurePicker>(error)));
1341
+ connectivity_state_ = GRPC_CHANNEL_TRANSIENT_FAILURE;
2137
1342
  }
1343
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) {
1344
+ gpr_log(GPR_INFO,
1345
+ "[xdslb %p] Priority %" PRIu32 " (%p) connectivity changed to %s",
1346
+ xds_policy(), priority_, this,
1347
+ ConnectivityStateName(connectivity_state_));
1348
+ }
1349
+ }
1350
+
1351
+ void XdsLb::PriorityList::LocalityMap::OnDelayedRemovalTimer(
1352
+ void* arg, grpc_error* error) {
1353
+ LocalityMap* self = static_cast<LocalityMap*>(arg);
1354
+ self->xds_policy_->combiner()->Run(
1355
+ GRPC_CLOSURE_INIT(&self->on_delayed_removal_timer_,
1356
+ OnDelayedRemovalTimerLocked, self, nullptr),
1357
+ GRPC_ERROR_REF(error));
1358
+ }
1359
+
1360
+ void XdsLb::PriorityList::LocalityMap::OnDelayedRemovalTimerLocked(
1361
+ void* arg, grpc_error* error) {
1362
+ LocalityMap* self = static_cast<LocalityMap*>(arg);
1363
+ self->delayed_removal_timer_callback_pending_ = false;
1364
+ if (error == GRPC_ERROR_NONE && !self->xds_policy_->shutting_down_) {
1365
+ auto* priority_list = self->priority_list();
1366
+ const bool keep = self->priority_list_update().Contains(self->priority_) &&
1367
+ self->priority_ <= priority_list->current_priority();
1368
+ if (!keep) {
1369
+ // This check is to make sure we always delete the locality maps from
1370
+ // the lowest priority even if the closures of the back-to-back timers
1371
+ // are not run in FIFO order.
1372
+ // TODO(juanlishen): Eliminate unnecessary maintenance overhead for some
1373
+ // deactivated locality maps when out-of-order closures are run.
1374
+ // TODO(juanlishen): Check the timer implementation to see if this
1375
+ // defense is necessary.
1376
+ if (self->priority_ == priority_list->LowestPriority()) {
1377
+ priority_list->priorities_.pop_back();
1378
+ } else {
1379
+ gpr_log(GPR_ERROR,
1380
+ "[xdslb %p] Priority %" PRIu32
1381
+ " is not the lowest priority (highest numeric value) but is "
1382
+ "attempted to be deleted.",
1383
+ self->xds_policy(), self->priority_);
1384
+ }
1385
+ }
1386
+ }
1387
+ self->Unref(DEBUG_LOCATION, "LocalityMap+timer");
2138
1388
  }
2139
1389
 
2140
- void XdsLb::LocalityMap::ShutdownLocked() { map_.clear(); }
1390
+ void XdsLb::PriorityList::LocalityMap::OnFailoverTimer(void* arg,
1391
+ grpc_error* error) {
1392
+ LocalityMap* self = static_cast<LocalityMap*>(arg);
1393
+ self->xds_policy_->combiner()->Run(
1394
+ GRPC_CLOSURE_INIT(&self->on_failover_timer_, OnFailoverTimerLocked, self,
1395
+ nullptr),
1396
+ GRPC_ERROR_REF(error));
1397
+ }
2141
1398
 
2142
- void XdsLb::LocalityMap::ResetBackoffLocked() {
2143
- for (auto& p : map_) {
2144
- p.second->ResetBackoffLocked();
1399
+ void XdsLb::PriorityList::LocalityMap::OnFailoverTimerLocked(
1400
+ void* arg, grpc_error* error) {
1401
+ LocalityMap* self = static_cast<LocalityMap*>(arg);
1402
+ self->failover_timer_callback_pending_ = false;
1403
+ if (error == GRPC_ERROR_NONE && !self->xds_policy_->shutting_down_) {
1404
+ self->priority_list()->FailoverOnConnectionFailureLocked();
2145
1405
  }
1406
+ self->Unref(DEBUG_LOCATION, "LocalityMap+OnFailoverTimerLocked");
2146
1407
  }
2147
1408
 
2148
1409
  //
2149
- // XdsLb::LocalityMap::LocalityEntry
1410
+ // XdsLb::PriorityList::LocalityMap::Locality
2150
1411
  //
2151
1412
 
2152
- XdsLb::LocalityMap::LocalityEntry::LocalityEntry(
2153
- RefCountedPtr<XdsLb> parent, RefCountedPtr<XdsLocalityName> name)
2154
- : parent_(std::move(parent)), name_(std::move(name)) {
1413
+ XdsLb::PriorityList::LocalityMap::Locality::Locality(
1414
+ RefCountedPtr<LocalityMap> locality_map,
1415
+ RefCountedPtr<XdsLocalityName> name)
1416
+ : locality_map_(std::move(locality_map)), name_(std::move(name)) {
2155
1417
  if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) {
2156
- gpr_log(GPR_INFO, "[xdslb %p] created LocalityEntry %p for %s",
2157
- parent_.get(), this, name_->AsHumanReadableString());
1418
+ gpr_log(GPR_INFO, "[xdslb %p] created Locality %p for %s", xds_policy(),
1419
+ this, name_->AsHumanReadableString());
2158
1420
  }
2159
- GRPC_CLOSURE_INIT(&on_delayed_removal_timer_, OnDelayedRemovalTimerLocked,
2160
- this, grpc_combiner_scheduler(parent_->combiner()));
2161
1421
  }
2162
1422
 
2163
- XdsLb::LocalityMap::LocalityEntry::~LocalityEntry() {
1423
+ XdsLb::PriorityList::LocalityMap::Locality::~Locality() {
2164
1424
  if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) {
2165
- gpr_log(GPR_INFO,
2166
- "[xdslb %p] LocalityEntry %p %s: destroying locality entry",
2167
- parent_.get(), this, name_->AsHumanReadableString());
1425
+ gpr_log(GPR_INFO, "[xdslb %p] Locality %p %s: destroying locality",
1426
+ xds_policy(), this, name_->AsHumanReadableString());
2168
1427
  }
2169
- parent_.reset(DEBUG_LOCATION, "LocalityEntry");
1428
+ locality_map_.reset(DEBUG_LOCATION, "Locality");
2170
1429
  }
2171
1430
 
2172
1431
  grpc_channel_args*
2173
- XdsLb::LocalityMap::LocalityEntry::CreateChildPolicyArgsLocked(
1432
+ XdsLb::PriorityList::LocalityMap::Locality::CreateChildPolicyArgsLocked(
2174
1433
  const grpc_channel_args* args_in) {
2175
1434
  const grpc_arg args_to_add[] = {
2176
1435
  // A channel arg indicating if the target is a backend inferred from a
@@ -2188,11 +1447,11 @@ XdsLb::LocalityMap::LocalityEntry::CreateChildPolicyArgsLocked(
2188
1447
  }
2189
1448
 
2190
1449
  OrphanablePtr<LoadBalancingPolicy>
2191
- XdsLb::LocalityMap::LocalityEntry::CreateChildPolicyLocked(
1450
+ XdsLb::PriorityList::LocalityMap::Locality::CreateChildPolicyLocked(
2192
1451
  const char* name, const grpc_channel_args* args) {
2193
1452
  Helper* helper = New<Helper>(this->Ref(DEBUG_LOCATION, "Helper"));
2194
1453
  LoadBalancingPolicy::Args lb_policy_args;
2195
- lb_policy_args.combiner = parent_->combiner();
1454
+ lb_policy_args.combiner = xds_policy()->combiner();
2196
1455
  lb_policy_args.args = args;
2197
1456
  lb_policy_args.channel_control_helper =
2198
1457
  UniquePtr<ChannelControlHelper>(helper);
@@ -2201,41 +1460,40 @@ XdsLb::LocalityMap::LocalityEntry::CreateChildPolicyLocked(
2201
1460
  name, std::move(lb_policy_args));
2202
1461
  if (GPR_UNLIKELY(lb_policy == nullptr)) {
2203
1462
  gpr_log(GPR_ERROR,
2204
- "[xdslb %p] LocalityEntry %p %s: failure creating child policy %s",
2205
- parent_.get(), this, name_->AsHumanReadableString(), name);
1463
+ "[xdslb %p] Locality %p %s: failure creating child policy %s",
1464
+ xds_policy(), this, name_->AsHumanReadableString(), name);
2206
1465
  return nullptr;
2207
1466
  }
2208
1467
  helper->set_child(lb_policy.get());
2209
1468
  if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) {
2210
1469
  gpr_log(GPR_INFO,
2211
- "[xdslb %p] LocalityEntry %p %s: Created new child policy %s (%p)",
2212
- parent_.get(), this, name_->AsHumanReadableString(), name,
1470
+ "[xdslb %p] Locality %p %s: Created new child policy %s (%p)",
1471
+ xds_policy(), this, name_->AsHumanReadableString(), name,
2213
1472
  lb_policy.get());
2214
1473
  }
2215
1474
  // Add the xDS's interested_parties pollset_set to that of the newly created
2216
- // child policy. This will make the child policy progress upon activity on xDS
2217
- // LB, which in turn is tied to the application's call.
1475
+ // child policy. This will make the child policy progress upon activity on
1476
+ // xDS LB, which in turn is tied to the application's call.
2218
1477
  grpc_pollset_set_add_pollset_set(lb_policy->interested_parties(),
2219
- parent_->interested_parties());
1478
+ xds_policy()->interested_parties());
2220
1479
  return lb_policy;
2221
1480
  }
2222
1481
 
2223
- void XdsLb::LocalityMap::LocalityEntry::UpdateLocked(
2224
- uint32_t locality_weight, ServerAddressList serverlist,
2225
- LoadBalancingPolicy::Config* child_policy_config,
2226
- const grpc_channel_args* args_in) {
2227
- if (parent_->shutting_down_) return;
1482
+ void XdsLb::PriorityList::LocalityMap::Locality::UpdateLocked(
1483
+ uint32_t locality_weight, ServerAddressList serverlist) {
1484
+ if (xds_policy()->shutting_down_) return;
2228
1485
  // Update locality weight.
2229
- locality_weight_ = locality_weight;
1486
+ weight_ = locality_weight;
2230
1487
  if (delayed_removal_timer_callback_pending_) {
2231
1488
  grpc_timer_cancel(&delayed_removal_timer_);
2232
1489
  }
2233
1490
  // Construct update args.
2234
1491
  UpdateArgs update_args;
2235
1492
  update_args.addresses = std::move(serverlist);
2236
- update_args.config =
2237
- child_policy_config == nullptr ? nullptr : child_policy_config->Ref();
2238
- update_args.args = CreateChildPolicyArgsLocked(args_in);
1493
+ update_args.config = xds_policy()->child_policy_config_ == nullptr
1494
+ ? nullptr
1495
+ : xds_policy()->child_policy_config_->Ref();
1496
+ update_args.args = CreateChildPolicyArgsLocked(xds_policy()->args_);
2239
1497
  // If the child policy name changes, we need to create a new child
2240
1498
  // policy. When this happens, we leave child_policy_ as-is and store
2241
1499
  // the new child policy in pending_child_policy_. Once the new child
@@ -2287,9 +1545,10 @@ void XdsLb::LocalityMap::LocalityEntry::UpdateLocked(
2287
1545
  // when the new child transitions into state READY.
2288
1546
  // TODO(juanlishen): If the child policy is not configured via service config,
2289
1547
  // use whatever algorithm is specified by the balancer.
2290
- const char* child_policy_name = child_policy_config == nullptr
2291
- ? "round_robin"
2292
- : child_policy_config->name();
1548
+ const char* child_policy_name =
1549
+ xds_policy()->child_policy_config_ == nullptr
1550
+ ? "round_robin"
1551
+ : xds_policy()->child_policy_config_->name();
2293
1552
  const bool create_policy =
2294
1553
  // case 1
2295
1554
  child_policy_ == nullptr ||
@@ -2306,8 +1565,8 @@ void XdsLb::LocalityMap::LocalityEntry::UpdateLocked(
2306
1565
  // pending_child_policy_ (cases 2b and 3b).
2307
1566
  if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) {
2308
1567
  gpr_log(GPR_INFO,
2309
- "[xdslb %p] LocalityEntry %p %s: Creating new %schild policy %s",
2310
- parent_.get(), this, name_->AsHumanReadableString(),
1568
+ "[xdslb %p] Locality %p %s: Creating new %schild policy %s",
1569
+ xds_policy(), this, name_->AsHumanReadableString(),
2311
1570
  child_policy_ == nullptr ? "" : "pending ", child_policy_name);
2312
1571
  }
2313
1572
  auto& lb_policy =
@@ -2325,30 +1584,28 @@ void XdsLb::LocalityMap::LocalityEntry::UpdateLocked(
2325
1584
  GPR_ASSERT(policy_to_update != nullptr);
2326
1585
  // Update the policy.
2327
1586
  if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) {
2328
- gpr_log(GPR_INFO,
2329
- "[xdslb %p] LocalityEntry %p %s: Updating %schild policy %p",
2330
- parent_.get(), this, name_->AsHumanReadableString(),
1587
+ gpr_log(GPR_INFO, "[xdslb %p] Locality %p %s: Updating %schild policy %p",
1588
+ xds_policy(), this, name_->AsHumanReadableString(),
2331
1589
  policy_to_update == pending_child_policy_.get() ? "pending " : "",
2332
1590
  policy_to_update);
2333
1591
  }
2334
1592
  policy_to_update->UpdateLocked(std::move(update_args));
2335
1593
  }
2336
1594
 
2337
- void XdsLb::LocalityMap::LocalityEntry::ShutdownLocked() {
1595
+ void XdsLb::PriorityList::LocalityMap::Locality::ShutdownLocked() {
2338
1596
  if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) {
2339
- gpr_log(GPR_INFO,
2340
- "[xdslb %p] LocalityEntry %p %s: shutting down locality entry",
2341
- parent_.get(), this, name_->AsHumanReadableString());
1597
+ gpr_log(GPR_INFO, "[xdslb %p] Locality %p %s: shutting down locality",
1598
+ xds_policy(), this, name_->AsHumanReadableString());
2342
1599
  }
2343
1600
  // Remove the child policy's interested_parties pollset_set from the
2344
1601
  // xDS policy.
2345
1602
  grpc_pollset_set_del_pollset_set(child_policy_->interested_parties(),
2346
- parent_->interested_parties());
1603
+ xds_policy()->interested_parties());
2347
1604
  child_policy_.reset();
2348
1605
  if (pending_child_policy_ != nullptr) {
2349
1606
  grpc_pollset_set_del_pollset_set(
2350
1607
  pending_child_policy_->interested_parties(),
2351
- parent_->interested_parties());
1608
+ xds_policy()->interested_parties());
2352
1609
  pending_child_policy_.reset();
2353
1610
  }
2354
1611
  // Drop our ref to the child's picker, in case it's holding a ref to
@@ -2357,141 +1614,124 @@ void XdsLb::LocalityMap::LocalityEntry::ShutdownLocked() {
2357
1614
  if (delayed_removal_timer_callback_pending_) {
2358
1615
  grpc_timer_cancel(&delayed_removal_timer_);
2359
1616
  }
1617
+ shutdown_ = true;
2360
1618
  }
2361
1619
 
2362
- void XdsLb::LocalityMap::LocalityEntry::ResetBackoffLocked() {
1620
+ void XdsLb::PriorityList::LocalityMap::Locality::ResetBackoffLocked() {
2363
1621
  child_policy_->ResetBackoffLocked();
2364
1622
  if (pending_child_policy_ != nullptr) {
2365
1623
  pending_child_policy_->ResetBackoffLocked();
2366
1624
  }
2367
1625
  }
2368
1626
 
2369
- void XdsLb::LocalityMap::LocalityEntry::Orphan() {
1627
+ void XdsLb::PriorityList::LocalityMap::Locality::Orphan() {
2370
1628
  ShutdownLocked();
2371
1629
  Unref();
2372
1630
  }
2373
1631
 
2374
- void XdsLb::LocalityMap::LocalityEntry::DeactivateLocked() {
2375
- // If locality retaining is disabled, delete the locality immediately.
2376
- if (parent_->locality_retention_interval_ms_ == 0) {
2377
- parent_->locality_map_.map_.erase(name_);
2378
- return;
2379
- }
1632
+ void XdsLb::PriorityList::LocalityMap::Locality::DeactivateLocked() {
2380
1633
  // If already deactivated, don't do that again.
2381
- if (locality_weight_ == 0) return;
1634
+ if (weight_ == 0) return;
2382
1635
  // Set the locality weight to 0 so that future xds picker won't contain this
2383
1636
  // locality.
2384
- locality_weight_ = 0;
1637
+ weight_ = 0;
2385
1638
  // Start a timer to delete the locality.
2386
- Ref(DEBUG_LOCATION, "LocalityEntry+timer").release();
1639
+ Ref(DEBUG_LOCATION, "Locality+timer").release();
1640
+ GRPC_CLOSURE_INIT(&on_delayed_removal_timer_, OnDelayedRemovalTimer, this,
1641
+ grpc_schedule_on_exec_ctx);
2387
1642
  grpc_timer_init(
2388
1643
  &delayed_removal_timer_,
2389
- ExecCtx::Get()->Now() + parent_->locality_retention_interval_ms_,
1644
+ ExecCtx::Get()->Now() + xds_policy()->locality_retention_interval_ms_,
2390
1645
  &on_delayed_removal_timer_);
2391
1646
  delayed_removal_timer_callback_pending_ = true;
2392
1647
  }
2393
1648
 
2394
- void XdsLb::LocalityMap::LocalityEntry::OnDelayedRemovalTimerLocked(
1649
+ void XdsLb::PriorityList::LocalityMap::Locality::OnDelayedRemovalTimer(
1650
+ void* arg, grpc_error* error) {
1651
+ Locality* self = static_cast<Locality*>(arg);
1652
+ self->xds_policy()->combiner()->Run(
1653
+ GRPC_CLOSURE_INIT(&self->on_delayed_removal_timer_,
1654
+ OnDelayedRemovalTimerLocked, self, nullptr),
1655
+ GRPC_ERROR_REF(error));
1656
+ }
1657
+
1658
+ void XdsLb::PriorityList::LocalityMap::Locality::OnDelayedRemovalTimerLocked(
2395
1659
  void* arg, grpc_error* error) {
2396
- LocalityEntry* self = static_cast<LocalityEntry*>(arg);
1660
+ Locality* self = static_cast<Locality*>(arg);
2397
1661
  self->delayed_removal_timer_callback_pending_ = false;
2398
- if (error == GRPC_ERROR_NONE && self->locality_weight_ == 0) {
2399
- self->parent_->locality_map_.map_.erase(self->name_);
1662
+ if (error == GRPC_ERROR_NONE && !self->shutdown_ && self->weight_ == 0) {
1663
+ self->locality_map_->localities_.erase(self->name_);
2400
1664
  }
2401
- self->Unref(DEBUG_LOCATION, "LocalityEntry+timer");
1665
+ self->Unref(DEBUG_LOCATION, "Locality+timer");
2402
1666
  }
2403
1667
 
2404
1668
  //
2405
- // XdsLb::LocalityEntry::Helper
1669
+ // XdsLb::Locality::Helper
2406
1670
  //
2407
1671
 
2408
- bool XdsLb::LocalityMap::LocalityEntry::Helper::CalledByPendingChild() const {
1672
+ bool XdsLb::PriorityList::LocalityMap::Locality::Helper::CalledByPendingChild()
1673
+ const {
2409
1674
  GPR_ASSERT(child_ != nullptr);
2410
- return child_ == entry_->pending_child_policy_.get();
1675
+ return child_ == locality_->pending_child_policy_.get();
2411
1676
  }
2412
1677
 
2413
- bool XdsLb::LocalityMap::LocalityEntry::Helper::CalledByCurrentChild() const {
1678
+ bool XdsLb::PriorityList::LocalityMap::Locality::Helper::CalledByCurrentChild()
1679
+ const {
2414
1680
  GPR_ASSERT(child_ != nullptr);
2415
- return child_ == entry_->child_policy_.get();
1681
+ return child_ == locality_->child_policy_.get();
2416
1682
  }
2417
1683
 
2418
1684
  RefCountedPtr<SubchannelInterface>
2419
- XdsLb::LocalityMap::LocalityEntry::Helper::CreateSubchannel(
1685
+ XdsLb::PriorityList::LocalityMap::Locality::Helper::CreateSubchannel(
2420
1686
  const grpc_channel_args& args) {
2421
- if (entry_->parent_->shutting_down_ ||
1687
+ if (locality_->xds_policy()->shutting_down_ ||
2422
1688
  (!CalledByPendingChild() && !CalledByCurrentChild())) {
2423
1689
  return nullptr;
2424
1690
  }
2425
- return entry_->parent_->channel_control_helper()->CreateSubchannel(args);
1691
+ return locality_->xds_policy()->channel_control_helper()->CreateSubchannel(
1692
+ args);
2426
1693
  }
2427
1694
 
2428
- void XdsLb::LocalityMap::LocalityEntry::Helper::UpdateState(
1695
+ void XdsLb::PriorityList::LocalityMap::Locality::Helper::UpdateState(
2429
1696
  grpc_connectivity_state state, UniquePtr<SubchannelPicker> picker) {
2430
- if (entry_->parent_->shutting_down_) return;
1697
+ if (locality_->xds_policy()->shutting_down_) return;
2431
1698
  // If this request is from the pending child policy, ignore it until
2432
1699
  // it reports READY, at which point we swap it into place.
2433
1700
  if (CalledByPendingChild()) {
2434
1701
  if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) {
2435
1702
  gpr_log(GPR_INFO,
2436
1703
  "[xdslb %p helper %p] pending child policy %p reports state=%s",
2437
- entry_->parent_.get(), this, entry_->pending_child_policy_.get(),
2438
- grpc_connectivity_state_name(state));
1704
+ locality_->xds_policy(), this,
1705
+ locality_->pending_child_policy_.get(),
1706
+ ConnectivityStateName(state));
2439
1707
  }
2440
1708
  if (state != GRPC_CHANNEL_READY) return;
2441
1709
  grpc_pollset_set_del_pollset_set(
2442
- entry_->child_policy_->interested_parties(),
2443
- entry_->parent_->interested_parties());
2444
- entry_->child_policy_ = std::move(entry_->pending_child_policy_);
1710
+ locality_->child_policy_->interested_parties(),
1711
+ locality_->xds_policy()->interested_parties());
1712
+ locality_->child_policy_ = std::move(locality_->pending_child_policy_);
2445
1713
  } else if (!CalledByCurrentChild()) {
2446
1714
  // This request is from an outdated child, so ignore it.
2447
1715
  return;
2448
1716
  }
2449
- // At this point, child_ must be the current child policy.
2450
- if (state == GRPC_CHANNEL_READY) {
2451
- entry_->parent_->MaybeCancelFallbackAtStartupChecks();
2452
- entry_->parent_->MaybeExitFallbackMode();
2453
- }
2454
- GPR_ASSERT(entry_->parent_->lb_chand_ != nullptr);
2455
- // Cache the picker and its state in the entry.
2456
- entry_->picker_wrapper_ = MakeRefCounted<PickerWrapper>(
1717
+ // Cache the picker and its state in the locality.
1718
+ locality_->picker_wrapper_ = MakeRefCounted<PickerWrapper>(
2457
1719
  std::move(picker),
2458
- entry_->parent_->client_stats_.FindLocalityStats(entry_->name_));
2459
- entry_->connectivity_state_ = state;
2460
- // Construct a new xds picker and pass it to the channel.
2461
- entry_->parent_->locality_map_.UpdateXdsPickerLocked();
2462
- }
2463
-
2464
- void XdsLb::LocalityMap::LocalityEntry::Helper::RequestReresolution() {
2465
- if (entry_->parent_->shutting_down_) return;
2466
- // If there is a pending child policy, ignore re-resolution requests
2467
- // from the current child policy (or any outdated child).
2468
- if (entry_->pending_child_policy_ != nullptr && !CalledByPendingChild()) {
2469
- return;
2470
- }
2471
- if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) {
2472
- gpr_log(GPR_INFO,
2473
- "[xdslb %p] Re-resolution requested from the internal RR policy "
2474
- "(%p).",
2475
- entry_->parent_.get(), entry_->child_policy_.get());
2476
- }
2477
- GPR_ASSERT(entry_->parent_->lb_chand_ != nullptr);
2478
- // If we are talking to a balancer, we expect to get updated addresses
2479
- // from the balancer, so we can ignore the re-resolution request from
2480
- // the child policy. Otherwise, pass the re-resolution request up to the
2481
- // channel.
2482
- if (entry_->parent_->lb_chand_->eds_calld() == nullptr ||
2483
- !entry_->parent_->lb_chand_->eds_calld()->seen_response()) {
2484
- entry_->parent_->channel_control_helper()->RequestReresolution();
2485
- }
1720
+ locality_->xds_policy()->client_stats_.FindLocalityStats(
1721
+ locality_->name_));
1722
+ locality_->connectivity_state_ = state;
1723
+ // Notify the locality map.
1724
+ locality_->locality_map_->OnLocalityStateUpdateLocked();
2486
1725
  }
2487
1726
 
2488
- void XdsLb::LocalityMap::LocalityEntry::Helper::AddTraceEvent(
1727
+ void XdsLb::PriorityList::LocalityMap::Locality::Helper::AddTraceEvent(
2489
1728
  TraceSeverity severity, StringView message) {
2490
- if (entry_->parent_->shutting_down_ ||
1729
+ if (locality_->xds_policy()->shutting_down_ ||
2491
1730
  (!CalledByPendingChild() && !CalledByCurrentChild())) {
2492
1731
  return;
2493
1732
  }
2494
- entry_->parent_->channel_control_helper()->AddTraceEvent(severity, message);
1733
+ locality_->xds_policy()->channel_control_helper()->AddTraceEvent(severity,
1734
+ message);
2495
1735
  }
2496
1736
 
2497
1737
  //
@@ -2502,7 +1742,7 @@ class XdsFactory : public LoadBalancingPolicyFactory {
2502
1742
  public:
2503
1743
  OrphanablePtr<LoadBalancingPolicy> CreateLoadBalancingPolicy(
2504
1744
  LoadBalancingPolicy::Args args) const override {
2505
- return OrphanablePtr<LoadBalancingPolicy>(New<XdsLb>(std::move(args)));
1745
+ return MakeOrphanable<XdsLb>(std::move(args));
2506
1746
  }
2507
1747
 
2508
1748
  const char* name() const override { return kXds; }
@@ -2514,32 +1754,18 @@ class XdsFactory : public LoadBalancingPolicyFactory {
2514
1754
  // xds was mentioned as a policy in the deprecated loadBalancingPolicy
2515
1755
  // field or in the client API.
2516
1756
  *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
2517
- "field:loadBalancingPolicy error:Xds Parser has required field - "
2518
- "balancerName. Please use loadBalancingConfig field of service "
2519
- "config instead.");
1757
+ "field:loadBalancingPolicy error:xds policy requires configuration. "
1758
+ "Please use loadBalancingConfig field of service config instead.");
2520
1759
  return nullptr;
2521
1760
  }
2522
1761
  GPR_DEBUG_ASSERT(strcmp(json->key, name()) == 0);
2523
-
2524
1762
  InlinedVector<grpc_error*, 3> error_list;
2525
- const char* balancer_name = nullptr;
2526
1763
  RefCountedPtr<LoadBalancingPolicy::Config> child_policy;
2527
1764
  RefCountedPtr<LoadBalancingPolicy::Config> fallback_policy;
2528
1765
  for (const grpc_json* field = json->child; field != nullptr;
2529
1766
  field = field->next) {
2530
1767
  if (field->key == nullptr) continue;
2531
- if (strcmp(field->key, "balancerName") == 0) {
2532
- if (balancer_name != nullptr) {
2533
- error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
2534
- "field:balancerName error:Duplicate entry"));
2535
- }
2536
- if (field->type != GRPC_JSON_STRING) {
2537
- error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
2538
- "field:balancerName error:type should be string"));
2539
- continue;
2540
- }
2541
- balancer_name = field->value;
2542
- } else if (strcmp(field->key, "childPolicy") == 0) {
1768
+ if (strcmp(field->key, "childPolicy") == 0) {
2543
1769
  if (child_policy != nullptr) {
2544
1770
  error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
2545
1771
  "field:childPolicy error:Duplicate entry"));
@@ -2567,7 +1793,7 @@ class XdsFactory : public LoadBalancingPolicyFactory {
2567
1793
  }
2568
1794
  if (error_list.empty()) {
2569
1795
  return RefCountedPtr<LoadBalancingPolicy::Config>(New<ParsedXdsConfig>(
2570
- balancer_name, std::move(child_policy), std::move(fallback_policy)));
1796
+ std::move(child_policy), std::move(fallback_policy)));
2571
1797
  } else {
2572
1798
  *error = GRPC_ERROR_CREATE_FROM_VECTOR("Xds Parser", &error_list);
2573
1799
  return nullptr;
@@ -2586,8 +1812,7 @@ class XdsFactory : public LoadBalancingPolicyFactory {
2586
1812
  void grpc_lb_policy_xds_init() {
2587
1813
  grpc_core::LoadBalancingPolicyRegistry::Builder::
2588
1814
  RegisterLoadBalancingPolicyFactory(
2589
- grpc_core::UniquePtr<grpc_core::LoadBalancingPolicyFactory>(
2590
- grpc_core::New<grpc_core::XdsFactory>()));
1815
+ grpc_core::MakeUnique<grpc_core::XdsFactory>());
2591
1816
  }
2592
1817
 
2593
1818
  void grpc_lb_policy_xds_shutdown() {}