grpc 1.60.2 → 1.61.0.pre2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (279) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +208 -165
  3. data/include/grpc/event_engine/event_engine.h +59 -12
  4. data/include/grpc/event_engine/internal/memory_allocator_impl.h +6 -0
  5. data/include/grpc/event_engine/internal/slice_cast.h +12 -0
  6. data/include/grpc/event_engine/memory_allocator.h +3 -1
  7. data/include/grpc/event_engine/slice.h +5 -0
  8. data/include/grpc/grpc_security.h +22 -1
  9. data/include/grpc/impl/call.h +29 -0
  10. data/include/grpc/impl/channel_arg_names.h +12 -1
  11. data/include/grpc/impl/slice_type.h +1 -1
  12. data/include/grpc/module.modulemap +1 -0
  13. data/src/core/ext/filters/backend_metrics/backend_metric_filter.cc +54 -7
  14. data/src/core/ext/filters/backend_metrics/backend_metric_filter.h +20 -6
  15. data/src/core/ext/filters/channel_idle/channel_idle_filter.cc +10 -13
  16. data/src/core/ext/filters/channel_idle/channel_idle_filter.h +18 -10
  17. data/src/core/ext/filters/channel_idle/legacy_channel_idle_filter.cc +326 -0
  18. data/src/core/ext/filters/channel_idle/legacy_channel_idle_filter.h +143 -0
  19. data/src/core/ext/filters/client_channel/backend_metric.cc +2 -2
  20. data/src/core/ext/filters/client_channel/client_channel.cc +32 -6
  21. data/src/core/ext/filters/client_channel/client_channel_internal.h +2 -0
  22. data/src/core/ext/filters/client_channel/global_subchannel_pool.cc +1 -1
  23. data/src/core/ext/filters/client_channel/lb_policy/address_filtering.cc +54 -21
  24. data/src/core/ext/filters/client_channel/lb_policy/address_filtering.h +3 -2
  25. data/src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc +2 -1
  26. data/src/core/ext/filters/client_channel/lb_policy/endpoint_list.cc +12 -15
  27. data/src/core/ext/filters/client_channel/lb_policy/endpoint_list.h +8 -5
  28. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +139 -92
  29. data/src/core/ext/filters/client_channel/lb_policy/health_check_client.cc +9 -4
  30. data/src/core/ext/filters/client_channel/lb_policy/oob_backend_metric.cc +9 -4
  31. data/src/core/ext/filters/client_channel/lb_policy/outlier_detection/outlier_detection.cc +10 -11
  32. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +94 -93
  33. data/src/core/ext/filters/client_channel/lb_policy/priority/priority.cc +5 -3
  34. data/src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.cc +12 -15
  35. data/src/core/ext/filters/client_channel/lb_policy/rls/rls.cc +38 -16
  36. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +25 -28
  37. data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +10 -10
  38. data/src/core/ext/filters/client_channel/lb_policy/weighted_round_robin/weighted_round_robin.cc +37 -35
  39. data/src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc +11 -9
  40. data/src/core/ext/filters/client_channel/lb_policy/xds/cds.cc +504 -461
  41. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc +232 -122
  42. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc +8 -6
  43. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_override_host.cc +642 -251
  44. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_override_host.h +2 -6
  45. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_wrr_locality.cc +7 -8
  46. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +2 -1
  47. data/src/core/ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.cc +3 -1
  48. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +2 -2
  49. data/src/core/ext/filters/client_channel/resolver/google_c2p/google_c2p_resolver.cc +2 -2
  50. data/src/core/ext/filters/client_channel/resolver/polling_resolver.cc +6 -8
  51. data/src/core/ext/filters/client_channel/resolver/xds/xds_dependency_manager.cc +1031 -0
  52. data/src/core/ext/filters/client_channel/resolver/xds/xds_dependency_manager.h +277 -0
  53. data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc +128 -270
  54. data/src/core/ext/filters/client_channel/resolver/xds/{xds_resolver.h → xds_resolver_attributes.h} +5 -4
  55. data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver_trace.cc +25 -0
  56. data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver_trace.h +30 -0
  57. data/src/core/ext/filters/client_channel/retry_filter.cc +1 -0
  58. data/src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc +35 -17
  59. data/src/core/ext/filters/deadline/deadline_filter.cc +12 -0
  60. data/src/core/ext/filters/fault_injection/fault_injection_filter.cc +17 -13
  61. data/src/core/ext/filters/fault_injection/fault_injection_filter.h +13 -4
  62. data/src/core/ext/filters/http/client/http_client_filter.cc +23 -32
  63. data/src/core/ext/filters/http/client/http_client_filter.h +10 -5
  64. data/src/core/ext/filters/http/client_authority_filter.cc +14 -14
  65. data/src/core/ext/filters/http/client_authority_filter.h +12 -4
  66. data/src/core/ext/filters/http/http_filters_plugin.cc +42 -20
  67. data/src/core/ext/filters/http/message_compress/compression_filter.cc +55 -80
  68. data/src/core/ext/filters/http/message_compress/compression_filter.h +54 -12
  69. data/src/core/ext/filters/http/message_compress/legacy_compression_filter.cc +325 -0
  70. data/src/core/ext/filters/http/message_compress/legacy_compression_filter.h +139 -0
  71. data/src/core/ext/filters/http/server/http_server_filter.cc +41 -41
  72. data/src/core/ext/filters/http/server/http_server_filter.h +11 -4
  73. data/src/core/ext/filters/message_size/message_size_filter.cc +56 -76
  74. data/src/core/ext/filters/message_size/message_size_filter.h +35 -23
  75. data/src/core/ext/filters/rbac/rbac_filter.cc +15 -11
  76. data/src/core/ext/filters/rbac/rbac_filter.h +11 -4
  77. data/src/core/ext/filters/server_config_selector/server_config_selector_filter.cc +25 -13
  78. data/src/core/ext/filters/stateful_session/stateful_session_filter.cc +47 -50
  79. data/src/core/ext/filters/stateful_session/stateful_session_filter.h +21 -4
  80. data/src/core/ext/transport/chttp2/alpn/alpn.cc +1 -1
  81. data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +2 -2
  82. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +11 -2
  83. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +68 -145
  84. data/src/core/ext/transport/chttp2/transport/chttp2_transport.h +3 -3
  85. data/src/core/ext/transport/chttp2/transport/flow_control.cc +21 -82
  86. data/src/core/ext/transport/chttp2/transport/flow_control.h +1 -8
  87. data/src/core/ext/transport/chttp2/transport/frame.cc +506 -0
  88. data/src/core/ext/transport/chttp2/transport/frame.h +214 -0
  89. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +1 -1
  90. data/src/core/ext/transport/chttp2/transport/frame_settings.cc +33 -79
  91. data/src/core/ext/transport/chttp2/transport/frame_settings.h +4 -7
  92. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +27 -36
  93. data/src/core/ext/transport/chttp2/transport/hpack_parser.h +0 -2
  94. data/src/core/ext/transport/chttp2/transport/http2_settings.cc +122 -32
  95. data/src/core/ext/transport/chttp2/transport/http2_settings.h +142 -37
  96. data/src/core/ext/transport/chttp2/transport/internal.h +1 -22
  97. data/src/core/ext/transport/chttp2/transport/parsing.cc +23 -37
  98. data/src/core/ext/transport/chttp2/transport/writing.cc +26 -58
  99. data/src/core/ext/transport/inproc/inproc_transport.cc +172 -13
  100. data/src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb.h +712 -0
  101. data/src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.c +151 -0
  102. data/src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.h +33 -0
  103. data/src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.c +133 -0
  104. data/src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.h +50 -0
  105. data/src/core/ext/xds/certificate_provider_store.cc +2 -1
  106. data/src/core/ext/xds/certificate_provider_store.h +0 -5
  107. data/src/core/ext/xds/xds_api.cc +31 -18
  108. data/src/core/ext/xds/xds_api.h +2 -2
  109. data/src/core/ext/xds/xds_bootstrap.h +3 -0
  110. data/src/core/ext/xds/xds_certificate_provider.cc +88 -287
  111. data/src/core/ext/xds/xds_certificate_provider.h +44 -111
  112. data/src/core/ext/xds/xds_client.cc +420 -414
  113. data/src/core/ext/xds/xds_client.h +31 -22
  114. data/src/core/ext/xds/xds_client_grpc.cc +3 -1
  115. data/src/core/ext/xds/xds_cluster.cc +104 -11
  116. data/src/core/ext/xds/xds_cluster.h +9 -1
  117. data/src/core/ext/xds/xds_cluster_specifier_plugin.cc +9 -5
  118. data/src/core/ext/xds/xds_common_types.cc +14 -10
  119. data/src/core/ext/xds/xds_endpoint.cc +9 -4
  120. data/src/core/ext/xds/xds_endpoint.h +5 -1
  121. data/src/core/ext/xds/xds_health_status.cc +12 -2
  122. data/src/core/ext/xds/xds_health_status.h +4 -2
  123. data/src/core/ext/xds/xds_http_rbac_filter.cc +5 -3
  124. data/src/core/ext/xds/xds_listener.cc +14 -8
  125. data/src/core/ext/xds/xds_resource_type_impl.h +6 -4
  126. data/src/core/ext/xds/xds_route_config.cc +34 -22
  127. data/src/core/ext/xds/xds_route_config.h +1 -0
  128. data/src/core/ext/xds/xds_server_config_fetcher.cc +61 -57
  129. data/src/core/ext/xds/xds_transport.h +3 -0
  130. data/src/core/ext/xds/xds_transport_grpc.cc +47 -50
  131. data/src/core/ext/xds/xds_transport_grpc.h +4 -0
  132. data/src/core/lib/channel/call_tracer.cc +12 -0
  133. data/src/core/lib/channel/call_tracer.h +17 -3
  134. data/src/core/lib/channel/channel_args.cc +24 -14
  135. data/src/core/lib/channel/channel_args.h +74 -13
  136. data/src/core/lib/channel/channel_stack.cc +27 -0
  137. data/src/core/lib/channel/channel_stack.h +10 -10
  138. data/src/core/lib/channel/connected_channel.cc +64 -18
  139. data/src/core/lib/channel/promise_based_filter.h +1041 -1
  140. data/src/core/lib/channel/server_call_tracer_filter.cc +43 -35
  141. data/src/core/lib/compression/compression_internal.cc +0 -3
  142. data/src/core/lib/event_engine/ares_resolver.cc +35 -14
  143. data/src/core/lib/event_engine/ares_resolver.h +9 -10
  144. data/src/core/lib/event_engine/cf_engine/dns_service_resolver.cc +8 -1
  145. data/src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc +132 -0
  146. data/src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.h +61 -0
  147. data/src/core/lib/event_engine/posix_engine/posix_engine.cc +52 -36
  148. data/src/core/lib/event_engine/posix_engine/posix_engine.h +4 -9
  149. data/src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.cc +11 -3
  150. data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.cc +9 -2
  151. data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.h +7 -0
  152. data/src/core/lib/event_engine/posix_engine/timer_manager.cc +17 -27
  153. data/src/core/lib/event_engine/posix_engine/timer_manager.h +0 -3
  154. data/src/core/lib/event_engine/ref_counted_dns_resolver_interface.h +55 -0
  155. data/src/core/lib/event_engine/windows/native_windows_dns_resolver.cc +114 -0
  156. data/src/core/lib/event_engine/windows/native_windows_dns_resolver.h +51 -0
  157. data/src/core/lib/event_engine/windows/windows_engine.cc +7 -7
  158. data/src/core/lib/experiments/config.cc +13 -0
  159. data/src/core/lib/experiments/config.h +3 -0
  160. data/src/core/lib/experiments/experiments.cc +245 -366
  161. data/src/core/lib/experiments/experiments.h +50 -156
  162. data/src/core/lib/gprpp/debug_location.h +13 -0
  163. data/src/core/lib/gprpp/dual_ref_counted.h +36 -7
  164. data/src/core/lib/gprpp/orphanable.h +27 -0
  165. data/src/core/lib/gprpp/ref_counted.h +63 -22
  166. data/src/core/lib/gprpp/ref_counted_ptr.h +70 -27
  167. data/src/core/lib/gprpp/ref_counted_string.h +13 -0
  168. data/src/core/lib/gprpp/status_helper.cc +1 -2
  169. data/src/core/lib/iomgr/combiner.cc +15 -51
  170. data/src/core/lib/iomgr/event_engine_shims/endpoint.cc +31 -0
  171. data/src/core/lib/iomgr/event_engine_shims/endpoint.h +16 -0
  172. data/src/core/lib/iomgr/tcp_client_posix.cc +4 -3
  173. data/src/core/lib/load_balancing/lb_policy.h +1 -1
  174. data/src/core/lib/promise/activity.cc +17 -2
  175. data/src/core/lib/promise/activity.h +5 -4
  176. data/src/core/lib/promise/all_ok.h +80 -0
  177. data/src/core/lib/promise/detail/join_state.h +2077 -0
  178. data/src/core/lib/promise/detail/promise_factory.h +1 -0
  179. data/src/core/lib/promise/detail/promise_like.h +8 -1
  180. data/src/core/lib/promise/detail/seq_state.h +3458 -150
  181. data/src/core/lib/promise/detail/status.h +42 -5
  182. data/src/core/lib/promise/for_each.h +13 -1
  183. data/src/core/lib/promise/if.h +4 -0
  184. data/src/core/lib/promise/latch.h +6 -3
  185. data/src/core/lib/promise/party.cc +33 -31
  186. data/src/core/lib/promise/party.h +142 -6
  187. data/src/core/lib/promise/poll.h +39 -13
  188. data/src/core/lib/promise/promise.h +4 -0
  189. data/src/core/lib/promise/seq.h +107 -7
  190. data/src/core/lib/promise/status_flag.h +196 -0
  191. data/src/core/lib/promise/try_join.h +132 -0
  192. data/src/core/lib/promise/try_seq.h +132 -10
  193. data/src/core/lib/resolver/endpoint_addresses.cc +0 -1
  194. data/src/core/lib/resolver/endpoint_addresses.h +48 -0
  195. data/src/core/lib/resource_quota/arena.h +2 -2
  196. data/src/core/lib/resource_quota/memory_quota.cc +57 -8
  197. data/src/core/lib/resource_quota/memory_quota.h +6 -0
  198. data/src/core/lib/security/authorization/grpc_server_authz_filter.cc +14 -11
  199. data/src/core/lib/security/authorization/grpc_server_authz_filter.h +14 -5
  200. data/src/core/lib/security/credentials/external/aws_external_account_credentials.cc +4 -0
  201. data/src/core/lib/security/credentials/external/aws_external_account_credentials.h +4 -0
  202. data/src/core/lib/security/credentials/external/external_account_credentials.cc +28 -20
  203. data/src/core/lib/security/credentials/external/external_account_credentials.h +4 -0
  204. data/src/core/lib/security/credentials/external/file_external_account_credentials.cc +4 -0
  205. data/src/core/lib/security/credentials/external/file_external_account_credentials.h +4 -0
  206. data/src/core/lib/security/credentials/external/url_external_account_credentials.cc +4 -0
  207. data/src/core/lib/security/credentials/external/url_external_account_credentials.h +4 -0
  208. data/src/core/lib/security/credentials/plugin/plugin_credentials.cc +2 -1
  209. data/src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h +0 -3
  210. data/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc +12 -0
  211. data/src/core/lib/security/credentials/tls/grpc_tls_crl_provider.cc +22 -5
  212. data/src/core/lib/security/credentials/tls/grpc_tls_crl_provider.h +1 -5
  213. data/src/core/lib/security/credentials/tls/tls_credentials.cc +16 -0
  214. data/src/core/lib/security/credentials/xds/xds_credentials.cc +21 -28
  215. data/src/core/lib/security/credentials/xds/xds_credentials.h +2 -4
  216. data/src/core/lib/security/security_connector/tls/tls_security_connector.cc +4 -3
  217. data/src/core/lib/security/transport/auth_filters.h +71 -4
  218. data/src/core/lib/security/transport/client_auth_filter.cc +2 -4
  219. data/src/core/lib/security/transport/legacy_server_auth_filter.cc +244 -0
  220. data/src/core/lib/security/transport/server_auth_filter.cc +70 -90
  221. data/src/core/lib/slice/slice_buffer.h +3 -0
  222. data/src/core/lib/surface/builtins.cc +1 -1
  223. data/src/core/lib/surface/call.cc +683 -196
  224. data/src/core/lib/surface/call.h +26 -13
  225. data/src/core/lib/surface/call_trace.cc +42 -1
  226. data/src/core/lib/surface/channel.cc +0 -1
  227. data/src/core/lib/surface/channel.h +0 -6
  228. data/src/core/lib/surface/channel_init.h +26 -0
  229. data/src/core/lib/surface/init.cc +14 -8
  230. data/src/core/lib/surface/server.cc +256 -237
  231. data/src/core/lib/surface/server.h +26 -54
  232. data/src/core/lib/surface/version.cc +2 -2
  233. data/src/core/lib/surface/wait_for_cq_end_op.h +94 -0
  234. data/src/core/lib/transport/call_final_info.cc +38 -0
  235. data/src/core/lib/transport/call_final_info.h +54 -0
  236. data/src/core/lib/transport/connectivity_state.cc +3 -2
  237. data/src/core/lib/transport/connectivity_state.h +4 -0
  238. data/src/core/lib/transport/metadata_batch.h +4 -4
  239. data/src/core/lib/transport/transport.cc +70 -19
  240. data/src/core/lib/transport/transport.h +395 -25
  241. data/src/core/plugin_registry/grpc_plugin_registry.cc +3 -0
  242. data/src/core/plugin_registry/grpc_plugin_registry_extra.cc +0 -3
  243. data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +1 -1
  244. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +1 -1
  245. data/src/core/tsi/alts/handshaker/transport_security_common_api.cc +1 -1
  246. data/src/core/tsi/ssl_transport_security.cc +65 -43
  247. data/src/ruby/ext/grpc/rb_channel_args.c +3 -1
  248. data/src/ruby/ext/grpc/rb_grpc.c +0 -1
  249. data/src/ruby/ext/grpc/rb_grpc.h +0 -2
  250. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +4 -0
  251. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +6 -0
  252. data/src/ruby/lib/grpc/version.rb +1 -1
  253. data/third_party/upb/upb/reflection/def_pool.h +2 -2
  254. data/third_party/zlib/adler32.c +5 -27
  255. data/third_party/zlib/compress.c +5 -16
  256. data/third_party/zlib/crc32.c +86 -162
  257. data/third_party/zlib/deflate.c +233 -336
  258. data/third_party/zlib/deflate.h +8 -8
  259. data/third_party/zlib/gzguts.h +11 -12
  260. data/third_party/zlib/infback.c +7 -23
  261. data/third_party/zlib/inffast.c +1 -4
  262. data/third_party/zlib/inffast.h +1 -1
  263. data/third_party/zlib/inflate.c +30 -99
  264. data/third_party/zlib/inftrees.c +6 -11
  265. data/third_party/zlib/inftrees.h +3 -3
  266. data/third_party/zlib/trees.c +224 -302
  267. data/third_party/zlib/uncompr.c +4 -12
  268. data/third_party/zlib/zconf.h +6 -2
  269. data/third_party/zlib/zlib.h +191 -188
  270. data/third_party/zlib/zutil.c +16 -44
  271. data/third_party/zlib/zutil.h +10 -10
  272. metadata +35 -13
  273. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc +0 -1173
  274. data/src/core/lib/event_engine/memory_allocator.cc +0 -74
  275. data/src/core/lib/transport/pid_controller.cc +0 -51
  276. data/src/core/lib/transport/pid_controller.h +0 -116
  277. data/third_party/upb/upb/collections/array.h +0 -17
  278. data/third_party/upb/upb/collections/map.h +0 -17
  279. data/third_party/upb/upb/upb.hpp +0 -18
