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

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

Potentially problematic release.


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

Files changed (275) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +54 -153
  3. data/include/grpc/event_engine/endpoint_config.h +11 -5
  4. data/include/grpc/event_engine/event_engine.h +1 -1
  5. data/include/grpc/impl/codegen/atm_gcc_atomic.h +19 -28
  6. data/include/grpc/impl/codegen/atm_gcc_sync.h +0 -2
  7. data/include/grpc/impl/codegen/atm_windows.h +0 -2
  8. data/include/grpc/impl/codegen/grpc_types.h +6 -0
  9. data/src/core/ext/filters/channel_idle/channel_idle_filter.cc +3 -3
  10. data/src/core/ext/filters/client_channel/backup_poller.cc +4 -6
  11. data/src/core/ext/filters/client_channel/client_channel.cc +33 -22
  12. data/src/core/ext/filters/client_channel/client_channel.h +1 -1
  13. data/src/core/ext/filters/client_channel/client_channel_plugin.cc +0 -16
  14. data/src/core/ext/filters/client_channel/http_proxy.cc +12 -19
  15. data/src/core/ext/filters/client_channel/http_proxy.h +3 -2
  16. data/src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc +6 -4
  17. data/src/core/ext/filters/client_channel/lb_policy/child_policy_handler.h +5 -4
  18. data/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc +0 -2
  19. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +112 -96
  20. data/src/core/ext/filters/client_channel/lb_policy/oob_backend_metric.cc +20 -11
  21. data/src/core/ext/filters/client_channel/lb_policy/outlier_detection/outlier_detection.cc +106 -108
  22. data/src/core/ext/filters/client_channel/lb_policy/outlier_detection/outlier_detection.h +16 -0
  23. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +20 -13
  24. data/src/core/ext/filters/client_channel/lb_policy/priority/priority.cc +165 -257
  25. data/src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.cc +218 -231
  26. data/src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.h +10 -6
  27. data/src/core/ext/filters/client_channel/lb_policy/rls/rls.cc +389 -444
  28. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +16 -16
  29. data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +8 -13
  30. data/src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc +84 -96
  31. data/src/core/ext/filters/client_channel/lb_policy/xds/cds.cc +38 -37
  32. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc +106 -186
  33. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc +106 -93
  34. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc +170 -218
  35. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +2 -2
  36. data/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +1 -1
  37. data/src/core/ext/filters/client_channel/resolver/google_c2p/google_c2p_resolver.cc +13 -15
  38. data/src/core/ext/filters/client_channel/resolver/polling_resolver.cc +84 -37
  39. data/src/core/ext/filters/client_channel/resolver/polling_resolver.h +11 -0
  40. data/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc +1 -0
  41. data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc +5 -3
  42. data/src/core/ext/filters/client_channel/resolver_result_parsing.cc +5 -4
  43. data/src/core/ext/filters/client_channel/retry_filter.cc +25 -29
  44. data/src/core/ext/filters/client_channel/subchannel.cc +38 -33
  45. data/src/core/ext/filters/client_channel/subchannel.h +12 -3
  46. data/src/core/ext/filters/client_channel/subchannel_stream_client.cc +1 -2
  47. data/src/core/ext/filters/fault_injection/fault_injection_filter.cc +23 -16
  48. data/src/core/ext/filters/fault_injection/fault_injection_filter.h +8 -0
  49. data/src/core/ext/filters/http/client/http_client_filter.cc +1 -2
  50. data/src/core/ext/filters/http/message_compress/message_compress_filter.cc +2 -4
  51. data/src/core/ext/filters/http/message_compress/message_decompress_filter.cc +0 -2
  52. data/src/core/ext/filters/http/server/http_server_filter.cc +1 -2
  53. data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +12 -8
  54. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +32 -26
  55. data/src/core/ext/transport/chttp2/transport/bin_encoder.cc +1 -1
  56. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +25 -130
  57. data/src/core/ext/transport/chttp2/transport/decode_huff.cc +287 -0
  58. data/src/core/ext/transport/chttp2/transport/decode_huff.h +1018 -0
  59. data/src/core/ext/transport/chttp2/transport/flow_control.cc +83 -51
  60. data/src/core/ext/transport/chttp2/transport/flow_control.h +11 -6
  61. data/src/core/ext/transport/chttp2/transport/frame_ping.cc +1 -2
  62. data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +2 -20
  63. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +28 -28
  64. data/src/core/ext/transport/chttp2/transport/hpack_parser_table.cc +1 -10
  65. data/src/core/ext/transport/chttp2/transport/hpack_parser_table.h +11 -6
  66. data/src/core/ext/transport/chttp2/transport/internal.h +2 -0
  67. data/src/core/ext/transport/chttp2/transport/parsing.cc +44 -0
  68. data/src/core/ext/transport/chttp2/transport/writing.cc +3 -14
  69. data/src/core/ext/transport/inproc/inproc_transport.cc +1 -3
  70. data/src/core/ext/xds/certificate_provider_store.cc +63 -3
  71. data/src/core/ext/xds/certificate_provider_store.h +9 -1
  72. data/src/core/ext/xds/file_watcher_certificate_provider_factory.cc +5 -5
  73. data/src/core/ext/xds/file_watcher_certificate_provider_factory.h +1 -1
  74. data/src/core/ext/xds/xds_api.cc +21 -17
  75. data/src/core/ext/xds/xds_api.h +7 -0
  76. data/src/core/ext/xds/xds_bootstrap.cc +5 -537
  77. data/src/core/ext/xds/xds_bootstrap.h +39 -111
  78. data/src/core/ext/xds/xds_bootstrap_grpc.cc +370 -0
  79. data/src/core/ext/xds/xds_bootstrap_grpc.h +169 -0
  80. data/src/core/ext/xds/xds_client.cc +219 -145
  81. data/src/core/ext/xds/xds_client.h +19 -17
  82. data/src/core/ext/xds/xds_client_grpc.cc +18 -80
  83. data/src/core/ext/xds/xds_client_grpc.h +2 -25
  84. data/src/core/ext/xds/xds_client_stats.cc +4 -4
  85. data/src/core/ext/xds/xds_cluster.cc +87 -79
  86. data/src/core/ext/xds/xds_cluster.h +5 -5
  87. data/src/core/ext/xds/xds_cluster_specifier_plugin.cc +3 -1
  88. data/src/core/ext/xds/xds_common_types.cc +13 -5
  89. data/src/core/ext/xds/xds_endpoint.cc +8 -6
  90. data/src/core/ext/xds/xds_endpoint.h +3 -4
  91. data/src/core/ext/xds/xds_lb_policy_registry.cc +4 -2
  92. data/src/core/ext/xds/xds_listener.cc +25 -20
  93. data/src/core/ext/xds/xds_listener.h +3 -4
  94. data/src/core/ext/xds/xds_resource_type.h +11 -8
  95. data/src/core/ext/xds/xds_route_config.cc +15 -16
  96. data/src/core/ext/xds/xds_route_config.h +3 -3
  97. data/src/core/ext/xds/xds_server_config_fetcher.cc +7 -5
  98. data/src/core/ext/xds/xds_transport_grpc.cc +15 -7
  99. data/src/core/lib/backoff/backoff.cc +2 -4
  100. data/src/core/lib/channel/call_finalization.h +1 -3
  101. data/src/core/lib/channel/channel_args.h +114 -14
  102. data/src/core/lib/channel/channel_trace.cc +3 -4
  103. data/src/core/lib/channel/promise_based_filter.cc +18 -19
  104. data/src/core/lib/channel/status_util.cc +27 -0
  105. data/src/core/lib/channel/status_util.h +10 -0
  106. data/src/core/lib/config/core_configuration.cc +5 -1
  107. data/src/core/lib/config/core_configuration.h +33 -0
  108. data/src/core/lib/debug/stats.cc +26 -30
  109. data/src/core/lib/debug/stats.h +2 -12
  110. data/src/core/lib/debug/stats_data.cc +118 -614
  111. data/src/core/lib/debug/stats_data.h +67 -465
  112. data/src/core/lib/debug/trace.cc +0 -2
  113. data/src/core/lib/event_engine/channel_args_endpoint_config.cc +12 -20
  114. data/src/core/lib/event_engine/channel_args_endpoint_config.h +13 -7
  115. data/src/core/lib/event_engine/forkable.cc +1 -1
  116. data/src/core/lib/event_engine/poller.h +14 -12
  117. data/src/core/lib/event_engine/posix_engine/timer_manager.cc +53 -32
  118. data/src/core/lib/event_engine/posix_engine/timer_manager.h +23 -1
  119. data/src/core/lib/event_engine/thread_pool.cc +131 -94
  120. data/src/core/lib/event_engine/thread_pool.h +56 -23
  121. data/src/core/lib/event_engine/time_util.cc +30 -0
  122. data/src/core/lib/event_engine/time_util.h +32 -0
  123. data/src/core/lib/event_engine/utils.cc +0 -5
  124. data/src/core/lib/event_engine/utils.h +0 -4
  125. data/src/core/lib/event_engine/windows/iocp.cc +13 -7
  126. data/src/core/lib/event_engine/windows/iocp.h +2 -1
  127. data/src/core/lib/event_engine/windows/win_socket.cc +1 -1
  128. data/src/core/lib/experiments/config.cc +146 -0
  129. data/src/core/lib/experiments/config.h +43 -0
  130. data/src/core/lib/experiments/experiments.cc +75 -0
  131. data/src/core/lib/experiments/experiments.h +56 -0
  132. data/src/core/lib/gpr/alloc.cc +1 -9
  133. data/src/core/lib/gpr/log_windows.cc +0 -1
  134. data/src/core/lib/gpr/string_util_windows.cc +3 -30
  135. data/src/core/lib/gpr/sync_abseil.cc +0 -14
  136. data/src/core/lib/gpr/sync_posix.cc +0 -14
  137. data/src/core/lib/gpr/time_posix.cc +0 -6
  138. data/src/core/lib/gpr/time_precise.h +1 -1
  139. data/src/core/lib/gpr/tmpfile_windows.cc +5 -7
  140. data/src/core/lib/gpr/useful.h +11 -0
  141. data/src/core/lib/{gpr → gprpp}/env.h +25 -12
  142. data/src/core/lib/{gpr → gprpp}/env_linux.cc +20 -15
  143. data/src/core/lib/{gpr → gprpp}/env_posix.cc +11 -10
  144. data/src/core/lib/gprpp/env_windows.cc +56 -0
  145. data/src/core/lib/gprpp/fork.cc +14 -22
  146. data/src/core/lib/gprpp/fork.h +0 -8
  147. data/src/core/lib/gprpp/global_config_env.cc +7 -6
  148. data/src/core/lib/gprpp/notification.h +67 -0
  149. data/src/core/lib/gprpp/packed_table.h +40 -0
  150. data/src/core/lib/gprpp/ref_counted_ptr.h +20 -33
  151. data/src/core/lib/gprpp/sorted_pack.h +98 -0
  152. data/src/core/lib/gprpp/status_helper.h +6 -0
  153. data/src/core/lib/gprpp/table.h +9 -1
  154. data/src/core/lib/gprpp/tchar.cc +49 -0
  155. data/src/core/lib/gprpp/tchar.h +33 -0
  156. data/src/core/lib/gprpp/time.cc +21 -0
  157. data/src/core/lib/gprpp/time.h +55 -0
  158. data/src/core/lib/gprpp/validation_errors.cc +61 -0
  159. data/src/core/lib/gprpp/validation_errors.h +110 -0
  160. data/src/core/{ext/filters/client_channel → lib/handshaker}/proxy_mapper.h +3 -3
  161. data/src/core/{ext/filters/client_channel → lib/handshaker}/proxy_mapper_registry.cc +14 -36
  162. data/src/core/lib/handshaker/proxy_mapper_registry.h +75 -0
  163. data/src/core/lib/iomgr/call_combiner.cc +0 -8
  164. data/src/core/lib/iomgr/closure.h +0 -1
  165. data/src/core/lib/iomgr/endpoint_pair_posix.cc +14 -10
  166. data/src/core/lib/iomgr/endpoint_pair_windows.cc +2 -2
  167. data/src/core/lib/iomgr/ev_epoll1_linux.cc +1 -38
  168. data/src/core/lib/iomgr/ev_poll_posix.cc +2 -17
  169. data/src/core/lib/iomgr/exec_ctx.cc +0 -10
  170. data/src/core/lib/iomgr/exec_ctx.h +7 -31
  171. data/src/core/lib/iomgr/iocp_windows.cc +1 -2
  172. data/src/core/lib/iomgr/iomgr.cc +6 -8
  173. data/src/core/lib/iomgr/iomgr_fwd.h +1 -0
  174. data/src/core/lib/iomgr/pollset.h +1 -1
  175. data/src/core/lib/iomgr/pollset_set.h +0 -1
  176. data/src/core/lib/iomgr/resolve_address.h +1 -0
  177. data/src/core/lib/iomgr/resolve_address_impl.h +1 -0
  178. data/src/core/lib/iomgr/resolve_address_posix.cc +1 -0
  179. data/src/core/lib/iomgr/resolve_address_windows.cc +1 -0
  180. data/src/core/lib/iomgr/sockaddr_utils_posix.cc +2 -1
  181. data/src/core/lib/iomgr/socket_utils_common_posix.cc +12 -34
  182. data/src/core/lib/iomgr/socket_utils_posix.cc +83 -1
  183. data/src/core/lib/iomgr/socket_utils_posix.h +98 -6
  184. data/src/core/lib/iomgr/tcp_client.cc +6 -7
  185. data/src/core/lib/iomgr/tcp_client.h +11 -11
  186. data/src/core/lib/iomgr/tcp_client_cfstream.cc +6 -6
  187. data/src/core/lib/iomgr/tcp_client_posix.cc +33 -29
  188. data/src/core/lib/iomgr/tcp_client_posix.h +12 -9
  189. data/src/core/lib/iomgr/tcp_client_windows.cc +6 -6
  190. data/src/core/lib/iomgr/tcp_posix.cc +131 -114
  191. data/src/core/lib/iomgr/tcp_posix.h +3 -1
  192. data/src/core/lib/iomgr/tcp_server.cc +5 -4
  193. data/src/core/lib/iomgr/tcp_server.h +9 -6
  194. data/src/core/lib/iomgr/tcp_server_posix.cc +17 -28
  195. data/src/core/lib/iomgr/tcp_server_utils_posix.h +2 -2
  196. data/src/core/lib/iomgr/tcp_server_utils_posix_common.cc +3 -3
  197. data/src/core/lib/iomgr/tcp_server_windows.cc +6 -7
  198. data/src/core/lib/iomgr/tcp_windows.cc +0 -1
  199. data/src/core/lib/iomgr/tcp_windows.h +0 -1
  200. data/src/core/lib/iomgr/timer_generic.cc +4 -4
  201. data/src/core/lib/iomgr/timer_manager.cc +1 -2
  202. data/src/core/lib/iomgr/wakeup_fd_eventfd.cc +0 -2
  203. data/src/core/lib/json/json_object_loader.cc +21 -52
  204. data/src/core/lib/json/json_object_loader.h +56 -76
  205. data/src/core/lib/json/json_util.cc +2 -1
  206. data/src/core/lib/load_balancing/lb_policy.h +5 -5
  207. data/src/core/lib/load_balancing/lb_policy_registry.cc +29 -55
  208. data/src/core/lib/load_balancing/lb_policy_registry.h +23 -11
  209. data/src/core/lib/promise/activity.h +2 -3
  210. data/src/core/lib/promise/context.h +1 -1
  211. data/src/core/lib/promise/sleep.cc +16 -4
  212. data/src/core/lib/promise/sleep.h +8 -2
  213. data/src/core/lib/resolver/resolver.h +13 -3
  214. data/src/core/lib/resource_quota/api.cc +9 -0
  215. data/src/core/lib/resource_quota/api.h +6 -0
  216. data/src/core/lib/resource_quota/arena.cc +1 -3
  217. data/src/core/lib/resource_quota/memory_quota.cc +8 -24
  218. data/src/core/lib/resource_quota/memory_quota.h +6 -19
  219. data/src/core/lib/resource_quota/periodic_update.cc +2 -3
  220. data/src/core/{ext/xds → lib/security/certificate_provider}/certificate_provider_factory.h +3 -3
  221. data/src/core/lib/security/certificate_provider/certificate_provider_registry.cc +60 -0
  222. data/src/core/lib/security/certificate_provider/certificate_provider_registry.h +70 -0
  223. data/src/core/lib/security/credentials/channel_creds_registry_init.cc +1 -0
  224. data/src/core/lib/security/credentials/external/aws_external_account_credentials.cc +15 -16
  225. data/src/core/lib/security/credentials/external/external_account_credentials.cc +2 -1
  226. data/src/core/lib/security/credentials/google_default/credentials_generic.cc +5 -8
  227. data/src/core/lib/security/credentials/google_default/google_default_credentials.cc +6 -6
  228. data/src/core/lib/security/credentials/jwt/jwt_verifier.cc +3 -2
  229. data/src/core/lib/security/credentials/jwt/jwt_verifier.h +1 -1
  230. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +1 -2
  231. data/src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc +4 -3
  232. data/src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h +4 -2
  233. data/src/core/lib/security/credentials/tls/tls_utils.cc +3 -1
  234. data/src/core/lib/security/transport/client_auth_filter.cc +12 -1
  235. data/src/core/lib/security/transport/secure_endpoint.cc +0 -4
  236. data/src/core/lib/surface/call.cc +1 -11
  237. data/src/core/lib/surface/channel.cc +3 -2
  238. data/src/core/lib/surface/completion_queue.cc +16 -28
  239. data/src/core/lib/surface/completion_queue.h +1 -1
  240. data/src/core/lib/surface/completion_queue_factory.cc +5 -0
  241. data/src/core/lib/surface/init.cc +16 -11
  242. data/src/core/lib/surface/init_internally.cc +24 -0
  243. data/src/core/lib/surface/init_internally.h +28 -0
  244. data/src/core/lib/surface/server.cc +1 -7
  245. data/src/core/lib/surface/server.h +4 -6
  246. data/src/core/lib/surface/version.cc +2 -2
  247. data/src/core/lib/transport/bdp_estimator.cc +1 -3
  248. data/src/core/lib/transport/metadata_batch.cc +2 -3
  249. data/src/core/lib/transport/metadata_batch.h +9 -7
  250. data/src/core/lib/transport/parsed_metadata.h +4 -2
  251. data/src/core/lib/transport/status_conversion.cc +1 -3
  252. data/src/core/lib/transport/tcp_connect_handshaker.cc +9 -5
  253. data/src/core/lib/transport/transport.h +0 -1
  254. data/src/core/lib/transport/transport_impl.h +0 -1
  255. data/src/core/plugin_registry/grpc_plugin_registry.cc +23 -46
  256. data/src/core/plugin_registry/grpc_plugin_registry_extra.cc +13 -25
  257. data/src/ruby/lib/grpc/2.6/grpc_c.so +0 -0
  258. data/src/ruby/lib/grpc/2.7/grpc_c.so +0 -0
  259. data/src/ruby/lib/grpc/3.0/grpc_c.so +0 -0
  260. data/src/ruby/lib/grpc/3.1/grpc_c.so +0 -0
  261. data/src/ruby/lib/grpc/grpc_c.so +0 -0
  262. data/src/ruby/lib/grpc/version.rb +1 -1
  263. data/src/ruby/spec/channel_spec.rb +5 -0
  264. data/src/ruby/spec/generic/server_interceptors_spec.rb +1 -1
  265. data/src/ruby/spec/user_agent_spec.rb +1 -1
  266. metadata +33 -19
  267. data/src/core/ext/filters/client_channel/proxy_mapper_registry.h +0 -56
  268. data/src/core/ext/xds/certificate_provider_registry.cc +0 -103
  269. data/src/core/ext/xds/certificate_provider_registry.h +0 -59
  270. data/src/core/lib/event_engine/promise.h +0 -78
  271. data/src/core/lib/gpr/env_windows.cc +0 -74
  272. data/src/core/lib/gpr/string_windows.h +0 -32
  273. data/src/core/lib/profiling/basic_timers.cc +0 -295
  274. data/src/core/lib/profiling/stap_timers.cc +0 -50
  275. data/src/core/lib/profiling/timers.h +0 -94