@@ -23,8 +23,10 @@
23
23
 
24
24
  #include <algorithm>
25
25
  #include <functional>
26
+ #include <memory>
26
27
  #include <type_traits>
27
28
 
29
+ #include "absl/cleanup/cleanup.h"
28
30
  #include "absl/strings/match.h"
29
31
  #include "absl/strings/str_cat.h"
30
32
  #include "absl/strings/str_join.h"
@@ -68,10 +70,10 @@ TraceFlag grpc_xds_client_refcount_trace(false, "xds_client_refcount");
68
70
  // An xds call wrapper that can restart a call upon failure. Holds a ref to
69
71
  // the xds channel. The template parameter is the kind of wrapped xds call.
70
72
  template <typename T>
71
- class XdsClient::ChannelState::RetryableCall
73
+ class XdsClient::XdsChannel::RetryableCall
72
74
  : public InternallyRefCounted<RetryableCall<T>> {
73
75
  public:
74
- explicit RetryableCall(WeakRefCountedPtr<ChannelState> chand);
76
+ explicit RetryableCall(WeakRefCountedPtr<XdsChannel> xds_channel);
75
77
 
76
78
  // Disable thread-safety analysis because this method is called via
77
79
  // OrphanablePtr<>, but there's no way to pass the lock annotation
@@ -80,8 +82,8 @@ class XdsClient::ChannelState::RetryableCall
80
82
 
81
83
  void OnCallFinishedLocked() ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsClient::mu_);
82
84
 
83
- T* calld() const { return calld_.get(); }
84
- ChannelState* chand() const { return chand_.get(); }
85
+ T* call() const { return call_.get(); }
86
+ XdsChannel* xds_channel() const { return xds_channel_.get(); }
85
87
 
86
88
  bool IsCurrentCallOnChannel() const;
87
89
 
@@ -93,9 +95,9 @@ class XdsClient::ChannelState::RetryableCall
93
95
 
94
96
  // The wrapped xds call that talks to the xds server. It's instantiated
95
97
  // every time we start a new call. It's null during call retry backoff.
96
- OrphanablePtr<T> calld_;
98
+ OrphanablePtr<T> call_;
97
99
  // The owning xds channel.
98
- WeakRefCountedPtr<ChannelState> chand_;
100
+ WeakRefCountedPtr<XdsChannel> xds_channel_;
99
101
 
100
102
  // Retry state.
101
103
  BackOff backoff_;
@@ -106,17 +108,18 @@ class XdsClient::ChannelState::RetryableCall
106
108
  };
107
109
 
108
110
  // Contains an ADS call to the xds server.
109
- class XdsClient::ChannelState::AdsCallState
110
- : public InternallyRefCounted<AdsCallState> {
111
+ class XdsClient::XdsChannel::AdsCall : public InternallyRefCounted<AdsCall> {
111
112
  public:
112
113
  // The ctor and dtor should not be used directly.
113
- explicit AdsCallState(RefCountedPtr<RetryableCall<AdsCallState>> parent);
114
+ explicit AdsCall(RefCountedPtr<RetryableCall<AdsCall>> retryable_call);
114
115
 
115
116
  void Orphan() override;
116
117
 
117
- RetryableCall<AdsCallState>* parent() const { return parent_.get(); }
118
- ChannelState* chand() const { return parent_->chand(); }
119
- XdsClient* xds_client() const { return chand()->xds_client(); }
118
+ RetryableCall<AdsCall>* retryable_call() const {
119
+ return retryable_call_.get();
120
+ }
121
+ XdsChannel* xds_channel() const { return retryable_call_->xds_channel(); }
122
+ XdsClient* xds_client() const { return xds_channel()->xds_client(); }
120
123
  bool seen_response() const { return seen_response_; }
121
124
 
122
125
  void SubscribeLocked(const XdsResourceType* type, const XdsResourceName& name,
@@ -129,6 +132,8 @@ class XdsClient::ChannelState::AdsCallState
129
132
  bool HasSubscribedResources() const;
130
133
 
131
134
  private:
135
+ class AdsReadDelayHandle;
136
+
132
137
  class AdsResponseParser : public XdsApi::AdsResponseParserInterface {
133
138
  public:
134
139
  struct Result {
@@ -140,10 +145,10 @@ class XdsClient::ChannelState::AdsCallState
140
145
  std::map<std::string /*authority*/, std::set<XdsResourceKey>>
141
146
  resources_seen;
142
147
  bool have_valid_resources = false;
148
+ RefCountedPtr<ReadDelayHandle> read_delay_handle;
143
149
  };
144
150
 
145
- explicit AdsResponseParser(AdsCallState* ads_call_state)
146
- : ads_call_state_(ads_call_state) {}
151
+ explicit AdsResponseParser(AdsCall* ads_call) : ads_call_(ads_call) {}
147
152
 
148
153
  absl::Status ProcessAdsResponseFields(AdsResponseFields fields) override
149
154
  ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsClient::mu_);
@@ -159,9 +164,9 @@ class XdsClient::ChannelState::AdsCallState
159
164
  Result TakeResult() { return std::move(result_); }
160
165
 
161
166
  private:
162
- XdsClient* xds_client() const { return ads_call_state_->xds_client(); }
167
+ XdsClient* xds_client() const { return ads_call_->xds_client(); }
163
168
 
164
- AdsCallState* ads_call_state_;
169
+ AdsCall* ads_call_;
165
170
  const Timestamp update_time_ = Timestamp::Now();
166
171
  Result result_;
167
172
  };
@@ -184,10 +189,9 @@ class XdsClient::ChannelState::AdsCallState
184
189
  subscription_sent_ = true;
185
190
  }
186
191
 
187
- void MaybeMarkSubscriptionSendComplete(
188
- RefCountedPtr<AdsCallState> ads_calld)
192
+ void MaybeMarkSubscriptionSendComplete(RefCountedPtr<AdsCall> ads_call)
189
193
  ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsClient::mu_) {
190
- if (subscription_sent_) MaybeStartTimer(std::move(ads_calld));
194
+ if (subscription_sent_) MaybeStartTimer(std::move(ads_call));
191
195
  }
192
196
 
193
197
  void MarkSeen() ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsClient::mu_) {
@@ -197,13 +201,13 @@ class XdsClient::ChannelState::AdsCallState
197
201
 
198
202
  void MaybeCancelTimer() ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsClient::mu_) {
199
203
  if (timer_handle_.has_value() &&
200
- ads_calld_->xds_client()->engine()->Cancel(*timer_handle_)) {
204
+ ads_call_->xds_client()->engine()->Cancel(*timer_handle_)) {
201
205
  timer_handle_.reset();
202
206
  }
203
207
  }
204
208
 
205
209
  private:
206
- void MaybeStartTimer(RefCountedPtr<AdsCallState> ads_calld)
210
+ void MaybeStartTimer(RefCountedPtr<AdsCall> ads_call)
207
211
  ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsClient::mu_) {
208
212
  // Don't start timer if we've already either seen the resource or
209
213
  // marked it as non-existing.
@@ -224,13 +228,13 @@ class XdsClient::ChannelState::AdsCallState
224
228
  // (a) we already have the resource and (b) the server may
225
229
  // optimize by not resending the resource that we already have.
226
230
  auto& authority_state =
227
- ads_calld->xds_client()->authority_state_map_[name_.authority];
231
+ ads_call->xds_client()->authority_state_map_[name_.authority];
228
232
  ResourceState& state = authority_state.resource_map[type_][name_.key];
229
233
  if (state.resource != nullptr) return;
230
234
  // Start timer.
231
- ads_calld_ = std::move(ads_calld);
232
- timer_handle_ = ads_calld_->xds_client()->engine()->RunAfter(
233
- ads_calld_->xds_client()->request_timeout_,
235
+ ads_call_ = std::move(ads_call);
236
+ timer_handle_ = ads_call_->xds_client()->engine()->RunAfter(
237
+ ads_call_->xds_client()->request_timeout_,
234
238
  [self = Ref(DEBUG_LOCATION, "timer")]() {
235
239
  ApplicationCallbackExecCtx callback_exec_ctx;
236
240
  ExecCtx exec_ctx;
@@ -243,32 +247,32 @@ class XdsClient::ChannelState::AdsCallState
243
247
  gpr_log(GPR_INFO,
244
248
  "[xds_client %p] xds server %s: timeout obtaining resource "
245
249
  "{type=%s name=%s} from xds server",
246
- ads_calld_->xds_client(),
247
- ads_calld_->chand()->server_.server_uri().c_str(),
250
+ ads_call_->xds_client(),
251
+ ads_call_->xds_channel()->server_.server_uri().c_str(),
248
252
  std::string(type_->type_url()).c_str(),
249
253
  XdsClient::ConstructFullXdsResourceName(
250
254
  name_.authority, type_->type_url(), name_.key)
251
255
  .c_str());
252
256
  }
253
257
  {
254
- MutexLock lock(&ads_calld_->xds_client()->mu_);
258
+ MutexLock lock(&ads_call_->xds_client()->mu_);
255
259
  timer_handle_.reset();
256
260
  resource_seen_ = true;
257
261
  auto& authority_state =
258
- ads_calld_->xds_client()->authority_state_map_[name_.authority];
262
+ ads_call_->xds_client()->authority_state_map_[name_.authority];
259
263
  ResourceState& state = authority_state.resource_map[type_][name_.key];
260
264
  state.meta.client_status = XdsApi::ResourceMetadata::DOES_NOT_EXIST;
261
- ads_calld_->xds_client()->NotifyWatchersOnResourceDoesNotExist(
262
- state.watchers);
265
+ ads_call_->xds_client()->NotifyWatchersOnResourceDoesNotExist(
266
+ state.watchers, ReadDelayHandle::NoWait());
263
267
  }
264
- ads_calld_->xds_client()->work_serializer_.DrainQueue();
265
- ads_calld_.reset();
268
+ ads_call_->xds_client()->work_serializer_.DrainQueue();
269
+ ads_call_.reset();
266
270
  }
267
271
 
268
272
  const XdsResourceType* type_;
269
273
  const XdsResourceName name_;
270
274
 
271
- RefCountedPtr<AdsCallState> ads_calld_;
275
+ RefCountedPtr<AdsCall> ads_call_;
272
276
  // True if we have sent the initial subscription request for this
273
277
  // resource on this ADS stream.
274
278
  bool subscription_sent_ ABSL_GUARDED_BY(&XdsClient::mu_) = false;
@@ -283,19 +287,19 @@ class XdsClient::ChannelState::AdsCallState
283
287
  class StreamEventHandler
284
288
  : public XdsTransportFactory::XdsTransport::StreamingCall::EventHandler {
285
289
  public:
286
- explicit StreamEventHandler(RefCountedPtr<AdsCallState> ads_calld)
287
- : ads_calld_(std::move(ads_calld)) {}
290
+ explicit StreamEventHandler(RefCountedPtr<AdsCall> ads_call)
291
+ : ads_call_(std::move(ads_call)) {}
288
292
 
289
- void OnRequestSent(bool ok) override { ads_calld_->OnRequestSent(ok); }
293
+ void OnRequestSent(bool ok) override { ads_call_->OnRequestSent(ok); }
290
294
  void OnRecvMessage(absl::string_view payload) override {
291
- ads_calld_->OnRecvMessage(payload);
295
+ ads_call_->OnRecvMessage(payload);
292
296
  }
293
297
  void OnStatusReceived(absl::Status status) override {
294
- ads_calld_->OnStatusReceived(std::move(status));
298
+ ads_call_->OnStatusReceived(std::move(status));
295
299
  }
296
300
 
297
301
  private:
298
- RefCountedPtr<AdsCallState> ads_calld_;
302
+ RefCountedPtr<AdsCall> ads_call_;
299
303
  };
300
304
 
301
305
  struct ResourceTypeState {
@@ -324,9 +328,10 @@ class XdsClient::ChannelState::AdsCallState
324
328
  ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsClient::mu_);
325
329
 
326
330
  // The owning RetryableCall<>.
327
- RefCountedPtr<RetryableCall<AdsCallState>> parent_;
331
+ RefCountedPtr<RetryableCall<AdsCall>> retryable_call_;
328
332
 
329
- OrphanablePtr<XdsTransportFactory::XdsTransport::StreamingCall> call_;
333
+ OrphanablePtr<XdsTransportFactory::XdsTransport::StreamingCall>
334
+ streaming_call_;
330
335
 
331
336
  bool sent_initial_message_ = false;
332
337
  bool seen_response_ = false;
@@ -342,87 +347,86 @@ class XdsClient::ChannelState::AdsCallState
342
347
  };
343
348
 
344
349
  // Contains an LRS call to the xds server.
345
- class XdsClient::ChannelState::LrsCallState
346
- : public InternallyRefCounted<LrsCallState> {
350
+ class XdsClient::XdsChannel::LrsCall : public InternallyRefCounted<LrsCall> {
347
351
  public:
348
352
  // The ctor and dtor should not be used directly.
349
- explicit LrsCallState(RefCountedPtr<RetryableCall<LrsCallState>> parent);
353
+ explicit LrsCall(RefCountedPtr<RetryableCall<LrsCall>> retryable_call);
350
354
 
351
355
  void Orphan() override;
352
356
 
353
- void MaybeStartReportingLocked()
354
- ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsClient::mu_);
355
-
356
- RetryableCall<LrsCallState>* parent() { return parent_.get(); }
357
- ChannelState* chand() const { return parent_->chand(); }
358
- XdsClient* xds_client() const { return chand()->xds_client(); }
357
+ RetryableCall<LrsCall>* retryable_call() { return retryable_call_.get(); }
358
+ XdsChannel* xds_channel() const { return retryable_call_->xds_channel(); }
359
+ XdsClient* xds_client() const { return xds_channel()->xds_client(); }
359
360
  bool seen_response() const { return seen_response_; }
360
361
 
361
362
  private:
362
363
  class StreamEventHandler
363
364
  : public XdsTransportFactory::XdsTransport::StreamingCall::EventHandler {
364
365
  public:
365
- explicit StreamEventHandler(RefCountedPtr<LrsCallState> lrs_calld)
366
- : lrs_calld_(std::move(lrs_calld)) {}
366
+ explicit StreamEventHandler(RefCountedPtr<LrsCall> lrs_call)
367
+ : lrs_call_(std::move(lrs_call)) {}
367
368
 
368
- void OnRequestSent(bool ok) override { lrs_calld_->OnRequestSent(ok); }
369
+ void OnRequestSent(bool /*ok*/) override { lrs_call_->OnRequestSent(); }
369
370
  void OnRecvMessage(absl::string_view payload) override {
370
- lrs_calld_->OnRecvMessage(payload);
371
+ lrs_call_->OnRecvMessage(payload);
371
372
  }
372
373
  void OnStatusReceived(absl::Status status) override {
373
- lrs_calld_->OnStatusReceived(std::move(status));
374
+ lrs_call_->OnStatusReceived(std::move(status));
374
375
  }
375
376
 
376
377
  private:
377
- RefCountedPtr<LrsCallState> lrs_calld_;
378
+ RefCountedPtr<LrsCall> lrs_call_;
378
379
  };
379
380
 
380
- // Reports client-side load stats according to a fixed interval.
381
- class Reporter : public InternallyRefCounted<Reporter> {
381
+ // A repeating timer for a particular duration.
382
+ class Timer : public InternallyRefCounted<Timer> {
382
383
  public:
383
- Reporter(RefCountedPtr<LrsCallState> parent, Duration report_interval)
384
- : parent_(std::move(parent)), report_interval_(report_interval) {
385
- ScheduleNextReportLocked();
386
- }
384
+ explicit Timer(RefCountedPtr<LrsCall> lrs_call)
385
+ : lrs_call_(std::move(lrs_call)) {}
386
+ ~Timer() override { lrs_call_.reset(DEBUG_LOCATION, "LRS timer"); }
387
387
 
388
388
  // Disable thread-safety analysis because this method is called via
389
389
  // OrphanablePtr<>, but there's no way to pass the lock annotation
390
390
  // through there.
391
391
  void Orphan() override ABSL_NO_THREAD_SAFETY_ANALYSIS;
392
392
 
393
- void OnReportDoneLocked() ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsClient::mu_);
394
-
395
- private:
396
393
  void ScheduleNextReportLocked()
397
394
  ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsClient::mu_);
398
- bool OnNextReportTimer();
399
- bool SendReportLocked() ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsClient::mu_);
400
395
 
401
- bool IsCurrentReporterOnCall() const {
402
- return this == parent_->reporter_.get();
396
+ private:
397
+ bool IsCurrentTimerOnCall() const {
398
+ return this == lrs_call_->timer_.get();
403
399
  }
404
- XdsClient* xds_client() const { return parent_->xds_client(); }
400
+ XdsClient* xds_client() const { return lrs_call_->xds_client(); }
401
+
402
+ void OnNextReportTimer();
405
403
 
406
404
  // The owning LRS call.
407
- RefCountedPtr<LrsCallState> parent_;
405
+ RefCountedPtr<LrsCall> lrs_call_;
408
406
 
409
- // The load reporting state.
410
- const Duration report_interval_;
411
- bool last_report_counters_were_zero_ = false;
412
407
  absl::optional<EventEngine::TaskHandle> timer_handle_
413
408
  ABSL_GUARDED_BY(&XdsClient::mu_);
414
409
  };
415
410
 
416
- void OnRequestSent(bool ok);
411
+ void MaybeScheduleNextReportLocked()
412
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsClient::mu_);
413
+
414
+ void SendReportLocked() ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsClient::mu_);
415
+
416
+ void SendMessageLocked(std::string payload)
417
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsClient::mu_);
418
+
419
+ void OnRequestSent();
417
420
  void OnRecvMessage(absl::string_view payload);
418
421
  void OnStatusReceived(absl::Status status);
419
422
 
420
423
  bool IsCurrentCallOnChannel() const;
421
424
 
422
425
  // The owning RetryableCall<>.
423
- RefCountedPtr<RetryableCall<LrsCallState>> parent_;
426
+ RefCountedPtr<RetryableCall<LrsCall>> retryable_call_;
424
427
 
425
- OrphanablePtr<XdsTransportFactory::XdsTransport::StreamingCall> call_;
428
+ OrphanablePtr<XdsTransportFactory::XdsTransport::StreamingCall>
429
+ streaming_call_;
426
430
 
427
431
  bool seen_response_ = false;
428
432
  bool send_message_pending_ ABSL_GUARDED_BY(&XdsClient::mu_) = false;
@@ -431,19 +435,19 @@ class XdsClient::ChannelState::LrsCallState
431
435
  bool send_all_clusters_ = false;
432
436
  std::set<std::string> cluster_names_; // Asked for by the LRS server.
433
437
  Duration load_reporting_interval_;
434
- OrphanablePtr<Reporter> reporter_;
438
+ bool last_report_counters_were_zero_ = false;
439
+ OrphanablePtr<Timer> timer_;
435
440
  };
436
441
 
437
442
  //
438
- // XdsClient::ChannelState
443
+ // XdsClient::XdsChannel
439
444
  //
440
445
 
441
- XdsClient::ChannelState::ChannelState(WeakRefCountedPtr<XdsClient> xds_client,
442
- const XdsBootstrap::XdsServer& server)
443
- : DualRefCounted<ChannelState>(
444
- GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_refcount_trace)
445
- ? "ChannelState"
446
- : nullptr),
446
+ XdsClient::XdsChannel::XdsChannel(WeakRefCountedPtr<XdsClient> xds_client,
447
+ const XdsBootstrap::XdsServer& server)
448
+ : DualRefCounted<XdsChannel>(
449
+ GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_refcount_trace) ? "XdsChannel"
450
+ : nullptr),
447
451
  xds_client_(std::move(xds_client)),