@@ -46,6 +46,7 @@
46
46
  #include "src/core/lib/gprpp/orphanable.h"
47
47
  #include "src/core/lib/gprpp/ref_counted_ptr.h"
48
48
  #include "src/core/lib/gprpp/sync.h"
49
+ #include "src/core/lib/iomgr/exec_ctx.h"
49
50
  #include "src/core/lib/uri/uri_parser.h"
50
51
 
51
52
  #define GRPC_XDS_INITIAL_CONNECT_BACKOFF_SECONDS 1
@@ -150,16 +151,19 @@ class XdsClient::ChannelState::AdsCallState
150
151
  ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsClient::mu_);
151
152
 
152
153
  void ParseResource(upb_Arena* arena, size_t idx, absl::string_view type_url,
154
+ absl::string_view resource_name,
153
155
  absl::string_view serialized_resource) override
154
156
  ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsClient::mu_);
155
157
 
158
+ void ResourceWrapperParsingFailed(size_t idx) override;
159
+
156
160
  Result TakeResult() { return std::move(result_); }
157
161
 
158
162
  private:
159
163
  XdsClient* xds_client() const { return ads_call_state_->xds_client(); }
160
164
 
161
165
  AdsCallState* ads_call_state_;
162
- const Timestamp update_time_ = ExecCtx::Get()->Now();
166
+ const Timestamp update_time_ = Timestamp::Now();
163
167
  Result result_;
164
168
  };
165
169
 
@@ -230,7 +234,7 @@ class XdsClient::ChannelState::AdsCallState
230
234
  "[xds_client %p] xds server %s: timeout obtaining resource "
231
235
  "{type=%s name=%s} from xds server",
232
236
  ads_calld_->xds_client(),
233
- ads_calld_->chand()->server_.server_uri.c_str(),
237
+ ads_calld_->chand()->server_.server_uri().c_str(),
234
238
  std::string(type_->type_url()).c_str(),
235
239
  XdsClient::ConstructFullXdsResourceName(
236
240
  name_.authority, type_->type_url(), name_.key)
@@ -423,24 +427,24 @@ XdsClient::ChannelState::ChannelState(WeakRefCountedPtr<XdsClient> xds_client,
423
427
  server_(server) {
424
428
  if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
425
429
  gpr_log(GPR_INFO, "[xds_client %p] creating channel to %s",
426
- xds_client_.get(), server.server_uri.c_str());
430
+ xds_client_.get(), server.server_uri().c_str());
427
431
  }
428
432
  absl::Status status;
429
433
  transport_ = xds_client_->transport_factory_->Create(
430
434
  server,
431
435
  [self = WeakRef(DEBUG_LOCATION, "OnConnectivityFailure")](
432
436
  absl::Status status) {
433
- self->OnConnectivityStateChange(std::move(status));
437
+ self->OnConnectivityFailure(std::move(status));
434
438
  },
435
439
  &status);
436
440
  GPR_ASSERT(transport_ != nullptr);
437
- if (!status.ok()) OnConnectivityStateChangeLocked(std::move(status));
441
+ if (!status.ok()) SetChannelStatusLocked(std::move(status));
438
442
  }
439
443
 
440
444
  XdsClient::ChannelState::~ChannelState() {
441
445
  if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
442
446
  gpr_log(GPR_INFO, "[xds_client %p] destroying xds channel %p for server %s",
443
- xds_client(), this, server_.server_uri.c_str());
447
+ xds_client(), this, server_.server_uri().c_str());
444
448
  }
445
449
  xds_client_.reset(DEBUG_LOCATION, "ChannelState");
446
450
  }
@@ -455,7 +459,7 @@ void XdsClient::ChannelState::Orphan() ABSL_NO_THREAD_SAFETY_ANALYSIS {
455
459
  // At this time, all strong refs are removed, remove from channel map to
456
460
  // prevent subsequent subscription from trying to use this ChannelState as
457
461
  // it is shutting down.
458
- xds_client_->xds_server_channel_map_.erase(server_);
462
+ xds_client_->xds_server_channel_map_.erase(&server_);
459
463
  ads_calld_.reset();
460
464
  lrs_calld_.reset();
461
465
  }
@@ -472,10 +476,6 @@ XdsClient::ChannelState::LrsCallState* XdsClient::ChannelState::lrs_calld()
472
476
  return lrs_calld_->calld();
473
477
  }
474
478
 