448
452
  server_(server) {
449
453
  if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
@@ -462,19 +466,19 @@ XdsClient::ChannelState::ChannelState(WeakRefCountedPtr<XdsClient> xds_client,
462
466
  if (!status.ok()) SetChannelStatusLocked(std::move(status));
463
467
  }
464
468
 
465
- XdsClient::ChannelState::~ChannelState() {
469
+ XdsClient::XdsChannel::~XdsChannel() {
466
470
  if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
467
471
  gpr_log(GPR_INFO, "[xds_client %p] destroying xds channel %p for server %s",
468
472
  xds_client(), this, server_.server_uri().c_str());
469
473
  }
470
- xds_client_.reset(DEBUG_LOCATION, "ChannelState");
474
+ xds_client_.reset(DEBUG_LOCATION, "XdsChannel");
471
475
  }
472
476
 
473
477
  // This method should only ever be called when holding the lock, but we can't
474
478
  // use a ABSL_EXCLUSIVE_LOCKS_REQUIRED annotation, because Orphan() will be
475
479
  // called from DualRefCounted::Unref, which cannot have a lock annotation for
476
480
  // a lock in this subclass.
477
- void XdsClient::ChannelState::Orphan() ABSL_NO_THREAD_SAFETY_ANALYSIS {
481
+ void XdsClient::XdsChannel::Orphan() ABSL_NO_THREAD_SAFETY_ANALYSIS {
478
482
  if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
479
483
  gpr_log(GPR_INFO, "[xds_client %p] orphaning xds channel %p for server %s",
480
484
  xds_client(), this, server_.server_uri().c_str());
@@ -482,69 +486,67 @@ void XdsClient::ChannelState::Orphan() ABSL_NO_THREAD_SAFETY_ANALYSIS {
482
486
  shutting_down_ = true;
483
487
  transport_.reset();
484
488
  // At this time, all strong refs are removed, remove from channel map to
485
- // prevent subsequent subscription from trying to use this ChannelState as
489
+ // prevent subsequent subscription from trying to use this XdsChannel as
486
490
  // it is shutting down.
487
491
  xds_client_->xds_server_channel_map_.erase(&server_);
488
- ads_calld_.reset();
489
- lrs_calld_.reset();
492
+ ads_call_.reset();
493
+ lrs_call_.reset();
490
494
  }
491
495
 
492
- void XdsClient::ChannelState::ResetBackoff() { transport_->ResetBackoff(); }
496
+ void XdsClient::XdsChannel::ResetBackoff() { transport_->ResetBackoff(); }
493
497
 
494
- XdsClient::ChannelState::AdsCallState* XdsClient::ChannelState::ads_calld()
495
- const {
496
- return ads_calld_->calld();
498
+ XdsClient::XdsChannel::AdsCall* XdsClient::XdsChannel::ads_call() const {
499
+ return ads_call_->call();
497
500
  }
498
501
 
499
- XdsClient::ChannelState::LrsCallState* XdsClient::ChannelState::lrs_calld()
500
- const {
501
- return lrs_calld_->calld();
502
+ XdsClient::XdsChannel::LrsCall* XdsClient::XdsChannel::lrs_call() const {
503
+ return lrs_call_->call();
502
504
  }
503
505
 
504
- void XdsClient::ChannelState::MaybeStartLrsCall() {
505
- if (lrs_calld_ != nullptr) return;
506
- lrs_calld_.reset(new RetryableCall<LrsCallState>(
507
- WeakRef(DEBUG_LOCATION, "ChannelState+lrs")));
506
+ void XdsClient::XdsChannel::MaybeStartLrsCall() {
507
+ if (lrs_call_ != nullptr) return;
508
+ lrs_call_.reset(
509
+ new RetryableCall<LrsCall>(WeakRef(DEBUG_LOCATION, "XdsChannel+lrs")));
508
510
  }
509
511
 
510
- void XdsClient::ChannelState::StopLrsCallLocked() {
512
+ void XdsClient::XdsChannel::StopLrsCallLocked() {
511
513
  xds_client_->xds_load_report_server_map_.erase(&server_);
512
- lrs_calld_.reset();
514
+ lrs_call_.reset();
513
515
  }
514
516
 
515
- void XdsClient::ChannelState::SubscribeLocked(const XdsResourceType* type,
516
- const XdsResourceName& name) {
517
- if (ads_calld_ == nullptr) {
517
+ void XdsClient::XdsChannel::SubscribeLocked(const XdsResourceType* type,
518
+ const XdsResourceName& name) {
519
+ if (ads_call_ == nullptr) {
518
520
  // Start the ADS call if this is the first request.
519
- ads_calld_.reset(new RetryableCall<AdsCallState>(
520
- WeakRef(DEBUG_LOCATION, "ChannelState+ads")));
521
- // Note: AdsCallState's ctor will automatically subscribe to all
521
+ ads_call_.reset(
522
+ new RetryableCall<AdsCall>(WeakRef(DEBUG_LOCATION, "XdsChannel+ads")));
523
+ // Note: AdsCall's ctor will automatically subscribe to all
522
524
  // resources that the XdsClient already has watchers for, so we can
523
525
  // return here.
524
526
  return;
525
527
  }
526
528
  // If the ADS call is in backoff state, we don't need to do anything now
527
529
  // because when the call is restarted it will resend all necessary requests.
528
- if (ads_calld() == nullptr) return;
530
+ if (ads_call() == nullptr) return;
529
531
  // Subscribe to this resource if the ADS call is active.
530
- ads_calld()->SubscribeLocked(type, name, /*delay_send=*/false);
531
- }
532
-
533
- void XdsClient::ChannelState::UnsubscribeLocked(const XdsResourceType* type,
534
- const XdsResourceName& name,
535
- bool delay_unsubscription) {
536
- if (ads_calld_ != nullptr) {
537
- auto* calld = ads_calld_->calld();
538
- if (calld != nullptr) {
539
- calld->UnsubscribeLocked(type, name, delay_unsubscription);
540
- if (!calld->HasSubscribedResources()) {
541
- ads_calld_.reset();
532
+ ads_call()->SubscribeLocked(type, name, /*delay_send=*/false);
533
+ }
534
+
535
+ void XdsClient::XdsChannel::UnsubscribeLocked(const XdsResourceType* type,
536
+ const XdsResourceName& name,
537
+ bool delay_unsubscription) {
538
+ if (ads_call_ != nullptr) {
539
+ auto* call = ads_call_->call();
540
+ if (call != nullptr) {
541
+ call->UnsubscribeLocked(type, name, delay_unsubscription);
542
+ if (!call->HasSubscribedResources()) {
543
+ ads_call_.reset();
542
544
  }
543
545
  }
544
546
  }
545
547
  }
546
548
 
547
- void XdsClient::ChannelState::OnConnectivityFailure(absl::Status status) {
549
+ void XdsClient::XdsChannel::OnConnectivityFailure(absl::Status status) {
548
550
  {
549
551
  MutexLock lock(&xds_client_->mu_);
550
552
  SetChannelStatusLocked(std::move(status));
@@ -552,7 +554,7 @@ void XdsClient::ChannelState::OnConnectivityFailure(absl::Status status) {
552
554
  xds_client_->work_serializer_.DrainQueue();
553
555
  }
554
556
 
555
- void XdsClient::ChannelState::SetChannelStatusLocked(absl::Status status) {
557
+ void XdsClient::XdsChannel::SetChannelStatusLocked(absl::Status status) {
556
558
  if (shutting_down_) return;
557
559
  status = absl::Status(status.code(), absl::StrCat("xDS channel for server ",
558
560
  server_.server_uri(), ": ",
@@ -574,7 +576,7 @@ void XdsClient::ChannelState::SetChannelStatusLocked(absl::Status status) {
574
576
  // Find all watchers for this channel.
575
577
  std::set<RefCountedPtr<ResourceWatcherInterface>> watchers;
576
578
  for (const auto& a : xds_client_->authority_state_map_) { // authority
577
- if (a.second.channel_state != this) continue;
579
+ if (a.second.xds_channel != this) continue;
578
580
  for (const auto& t : a.second.resource_map) { // type
579
581
  for (const auto& r : t.second) { // resource id
580
582
  for (const auto& w : r.second.watchers) { // watchers
@@ -588,20 +590,20 @@ void XdsClient::ChannelState::SetChannelStatusLocked(absl::Status status) {
588
590
  [watchers = std::move(watchers), status = std::move(status)]()
589
591
  ABSL_EXCLUSIVE_LOCKS_REQUIRED(xds_client_->work_serializer_) {
590
592
  for (const auto& watcher : watchers) {
591
- watcher->OnError(status);
593
+ watcher->OnError(status, ReadDelayHandle::NoWait());
592
594
  }
593
595
  },
594
596
  DEBUG_LOCATION);
595
597
  }
596
598
 
597
599
  //
598
- // XdsClient::ChannelState::RetryableCall<>
600
+ // XdsClient::XdsChannel::RetryableCall<>
599
601
  //
600
602
 
601
603
  template <typename T>
602
- XdsClient::ChannelState::RetryableCall<T>::RetryableCall(
603
- WeakRefCountedPtr<ChannelState> chand)
604
- : chand_(std::move(chand)),
604
+ XdsClient::XdsChannel::RetryableCall<T>::RetryableCall(
605
+ WeakRefCountedPtr<XdsChannel> xds_channel)
606
+ : xds_channel_(std::move(xds_channel)),
605
607
  backoff_(BackOff::Options()
606
608
  .set_initial_backoff(Duration::Seconds(
607
609
  GRPC_XDS_INITIAL_CONNECT_BACKOFF_SECONDS))
@@ -613,42 +615,43 @@ XdsClient::ChannelState::RetryableCall<T>::RetryableCall(
613
615
  }
614
616
 
615
617
  template <typename T>
616
- void XdsClient::ChannelState::RetryableCall<T>::Orphan() {
618
+ void XdsClient::XdsChannel::RetryableCall<T>::Orphan() {
617
619
  shutting_down_ = true;
618
- calld_.reset();
620
+ call_.reset();
619
621
  if (timer_handle_.has_value()) {
620
- chand()->xds_client()->engine()->Cancel(*timer_handle_);
622
+ xds_channel()->xds_client()->engine()->Cancel(*timer_handle_);
621
623
  timer_handle_.reset();
622
624
  }
623
625
  this->Unref(DEBUG_LOCATION, "RetryableCall+orphaned");
624
626
  }
625
627
 
626
628
  template <typename T>
627
- void XdsClient::ChannelState::RetryableCall<T>::OnCallFinishedLocked() {
629
+ void XdsClient::XdsChannel::RetryableCall<T>::OnCallFinishedLocked() {
628
630
  // If we saw a response on the current stream, reset backoff.
629
- if (calld_->seen_response()) backoff_.Reset();
630
- calld_.reset();
631
+ if (call_->seen_response()) backoff_.Reset();
632
+ call_.reset();
631
633
  // Start retry timer.
632
634
  StartRetryTimerLocked();
633
635
  }
634
636
 
635
637
  template <typename T>
636
- void XdsClient::ChannelState::RetryableCall<T>::StartNewCallLocked() {
638
+ void XdsClient::XdsChannel::RetryableCall<T>::StartNewCallLocked() {
637
639
  if (shutting_down_) return;
638
- GPR_ASSERT(chand_->transport_ != nullptr);
639
- GPR_ASSERT(calld_ == nullptr);
640
+ GPR_ASSERT(xds_channel_->transport_ != nullptr);
641
+ GPR_ASSERT(call_ == nullptr);
640
642
  if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
641
643
  gpr_log(GPR_INFO,
642
644
  "[xds_client %p] xds server %s: start new call from retryable "
643
645
  "call %p",
644
- chand()->xds_client(), chand()->server_.server_uri().c_str(), this);
646
+ xds_channel()->xds_client(),
647
+ xds_channel()->server_.server_uri().c_str(), this);
645
648
  }
646
- calld_ = MakeOrphanable<T>(
649
+ call_ = MakeOrphanable<T>(
647
650
  this->Ref(DEBUG_LOCATION, "RetryableCall+start_new_call"));
648
651
  }
649
652
 
650
653
  template <typename T>
651
- void XdsClient::ChannelState::RetryableCall<T>::StartRetryTimerLocked() {
654
+ void XdsClient::XdsChannel::RetryableCall<T>::StartRetryTimerLocked() {
652
655
  if (shutting_down_) return;
653
656
  const Timestamp next_attempt_time = backoff_.NextAttemptTime();
654
657
  const Duration timeout =
@@ -657,10 +660,10 @@ void XdsClient::ChannelState::RetryableCall<T>::StartRetryTimerLocked() {
657
660
  gpr_log(GPR_INFO,
658
661
  "[xds_client %p] xds server %s: call attempt failed; "
659
662
  "retry timer will fire in %" PRId64 "ms.",
660
- chand()->xds_client(), chand()->server_.server_uri().c_str(),
661
- timeout.millis());
663
+ xds_channel()->xds_client(),
664
+ xds_channel()->server_.server_uri().c_str(), timeout.millis());
662
665
  }
663
- timer_handle_ = chand()->xds_client()->engine()->RunAfter(
666
+ timer_handle_ = xds_channel()->xds_client()->engine()->RunAfter(
664
667
  timeout,
665
668
  [self = this->Ref(DEBUG_LOCATION, "RetryableCall+retry_timer_start")]() {
666
669
  ApplicationCallbackExecCtx callback_exec_ctx;
@@ -670,8 +673,8 @@ void XdsClient::ChannelState::RetryableCall<T>::StartRetryTimerLocked() {
670
673
  }
671
674
 
672
675
  template <typename T>
673
- void XdsClient::ChannelState::RetryableCall<T>::OnRetryTimer() {
674
- MutexLock lock(&chand_->xds_client()->mu_);
676
+ void XdsClient::XdsChannel::RetryableCall<T>::OnRetryTimer() {
677
+ MutexLock lock(&xds_channel_->xds_client()->mu_);
675
678
  if (timer_handle_.has_value()) {
676
679
  timer_handle_.reset();
677
680
  if (shutting_down_) return;
@@ -679,31 +682,52 @@ void XdsClient::ChannelState::RetryableCall<T>::OnRetryTimer() {
679
682
  gpr_log(GPR_INFO,
680
683
  "[xds_client %p] xds server %s: retry timer fired (retryable "
681
684
  "call: %p)",
682
- chand()->xds_client(), chand()->server_.server_uri().c_str(),
683
- this);
685
+ xds_channel()->xds_client(),
686
+ xds_channel()->server_.server_uri().c_str(), this);
684
687
  }
685
688
  StartNewCallLocked();
686
689
  }
687
690
  }
688
691
 
689
692
  //
690
- // XdsClient::ChannelState::AdsCallState::AdsResponseParser
693
+ // XdsClient::XdsChannel::AdsCall::AdsReadDelayHandle
691
694
  //
692
695
 
693
- absl::Status XdsClient::ChannelState::AdsCallState::AdsResponseParser::
694
- ProcessAdsResponseFields(AdsResponseFields fields) {
696
+ class XdsClient::XdsChannel::AdsCall::AdsReadDelayHandle
697
+ : public XdsClient::ReadDelayHandle {
698
+ public:
699
+ explicit AdsReadDelayHandle(RefCountedPtr<AdsCall> ads_call)
700
+ : ads_call_(std::move(ads_call)) {}
701
+
702
+ ~AdsReadDelayHandle() override {
703
+ MutexLock lock(&ads_call_->xds_client()->mu_);
704
+ auto call = ads_call_->streaming_call_.get();
705
+ if (call != nullptr) call->StartRecvMessage();
706
+ }
707
+
708
+ private:
709
+ RefCountedPtr<AdsCall> ads_call_;
710
+ };
711
+
712
+ //
713
+ // XdsClient::XdsChannel::AdsCall::AdsResponseParser
714
+ //
715
+
716
+ absl::Status
717
+ XdsClient::XdsChannel::AdsCall::AdsResponseParser::ProcessAdsResponseFields(
718
+ AdsResponseFields fields) {
695
719
  if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
696
720
  gpr_log(
697
721
  GPR_INFO,
698
722
  "[xds_client %p] xds server %s: received ADS response: type_url=%s, "
699
723
  "version=%s, nonce=%s, num_resources=%" PRIuPTR,
700
- ads_call_state_->xds_client(),
701
- ads_call_state_->chand()->server_.server_uri().c_str(),
724
+ ads_call_->xds_client(),
725
+ ads_call_->xds_channel()->server_.server_uri().c_str(),
702
726
  fields.type_url.c_str(), fields.version.c_str(), fields.nonce.c_str(),
703
727
  fields.num_resources);
704
728
  }
705
729
  result_.type =
706
- ads_call_state_->xds_client()->GetResourceTypeLocked(fields.type_url);
730
+ ads_call_->xds_client()->GetResourceTypeLocked(fields.type_url);
707
731
  if (result_.type == nullptr) {
708
732
  return absl::InvalidArgumentError(
709
733
  absl::StrCat("unknown resource type ", fields.type_url));
@@ -711,6 +735,8 @@ absl::Status XdsClient::ChannelState::AdsCallState::AdsResponseParser::
711
735
  result_.type_url = std::move(fields.type_url);
712
736
  result_.version = std::move(fields.version);
713
737
  result_.nonce = std::move(fields.nonce);
738
+ result_.read_delay_handle =
739
+ MakeRefCounted<AdsReadDelayHandle>(ads_call_->Ref());
714
740
  return absl::OkStatus();
715
741
  }
716
742
 
@@ -740,7 +766,7 @@ void UpdateResourceMetadataNacked(const std::string& version,
740
766
 
741
767
  } // namespace
742
768
 
743
- void XdsClient::ChannelState::AdsCallState::AdsResponseParser::ParseResource(
769
+ void XdsClient::XdsChannel::AdsCall::AdsResponseParser::ParseResource(
744
770
  upb_Arena* arena, size_t idx, absl::string_view type_url,
745
771
  absl::string_view resource_name, absl::string_view serialized_resource) {
746
772
  std::string error_prefix = absl::StrCat(
@@ -755,8 +781,8 @@ void XdsClient::ChannelState::AdsCallState::AdsResponseParser::ParseResource(
755
781
  }
756
782
  // Parse the resource.
757
783
  XdsResourceType::DecodeContext context = {
758
- xds_client(), ads_call_state_->chand()->server_, &grpc_xds_client_trace,
759
- xds_client()->symtab_.ptr(), arena};
784
+ xds_client(), ads_call_->xds_channel()->server_, &grpc_xds_client_trace,
785
+ xds_client()->def_pool_.ptr(), arena};
760
786
  XdsResourceType::DecodeResult decode_result =
761
787
  result_.type->Decode(context, serialized_resource);
762
788
  // If we didn't already have the resource name from the Resource
@@ -789,8 +815,8 @@ void XdsClient::ChannelState::AdsCallState::AdsResponseParser::ParseResource(
789
815
  return;
790
816
  }
791
817
  // Cancel resource-does-not-exist timer, if needed.
792
- auto timer_it = ads_call_state_->state_map_.find(result_.type);
793
- if (timer_it != ads_call_state_->state_map_.end()) {
818
+ auto timer_it = ads_call_->state_map_.find(result_.type);
819
+ if (timer_it != ads_call_->state_map_.end()) {
794
820
  auto it = timer_it->second.subscribed_resources.find(
795
821
  parsed_resource_name->authority);
796
822
  if (it != timer_it->second.subscribed_resources.end()) {
@@ -832,7 +858,7 @@ void XdsClient::ChannelState::AdsCallState::AdsResponseParser::ParseResource(
832
858
  "resource for which we previously ignored a deletion: type %s "
833
859
  "name %s",
834
860
  xds_client(),
835
- ads_call_state_->chand()->server_.server_uri().c_str(),
861
+ ads_call_->xds_channel()->server_.server_uri().c_str(),
836
862
  std::string(type_url).c_str(), std::string(resource_name).c_str());
837
863
  resource_state.ignored_deletion = false;
838
864
  }
@@ -841,7 +867,8 @@ void XdsClient::ChannelState::AdsCallState::AdsResponseParser::ParseResource(
841
867
  xds_client()->NotifyWatchersOnErrorLocked(
842
868
  resource_state.watchers,
843
869
  absl::UnavailableError(
844
- absl::StrCat("invalid resource: ", decode_status.ToString())));
870
+ absl::StrCat("invalid resource: ", decode_status.ToString())),
871
+ result_.read_delay_handle);
845
872
  UpdateResourceMetadataNacked(result_.version, decode_status.ToString(),
846
873
  update_time_, &resource_state.meta);
847
874
  return;
@@ -867,57 +894,57 @@ void XdsClient::ChannelState::AdsCallState::AdsResponseParser::ParseResource(
867
894
  // Notify watchers.
868
895
  auto& watchers_list = resource_state.watchers;
869
896
  xds_client()->work_serializer_.Schedule(
870
- [watchers_list, value = resource_state.resource]()
897
+ [watchers_list, value = resource_state.resource,
898
+ read_delay_handle = result_.read_delay_handle]()
871
899
  ABSL_EXCLUSIVE_LOCKS_REQUIRED(&xds_client()->work_serializer_) {
872
900
  for (const auto& p : watchers_list) {
873
- p.first->OnGenericResourceChanged(value);
901
+ p.first->OnGenericResourceChanged(value, read_delay_handle);
874
902
  }
875
903
  },
876
904
  DEBUG_LOCATION);
877
905
  }
878
906
 
879
- void XdsClient::ChannelState::AdsCallState::AdsResponseParser::
907
+ void XdsClient::XdsChannel::AdsCall::AdsResponseParser::
880
908
  ResourceWrapperParsingFailed(size_t idx, absl::string_view message) {
881
909
  result_.errors.emplace_back(
882
910
  absl::StrCat("resource index ", idx, ": ", message));
883
911
  }
884
912
 
885
913
  //
886
- // XdsClient::ChannelState::AdsCallState
914
+ // XdsClient::XdsChannel::AdsCall
887
915
  //
888
916
 
889
- XdsClient::ChannelState::AdsCallState::AdsCallState(
890
- RefCountedPtr<RetryableCall<AdsCallState>> parent)
891
- : InternallyRefCounted<AdsCallState>(
892
- GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_refcount_trace)
893
- ? "AdsCallState"
894
- : nullptr),
895
- parent_(std::move(parent)) {
917
+ XdsClient::XdsChannel::AdsCall::AdsCall(
918
+ RefCountedPtr<RetryableCall<AdsCall>> retryable_call)
919
+ : InternallyRefCounted<AdsCall>(
920
+ GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_refcount_trace) ? "AdsCall"
921
+ : nullptr),
922
+ retryable_call_(std::move(retryable_call)) {
896
923
  GPR_ASSERT(xds_client() != nullptr);
897
924
  // Init the ADS call.
898
925
  const char* method =
899
926
  "/envoy.service.discovery.v3.AggregatedDiscoveryService/"
900
927
  "StreamAggregatedResources";
901
- call_ = chand()->transport_->CreateStreamingCall(
928
+ streaming_call_ = xds_channel()->transport_->CreateStreamingCall(
902
929
  method, std::make_unique<StreamEventHandler>(
903
930
  // Passing the initial ref here. This ref will go away when
904
931
  // the StreamEventHandler is destroyed.
905
- RefCountedPtr<AdsCallState>(this)));
906
- GPR_ASSERT(call_ != nullptr);
932
+ RefCountedPtr<AdsCall>(this)));
933
+ GPR_ASSERT(streaming_call_ != nullptr);
907
934
  // Start the call.
908
935
  if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
909
936
  gpr_log(GPR_INFO,
910
937
  "[xds_client %p] xds server %s: starting ADS call "
911
- "(calld: %p, call: %p)",
912
- xds_client(), chand()->server_.server_uri().c_str(), this,
913
- call_.get());
938
+ "(ads_call: %p, streaming_call: %p)",
939
+ xds_client(), xds_channel()->server_.server_uri().c_str(), this,
940
+ streaming_call_.get());
914
941
  }
915
942
  // If this is a reconnect, add any necessary subscriptions from what's
916
943
  // already in the cache.
917
944
  for (const auto& a : xds_client()->authority_state_map_) {
918
945
  const std::string& authority = a.first;
919
946
  // Skip authorities that are not using this xDS channel.
920
- if (a.second.channel_state != chand()) continue;
947
+ if (a.second.xds_channel != xds_channel()) continue;
921
948
  for (const auto& t : a.second.resource_map) {
922
949
  const XdsResourceType* type = t.first;
923
950
  for (const auto& r : t.second) {
@@ -930,17 +957,19 @@ XdsClient::ChannelState::AdsCallState::AdsCallState(
930
957
  for (const auto& p : state_map_) {
931
958
  SendMessageLocked(p.first);
932
959
  }
960
+ streaming_call_->StartRecvMessage();
933
961
  }
934
962
 
935
- void XdsClient::ChannelState::AdsCallState::Orphan() {
963
+ void XdsClient::XdsChannel::AdsCall::Orphan() {
936
964
  state_map_.clear();
937
965
  // Note that the initial ref is held by the StreamEventHandler, which
938
- // will be destroyed when call_ is destroyed, which may not happen
939
- // here, since there may be other refs held to call_ by internal callbacks.
940
- call_.reset();
966
+ // will be destroyed when streaming_call_ is destroyed, which may not happen
967
+ // here, since there may be other refs held to streaming_call_ by internal
968
+ // callbacks.
969
+ streaming_call_.reset();
941
970
  }
942
971
 
943
- void XdsClient::ChannelState::AdsCallState::SendMessageLocked(
972
+ void XdsClient::XdsChannel::AdsCall::SendMessageLocked(
944
973
  const XdsResourceType* type)
945
974
  ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsClient::mu_) {
946
975
  // Buffer message sending if an existing message is in flight.
@@ -950,24 +979,25 @@ void XdsClient::ChannelState::AdsCallState::SendMessageLocked(
950
979
  }
951
980
  auto& state = state_map_[type];
952
981
  std::string serialized_message = xds_client()->api_.CreateAdsRequest(
953
- type->type_url(), chand()->resource_type_version_map_[type], state.nonce,
954
- ResourceNamesForRequest(type), state.status, !sent_initial_message_);
982
+ type->type_url(), xds_channel()->resource_type_version_map_[type],
983
+ state.nonce, ResourceNamesForRequest(type), state.status,
984
+ !sent_initial_message_);
955
985
  sent_initial_message_ = true;
956
986
  if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
957
987
  gpr_log(GPR_INFO,
958
988
  "[xds_client %p] xds server %s: sending ADS request: type=%s "
959
989
  "version=%s nonce=%s error=%s",
960
- xds_client(), chand()->server_.server_uri().c_str(),
990
+ xds_client(), xds_channel()->server_.server_uri().c_str(),
961
991
  std::string(type->type_url()).c_str(),
962
- chand()->resource_type_version_map_[type].c_str(),
992
+ xds_channel()->resource_type_version_map_[type].c_str(),
963
993
  state.nonce.c_str(), state.status.ToString().c_str());
964
994
  }
965
995
  state.status = absl::OkStatus();
966
- call_->SendMessage(std::move(serialized_message));
996
+ streaming_call_->SendMessage(std::move(serialized_message));
967
997
  send_message_pending_ = type;
968
998
  }
969
999
 
970
- void XdsClient::ChannelState::AdsCallState::SubscribeLocked(
1000
+ void XdsClient::XdsChannel::AdsCall::SubscribeLocked(
971
1001
  const XdsResourceType* type, const XdsResourceName& name, bool delay_send) {
972
1002
  auto& state = state_map_[type].subscribed_resources[name.authority][name.key];
973
1003
  if (state == nullptr) {
@@ -976,7 +1006,7 @@ void XdsClient::ChannelState::AdsCallState::SubscribeLocked(
976
1006
  }
977
1007
  }
978
1008
 
979
- void XdsClient::ChannelState::AdsCallState::UnsubscribeLocked(
1009
+ void XdsClient::XdsChannel::AdsCall::UnsubscribeLocked(
980
1010
  const XdsResourceType* type, const XdsResourceName& name,
981
1011
  bool delay_unsubscription) {
982
1012
  auto& type_state_map = state_map_[type];
@@ -993,14 +1023,14 @@ void XdsClient::ChannelState::AdsCallState::UnsubscribeLocked(
993
1023
  }
994
1024
  }
995
1025
 
996
- bool XdsClient::ChannelState::AdsCallState::HasSubscribedResources() const {
1026
+ bool XdsClient::XdsChannel::AdsCall::HasSubscribedResources() const {
997
1027
  for (const auto& p : state_map_) {
998
1028
  if (!p.second.subscribed_resources.empty()) return true;
999
1029
  }
1000
1030
  return false;
1001
1031
  }
1002
1032
 
1003
- void XdsClient::ChannelState::AdsCallState::OnRequestSent(bool ok) {
1033
+ void XdsClient::XdsChannel::AdsCall::OnRequestSent(bool ok) {
1004
1034
  MutexLock lock(&xds_client()->mu_);
1005
1035
  // For each resource that was in the message we just sent, start the
1006
1036
  // resource timer if needed.
@@ -1032,25 +1062,28 @@ void XdsClient::ChannelState::AdsCallState::OnRequestSent(bool ok) {
1032
1062
  }
1033
1063
  }
1034
1064
 
1035
- void XdsClient::ChannelState::AdsCallState::OnRecvMessage(
1036
- absl::string_view payload) {
1065
+ void XdsClient::XdsChannel::AdsCall::OnRecvMessage(absl::string_view payload) {
1066
+ // Needs to be destroyed after the mutex is released.
1067
+ RefCountedPtr<ReadDelayHandle> read_delay_handle;
1037
1068
  {
1038
1069
  MutexLock lock(&xds_client()->mu_);
1039
1070
  if (!IsCurrentCallOnChannel()) return;
1040
1071
  // Parse and validate the response.
1041
1072
  AdsResponseParser parser(this);
1042
1073
  absl::Status status = xds_client()->api_.ParseAdsResponse(payload, &parser);
1074
+ // This includes a handle that will trigger an ADS read.
1075
+ AdsResponseParser::Result result = parser.TakeResult();
1076
+ read_delay_handle = std::move(result.read_delay_handle);
1043
1077
  if (!status.ok()) {
1044
1078
  // Ignore unparsable response.
1045
1079
  gpr_log(GPR_ERROR,
1046
1080
  "[xds_client %p] xds server %s: error parsing ADS response (%s) "
1047
1081
  "-- ignoring",
1048
- xds_client(), chand()->server_.server_uri().c_str(),
1082
+ xds_client(), xds_channel()->server_.server_uri().c_str(),
1049
1083
  status.ToString().c_str());
1050
1084
  } else {
1051
1085
  seen_response_ = true;
1052
- chand()->status_ = absl::OkStatus();
1053
- AdsResponseParser::Result result = parser.TakeResult();
1086
+ xds_channel()->status_ = absl::OkStatus();
1054
1087
  // Update nonce.
1055
1088
  auto& state = state_map_[result.type];
1056
1089
  state.nonce = result.nonce;
@@ -1063,7 +1096,7 @@ void XdsClient::ChannelState::AdsCallState::OnRecvMessage(
1063
1096
  "[xds_client %p] xds server %s: ADS response invalid for "
1064
1097
  "resource "
1065
1098
  "type %s version %s, will NACK: nonce=%s status=%s",
1066
- xds_client(), chand()->server_.server_uri().c_str(),
1099
+ xds_client(), xds_channel()->server_.server_uri().c_str(),
1067
1100
  result.type_url.c_str(), result.version.c_str(),
1068
1101
  state.nonce.c_str(), state.status.ToString().c_str());
1069
1102
  }
@@ -1073,7 +1106,7 @@ void XdsClient::ChannelState::AdsCallState::OnRecvMessage(
1073
1106
  const std::string& authority = a.first;
1074
1107
  AuthorityState& authority_state = a.second;
1075
1108
  // Skip authorities that are not using this xDS channel.
1076
- if (authority_state.channel_state != chand()) continue;
1109
+ if (authority_state.xds_channel != xds_channel()) continue;
1077
1110
  auto seen_authority_it = result.resources_seen.find(authority);
1078
1111
  // Find this resource type.
1079
1112
  auto type_it = authority_state.resource_map.find(result.type);
@@ -1093,12 +1126,13 @@ void XdsClient::ChannelState::AdsCallState::OnRecvMessage(
1093
1126
  // that the resource does not exist. For that case, we rely on
1094
1127
  // the request timeout instead.
1095
1128
  if (resource_state.resource == nullptr) continue;
1096
- if (chand()->server_.IgnoreResourceDeletion()) {
1129
+ if (xds_channel()->server_.IgnoreResourceDeletion()) {
1097
1130
  if (!resource_state.ignored_deletion) {
1098
1131
  gpr_log(GPR_ERROR,
1099
1132
  "[xds_client %p] xds server %s: ignoring deletion "
1100
1133
  "for resource type %s name %s",
1101
- xds_client(), chand()->server_.server_uri().c_str(),
1134
+ xds_client(),
1135
+ xds_channel()->server_.server_uri().c_str(),
1102
1136
  result.type_url.c_str(),
1103
1137
  XdsClient::ConstructFullXdsResourceName(
1104
1138
  authority, result.type_url.c_str(), resource_key)
@@ -1110,7 +1144,7 @@ void XdsClient::ChannelState::AdsCallState::OnRecvMessage(
1110
1144
  resource_state.meta.client_status =
1111
1145
  XdsApi::ResourceMetadata::DOES_NOT_EXIST;
1112
1146
  xds_client()->NotifyWatchersOnResourceDoesNotExist(
1113
- resource_state.watchers);
1147
+ resource_state.watchers, read_delay_handle);
1114
1148
  }
1115
1149
  }
1116
1150
  }
@@ -1118,14 +1152,8 @@ void XdsClient::ChannelState::AdsCallState::OnRecvMessage(
1118
1152
  }
1119
1153
  // If we had valid resources or the update was empty, update the version.
1120
1154
  if (result.have_valid_resources || result.errors.empty()) {
1121
- chand()->resource_type_version_map_[result.type] =
1155
+ xds_channel()->resource_type_version_map_[result.type] =
1122
1156
  std::move(result.version);
1123
- // Start load reporting if needed.
1124
- auto& lrs_call = chand()->lrs_calld_;
1125
- if (lrs_call != nullptr) {
1126
- LrsCallState* lrs_calld = lrs_call->calld();
1127
- if (lrs_calld != nullptr) lrs_calld->MaybeStartReportingLocked();
1128
- }
1129
1157
  }
1130
1158
  // Send ACK or NACK.
1131
1159
  SendMessageLocked(result.type);
@@ -1134,16 +1162,16 @@ void XdsClient::ChannelState::AdsCallState::OnRecvMessage(
1134
1162
  xds_client()->work_serializer_.DrainQueue();
1135
1163
  }
1136
1164
 
1137
- void XdsClient::ChannelState::AdsCallState::OnStatusReceived(
1138
- absl::Status status) {
1165
+ void XdsClient::XdsChannel::AdsCall::OnStatusReceived(absl::Status status) {
1139
1166
  {
1140
1167
  MutexLock lock(&xds_client()->mu_);
1141
1168
  if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
1142
1169
  gpr_log(GPR_INFO,
1143
1170
  "[xds_client %p] xds server %s: ADS call status received "
1144
- "(chand=%p, ads_calld=%p, call=%p): %s",
1145
- xds_client(), chand()->server_.server_uri().c_str(), chand(),
1146
- this, call_.get(), status.ToString().c_str());
1171
+ "(xds_channel=%p, ads_call=%p, streaming_call=%p): %s",
1172
+ xds_client(), xds_channel()->server_.server_uri().c_str(),
1173
+ xds_channel(), this, streaming_call_.get(),
1174
+ status.ToString().c_str());
1147
1175
  }
1148
1176
  // Cancel any does-not-exist timers that may be pending.
1149
1177
  for (const auto& p : state_map_) {
@@ -1156,12 +1184,12 @@ void XdsClient::ChannelState::AdsCallState::OnStatusReceived(
1156
1184
  // Ignore status from a stale call.
1157
1185
  if (IsCurrentCallOnChannel()) {
1158
1186
  // Try to restart the call.
1159
- parent_->OnCallFinishedLocked();
1187
+ retryable_call_->OnCallFinishedLocked();
1160
1188
  // If we didn't receive a response on the stream, report the
1161
1189
  // stream failure as a connectivity failure, which will report the
1162
1190
  // error to all watchers of resources on this channel.
1163
1191
  if (!seen_response_) {
1164
- chand()->SetChannelStatusLocked(absl::UnavailableError(
1192
+ xds_channel()->SetChannelStatusLocked(absl::UnavailableError(
1165
1193
  absl::StrCat("xDS call failed with no responses received; status: ",
1166
1194
  status.ToString())));
1167
1195
  }
@@ -1170,15 +1198,15 @@ void XdsClient::ChannelState::AdsCallState::OnStatusReceived(
1170
1198
  xds_client()->work_serializer_.DrainQueue();
1171
1199
  }
1172
1200
 
1173
- bool XdsClient::ChannelState::AdsCallState::IsCurrentCallOnChannel() const {
1201
+ bool XdsClient::XdsChannel::AdsCall::IsCurrentCallOnChannel() const {
1174
1202
  // If the retryable ADS call is null (which only happens when the xds
1175
1203
  // channel is shutting down), all the ADS calls are stale.
1176
- if (chand()->ads_calld_ == nullptr) return false;
1177
- return this == chand()->ads_calld_->calld();
1204
+ if (xds_channel()->ads_call_ == nullptr) return false;
1205
+ return this == xds_channel()->ads_call_->call();
1178
1206
  }
1179
1207
 
1180
1208
  std::vector<std::string>
1181
- XdsClient::ChannelState::AdsCallState::ResourceNamesForRequest(
1209
+ XdsClient::XdsChannel::AdsCall::ResourceNamesForRequest(
1182
1210
  const XdsResourceType* type) {
1183
1211
  std::vector<std::string> resource_names;
1184
1212
  auto it = state_map_.find(type);
@@ -1198,39 +1226,107 @@ XdsClient::ChannelState::AdsCallState::ResourceNamesForRequest(
1198
1226
  }
1199
1227
 
1200
1228
  //
1201
- // XdsClient::ChannelState::LrsCallState::Reporter
1229
+ // XdsClient::XdsChannel::LrsCall::Timer
1202
1230
  //
1203
1231
 
1204
- void XdsClient::ChannelState::LrsCallState::Reporter::Orphan() {
1205
- if (timer_handle_.has_value() &&
1206
- xds_client()->engine()->Cancel(*timer_handle_)) {
1232
+ void XdsClient::XdsChannel::LrsCall::Timer::Orphan() {
1233
+ if (timer_handle_.has_value()) {
1234
+ xds_client()->engine()->Cancel(*timer_handle_);
1207
1235
  timer_handle_.reset();
1208
- Unref(DEBUG_LOCATION, "Orphan");
1209
1236
  }
1237
+ Unref(DEBUG_LOCATION, "Orphan");
1210
1238
  }
1211
1239
 
1212
- void XdsClient::ChannelState::LrsCallState::Reporter::
1213
- ScheduleNextReportLocked() {
1240
+ void XdsClient::XdsChannel::LrsCall::Timer::ScheduleNextReportLocked() {
1214
1241
  if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
1215
1242
  gpr_log(GPR_INFO,
1216
- "[xds_client %p] xds server %s: scheduling load report timer",
1217
- xds_client(), parent_->chand()->server_.server_uri().c_str());
1218
- }
1219
- timer_handle_ = xds_client()->engine()->RunAfter(report_interval_, [this]() {
1220
- ApplicationCallbackExecCtx callback_exec_ctx;
1221
- ExecCtx exec_ctx;
1222
- if (OnNextReportTimer()) {
1223
- Unref(DEBUG_LOCATION, "OnNextReportTimer()");
1224
- }
1225
- });
1243
+ "[xds_client %p] xds server %s: scheduling next load report in %s",
1244
+ xds_client(),
1245
+ lrs_call_->xds_channel()->server_.server_uri().c_str(),
1246
+ lrs_call_->load_reporting_interval_.ToString().c_str());
1247
+ }
1248
+ timer_handle_ = xds_client()->engine()->RunAfter(
1249
+ lrs_call_->load_reporting_interval_,
1250
+ [self = Ref(DEBUG_LOCATION, "timer")]() {
1251
+ ApplicationCallbackExecCtx callback_exec_ctx;
1252
+ ExecCtx exec_ctx;
1253
+ self->OnNextReportTimer();
1254
+ });
1226
1255
  }
1227
1256
 
1228
- bool XdsClient::ChannelState::LrsCallState::Reporter::OnNextReportTimer() {
1257
+ void XdsClient::XdsChannel::LrsCall::Timer::OnNextReportTimer() {
1229
1258
  MutexLock lock(&xds_client()->mu_);
1230
1259
  timer_handle_.reset();
1231
- if (!IsCurrentReporterOnCall()) return true;
1232
- SendReportLocked();
1233
- return false;
1260
+ if (IsCurrentTimerOnCall()) lrs_call_->SendReportLocked();
1261
+ }
1262
+
1263
+ //
1264
+ // XdsClient::XdsChannel::LrsCall
1265
+ //
1266
+
1267
+ XdsClient::XdsChannel::LrsCall::LrsCall(
1268
+ RefCountedPtr<RetryableCall<LrsCall>> retryable_call)
1269
+ : InternallyRefCounted<LrsCall>(
1270
+ GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_refcount_trace) ? "LrsCall"
1271
+ : nullptr),
1272
+ retryable_call_(std::move(retryable_call)) {
1273
+ // Init the LRS call. Note that the call will progress every time there's
1274
+ // activity in xds_client()->interested_parties_, which is comprised of
1275
+ // the polling entities from client_channel.
1276
+ GPR_ASSERT(xds_client() != nullptr);
1277
+ const char* method =
1278
+ "/envoy.service.load_stats.v3.LoadReportingService/StreamLoadStats";
1279
+ streaming_call_ = xds_channel()->transport_->CreateStreamingCall(
1280
+ method, std::make_unique<StreamEventHandler>(
1281
+ // Passing the initial ref here. This ref will go away when
1282
+ // the StreamEventHandler is destroyed.
1283
+ RefCountedPtr<LrsCall>(this)));
1284
+ GPR_ASSERT(streaming_call_ != nullptr);
1285
+ // Start the call.
1286
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
1287
+ gpr_log(GPR_INFO,
1288
+ "[xds_client %p] xds server %s: starting LRS call (lrs_call=%p, "
1289
+ "streaming_call=%p)",
1290
+ xds_client(), xds_channel()->server_.server_uri().c_str(), this,
1291
+ streaming_call_.get());
1292
+ }
1293
+ // Send the initial request.
1294
+ std::string serialized_payload = xds_client()->api_.CreateLrsInitialRequest();
1295
+ SendMessageLocked(std::move(serialized_payload));
1296
+ // Read initial response.
1297
+ streaming_call_->StartRecvMessage();
1298
+ }
1299
+
1300
+ void XdsClient::XdsChannel::LrsCall::Orphan() {
1301
+ timer_.reset();
1302
+ // Note that the initial ref is held by the StreamEventHandler, which
1303
+ // will be destroyed when streaming_call_ is destroyed, which may not happen
1304
+ // here, since there may be other refs held to streaming_call_ by internal
1305
+ // callbacks.
1306
+ streaming_call_.reset();
1307
+ }
1308
+
1309
+ void XdsClient::XdsChannel::LrsCall::MaybeScheduleNextReportLocked() {
1310
+ // If there are no more registered stats to report, cancel the call.
1311
+ auto it =
1312
+ xds_client()->xds_load_report_server_map_.find(&xds_channel()->server_);
1313
+ if (it == xds_client()->xds_load_report_server_map_.end() ||
1314
+ it->second.load_report_map.empty()) {
1315
+ it->second.xds_channel->StopLrsCallLocked();
1316
+ return;
1317
+ }
1318
+ // Don't start if the previous send_message op hasn't completed yet.
1319
+ // If this happens, we'll be called again from OnRequestSent().
1320
+ if (send_message_pending_) return;
1321
+ // Don't start if no LRS response has arrived.
1322
+ if (!seen_response()) return;
1323
+ // If there is no timer, create one.
1324
+ // This happens on the initial response and whenever the interval changes.
1325
+ if (timer_ == nullptr) {
1326
+ timer_ = MakeOrphanable<Timer>(Ref(DEBUG_LOCATION, "LRS timer"));
1327
+ }
1328
+ // Schedule the next load report.
1329
+ timer_->ScheduleNextReportLocked();
1234
1330
  }
1235
1331
 
1236
1332
  namespace {
@@ -1249,142 +1345,43 @@ bool LoadReportCountersAreZero(const XdsApi::ClusterLoadReportMap& snapshot) {
1249
1345
 
1250
1346
  } // namespace
1251
1347
 
1252
- bool XdsClient::ChannelState::LrsCallState::Reporter::SendReportLocked() {
1348
+ void XdsClient::XdsChannel::LrsCall::SendReportLocked() {
1253
1349
  // Construct snapshot from all reported stats.
1254
1350
  XdsApi::ClusterLoadReportMap snapshot =
1255
- xds_client()->BuildLoadReportSnapshotLocked(parent_->chand()->server_,
1256
- parent_->send_all_clusters_,
1257
- parent_->cluster_names_);
1351
+ xds_client()->BuildLoadReportSnapshotLocked(
1352
+ xds_channel()->server_, send_all_clusters_, cluster_names_);
1258
1353
  // Skip client load report if the counters were all zero in the last
1259
1354
  // report and they are still zero in this one.
1260
1355
  const bool old_val = last_report_counters_were_zero_;
1261
1356
  last_report_counters_were_zero_ = LoadReportCountersAreZero(snapshot);
1262
1357
  if (old_val && last_report_counters_were_zero_) {
1263
- auto it = xds_client()->xds_load_report_server_map_.find(
1264
- &parent_->chand()->server_);
1265
- if (it == xds_client()->xds_load_report_server_map_.end() ||
1266
- it->second.load_report_map.empty()) {
1267
- it->second.channel_state->StopLrsCallLocked();
1268
- return true;
1269
- }
1270
- ScheduleNextReportLocked();
1271
- return false;
1358
+ MaybeScheduleNextReportLocked();
1359
+ return;
1272
1360
  }
1273
1361
  // Send a request that contains the snapshot.
1274
1362
  std::string serialized_payload =
1275
1363
  xds_client()->api_.CreateLrsRequest(std::move(snapshot));
1276
- parent_->call_->SendMessage(std::move(serialized_payload));
1277
- parent_->send_message_pending_ = true;
1278
- return false;
1279
- }
1280
-
1281
- void XdsClient::ChannelState::LrsCallState::Reporter::OnReportDoneLocked() {
1282
- // If a reporter starts a send_message op, then the reporting interval
1283
- // changes and we destroy that reporter and create a new one, and then
1284
- // the send_message op started by the old reporter finishes, this
1285
- // method will be called even though it was for a completion started
1286
- // by the old reporter. In that case, the timer will be pending, so
1287
- // we just ignore the completion and wait for the timer to fire.
1288
- if (timer_handle_.has_value()) return;
1289
- // If there are no more registered stats to report, cancel the call.
1290
- auto it = xds_client()->xds_load_report_server_map_.find(
1291
- &parent_->chand()->server_);
1292
- if (it == xds_client()->xds_load_report_server_map_.end()) return;
1293
- if (it->second.load_report_map.empty()) {
1294
- if (it->second.channel_state != nullptr) {
1295
- it->second.channel_state->StopLrsCallLocked();
1296
- }
1297
- return;
1298
- }
1299
- // Otherwise, schedule the next load report.
1300
- ScheduleNextReportLocked();
1364
+ SendMessageLocked(std::move(serialized_payload));
1301
1365
  }
1302
1366
 
1303
- //
1304
- // XdsClient::ChannelState::LrsCallState
1305
- //
1306
-
1307
- XdsClient::ChannelState::LrsCallState::LrsCallState(
1308
- RefCountedPtr<RetryableCall<LrsCallState>> parent)
1309
- : InternallyRefCounted<LrsCallState>(
1310
- GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_refcount_trace)
1311
- ? "LrsCallState"
1312
- : nullptr),
1313
- parent_(std::move(parent)) {
1314
- // Init the LRS call. Note that the call will progress every time there's
1315
- // activity in xds_client()->interested_parties_, which is comprised of
1316
- // the polling entities from client_channel.
1317
- GPR_ASSERT(xds_client() != nullptr);
1318
- const char* method =
1319
- "/envoy.service.load_stats.v3.LoadReportingService/StreamLoadStats";
1320
- call_ = chand()->transport_->CreateStreamingCall(
1321
- method, std::make_unique<StreamEventHandler>(
1322
- // Passing the initial ref here. This ref will go away when
1323
- // the StreamEventHandler is destroyed.
1324
- RefCountedPtr<LrsCallState>(this)));
1325
- GPR_ASSERT(call_ != nullptr);
1326
- // Start the call.
1327
- if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
1328
- gpr_log(GPR_INFO,
1329
- "[xds_client %p] xds server %s: starting LRS call (calld=%p, "
1330
- "call=%p)",
1331
- xds_client(), chand()->server_.server_uri().c_str(), this,
1332
- call_.get());
1333
- }
1334
- // Send the initial request.
1335
- std::string serialized_payload = xds_client()->api_.CreateLrsInitialRequest();
1336
- call_->SendMessage(std::move(serialized_payload));
1367
+ void XdsClient::XdsChannel::LrsCall::SendMessageLocked(std::string payload) {
1337
1368
  send_message_pending_ = true;
1369
+ streaming_call_->SendMessage(std::move(payload));
1338
1370
  }
1339
1371
 
1340
- void XdsClient::ChannelState::LrsCallState::Orphan() {
1341
- reporter_.reset();
1342
- // Note that the initial ref is held by the StreamEventHandler, which
1343
- // will be destroyed when call_ is destroyed, which may not happen
1344
- // here, since there may be other refs held to call_ by internal callbacks.
1345
- call_.reset();
1346
- }
1347
-
1348
- void XdsClient::ChannelState::LrsCallState::MaybeStartReportingLocked() {
1349
- // Don't start again if already started.
1350
- if (reporter_ != nullptr) return;
1351
- // Don't start if the previous send_message op (of the initial request or
1352
- // the last report of the previous reporter) hasn't completed.
1353
- if (call_ != nullptr && send_message_pending_) return;
1354
- // Don't start if no LRS response has arrived.
1355
- if (!seen_response()) return;
1356
- // Don't start if the ADS call hasn't received any valid response. Note that
1357
- // this must be the first channel because it is the current channel but its
1358
- // ADS call hasn't seen any response.
1359
- if (chand()->ads_calld_ == nullptr ||
1360
- chand()->ads_calld_->calld() == nullptr ||
1361
- !chand()->ads_calld_->calld()->seen_response()) {
1362
- return;
1363
- }
1364
- // Start reporting.
1365
- if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
1366
- gpr_log(GPR_INFO, "[xds_client %p] xds server %s: creating load reporter",
1367
- xds_client(), chand()->server_.server_uri().c_str());
1368
- }
1369
- reporter_ = MakeOrphanable<Reporter>(
1370
- Ref(DEBUG_LOCATION, "LRS+load_report+start"), load_reporting_interval_);
1371
- }
1372
-
1373
- void XdsClient::ChannelState::LrsCallState::OnRequestSent(bool /*ok*/) {
1372
+ void XdsClient::XdsChannel::LrsCall::OnRequestSent() {
1374
1373
  MutexLock lock(&xds_client()->mu_);
1375
1374
  send_message_pending_ = false;
1376
- if (reporter_ != nullptr) {
1377
- reporter_->OnReportDoneLocked();
1378
- } else {
1379
- MaybeStartReportingLocked();
1380
- }
1375
+ if (IsCurrentCallOnChannel()) MaybeScheduleNextReportLocked();
1381
1376
  }
1382
1377
 
1383
- void XdsClient::ChannelState::LrsCallState::OnRecvMessage(
1384
- absl::string_view payload) {
1378
+ void XdsClient::XdsChannel::LrsCall::OnRecvMessage(absl::string_view payload) {
1385
1379
  MutexLock lock(&xds_client()->mu_);
1386
1380
  // If we're no longer the current call, ignore the result.
1387
1381
  if (!IsCurrentCallOnChannel()) return;
1382
+ // Start recv after any code branch
1383
+ auto cleanup = absl::MakeCleanup(
1384
+ [call = streaming_call_.get()]() { call->StartRecvMessage(); });
1388
1385
  // Parse the response.
1389
1386
  bool send_all_clusters = false;
1390
1387
  std::set<std::string> new_cluster_names;
@@ -1395,7 +1392,7 @@ void XdsClient::ChannelState::LrsCallState::OnRecvMessage(
1395
1392
  if (!status.ok()) {
1396
1393
  gpr_log(GPR_ERROR,
1397
1394
  "[xds_client %p] xds server %s: LRS response parsing failed: %s",
1398
- xds_client(), chand()->server_.server_uri().c_str(),
1395
+ xds_client(), xds_channel()->server_.server_uri().c_str(),
1399
1396
  status.ToString().c_str());
1400
1397
  return;
1401
1398
  }
@@ -1406,7 +1403,7 @@ void XdsClient::ChannelState::LrsCallState::OnRecvMessage(
1406
1403
  "[xds_client %p] xds server %s: LRS response received, %" PRIuPTR
1407
1404
  " cluster names, send_all_clusters=%d, load_report_interval=%" PRId64
1408
1405
  "ms",
1409
- xds_client(), chand()->server_.server_uri().c_str(),
1406
+ xds_client(), xds_channel()->server_.server_uri().c_str(),
1410
1407
  new_cluster_names.size(), send_all_clusters,
1411
1408
  new_load_reporting_interval.millis());
1412
1409
  size_t i = 0;
@@ -1423,7 +1420,7 @@ void XdsClient::ChannelState::LrsCallState::OnRecvMessage(
1423
1420
  gpr_log(GPR_INFO,
1424
1421
  "[xds_client %p] xds server %s: increased load_report_interval "
1425
1422
  "to minimum value %dms",
1426
- xds_client(), chand()->server_.server_uri().c_str(),
1423
+ xds_client(), xds_channel()->server_.server_uri().c_str(),
1427
1424
  GRPC_XDS_MIN_CLIENT_LOAD_REPORTING_INTERVAL_MS);
1428
1425
  }
1429
1426
  }
@@ -1435,42 +1432,46 @@ void XdsClient::ChannelState::LrsCallState::OnRecvMessage(
1435
1432
  gpr_log(GPR_INFO,
1436
1433
  "[xds_client %p] xds server %s: incoming LRS response identical "
1437
1434
  "to current, ignoring.",
1438
- xds_client(), chand()->server_.server_uri().c_str());
1435
+ xds_client(), xds_channel()->server_.server_uri().c_str());
1439
1436
  }
1440
1437
  return;
1441
1438
  }
1442
- // Stop current load reporting (if any) to adopt the new config.
1443
- reporter_.reset();
1439
+ // If the interval has changed, we'll need to restart the timer below.
1440
+ const bool restart_timer =
1441
+ load_reporting_interval_ != new_load_reporting_interval;
1444
1442
  // Record the new config.
1445
1443
  send_all_clusters_ = send_all_clusters;
1446
1444
  cluster_names_ = std::move(new_cluster_names);
1447
1445
  load_reporting_interval_ = new_load_reporting_interval;
1448
- // Try starting sending load report.
1449
- MaybeStartReportingLocked();
1446
+ // Restart timer if needed.
1447
+ if (restart_timer) {
1448
+ timer_.reset();
1449
+ MaybeScheduleNextReportLocked();
1450
+ }
1450
1451
  }
1451
1452
 
1452
- void XdsClient::ChannelState::LrsCallState::OnStatusReceived(
1453
- absl::Status status) {
1453
+ void XdsClient::XdsChannel::LrsCall::OnStatusReceived(absl::Status status) {
1454
1454
  MutexLock lock(&xds_client()->mu_);
1455
1455
  if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
1456
1456
  gpr_log(GPR_INFO,
1457
1457
  "[xds_client %p] xds server %s: LRS call status received "
1458
- "(chand=%p, calld=%p, call=%p): %s",
1459
- xds_client(), chand()->server_.server_uri().c_str(), chand(), this,
1460
- call_.get(), status.ToString().c_str());
1458
+ "(xds_channel=%p, lrs_call=%p, streaming_call=%p): %s",
1459
+ xds_client(), xds_channel()->server_.server_uri().c_str(),
1460
+ xds_channel(), this, streaming_call_.get(),
1461
+ status.ToString().c_str());
1461
1462
  }
1462
1463
  // Ignore status from a stale call.
1463
1464
  if (IsCurrentCallOnChannel()) {
1464
1465
  // Try to restart the call.
1465
- parent_->OnCallFinishedLocked();
1466
+ retryable_call_->OnCallFinishedLocked();
1466
1467
  }
1467
1468
  }
1468
1469
 
1469
- bool XdsClient::ChannelState::LrsCallState::IsCurrentCallOnChannel() const {
1470
+ bool XdsClient::XdsChannel::LrsCall::IsCurrentCallOnChannel() const {
1470
1471
  // If the retryable LRS call is null (which only happens when the xds
1471
1472
  // channel is shutting down), all the LRS calls are stale.
1472
- if (chand()->lrs_calld_ == nullptr) return false;
1473
- return this == chand()->lrs_calld_->calld();
1473
+ if (xds_channel()->lrs_call_ == nullptr) return false;
1474
+ return this == xds_channel()->lrs_call_->call();
1474
1475
  }
1475
1476
 
1476
1477
  //
@@ -1490,7 +1491,7 @@ XdsClient::XdsClient(
1490
1491
  transport_factory_(std::move(transport_factory)),
1491
1492
  request_timeout_(resource_request_timeout),
1492
1493
  xds_federation_enabled_(XdsFederationEnabled()),
1493
- api_(this, &grpc_xds_client_trace, bootstrap_->node(), &symtab_,
1494
+ api_(this, &grpc_xds_client_trace, bootstrap_->node(), &def_pool_,
1494
1495
  std::move(user_agent_name), std::move(user_agent_version)),
1495
1496
  work_serializer_(engine),
1496
1497
  engine_(std::move(engine)) {
@@ -1521,24 +1522,24 @@ void XdsClient::Orphan() {
1521
1522
  invalid_watchers_.clear();
1522
1523
  // We may still be sending lingering queued load report data, so don't
1523
1524
  // just clear the load reporting map, but we do want to clear the refs
1524
- // we're holding to the ChannelState objects, to make sure that
1525
+ // we're holding to the XdsChannel objects, to make sure that
1525
1526
  // everything shuts down properly.
1526
1527
  for (auto& p : xds_load_report_server_map_) {
1527
- p.second.channel_state.reset(DEBUG_LOCATION, "XdsClient::Orphan()");
1528
+ p.second.xds_channel.reset(DEBUG_LOCATION, "XdsClient::Orphan()");
1528
1529
  }
1529
1530
  }
1530
1531
 
1531
- RefCountedPtr<XdsClient::ChannelState> XdsClient::GetOrCreateChannelStateLocked(
1532
+ RefCountedPtr<XdsClient::XdsChannel> XdsClient::GetOrCreateXdsChannelLocked(
1532
1533
  const XdsBootstrap::XdsServer& server, const char* reason) {
1533
1534
  auto it = xds_server_channel_map_.find(&server);
1534
1535
  if (it != xds_server_channel_map_.end()) {
1535
1536
  return it->second->Ref(DEBUG_LOCATION, reason);
1536
1537
  }
1537
1538
  // Channel not found, so create a new one.
1538
- auto channel_state = MakeRefCounted<ChannelState>(
1539
- WeakRef(DEBUG_LOCATION, "ChannelState"), server);
1540
- xds_server_channel_map_[&server] = channel_state.get();
1541
- return channel_state;
1539
+ auto xds_channel =
1540
+ MakeRefCounted<XdsChannel>(WeakRef(DEBUG_LOCATION, "XdsChannel"), server);
1541
+ xds_server_channel_map_[&server] = xds_channel.get();
1542
+ return xds_channel;
1542
1543
  }
1543
1544
 
1544
1545
  void XdsClient::WatchResource(const XdsResourceType* type,
@@ -1555,7 +1556,7 @@ void XdsClient::WatchResource(const XdsResourceType* type,
1555
1556
  work_serializer_.Run(
1556
1557
  [watcher = std::move(watcher), status = std::move(status)]()
1557
1558
  ABSL_EXCLUSIVE_LOCKS_REQUIRED(&work_serializer_) {
1558
- watcher->OnError(status);
1559
+ watcher->OnError(status, ReadDelayHandle::NoWait());
1559
1560
  },
1560
1561
  DEBUG_LOCATION);
1561
1562
  };
@@ -1606,7 +1607,8 @@ void XdsClient::WatchResource(const XdsResourceType* type,
1606
1607
  work_serializer_.Schedule(
1607
1608
  [watcher, value = resource_state.resource]()
1608
1609
  ABSL_EXCLUSIVE_LOCKS_REQUIRED(&work_serializer_) {
1609
- watcher->OnGenericResourceChanged(value);
1610
+ watcher->OnGenericResourceChanged(value,
1611
+ ReadDelayHandle::NoWait());
1610
1612
  },
1611
1613
  DEBUG_LOCATION);
1612
1614
  } else if (resource_state.meta.client_status ==
@@ -1618,7 +1620,7 @@ void XdsClient::WatchResource(const XdsResourceType* type,
1618
1620
  }
1619
1621
  work_serializer_.Schedule(
1620
1622
  [watcher]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(&work_serializer_) {
1621
- watcher->OnResourceDoesNotExist();
1623
+ watcher->OnResourceDoesNotExist(ReadDelayHandle::NoWait());
1622
1624
  },
1623
1625
  DEBUG_LOCATION);
1624
1626
  } else if (resource_state.meta.client_status ==
@@ -1638,18 +1640,19 @@ void XdsClient::WatchResource(const XdsResourceType* type,
1638
1640
  work_serializer_.Schedule(
1639
1641
  [watcher, details = std::move(details)]()
1640
1642
  ABSL_EXCLUSIVE_LOCKS_REQUIRED(&work_serializer_) {
1641
- watcher->OnError(absl::UnavailableError(
1642
- absl::StrCat("invalid resource: ", details)));
1643
+ watcher->OnError(absl::UnavailableError(absl::StrCat(
1644
+ "invalid resource: ", details)),
1645
+ ReadDelayHandle::NoWait());
1643
1646
  },
1644
1647
  DEBUG_LOCATION);
1645
1648
  }
1646
1649
  // If the authority doesn't yet have a channel, set it, creating it if
1647
1650
  // needed.
1648
- if (authority_state.channel_state == nullptr) {
1649
- authority_state.channel_state =
1650
- GetOrCreateChannelStateLocked(*xds_server, "start watch");
1651
+ if (authority_state.xds_channel == nullptr) {
1652
+ authority_state.xds_channel =
1653
+ GetOrCreateXdsChannelLocked(*xds_server, "start watch");
1651
1654
  }
1652
- absl::Status channel_status = authority_state.channel_state->status();
1655
+ absl::Status channel_status = authority_state.xds_channel->status();
1653
1656
  if (!channel_status.ok()) {
1654
1657
  if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
1655
1658
  gpr_log(GPR_INFO,
@@ -1660,11 +1663,11 @@ void XdsClient::WatchResource(const XdsResourceType* type,
1660
1663
  work_serializer_.Schedule(
1661
1664
  [watcher = std::move(watcher), status = std::move(channel_status)]()
1662
1665
  ABSL_EXCLUSIVE_LOCKS_REQUIRED(&work_serializer_) mutable {
1663
- watcher->OnError(std::move(status));
1666
+ watcher->OnError(std::move(status), ReadDelayHandle::NoWait());
1664
1667
  },
1665
1668
  DEBUG_LOCATION);
1666
1669
  }
1667
- authority_state.channel_state->SubscribeLocked(type, *resource_name);
1670
+ authority_state.xds_channel->SubscribeLocked(type, *resource_name);
1668
1671
  }
1669
1672
  work_serializer_.DrainQueue();
1670
1673
  }
@@ -1702,13 +1705,13 @@ void XdsClient::CancelResourceWatch(const XdsResourceType* type,
1702
1705
  this, std::string(type->type_url()).c_str(),
1703
1706
  std::string(name).c_str());
1704
1707
  }
1705
- authority_state.channel_state->UnsubscribeLocked(type, *resource_name,
1706
- delay_unsubscription);
1708
+ authority_state.xds_channel->UnsubscribeLocked(type, *resource_name,
1709
+ delay_unsubscription);
1707
1710
  type_map.erase(resource_it);
1708
1711
  if (type_map.empty()) {
1709
1712
  authority_state.resource_map.erase(type_it);
1710
1713
  if (authority_state.resource_map.empty()) {
1711
- authority_state.channel_state.reset();
1714
+ authority_state.xds_channel.reset();
1712
1715
  }
1713
1716
  }
1714
1717
  }
@@ -1722,7 +1725,7 @@ void XdsClient::MaybeRegisterResourceTypeLocked(
1722
1725
  return;
1723
1726
  }
1724
1727
  resource_types_.emplace(resource_type->type_url(), resource_type);
1725
- resource_type->InitUpbSymtab(this, symtab_.ptr());
1728
+ resource_type->InitUpbSymtab(this, def_pool_.ptr());
1726
1729
  }
1727
1730
 
1728
1731
  const XdsResourceType* XdsClient::GetResourceTypeLocked(
@@ -1792,9 +1795,9 @@ RefCountedPtr<XdsClusterDropStats> XdsClient::AddClusterDropStats(
1792
1795
  // in the load_report_map_ key, so that they have the same lifetime.
1793
1796
  auto server_it =
1794
1797
  xds_load_report_server_map_.emplace(server, LoadReportServer()).first;
1795
- if (server_it->second.channel_state == nullptr) {
1796
- server_it->second.channel_state = GetOrCreateChannelStateLocked(
1797
- *server, "load report map (drop stats)");
1798
+ if (server_it->second.xds_channel == nullptr) {
1799
+ server_it->second.xds_channel =
1800
+ GetOrCreateXdsChannelLocked(*server, "load report map (drop stats)");
1798
1801
  }
1799
1802
  auto load_report_it = server_it->second.load_report_map
1800
1803
  .emplace(std::move(key), LoadReportState())
@@ -1814,7 +1817,7 @@ RefCountedPtr<XdsClusterDropStats> XdsClient::AddClusterDropStats(
1814
1817
  load_report_it->first.second /*eds_service_name*/);
1815
1818
  load_report_state.drop_stats = cluster_drop_stats.get();
1816
1819
  }
1817
- server_it->second.channel_state->MaybeStartLrsCall();
1820
+ server_it->second.xds_channel->MaybeStartLrsCall();
1818
1821
  }
1819
1822
  work_serializer_.DrainQueue();
1820
1823
  return cluster_drop_stats;
@@ -1860,8 +1863,8 @@ RefCountedPtr<XdsClusterLocalityStats> XdsClient::AddClusterLocalityStats(
1860
1863
  // in the load_report_map_ key, so that they have the same lifetime.
1861
1864
  auto server_it =
1862
1865
  xds_load_report_server_map_.emplace(server, LoadReportServer()).first;
1863
- if (server_it->second.channel_state == nullptr) {
1864
- server_it->second.channel_state = GetOrCreateChannelStateLocked(
1866
+ if (server_it->second.xds_channel == nullptr) {
1867
+ server_it->second.xds_channel = GetOrCreateXdsChannelLocked(
1865
1868
  *server, "load report map (locality stats)");
1866
1869
  }
1867
1870
  auto load_report_it = server_it->second.load_report_map
@@ -1885,7 +1888,7 @@ RefCountedPtr<XdsClusterLocalityStats> XdsClient::AddClusterLocalityStats(
1885
1888
  std::move(locality));
1886
1889
  locality_state.locality_stats = cluster_locality_stats.get();
1887
1890
  }
1888
- server_it->second.channel_state->MaybeStartLrsCall();
1891
+ server_it->second.xds_channel->MaybeStartLrsCall();
1889
1892
  }
1890
1893
  work_serializer_.DrainQueue();
1891
1894
  return cluster_locality_stats;
@@ -1927,7 +1930,7 @@ void XdsClient::ResetBackoff() {
1927
1930
  void XdsClient::NotifyWatchersOnErrorLocked(
1928
1931
  const std::map<ResourceWatcherInterface*,
1929
1932
  RefCountedPtr<ResourceWatcherInterface>>& watchers,
1930
- absl::Status status) {
1933
+ absl::Status status, RefCountedPtr<ReadDelayHandle> read_delay_handle) {
1931
1934
  const auto* node = bootstrap_->node();
1932
1935
  if (node != nullptr) {
1933
1936
  status = absl::Status(
@@ -1935,10 +1938,11 @@ void XdsClient::NotifyWatchersOnErrorLocked(
1935
1938
  absl::StrCat(status.message(), " (node ID:", node->id(), ")"));
1936
1939
  }
1937
1940
  work_serializer_.Schedule(
1938
- [watchers, status = std::move(status)]()
1941
+ [watchers, status = std::move(status),
1942
+ read_delay_handle = std::move(read_delay_handle)]()
1939
1943
  ABSL_EXCLUSIVE_LOCKS_REQUIRED(&work_serializer_) {
1940
1944
  for (const auto& p : watchers) {
1941
- p.first->OnError(status);
1945
+ p.first->OnError(status, read_delay_handle);
1942
1946
  }
1943
1947
  },
1944
1948
  DEBUG_LOCATION);
@@ -1946,13 +1950,15 @@ void XdsClient::NotifyWatchersOnErrorLocked(
1946
1950
 
1947
1951
  void XdsClient::NotifyWatchersOnResourceDoesNotExist(
1948
1952
  const std::map<ResourceWatcherInterface*,
1949
- RefCountedPtr<ResourceWatcherInterface>>& watchers) {
1953
+ RefCountedPtr<ResourceWatcherInterface>>& watchers,
1954
+ RefCountedPtr<ReadDelayHandle> read_delay_handle) {
1950
1955
  work_serializer_.Schedule(
1951
- [watchers]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(&work_serializer_) {
1952
- for (const auto& p : watchers) {
1953
- p.first->OnResourceDoesNotExist();
1954
- }
1955
- },
1956
+ [watchers, read_delay_handle = std::move(read_delay_handle)]()
1957
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(&work_serializer_) {
1958
+ for (const auto& p : watchers) {
1959
+ p.first->OnResourceDoesNotExist(read_delay_handle);
1960
+ }
1961
+ },
1956
1962
  DEBUG_LOCATION);
1957
1963
  }
1958
1964