475
- bool XdsClient::ChannelState::HasActiveAdsCall() const {
476
- return ads_calld_ != nullptr && ads_calld_->calld() != nullptr;
477
- }
478
-
479
479
  void XdsClient::ChannelState::MaybeStartLrsCall() {
480
480
  if (lrs_calld_ != nullptr) return;
481
481
  lrs_calld_.reset(new RetryableCall<LrsCallState>(
@@ -483,7 +483,7 @@ void XdsClient::ChannelState::MaybeStartLrsCall() {
483
483
  }
484
484
 
485
485
  void XdsClient::ChannelState::StopLrsCallLocked() {
486
- xds_client_->xds_load_report_server_map_.erase(server_);
486
+ xds_client_->xds_load_report_server_map_.erase(&server_);
487
487
  lrs_calld_.reset();
488
488
  }
489
489
 
@@ -519,27 +519,54 @@ void XdsClient::ChannelState::UnsubscribeLocked(const XdsResourceType* type,
519
519
  }
520
520
  }
521
521
 
522
- void XdsClient::ChannelState::OnConnectivityStateChange(absl::Status status) {
522
+ void XdsClient::ChannelState::OnConnectivityFailure(absl::Status status) {
523
523
  {
524
524
  MutexLock lock(&xds_client_->mu_);
525
- OnConnectivityStateChangeLocked(std::move(status));
525
+ SetChannelStatusLocked(std::move(status));
526
526
  }
527
527
  xds_client_->work_serializer_.DrainQueue();
528
528
  }
529
529
 
530
- void XdsClient::ChannelState::OnConnectivityStateChangeLocked(
531
- absl::Status status) {
532
- if (!shutting_down_) {
533
- // Notify all watchers of error.
534
- gpr_log(GPR_INFO,
535
- "[xds_client %p] xds channel for server %s in "
536
- "state TRANSIENT_FAILURE: %s",
537
- xds_client(), server_.server_uri.c_str(),
538
- status.ToString().c_str());
539
- xds_client_->NotifyOnErrorLocked(absl::UnavailableError(
540
- absl::StrCat("xds channel in TRANSIENT_FAILURE, connectivity error: ",
541
- status.ToString())));
530
+ void XdsClient::ChannelState::SetChannelStatusLocked(absl::Status status) {
531
+ if (shutting_down_) return;
532
+ status = absl::Status(status.code(), absl::StrCat("xDS channel for server ",
533
+ server_.server_uri(), ": ",
534
+ status.message()));
535
+ gpr_log(GPR_INFO, "[xds_client %p] %s", xds_client(),
536
+ status.ToString().c_str());
537
+ // If the node ID is set, append that to the status message that we send to
538
+ // the watchers, so that it will appear in log messages visible to users.
539
+ const auto* node = xds_client_->bootstrap_->node();
540
+ if (node != nullptr) {
541
+ status = absl::Status(
542
+ status.code(),
543
+ absl::StrCat(status.message(),
544
+ " (node ID:", xds_client_->bootstrap_->node()->id(), ")"));
545
+ }
546
+ // Save status in channel, so that we can immediately generate an
547
+ // error for any new watchers that may be started.
548
+ status_ = status;
549
+ // Find all watchers for this channel.
550
+ std::set<RefCountedPtr<ResourceWatcherInterface>> watchers;
551
+ for (const auto& a : xds_client_->authority_state_map_) { // authority
552
+ if (a.second.channel_state != this) continue;
553
+ for (const auto& t : a.second.resource_map) { // type
554
+ for (const auto& r : t.second) { // resource id
555
+ for (const auto& w : r.second.watchers) { // watchers
556
+ watchers.insert(w.second);
557
+ }
558
+ }
559
+ }
542
560
  }
561
+ // Enqueue notification for the watchers.
562
+ xds_client_->work_serializer_.Schedule(
563
+ [watchers = std::move(watchers), status = std::move(status)]()
564
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(xds_client_->work_serializer_) {
565
+ for (const auto& watcher : watchers) {
566
+ watcher->OnError(status);
567
+ }
568
+ },
569
+ DEBUG_LOCATION);
543
570
  }
544
571
 
545
572
  //
@@ -589,7 +616,7 @@ void XdsClient::ChannelState::RetryableCall<T>::StartNewCallLocked() {
589
616
  gpr_log(GPR_INFO,
590
617
  "[xds_client %p] xds server %s: start new call from retryable "
591
618
  "call %p",
592
- chand()->xds_client(), chand()->server_.server_uri.c_str(), this);
619
+ chand()->xds_client(), chand()->server_.server_uri().c_str(), this);
593
620
  }
594
621
  calld_ = MakeOrphanable<T>(
595
622
  this->Ref(DEBUG_LOCATION, "RetryableCall+start_new_call"));
@@ -600,12 +627,12 @@ void XdsClient::ChannelState::RetryableCall<T>::StartRetryTimerLocked() {
600
627
  if (shutting_down_) return;
601
628
  const Timestamp next_attempt_time = backoff_.NextAttemptTime();
602
629
  const Duration timeout =
603
- std::max(next_attempt_time - ExecCtx::Get()->Now(), Duration::Zero());
630
+ std::max(next_attempt_time - Timestamp::Now(), Duration::Zero());
604
631
  if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
605
632
  gpr_log(GPR_INFO,
606
633
  "[xds_client %p] xds server %s: call attempt failed; "
607
634
  "retry timer will fire in %" PRId64 "ms.",
608
- chand()->xds_client(), chand()->server_.server_uri.c_str(),
635
+ chand()->xds_client(), chand()->server_.server_uri().c_str(),
609
636
  timeout.millis());
610
637
  }
611
638
  timer_handle_ = GetDefaultEventEngine()->RunAfter(
@@ -627,7 +654,8 @@ void XdsClient::ChannelState::RetryableCall<T>::OnRetryTimer() {
627
654
  gpr_log(GPR_INFO,
628
655
  "[xds_client %p] xds server %s: retry timer fired (retryable "
629
656
  "call: %p)",
630
- chand()->xds_client(), chand()->server_.server_uri.c_str(), this);
657
+ chand()->xds_client(), chand()->server_.server_uri().c_str(),
658
+ this);
631
659
  }
632
660
  StartNewCallLocked();
633
661
  }
@@ -645,7 +673,7 @@ absl::Status XdsClient::ChannelState::AdsCallState::AdsResponseParser::
645
673
  "[xds_client %p] xds server %s: received ADS response: type_url=%s, "
646
674
  "version=%s, nonce=%s, num_resources=%" PRIuPTR,
647
675
  ads_call_state_->xds_client(),
648
- ads_call_state_->chand()->server_.server_uri.c_str(),
676
+ ads_call_state_->chand()->server_.server_uri().c_str(),
649
677
  fields.type_url.c_str(), fields.version.c_str(), fields.nonce.c_str(),
650
678
  fields.num_resources);
651
679
  }
@@ -689,42 +717,60 @@ void UpdateResourceMetadataNacked(const std::string& version,
689
717
 
690
718
  void XdsClient::ChannelState::AdsCallState::AdsResponseParser::ParseResource(
691
719
  upb_Arena* arena, size_t idx, absl::string_view type_url,
692
- absl::string_view serialized_resource) {
720
+ absl::string_view resource_name, absl::string_view serialized_resource) {
721
+ std::string error_prefix = absl::StrCat(
722
+ "resource index ", idx, ": ",
723
+ resource_name.empty() ? "" : absl::StrCat(resource_name, ": "));
693
724
  // Check the type_url of the resource.
694
725
  bool is_v2 = false;
695
726
  if (!result_.type->IsType(type_url, &is_v2)) {
696
727
  result_.errors.emplace_back(
697
- absl::StrCat("resource index ", idx, ": incorrect resource type ",
698
- type_url, " (should be ", result_.type_url, ")"));
728
+ absl::StrCat(error_prefix, "incorrect resource type ", type_url,
729
+ " (should be ", result_.type_url, ")"));
699
730
  return;
700
731
  }
701
732
  // Parse the resource.
702
733
  XdsResourceType::DecodeContext context = {
703
734
  xds_client(), ads_call_state_->chand()->server_, &grpc_xds_client_trace,
704
735
  xds_client()->symtab_.ptr(), arena};
705
- absl::StatusOr<XdsResourceType::DecodeResult> result =
736
+ XdsResourceType::DecodeResult decode_result =
706
737
  result_.type->Decode(context, serialized_resource, is_v2);
707
- if (!result.ok()) {
738
+ // If we didn't already have the resource name from the Resource
739
+ // wrapper, try to get it from the decoding result.
740
+ if (resource_name.empty()) {
741
+ if (decode_result.name.has_value()) {
742
+ resource_name = *decode_result.name;
743
+ error_prefix =
744
+ absl::StrCat("resource index ", idx, ": ", resource_name, ": ");
745
+ } else {
746
+ // We don't have any way of determining the resource name, so
747
+ // there's nothing more we can do here.
748
+ result_.errors.emplace_back(absl::StrCat(
749
+ error_prefix, decode_result.resource.status().ToString()));
750
+ return;
751
+ }
752
+ }
753
+ // If decoding failed, make sure we include the error in the NACK.
754
+ const absl::Status& decode_status = decode_result.resource.status();
755
+ if (!decode_status.ok()) {
708
756
  result_.errors.emplace_back(
709
- absl::StrCat("resource index ", idx, ": ", result.status().ToString()));
710
- return;
757
+ absl::StrCat(error_prefix, decode_status.ToString()));
711
758
  }
712
759
  // Check the resource name.
713
- auto resource_name =
714
- xds_client()->ParseXdsResourceName(result->name, result_.type);
715
- if (!resource_name.ok()) {
716
- result_.errors.emplace_back(absl::StrCat(
717
- "resource index ", idx, ": Cannot parse xDS resource name \"",
718
- result->name, "\""));
760
+ auto parsed_resource_name =
761
+ xds_client()->ParseXdsResourceName(resource_name, result_.type);
762
+ if (!parsed_resource_name.ok()) {
763
+ result_.errors.emplace_back(
764
+ absl::StrCat(error_prefix, "Cannot parse xDS resource name"));
719
765
  return;
720
766
  }
721
767
  // Cancel resource-does-not-exist timer, if needed.
722
768
  auto timer_it = ads_call_state_->state_map_.find(result_.type);
723
769
  if (timer_it != ads_call_state_->state_map_.end()) {
724
- auto it =
725
- timer_it->second.subscribed_resources.find(resource_name->authority);
770
+ auto it = timer_it->second.subscribed_resources.find(
771
+ parsed_resource_name->authority);
726
772
  if (it != timer_it->second.subscribed_resources.end()) {
727
- auto res_it = it->second.find(resource_name->key);
773
+ auto res_it = it->second.find(parsed_resource_name->key);
728
774
  if (res_it != it->second.end()) {
729
775
  res_it->second->MaybeCancelTimer();
730
776
  }
@@ -732,7 +778,7 @@ void XdsClient::ChannelState::AdsCallState::AdsResponseParser::ParseResource(
732
778
  }
733
779
  // Lookup the authority in the cache.
734
780
  auto authority_it =
735
- xds_client()->authority_state_map_.find(resource_name->authority);
781
+ xds_client()->authority_state_map_.find(parsed_resource_name->authority);
736
782
  if (authority_it == xds_client()->authority_state_map_.end()) {
737
783
  return; // Skip resource -- we don't have a subscription for it.
738
784
  }
@@ -744,14 +790,15 @@ void XdsClient::ChannelState::AdsCallState::AdsResponseParser::ParseResource(
744
790
  }
745
791
  auto& type_map = type_it->second;
746
792
  // Found type, so look up resource key.
747
- auto it = type_map.find(resource_name->key);
793
+ auto it = type_map.find(parsed_resource_name->key);
748
794
  if (it == type_map.end()) {
749
795
  return; // Skip resource -- we don't have a subscription for it.
750
796
  }
751
797
  ResourceState& resource_state = it->second;
752
798
  // If needed, record that we've seen this resource.
753
799
  if (result_.type->AllResourcesRequiredInSotW()) {
754
- result_.resources_seen[resource_name->authority].insert(resource_name->key);
800
+ result_.resources_seen[parsed_resource_name->authority].insert(
801
+ parsed_resource_name->key);
755
802
  }
756
803
  // If we previously ignored the resource's deletion, log that we're
757
804
  // now re-adding it.
@@ -760,21 +807,18 @@ void XdsClient::ChannelState::AdsCallState::AdsResponseParser::ParseResource(
760
807
  "[xds_client %p] xds server %s: server returned new version of "
761
808
  "resource for which we previously ignored a deletion: type %s "
762
809
  "name %s",
763
- xds_client(), ads_call_state_->chand()->server_.server_uri.c_str(),
764
- std::string(type_url).c_str(), result->name.c_str());
810
+ xds_client(),
811
+ ads_call_state_->chand()->server_.server_uri().c_str(),
812
+ std::string(type_url).c_str(), std::string(resource_name).c_str());
765
813
  resource_state.ignored_deletion = false;
766
814
  }
767
815
  // Update resource state based on whether the resource is valid.
768
- if (!result->resource.ok()) {
769
- result_.errors.emplace_back(absl::StrCat(
770
- "resource index ", idx, ": ", result->name,
771
- ": validation error: ", result->resource.status().ToString()));
816
+ if (!decode_status.ok()) {
772
817
  xds_client()->NotifyWatchersOnErrorLocked(
773
818
  resource_state.watchers,
774
- absl::UnavailableError(absl::StrCat(
775
- "invalid resource: ", result->resource.status().ToString())));
776
- UpdateResourceMetadataNacked(result_.version,
777
- result->resource.status().ToString(),
819
+ absl::UnavailableError(
820
+ absl::StrCat("invalid resource: ", decode_status.ToString())));
821
+ UpdateResourceMetadataNacked(result_.version, decode_status.ToString(),
778
822
  update_time_, &resource_state.meta);
779
823
  return;
780
824
  }
@@ -783,16 +827,17 @@ void XdsClient::ChannelState::AdsCallState::AdsResponseParser::ParseResource(
783
827
  // If it didn't change, ignore it.
784
828
  if (resource_state.resource != nullptr &&
785
829
  result_.type->ResourcesEqual(resource_state.resource.get(),
786
- result->resource->get())) {
830
+ decode_result.resource->get())) {
787
831
  if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
788
832
  gpr_log(GPR_INFO,
789
833
  "[xds_client %p] %s resource %s identical to current, ignoring.",
790
- xds_client(), result_.type_url.c_str(), result->name.c_str());
834
+ xds_client(), result_.type_url.c_str(),
835
+ std::string(resource_name).c_str());
791
836
  }
792
837
  return;
793
838
  }
794
839
  // Update the resource state.
795
- resource_state.resource = std::move(*result->resource);
840
+ resource_state.resource = std::move(*decode_result.resource);
796
841
  resource_state.meta = CreateResourceMetadataAcked(
797
842
  std::string(serialized_resource), result_.version, update_time_);
798
843
  // Notify watchers.
@@ -810,6 +855,12 @@ void XdsClient::ChannelState::AdsCallState::AdsResponseParser::ParseResource(
810
855
  DEBUG_LOCATION);
811
856
  }
812
857
 
858
+ void XdsClient::ChannelState::AdsCallState::AdsResponseParser::
859
+ ResourceWrapperParsingFailed(size_t idx) {
860
+ result_.errors.emplace_back(absl::StrCat(
861
+ "resource index ", idx, ": Can't decode Resource proto wrapper"));
862
+ }
863
+
813
864
  //
814
865
  // XdsClient::ChannelState::AdsCallState
815
866
  //
@@ -840,7 +891,7 @@ XdsClient::ChannelState::AdsCallState::AdsCallState(
840
891
  gpr_log(GPR_INFO,
841
892
  "[xds_client %p] xds server %s: starting ADS call "
842
893
  "(calld: %p, call: %p)",
843
- xds_client(), chand()->server_.server_uri.c_str(), this,
894
+ xds_client(), chand()->server_.server_uri().c_str(), this,
844
895
  call_.get());
845
896
  }
846
897
  // If this is a reconnect, add any necessary subscriptions from what's
@@ -890,7 +941,7 @@ void XdsClient::ChannelState::AdsCallState::SendMessageLocked(
890
941
  gpr_log(GPR_INFO,
891
942
  "[xds_client %p] xds server %s: sending ADS request: type=%s "
892
943
  "version=%s nonce=%s error=%s",
893
- xds_client(), chand()->server_.server_uri.c_str(),
944
+ xds_client(), chand()->server_.server_uri().c_str(),
894
945
  std::string(type->type_url()).c_str(),
895
946
  chand()->resource_type_version_map_[type].c_str(),
896
947
  state.nonce.c_str(), state.status.ToString().c_str());
@@ -963,15 +1014,16 @@ void XdsClient::ChannelState::AdsCallState::OnRecvMessage(
963
1014
  gpr_log(GPR_ERROR,
964
1015
  "[xds_client %p] xds server %s: error parsing ADS response (%s) "
965
1016
  "-- ignoring",
966
- xds_client(), chand()->server_.server_uri.c_str(),
1017
+ xds_client(), chand()->server_.server_uri().c_str(),
967
1018
  status.ToString().c_str());
968
1019
  } else {
969
1020
  seen_response_ = true;
1021
+ chand()->status_ = absl::OkStatus();
970
1022
  AdsResponseParser::Result result = parser.TakeResult();
971
1023
  // Update nonce.
972
1024
  auto& state = state_map_[result.type];
973
1025
  state.nonce = result.nonce;
974
- // If we got an error, set state.error so that we'll NACK the update.
1026
+ // If we got an error, set state.status so that we'll NACK the update.
975
1027
  if (!result.errors.empty()) {
976
1028
  state.status = absl::UnavailableError(
977
1029
  absl::StrCat("xDS response validation errors: [",
@@ -980,7 +1032,7 @@ void XdsClient::ChannelState::AdsCallState::OnRecvMessage(
980
1032
  "[xds_client %p] xds server %s: ADS response invalid for "
981
1033
  "resource "
982
1034
  "type %s version %s, will NACK: nonce=%s status=%s",
983
- xds_client(), chand()->server_.server_uri.c_str(),
1035
+ xds_client(), chand()->server_.server_uri().c_str(),
984
1036
  result.type_url.c_str(), result.version.c_str(),
985
1037
  state.nonce.c_str(), state.status.ToString().c_str());
986
1038
  }
@@ -1015,7 +1067,7 @@ void XdsClient::ChannelState::AdsCallState::OnRecvMessage(
1015
1067
  gpr_log(GPR_ERROR,
1016
1068
  "[xds_client %p] xds server %s: ignoring deletion "
1017
1069
  "for resource type %s name %s",
1018
- xds_client(), chand()->server_.server_uri.c_str(),
1070
+ xds_client(), chand()->server_.server_uri().c_str(),
1019
1071
  result.type_url.c_str(),
1020
1072
  XdsClient::ConstructFullXdsResourceName(
1021
1073
  authority, result.type_url.c_str(), resource_key)
@@ -1057,17 +1109,16 @@ void XdsClient::ChannelState::AdsCallState::OnStatusReceived(
1057
1109
  gpr_log(GPR_INFO,
1058
1110
  "[xds_client %p] xds server %s: ADS call status received "
1059
1111
  "(chand=%p, ads_calld=%p, call=%p): %s",
1060
- xds_client(), chand()->server_.server_uri.c_str(), chand(), this,
1061
- call_.get(), status.ToString().c_str());
1112
+ xds_client(), chand()->server_.server_uri().c_str(), chand(),
1113
+ this, call_.get(), status.ToString().c_str());
1062
1114
  }
1063
1115
  // Ignore status from a stale call.
1064
1116
  if (IsCurrentCallOnChannel()) {
1065
1117
  // Try to restart the call.
1066
1118
  parent_->OnCallFinishedLocked();
1067
- // Send error to all watchers.
1068
- xds_client()->NotifyOnErrorLocked(absl::UnavailableError(absl::StrFormat(
1069
- "xDS call failed: xDS server: %s, ADS call status: %s",
1070
- chand()->server_.server_uri, status.ToString().c_str())));
1119
+ // Send error to all watchers for the channel.
1120
+ chand()->SetChannelStatusLocked(absl::UnavailableError(absl::StrFormat(
1121
+ "xDS call failed; status: %s", status.ToString().c_str())));
1071
1122
  }
1072
1123
  }
1073
1124
  xds_client()->work_serializer_.DrainQueue();
@@ -1159,7 +1210,7 @@ bool XdsClient::ChannelState::LrsCallState::Reporter::SendReportLocked() {
1159
1210
  last_report_counters_were_zero_ = LoadReportCountersAreZero(snapshot);
1160
1211
  if (old_val && last_report_counters_were_zero_) {
1161
1212
  auto it = xds_client()->xds_load_report_server_map_.find(
1162
- parent_->chand()->server_);
1213
+ &parent_->chand()->server_);
1163
1214
  if (it == xds_client()->xds_load_report_server_map_.end() ||
1164
1215
  it->second.load_report_map.empty()) {
1165
1216
  it->second.channel_state->StopLrsCallLocked();
@@ -1185,8 +1236,8 @@ void XdsClient::ChannelState::LrsCallState::Reporter::OnReportDoneLocked() {
1185
1236
  // we just ignore the completion and wait for the timer to fire.
1186
1237
  if (timer_handle_.has_value()) return;
1187
1238
  // If there are no more registered stats to report, cancel the call.
1188
- auto it =
1189
- xds_client()->xds_load_report_server_map_.find(parent_->chand()->server_);
1239
+ auto it = xds_client()->xds_load_report_server_map_.find(
1240
+ &parent_->chand()->server_);
1190
1241
  if (it == xds_client()->xds_load_report_server_map_.end()) return;
1191
1242
  if (it->second.load_report_map.empty()) {
1192
1243
  if (it->second.channel_state != nullptr) {
@@ -1229,7 +1280,7 @@ XdsClient::ChannelState::LrsCallState::LrsCallState(
1229
1280
  gpr_log(GPR_INFO,
1230
1281
  "[xds_client %p] xds server %s: starting LRS call (calld=%p, "
1231
1282
  "call=%p)",
1232
- xds_client(), chand()->server_.server_uri.c_str(), this,
1283
+ xds_client(), chand()->server_.server_uri().c_str(), this,
1233
1284
  call_.get());
1234
1285
  }
1235
1286
  // Send the initial request.
@@ -1293,7 +1344,7 @@ void XdsClient::ChannelState::LrsCallState::OnRecvMessage(
1293
1344
  if (!status.ok()) {
1294
1345
  gpr_log(GPR_ERROR,
1295
1346
  "[xds_client %p] xds server %s: LRS response parsing failed: %s",
1296
- xds_client(), chand()->server_.server_uri.c_str(),
1347
+ xds_client(), chand()->server_.server_uri().c_str(),
1297
1348
  status.ToString().c_str());
1298
1349
  return;
1299
1350
  }
@@ -1304,7 +1355,7 @@ void XdsClient::ChannelState::LrsCallState::OnRecvMessage(
1304
1355
  "[xds_client %p] xds server %s: LRS response received, %" PRIuPTR
1305
1356
  " cluster names, send_all_clusters=%d, load_report_interval=%" PRId64
1306
1357
  "ms",
1307
- xds_client(), chand()->server_.server_uri.c_str(),
1358
+ xds_client(), chand()->server_.server_uri().c_str(),
1308
1359
  new_cluster_names.size(), send_all_clusters,
1309
1360
  new_load_reporting_interval.millis());
1310
1361
  size_t i = 0;
@@ -1321,7 +1372,7 @@ void XdsClient::ChannelState::LrsCallState::OnRecvMessage(
1321
1372
  gpr_log(GPR_INFO,
1322
1373
  "[xds_client %p] xds server %s: increased load_report_interval "
1323
1374
  "to minimum value %dms",
1324
- xds_client(), chand()->server_.server_uri.c_str(),
1375
+ xds_client(), chand()->server_.server_uri().c_str(),
1325
1376
  GRPC_XDS_MIN_CLIENT_LOAD_REPORTING_INTERVAL_MS);
1326
1377
  }
1327
1378
  }
@@ -1333,7 +1384,7 @@ void XdsClient::ChannelState::LrsCallState::OnRecvMessage(
1333
1384
  gpr_log(GPR_INFO,
1334
1385
  "[xds_client %p] xds server %s: incoming LRS response identical "
1335
1386
  "to current, ignoring.",
1336
- xds_client(), chand()->server_.server_uri.c_str());
1387
+ xds_client(), chand()->server_.server_uri().c_str());
1337
1388
  }
1338
1389
  return;
1339
1390
  }
@@ -1354,7 +1405,7 @@ void XdsClient::ChannelState::LrsCallState::OnStatusReceived(
1354
1405
  gpr_log(GPR_INFO,
1355
1406
  "[xds_client %p] xds server %s: LRS call status received "
1356
1407
  "(chand=%p, calld=%p, call=%p): %s",
1357
- xds_client(), chand()->server_.server_uri.c_str(), chand(), this,
1408
+ xds_client(), chand()->server_.server_uri().c_str(), chand(), this,
1358
1409
  call_.get(), status.ToString().c_str());
1359
1410
  }
1360
1411
  // Ignore status from a stale call.
@@ -1389,6 +1440,7 @@ XdsClient::XdsClient(std::unique_ptr<XdsBootstrap> bootstrap,
1389
1440
  if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
1390
1441
  gpr_log(GPR_INFO, "[xds_client %p] creating xds client", this);
1391
1442
  }
1443
+ GPR_ASSERT(bootstrap_ != nullptr);
1392
1444
  }
1393
1445
 
1394
1446
  XdsClient::~XdsClient() {
@@ -1417,14 +1469,14 @@ void XdsClient::Orphan() {
1417
1469
 
1418
1470
  RefCountedPtr<XdsClient::ChannelState> XdsClient::GetOrCreateChannelStateLocked(
1419
1471
  const XdsBootstrap::XdsServer& server, const char* reason) {
1420
- auto it = xds_server_channel_map_.find(server);
1472
+ auto it = xds_server_channel_map_.find(&server);
1421
1473
  if (it != xds_server_channel_map_.end()) {
1422
1474
  return it->second->Ref(DEBUG_LOCATION, reason);
1423
1475
  }
1424
1476
  // Channel not found, so create a new one.
1425
1477
  auto channel_state = MakeRefCounted<ChannelState>(
1426
1478
  WeakRef(DEBUG_LOCATION, "ChannelState"), server);
1427
- xds_server_channel_map_[server] = channel_state.get();
1479
+ xds_server_channel_map_[&server] = channel_state.get();
1428
1480
  return channel_state;
1429
1481
  }
1430
1482
 
@@ -1440,17 +1492,16 @@ void XdsClient::WatchResource(const XdsResourceType* type,
1440
1492
  invalid_watchers_[w] = watcher;
1441
1493
  }
1442
1494
  work_serializer_.Run(
1443
- // TODO(yashykt): When we move to C++14, capture watcher using
1444
- // std::move()
1445
- [watcher, status]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(&work_serializer_) {
1446
- watcher->OnError(status);
1447
- },
1495
+ [watcher = std::move(watcher), status = std::move(status)]()
1496
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(&work_serializer_) {
1497
+ watcher->OnError(status);
1498
+ },
1448
1499
  DEBUG_LOCATION);
1449
1500
  };
1450
1501
  auto resource_name = ParseXdsResourceName(name, type);
1451
1502
  if (!resource_name.ok()) {
1452
- fail(absl::UnavailableError(absl::StrFormat(
1453
- "Unable to parse resource name for listener %s", name)));
1503
+ fail(absl::UnavailableError(
1504
+ absl::StrCat("Unable to parse resource name ", name)));
1454
1505
  return;
1455
1506
  }
1456
1507
  // Find server to use.
@@ -1464,9 +1515,7 @@ void XdsClient::WatchResource(const XdsResourceType* type,
1464
1515
  "\" not present in bootstrap config")));
1465
1516
  return;
1466
1517
  }
1467
- if (!authority->xds_servers.empty()) {
1468
- xds_server = &authority->xds_servers[0];
1469
- }
1518
+ xds_server = authority->server();
1470
1519
  }
1471
1520
  if (xds_server == nullptr) xds_server = &bootstrap_->server();
1472
1521
  {
@@ -1492,6 +1541,39 @@ void XdsClient::WatchResource(const XdsResourceType* type,
1492
1541
  delete value;
1493
1542
  },
1494
1543
  DEBUG_LOCATION);
1544
+ } else if (resource_state.meta.client_status ==
1545
+ XdsApi::ResourceMetadata::DOES_NOT_EXIST) {
1546
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
1547
+ gpr_log(GPR_INFO,
1548
+ "[xds_client %p] reporting cached does-not-exist for %s", this,
1549
+ std::string(name).c_str());
1550
+ }
1551
+ work_serializer_.Schedule(
1552
+ [watcher]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(&work_serializer_) {
1553
+ watcher->OnResourceDoesNotExist();
1554
+ },
1555
+ DEBUG_LOCATION);
1556
+ } else if (resource_state.meta.client_status ==
1557
+ XdsApi::ResourceMetadata::NACKED) {
1558
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
1559
+ gpr_log(
1560
+ GPR_INFO,
1561
+ "[xds_client %p] reporting cached validation failure for %s: %s",
1562
+ this, std::string(name).c_str(),
1563
+ resource_state.meta.failed_details.c_str());
1564
+ }
1565
+ std::string details = resource_state.meta.failed_details;
1566
+ const auto* node = bootstrap_->node();
1567
+ if (node != nullptr) {
1568
+ absl::StrAppend(&details, " (node ID:", bootstrap_->node()->id(), ")");
1569
+ }
1570
+ work_serializer_.Schedule(
1571
+ [watcher, details = std::move(details)]()
1572
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(&work_serializer_) {
1573
+ watcher->OnError(absl::UnavailableError(
1574
+ absl::StrCat("invalid resource: ", details)));
1575
+ },
1576
+ DEBUG_LOCATION);
1495
1577
  }
1496
1578
  // If the authority doesn't yet have a channel, set it, creating it if
1497
1579
  // needed.
@@ -1499,6 +1581,21 @@ void XdsClient::WatchResource(const XdsResourceType* type,
1499
1581
  authority_state.channel_state =
1500
1582
  GetOrCreateChannelStateLocked(*xds_server, "start watch");
1501
1583
  }
1584
+ absl::Status channel_status = authority_state.channel_state->status();
1585
+ if (!channel_status.ok()) {
1586
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
1587
+ gpr_log(GPR_INFO,
1588
+ "[xds_client %p] returning cached channel error for %s: %s",
1589
+ this, std::string(name).c_str(),
1590
+ channel_status.ToString().c_str());
1591
+ }
1592
+ work_serializer_.Schedule(
1593
+ [watcher = std::move(watcher), status = std::move(channel_status)]()
1594
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(&work_serializer_) mutable {
1595
+ watcher->OnError(std::move(status));
1596
+ },
1597
+ DEBUG_LOCATION);
1598
+ }
1502
1599
  authority_state.channel_state->SubscribeLocked(type, *resource_name);
1503
1600
  }
1504
1601
  work_serializer_.DrainQueue();
@@ -1616,7 +1713,8 @@ std::string XdsClient::ConstructFullXdsResourceName(
1616
1713
  RefCountedPtr<XdsClusterDropStats> XdsClient::AddClusterDropStats(
1617
1714
  const XdsBootstrap::XdsServer& xds_server, absl::string_view cluster_name,
1618
1715
  absl::string_view eds_service_name) {
1619
- if (!bootstrap_->XdsServerExists(xds_server)) return nullptr;
1716
+ const auto* server = bootstrap_->FindXdsServer(xds_server);
1717
+ if (server == nullptr) return nullptr;
1620
1718
  auto key =
1621
1719
  std::make_pair(std::string(cluster_name), std::string(eds_service_name));
1622
1720
  RefCountedPtr<XdsClusterDropStats> cluster_drop_stats;
@@ -1628,11 +1726,10 @@ RefCountedPtr<XdsClusterDropStats> XdsClient::AddClusterDropStats(
1628
1726
  // XdsBootstrap::XdsServer and strings
1629
1727
  // in the load_report_map_ key, so that they have the same lifetime.
1630
1728
  auto server_it =
1631
- xds_load_report_server_map_.emplace(xds_server, LoadReportServer())
1632
- .first;
1729
+ xds_load_report_server_map_.emplace(server, LoadReportServer()).first;
1633
1730
  if (server_it->second.channel_state == nullptr) {
1634
1731
  server_it->second.channel_state = GetOrCreateChannelStateLocked(
1635
- xds_server, "load report map (drop stats)");
1732
+ *server, "load report map (drop stats)");
1636
1733
  }
1637
1734
  auto load_report_it = server_it->second.load_report_map
1638
1735
  .emplace(std::move(key), LoadReportState())
@@ -1647,7 +1744,7 @@ RefCountedPtr<XdsClusterDropStats> XdsClient::AddClusterDropStats(
1647
1744
  load_report_state.drop_stats->GetSnapshotAndReset();
1648
1745
  }
1649
1746
  cluster_drop_stats = MakeRefCounted<XdsClusterDropStats>(
1650
- Ref(DEBUG_LOCATION, "DropStats"), server_it->first,
1747
+ Ref(DEBUG_LOCATION, "DropStats"), *server,
1651
1748
  load_report_it->first.first /*cluster_name*/,
1652
1749
  load_report_it->first.second /*eds_service_name*/);
1653
1750
  load_report_state.drop_stats = cluster_drop_stats.get();
@@ -1662,8 +1759,10 @@ void XdsClient::RemoveClusterDropStats(
1662
1759
  const XdsBootstrap::XdsServer& xds_server, absl::string_view cluster_name,
1663
1760
  absl::string_view eds_service_name,
1664
1761
  XdsClusterDropStats* cluster_drop_stats) {
1762
+ const auto* server = bootstrap_->FindXdsServer(xds_server);
1763
+ if (server == nullptr) return;
1665
1764
  MutexLock lock(&mu_);
1666
- auto server_it = xds_load_report_server_map_.find(xds_server);
1765
+ auto server_it = xds_load_report_server_map_.find(server);
1667
1766
  if (server_it == xds_load_report_server_map_.end()) return;
1668
1767
  auto load_report_it = server_it->second.load_report_map.find(
1669
1768
  std::make_pair(std::string(cluster_name), std::string(eds_service_name)));
@@ -1682,7 +1781,8 @@ RefCountedPtr<XdsClusterLocalityStats> XdsClient::AddClusterLocalityStats(
1682
1781
  const XdsBootstrap::XdsServer& xds_server, absl::string_view cluster_name,
1683
1782
  absl::string_view eds_service_name,
1684
1783
  RefCountedPtr<XdsLocalityName> locality) {
1685
- if (!bootstrap_->XdsServerExists(xds_server)) return nullptr;
1784
+ const auto* server = bootstrap_->FindXdsServer(xds_server);
1785
+ if (server == nullptr) return nullptr;
1686
1786
  auto key =
1687
1787
  std::make_pair(std::string(cluster_name), std::string(eds_service_name));
1688
1788
  RefCountedPtr<XdsClusterLocalityStats> cluster_locality_stats;
@@ -1694,11 +1794,10 @@ RefCountedPtr<XdsClusterLocalityStats> XdsClient::AddClusterLocalityStats(
1694
1794
  // XdsBootstrap::XdsServer and strings
1695
1795
  // in the load_report_map_ key, so that they have the same lifetime.
1696
1796
  auto server_it =
1697
- xds_load_report_server_map_.emplace(xds_server, LoadReportServer())
1698
- .first;
1797
+ xds_load_report_server_map_.emplace(server, LoadReportServer()).first;
1699
1798
  if (server_it->second.channel_state == nullptr) {
1700
1799
  server_it->second.channel_state = GetOrCreateChannelStateLocked(
1701
- xds_server, "load report map (locality stats)");
1800
+ *server, "load report map (locality stats)");
1702
1801
  }
1703
1802
  auto load_report_it = server_it->second.load_report_map
1704
1803
  .emplace(std::move(key), LoadReportState())
@@ -1715,7 +1814,7 @@ RefCountedPtr<XdsClusterLocalityStats> XdsClient::AddClusterLocalityStats(
1715
1814
  locality_state.locality_stats->GetSnapshotAndReset();
1716
1815
  }
1717
1816
  cluster_locality_stats = MakeRefCounted<XdsClusterLocalityStats>(
1718
- Ref(DEBUG_LOCATION, "LocalityStats"), server_it->first,
1817
+ Ref(DEBUG_LOCATION, "LocalityStats"), *server,
1719
1818
  load_report_it->first.first /*cluster_name*/,
1720
1819
  load_report_it->first.second /*eds_service_name*/,
1721
1820
  std::move(locality));
@@ -1732,8 +1831,10 @@ void XdsClient::RemoveClusterLocalityStats(
1732
1831
  absl::string_view eds_service_name,
1733
1832
  const RefCountedPtr<XdsLocalityName>& locality,
1734
1833
  XdsClusterLocalityStats* cluster_locality_stats) {
1834
+ const auto* server = bootstrap_->FindXdsServer(xds_server);
1835
+ if (server == nullptr) return;
1735
1836
  MutexLock lock(&mu_);
1736
- auto server_it = xds_load_report_server_map_.find(xds_server);
1837
+ auto server_it = xds_load_report_server_map_.find(server);
1737
1838
  if (server_it == xds_load_report_server_map_.end()) return;
1738
1839
  auto load_report_it = server_it->second.load_report_map.find(
1739
1840
  std::make_pair(std::string(cluster_name), std::string(eds_service_name)));
@@ -1758,34 +1859,6 @@ void XdsClient::ResetBackoff() {
1758
1859
  }
1759
1860
  }
1760
1861
 
1761
- void XdsClient::NotifyOnErrorLocked(absl::Status status) {
1762
- const auto* node = bootstrap_->node();
1763
- if (node != nullptr) {
1764
- status = absl::Status(
1765
- status.code(), absl::StrCat(status.message(),
1766
- " (node ID:", bootstrap_->node()->id, ")"));
1767
- }
1768
- std::set<RefCountedPtr<ResourceWatcherInterface>> watchers;
1769
- for (const auto& a : authority_state_map_) { // authority
1770
- for (const auto& t : a.second.resource_map) { // type
1771
- for (const auto& r : t.second) { // resource id
1772
- for (const auto& w : r.second.watchers) { // watchers
1773
- watchers.insert(w.second);
1774
- }
1775
- }
1776
- }
1777
- }
1778
- work_serializer_.Schedule(
1779
- // TODO(yashykt): When we move to C++14, capture watchers using
1780
- // std::move()
1781
- [watchers, status]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(work_serializer_) {
1782
- for (const auto& watcher : watchers) {
1783
- watcher->OnError(status);
1784
- }
1785
- },
1786
- DEBUG_LOCATION);
1787
- }
1788
-
1789
1862
  void XdsClient::NotifyWatchersOnErrorLocked(
1790
1863
  const std::map<ResourceWatcherInterface*,
1791
1864
  RefCountedPtr<ResourceWatcherInterface>>& watchers,
@@ -1793,15 +1866,16 @@ void XdsClient::NotifyWatchersOnErrorLocked(
1793
1866
  const auto* node = bootstrap_->node();
1794
1867
  if (node != nullptr) {
1795
1868
  status = absl::Status(
1796
- status.code(), absl::StrCat(status.message(),
1797
- " (node ID:", bootstrap_->node()->id, ")"));
1869
+ status.code(),
1870
+ absl::StrCat(status.message(), " (node ID:", node->id(), ")"));
1798
1871
  }
1799
1872
  work_serializer_.Schedule(
1800
- [watchers, status]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(&work_serializer_) {
1801
- for (const auto& p : watchers) {
1802
- p.first->OnError(status);
1803
- }
1804
- },
1873
+ [watchers, status = std::move(status)]()
1874
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(&work_serializer_) {
1875
+ for (const auto& p : watchers) {
1876
+ p.first->OnError(status);
1877
+ }
1878
+ },
1805
1879
  DEBUG_LOCATION);
1806
1880
  }
1807
1881
 
@@ -1824,7 +1898,7 @@ XdsApi::ClusterLoadReportMap XdsClient::BuildLoadReportSnapshotLocked(
1824
1898
  gpr_log(GPR_INFO, "[xds_client %p] start building load report", this);
1825
1899
  }
1826
1900
  XdsApi::ClusterLoadReportMap snapshot_map;
1827
- auto server_it = xds_load_report_server_map_.find(xds_server);
1901
+ auto server_it = xds_load_report_server_map_.find(&xds_server);
1828
1902
  if (server_it == xds_load_report_server_map_.end()) return snapshot_map;
1829
1903
  auto& load_report_map = server_it->second.load_report_map;
1830
1904
  for (auto load_report_it = load_report_map.begin();
@@ -1883,7 +1957,7 @@ XdsApi::ClusterLoadReportMap XdsClient::BuildLoadReportSnapshotLocked(
1883
1957
  }
1884
1958
  }
1885
1959
  // Compute load report interval.
1886
- const Timestamp now = ExecCtx::Get()->Now();
1960
+ const Timestamp now = Timestamp::Now();
1887
1961
  snapshot.load_report_interval = now - load_report.last_report_time;
1888
1962
  load_report.last_report_time = now;
1889
1963
  // Record snapshot.