grpc 1.28.0.pre2 → 1.31.0.pre1

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 (660) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +8313 -11862
  3. data/include/grpc/grpc.h +2 -2
  4. data/include/grpc/grpc_security.h +30 -9
  5. data/include/grpc/grpc_security_constants.h +4 -0
  6. data/include/grpc/impl/codegen/grpc_types.h +23 -23
  7. data/include/grpc/impl/codegen/port_platform.h +6 -34
  8. data/include/grpc/module.modulemap +24 -39
  9. data/src/core/ext/filters/client_channel/backend_metric.cc +18 -12
  10. data/src/core/ext/filters/client_channel/client_channel.cc +618 -482
  11. data/src/core/ext/filters/client_channel/client_channel_plugin.cc +3 -2
  12. data/src/core/ext/filters/client_channel/config_selector.cc +62 -0
  13. data/src/core/ext/filters/client_channel/config_selector.h +93 -0
  14. data/src/core/ext/filters/client_channel/global_subchannel_pool.cc +24 -2
  15. data/src/core/ext/filters/client_channel/health/health_check_client.cc +9 -22
  16. data/src/core/ext/filters/client_channel/health/health_check_client.h +3 -3
  17. data/src/core/ext/filters/client_channel/http_connect_handshaker.cc +6 -5
  18. data/src/core/ext/filters/client_channel/http_proxy.cc +23 -14
  19. data/src/core/ext/filters/client_channel/lb_policy.cc +19 -18
  20. data/src/core/ext/filters/client_channel/lb_policy.h +44 -33
  21. data/src/core/ext/filters/client_channel/lb_policy/address_filtering.cc +83 -0
  22. data/src/core/ext/filters/client_channel/lb_policy/address_filtering.h +99 -0
  23. data/src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc +297 -0
  24. data/src/core/ext/filters/client_channel/lb_policy/child_policy_handler.h +83 -0
  25. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +311 -497
  26. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc +89 -0
  27. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.h +40 -0
  28. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc +11 -9
  29. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h +3 -2
  30. data/src/core/ext/filters/client_channel/lb_policy/priority/priority.cc +871 -0
  31. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +1 -1
  32. data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +9 -17
  33. data/src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc +734 -0
  34. data/src/core/ext/filters/client_channel/lb_policy/xds/cds.cc +117 -41
  35. data/src/core/ext/filters/client_channel/lb_policy/xds/eds.cc +938 -0
  36. data/src/core/ext/filters/client_channel/lb_policy/xds/lrs.cc +528 -0
  37. data/src/core/ext/filters/client_channel/lb_policy/xds/xds.h +1 -2
  38. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_routing.cc +1142 -0
  39. data/src/core/ext/filters/client_channel/lb_policy_registry.cc +10 -7
  40. data/src/core/ext/filters/client_channel/local_subchannel_pool.h +2 -1
  41. data/src/core/ext/filters/client_channel/parse_address.cc +22 -21
  42. data/src/core/ext/filters/client_channel/resolver.cc +5 -8
  43. data/src/core/ext/filters/client_channel/resolver.h +12 -14
  44. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +78 -61
  45. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc +41 -40
  46. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h +8 -7
  47. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc +22 -24
  48. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc +12 -10
  49. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +79 -122
  50. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +199 -163
  51. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h +5 -3
  52. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc +7 -4
  53. data/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +46 -45
  54. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +93 -102
  55. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h +0 -4
  56. data/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc +2 -2
  57. data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc +64 -12
  58. data/src/core/ext/filters/client_channel/resolver_factory.h +2 -2
  59. data/src/core/ext/filters/client_channel/resolver_registry.cc +19 -17
  60. data/src/core/ext/filters/client_channel/resolver_registry.h +8 -8
  61. data/src/core/ext/filters/client_channel/resolver_result_parsing.cc +21 -22
  62. data/src/core/ext/filters/client_channel/resolver_result_parsing.h +19 -16
  63. data/src/core/ext/filters/client_channel/resolving_lb_policy.cc +73 -217
  64. data/src/core/ext/filters/client_channel/resolving_lb_policy.h +45 -27
  65. data/src/core/ext/filters/client_channel/server_address.cc +6 -9
  66. data/src/core/ext/filters/client_channel/server_address.h +6 -12
  67. data/src/core/ext/filters/client_channel/service_config.cc +104 -144
  68. data/src/core/ext/filters/client_channel/service_config.h +28 -98
  69. data/src/core/ext/filters/client_channel/service_config_call_data.h +68 -0
  70. data/src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc +142 -0
  71. data/src/core/ext/filters/client_channel/service_config_parser.cc +87 -0
  72. data/src/core/ext/filters/client_channel/service_config_parser.h +89 -0
  73. data/src/core/ext/filters/client_channel/subchannel.cc +55 -25
  74. data/src/core/ext/filters/client_channel/subchannel.h +35 -11
  75. data/src/core/ext/filters/client_channel/xds/xds_api.cc +1200 -246
  76. data/src/core/ext/filters/client_channel/xds/xds_api.h +130 -44
  77. data/src/core/ext/filters/client_channel/xds/xds_bootstrap.cc +90 -29
  78. data/src/core/ext/filters/client_channel/xds/xds_bootstrap.h +9 -4
  79. data/src/core/ext/filters/client_channel/xds/xds_channel_secure.cc +4 -2
  80. data/src/core/ext/filters/client_channel/xds/xds_client.cc +839 -431
  81. data/src/core/ext/filters/client_channel/xds/xds_client.h +84 -33
  82. data/src/core/ext/filters/client_channel/xds/xds_client_stats.cc +11 -12
  83. data/src/core/ext/filters/client_channel/xds/xds_client_stats.h +40 -28
  84. data/src/core/ext/filters/http/client/http_client_filter.cc +28 -33
  85. data/src/core/ext/filters/http/client_authority_filter.cc +4 -4
  86. data/src/core/ext/filters/http/http_filters_plugin.cc +28 -12
  87. data/src/core/ext/filters/http/message_compress/message_compress_filter.cc +258 -221
  88. data/src/core/ext/filters/http/message_compress/message_decompress_filter.cc +399 -0
  89. data/src/core/ext/filters/http/message_compress/message_decompress_filter.h +31 -0
  90. data/src/core/ext/filters/message_size/message_size_filter.cc +61 -88
  91. data/src/core/ext/filters/message_size/message_size_filter.h +10 -4
  92. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +386 -350
  93. data/src/core/ext/transport/chttp2/server/chttp2_server.h +6 -2
  94. data/src/core/ext/transport/chttp2/server/insecure/server_chttp2.cc +1 -1
  95. data/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc +7 -13
  96. data/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc +7 -8
  97. data/src/core/ext/transport/chttp2/transport/bin_encoder.cc +4 -6
  98. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +42 -26
  99. data/src/core/ext/transport/chttp2/transport/chttp2_transport.h +1 -0
  100. data/src/core/ext/transport/chttp2/transport/flow_control.cc +25 -30
  101. data/src/core/ext/transport/chttp2/transport/flow_control.h +14 -16
  102. data/src/core/ext/transport/chttp2/transport/frame_data.cc +9 -12
  103. data/src/core/ext/transport/chttp2/transport/frame_goaway.cc +4 -6
  104. data/src/core/ext/transport/chttp2/transport/frame_goaway.h +2 -3
  105. data/src/core/ext/transport/chttp2/transport/frame_ping.cc +5 -6
  106. data/src/core/ext/transport/chttp2/transport/frame_ping.h +2 -3
  107. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +12 -13
  108. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.h +2 -3
  109. data/src/core/ext/transport/chttp2/transport/frame_settings.cc +6 -7
  110. data/src/core/ext/transport/chttp2/transport/frame_settings.h +2 -3
  111. data/src/core/ext/transport/chttp2/transport/frame_window_update.cc +9 -12
  112. data/src/core/ext/transport/chttp2/transport/frame_window_update.h +2 -3
  113. data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +29 -16
  114. data/src/core/ext/transport/chttp2/transport/hpack_encoder.h +2 -3
  115. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +25 -29
  116. data/src/core/ext/transport/chttp2/transport/hpack_parser.h +2 -3
  117. data/src/core/ext/transport/chttp2/transport/hpack_table.cc +13 -17
  118. data/src/core/ext/transport/chttp2/transport/hpack_table.h +2 -2
  119. data/src/core/ext/transport/chttp2/transport/http2_settings.h +4 -5
  120. data/src/core/ext/transport/chttp2/transport/huffsyms.h +2 -3
  121. data/src/core/ext/transport/chttp2/transport/internal.h +27 -21
  122. data/src/core/ext/transport/chttp2/transport/parsing.cc +33 -43
  123. data/src/core/ext/transport/chttp2/transport/stream_map.h +2 -3
  124. data/src/core/ext/transport/chttp2/transport/writing.cc +24 -22
  125. data/src/core/ext/transport/inproc/inproc_transport.cc +54 -15
  126. data/src/core/ext/upb-generated/envoy/annotations/deprecation.upb.h +0 -1
  127. data/src/core/ext/upb-generated/envoy/annotations/resource.upb.h +3 -4
  128. data/src/core/ext/upb-generated/envoy/api/v2/auth/cert.upb.c +4 -229
  129. data/src/core/ext/upb-generated/envoy/api/v2/auth/cert.upb.h +5 -876
  130. data/src/core/ext/upb-generated/envoy/api/v2/auth/common.upb.c +114 -0
  131. data/src/core/ext/upb-generated/envoy/api/v2/auth/common.upb.h +429 -0
  132. data/src/core/ext/upb-generated/envoy/api/v2/auth/secret.upb.c +72 -0
  133. data/src/core/ext/upb-generated/envoy/api/v2/auth/secret.upb.h +198 -0
  134. data/src/core/ext/upb-generated/envoy/api/v2/auth/tls.upb.c +105 -0
  135. data/src/core/ext/upb-generated/envoy/api/v2/auth/tls.upb.h +388 -0
  136. data/src/core/ext/upb-generated/envoy/api/v2/cds.upb.c +1 -0
  137. data/src/core/ext/upb-generated/envoy/api/v2/cds.upb.h +1 -2
  138. data/src/core/ext/upb-generated/envoy/api/v2/cluster.upb.c +23 -10
  139. data/src/core/ext/upb-generated/envoy/api/v2/cluster.upb.h +352 -310
  140. data/src/core/ext/upb-generated/envoy/api/v2/cluster/circuit_breaker.upb.c +1 -0
  141. data/src/core/ext/upb-generated/envoy/api/v2/cluster/circuit_breaker.upb.h +42 -34
  142. data/src/core/ext/upb-generated/envoy/api/v2/cluster/filter.upb.c +1 -0
  143. data/src/core/ext/upb-generated/envoy/api/v2/cluster/filter.upb.h +7 -7
  144. data/src/core/ext/upb-generated/envoy/api/v2/cluster/outlier_detection.upb.c +1 -0
  145. data/src/core/ext/upb-generated/envoy/api/v2/cluster/outlier_detection.upb.h +79 -61
  146. data/src/core/ext/upb-generated/envoy/api/v2/core/address.upb.c +2 -1
  147. data/src/core/ext/upb-generated/envoy/api/v2/core/address.upb.h +55 -49
  148. data/src/core/ext/upb-generated/envoy/api/v2/core/backoff.upb.c +35 -0
  149. data/src/core/ext/upb-generated/envoy/api/v2/core/backoff.upb.h +79 -0
  150. data/src/core/ext/upb-generated/envoy/api/v2/core/base.upb.c +48 -27
  151. data/src/core/ext/upb-generated/envoy/api/v2/core/base.upb.h +258 -214
  152. data/src/core/ext/upb-generated/envoy/api/v2/core/config_source.upb.c +1 -0
  153. data/src/core/ext/upb-generated/envoy/api/v2/core/config_source.upb.h +51 -45
  154. data/src/core/ext/upb-generated/envoy/api/v2/core/event_service_config.upb.c +34 -0
  155. data/src/core/ext/upb-generated/envoy/api/v2/core/event_service_config.upb.h +71 -0
  156. data/src/core/ext/upb-generated/envoy/api/v2/core/grpc_service.upb.c +2 -1
  157. data/src/core/ext/upb-generated/envoy/api/v2/core/grpc_service.upb.h +107 -100
  158. data/src/core/ext/upb-generated/envoy/api/v2/core/health_check.upb.c +24 -20
  159. data/src/core/ext/upb-generated/envoy/api/v2/core/health_check.upb.h +157 -122
  160. data/src/core/ext/upb-generated/envoy/api/v2/core/http_uri.upb.c +1 -0
  161. data/src/core/ext/upb-generated/envoy/api/v2/core/http_uri.upb.h +9 -9
  162. data/src/core/ext/upb-generated/envoy/api/v2/core/protocol.upb.c +38 -18
  163. data/src/core/ext/upb-generated/envoy/api/v2/core/protocol.upb.h +173 -73
  164. data/src/core/ext/upb-generated/envoy/api/v2/core/socket_option.upb.c +34 -0
  165. data/src/core/ext/upb-generated/envoy/api/v2/core/socket_option.upb.h +88 -0
  166. data/src/core/ext/upb-generated/envoy/api/v2/discovery.upb.c +2 -1
  167. data/src/core/ext/upb-generated/envoy/api/v2/discovery.upb.h +95 -101
  168. data/src/core/ext/upb-generated/envoy/api/v2/eds.upb.c +1 -0
  169. data/src/core/ext/upb-generated/envoy/api/v2/eds.upb.h +1 -2
  170. data/src/core/ext/upb-generated/envoy/api/v2/endpoint.upb.c +2 -1
  171. data/src/core/ext/upb-generated/envoy/api/v2/endpoint.upb.h +49 -65
  172. data/src/core/ext/upb-generated/envoy/api/v2/endpoint/endpoint.upb.c +1 -0
  173. data/src/core/ext/upb-generated/envoy/api/v2/endpoint/endpoint.upb.h +0 -1
  174. data/src/core/ext/upb-generated/envoy/api/v2/endpoint/endpoint_components.upb.c +9 -6
  175. data/src/core/ext/upb-generated/envoy/api/v2/endpoint/endpoint_components.upb.h +53 -38
  176. data/src/core/ext/upb-generated/envoy/api/v2/endpoint/load_report.upb.c +1 -0
  177. data/src/core/ext/upb-generated/envoy/api/v2/endpoint/load_report.upb.h +70 -62
  178. data/src/core/ext/upb-generated/envoy/api/v2/lds.upb.c +1 -0
  179. data/src/core/ext/upb-generated/envoy/api/v2/lds.upb.h +1 -2
  180. data/src/core/ext/upb-generated/envoy/api/v2/listener.upb.c +15 -10
  181. data/src/core/ext/upb-generated/envoy/api/v2/listener.upb.h +95 -63
  182. data/src/core/ext/upb-generated/envoy/api/v2/listener/listener.upb.c +1 -0
  183. data/src/core/ext/upb-generated/envoy/api/v2/listener/listener.upb.h +0 -1
  184. data/src/core/ext/upb-generated/envoy/api/v2/listener/listener_components.upb.c +3 -2
  185. data/src/core/ext/upb-generated/envoy/api/v2/listener/listener_components.upb.h +91 -80
  186. data/src/core/ext/upb-generated/envoy/api/v2/listener/udp_listener_config.upb.c +1 -0
  187. data/src/core/ext/upb-generated/envoy/api/v2/listener/udp_listener_config.upb.h +9 -10
  188. data/src/core/ext/upb-generated/envoy/api/v2/rds.upb.c +1 -0
  189. data/src/core/ext/upb-generated/envoy/api/v2/rds.upb.h +1 -2
  190. data/src/core/ext/upb-generated/envoy/api/v2/route.upb.c +1 -0
  191. data/src/core/ext/upb-generated/envoy/api/v2/route.upb.h +36 -31
  192. data/src/core/ext/upb-generated/envoy/api/v2/route/route.upb.c +1 -0
  193. data/src/core/ext/upb-generated/envoy/api/v2/route/route.upb.h +0 -1
  194. data/src/core/ext/upb-generated/envoy/api/v2/route/route_components.upb.c +68 -46
  195. data/src/core/ext/upb-generated/envoy/api/v2/route/route_components.upb.h +770 -722
  196. data/src/core/ext/upb-generated/envoy/api/v2/scoped_route.upb.c +1 -0
  197. data/src/core/ext/upb-generated/envoy/api/v2/scoped_route.upb.h +16 -15
  198. data/src/core/ext/upb-generated/envoy/api/v2/srds.upb.c +1 -0
  199. data/src/core/ext/upb-generated/envoy/api/v2/srds.upb.h +1 -2
  200. data/src/core/ext/upb-generated/envoy/config/filter/accesslog/v2/accesslog.upb.c +2 -1
  201. data/src/core/ext/upb-generated/envoy/config/filter/accesslog/v2/accesslog.upb.h +95 -88
  202. data/src/core/ext/upb-generated/envoy/config/filter/network/http_connection_manager/v2/http_connection_manager.upb.c +48 -28
  203. data/src/core/ext/upb-generated/envoy/config/filter/network/http_connection_manager/v2/http_connection_manager.upb.h +305 -210
  204. data/src/core/ext/upb-generated/envoy/config/listener/v2/api_listener.upb.c +1 -0
  205. data/src/core/ext/upb-generated/envoy/config/listener/v2/api_listener.upb.h +5 -5
  206. data/src/core/ext/upb-generated/envoy/config/trace/v2/http_tracer.upb.c +51 -0
  207. data/src/core/ext/upb-generated/envoy/config/trace/v2/http_tracer.upb.h +125 -0
  208. data/src/core/ext/upb-generated/envoy/service/discovery/v2/ads.upb.c +1 -0
  209. data/src/core/ext/upb-generated/envoy/service/discovery/v2/ads.upb.h +1 -2
  210. data/src/core/ext/upb-generated/envoy/service/load_stats/v2/lrs.upb.c +4 -2
  211. data/src/core/ext/upb-generated/envoy/service/load_stats/v2/lrs.upb.h +22 -16
  212. data/src/core/ext/upb-generated/envoy/type/http.upb.c +1 -0
  213. data/src/core/ext/upb-generated/envoy/type/http.upb.h +0 -1
  214. data/src/core/ext/upb-generated/envoy/type/matcher/regex.upb.c +16 -0
  215. data/src/core/ext/upb-generated/envoy/type/matcher/regex.upb.h +48 -11
  216. data/src/core/ext/upb-generated/envoy/type/matcher/string.upb.c +1 -0
  217. data/src/core/ext/upb-generated/envoy/type/matcher/string.upb.h +14 -14
  218. data/src/core/ext/upb-generated/envoy/type/metadata/v2/metadata.upb.c +1 -0
  219. data/src/core/ext/upb-generated/envoy/type/metadata/v2/metadata.upb.h +23 -23
  220. data/src/core/ext/upb-generated/envoy/type/percent.upb.c +1 -0
  221. data/src/core/ext/upb-generated/envoy/type/percent.upb.h +8 -9
  222. data/src/core/ext/upb-generated/envoy/type/range.upb.c +1 -0
  223. data/src/core/ext/upb-generated/envoy/type/range.upb.h +15 -16
  224. data/src/core/ext/upb-generated/envoy/type/semantic_version.upb.c +1 -0
  225. data/src/core/ext/upb-generated/envoy/type/semantic_version.upb.h +7 -8
  226. data/src/core/ext/upb-generated/envoy/type/tracing/v2/custom_tag.upb.c +1 -0
  227. data/src/core/ext/upb-generated/envoy/type/tracing/v2/custom_tag.upb.h +36 -35
  228. data/src/core/ext/upb-generated/gogoproto/gogo.upb.h +0 -1
  229. data/src/core/ext/upb-generated/google/api/annotations.upb.h +0 -1
  230. data/src/core/ext/upb-generated/google/api/http.upb.h +29 -28
  231. data/src/core/ext/upb-generated/google/protobuf/any.upb.h +5 -6
  232. data/src/core/ext/upb-generated/google/protobuf/descriptor.upb.c +12 -11
  233. data/src/core/ext/upb-generated/google/protobuf/descriptor.upb.h +421 -389
  234. data/src/core/ext/upb-generated/google/protobuf/duration.upb.h +5 -6
  235. data/src/core/ext/upb-generated/google/protobuf/empty.upb.h +1 -2
  236. data/src/core/ext/upb-generated/google/protobuf/struct.upb.c +1 -1
  237. data/src/core/ext/upb-generated/google/protobuf/struct.upb.h +33 -54
  238. data/src/core/ext/upb-generated/google/protobuf/timestamp.upb.h +5 -6
  239. data/src/core/ext/upb-generated/google/protobuf/wrappers.upb.h +27 -28
  240. data/src/core/ext/upb-generated/google/rpc/status.upb.h +8 -8
  241. data/src/core/ext/upb-generated/src/proto/grpc/gcp/altscontext.upb.c +1 -1
  242. data/src/core/ext/upb-generated/src/proto/grpc/gcp/altscontext.upb.h +32 -45
  243. data/src/core/ext/upb-generated/src/proto/grpc/gcp/handshaker.upb.c +4 -4
  244. data/src/core/ext/upb-generated/src/proto/grpc/gcp/handshaker.upb.h +157 -178
  245. data/src/core/ext/upb-generated/src/proto/grpc/gcp/transport_security_common.upb.h +14 -13
  246. data/src/core/ext/upb-generated/src/proto/grpc/health/v1/health.upb.h +6 -7
  247. data/src/core/ext/upb-generated/src/proto/grpc/lb/v1/load_balancer.upb.h +59 -56
  248. data/src/core/ext/upb-generated/udpa/annotations/migrate.upb.h +11 -12
  249. data/src/core/ext/upb-generated/udpa/annotations/sensitive.upb.h +0 -1
  250. data/src/core/ext/upb-generated/udpa/annotations/status.upb.c +28 -0
  251. data/src/core/ext/upb-generated/udpa/annotations/status.upb.h +64 -0
  252. data/src/core/ext/upb-generated/udpa/data/orca/v1/orca_load_report.upb.c +6 -6
  253. data/src/core/ext/upb-generated/udpa/data/orca/v1/orca_load_report.upb.h +41 -68
  254. data/src/core/ext/upb-generated/validate/validate.upb.c +21 -20
  255. data/src/core/ext/upb-generated/validate/validate.upb.h +569 -562
  256. data/src/core/lib/channel/channel_args.cc +15 -14
  257. data/src/core/lib/channel/channel_args.h +3 -1
  258. data/src/core/lib/channel/channel_stack.h +20 -13
  259. data/src/core/lib/channel/channel_trace.cc +2 -6
  260. data/src/core/lib/channel/channelz.cc +10 -21
  261. data/src/core/lib/channel/channelz.h +3 -2
  262. data/src/core/lib/channel/channelz_registry.cc +5 -3
  263. data/src/core/lib/channel/connected_channel.cc +7 -5
  264. data/src/core/lib/channel/context.h +1 -1
  265. data/src/core/lib/channel/handshaker.cc +11 -13
  266. data/src/core/lib/channel/handshaker.h +4 -2
  267. data/src/core/lib/channel/handshaker_registry.cc +5 -17
  268. data/src/core/lib/channel/status_util.cc +2 -3
  269. data/src/core/lib/compression/message_compress.cc +5 -1
  270. data/src/core/lib/debug/stats.cc +21 -27
  271. data/src/core/lib/debug/stats.h +3 -1
  272. data/src/core/lib/gpr/log_linux.cc +6 -8
  273. data/src/core/lib/gpr/log_posix.cc +6 -8
  274. data/src/core/lib/gpr/spinlock.h +2 -3
  275. data/src/core/lib/gpr/string.cc +10 -33
  276. data/src/core/lib/gpr/string.h +4 -18
  277. data/src/core/lib/gpr/sync_abseil.cc +2 -0
  278. data/src/core/lib/gpr/time.cc +4 -0
  279. data/src/core/lib/gpr/time_posix.cc +1 -1
  280. data/src/core/lib/gprpp/atomic.h +6 -6
  281. data/src/core/lib/gprpp/fork.cc +1 -1
  282. data/src/core/lib/gprpp/global_config_env.cc +8 -6
  283. data/src/core/lib/gprpp/host_port.cc +29 -35
  284. data/src/core/lib/gprpp/host_port.h +14 -17
  285. data/src/core/lib/gprpp/map.h +5 -11
  286. data/src/core/lib/gprpp/ref_counted_ptr.h +5 -0
  287. data/src/core/lib/gprpp/sync.h +9 -0
  288. data/src/core/lib/http/format_request.cc +46 -65
  289. data/src/core/lib/http/httpcli.cc +15 -13
  290. data/src/core/lib/http/httpcli.h +2 -3
  291. data/src/core/lib/http/httpcli_security_connector.cc +10 -10
  292. data/src/core/lib/http/parser.h +2 -3
  293. data/src/core/lib/iomgr/buffer_list.h +22 -21
  294. data/src/core/lib/iomgr/call_combiner.h +3 -2
  295. data/src/core/lib/iomgr/cfstream_handle.cc +4 -2
  296. data/src/core/lib/iomgr/closure.h +2 -3
  297. data/src/core/lib/iomgr/dualstack_socket_posix.cc +47 -0
  298. data/src/core/lib/iomgr/endpoint_cfstream.cc +2 -3
  299. data/src/core/lib/iomgr/endpoint_pair.h +2 -3
  300. data/src/core/lib/iomgr/endpoint_pair_posix.cc +10 -10
  301. data/src/core/lib/iomgr/error.cc +6 -9
  302. data/src/core/lib/iomgr/error.h +0 -1
  303. data/src/core/lib/iomgr/error_cfstream.cc +9 -8
  304. data/src/core/lib/iomgr/ev_apple.cc +356 -0
  305. data/src/core/lib/iomgr/ev_apple.h +43 -0
  306. data/src/core/lib/iomgr/ev_epoll1_linux.cc +25 -29
  307. data/src/core/lib/iomgr/ev_epollex_linux.cc +17 -24
  308. data/src/core/lib/iomgr/ev_poll_posix.cc +9 -8
  309. data/src/core/lib/iomgr/ev_posix.cc +4 -3
  310. data/src/core/lib/iomgr/exec_ctx.h +14 -2
  311. data/src/core/lib/iomgr/iomgr.cc +10 -0
  312. data/src/core/lib/iomgr/iomgr.h +10 -0
  313. data/src/core/lib/iomgr/iomgr_posix_cfstream.cc +84 -20
  314. data/src/core/lib/iomgr/is_epollexclusive_available.cc +14 -0
  315. data/src/core/lib/iomgr/pollset_set_custom.cc +10 -10
  316. data/src/core/lib/{gprpp/optional.h → iomgr/pollset_uv.h} +11 -12
  317. data/src/core/lib/iomgr/port.h +2 -21
  318. data/src/core/lib/iomgr/python_util.h +46 -0
  319. data/src/core/lib/iomgr/resolve_address.h +4 -6
  320. data/src/core/lib/iomgr/resolve_address_custom.cc +42 -57
  321. data/src/core/lib/iomgr/resolve_address_custom.h +4 -2
  322. data/src/core/lib/iomgr/resolve_address_posix.cc +10 -11
  323. data/src/core/lib/iomgr/resolve_address_windows.cc +16 -25
  324. data/src/core/lib/iomgr/resource_quota.cc +38 -37
  325. data/src/core/lib/iomgr/sockaddr_utils.cc +29 -33
  326. data/src/core/lib/iomgr/sockaddr_utils.h +10 -15
  327. data/src/core/lib/iomgr/socket_factory_posix.h +2 -3
  328. data/src/core/lib/iomgr/socket_mutator.h +2 -3
  329. data/src/core/lib/iomgr/socket_utils_common_posix.cc +102 -81
  330. data/src/core/lib/iomgr/socket_utils_posix.h +3 -0
  331. data/src/core/lib/iomgr/socket_windows.cc +4 -5
  332. data/src/core/lib/iomgr/tcp_client_cfstream.cc +14 -18
  333. data/src/core/lib/iomgr/tcp_client_custom.cc +6 -9
  334. data/src/core/lib/iomgr/tcp_client_posix.cc +30 -36
  335. data/src/core/lib/iomgr/tcp_client_windows.cc +10 -11
  336. data/src/core/lib/iomgr/tcp_custom.cc +3 -4
  337. data/src/core/lib/iomgr/tcp_custom.h +1 -1
  338. data/src/core/lib/iomgr/tcp_server.cc +3 -4
  339. data/src/core/lib/iomgr/tcp_server.h +7 -5
  340. data/src/core/lib/iomgr/tcp_server_custom.cc +11 -23
  341. data/src/core/lib/iomgr/tcp_server_posix.cc +38 -44
  342. data/src/core/lib/iomgr/tcp_server_utils_posix.h +3 -4
  343. data/src/core/lib/iomgr/tcp_server_utils_posix_common.cc +7 -8
  344. data/src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.cc +10 -18
  345. data/src/core/lib/iomgr/tcp_server_windows.cc +16 -16
  346. data/src/core/lib/iomgr/tcp_uv.cc +3 -2
  347. data/src/core/lib/iomgr/time_averaged_stats.h +2 -3
  348. data/src/core/lib/iomgr/timer_generic.cc +15 -15
  349. data/src/core/lib/{gprpp/inlined_vector.h → iomgr/timer_generic.h} +19 -17
  350. data/src/core/lib/iomgr/timer_heap.h +2 -3
  351. data/src/core/lib/iomgr/udp_server.cc +32 -36
  352. data/src/core/lib/iomgr/udp_server.h +5 -2
  353. data/src/core/lib/iomgr/unix_sockets_posix.cc +9 -14
  354. data/src/core/lib/iomgr/unix_sockets_posix.h +3 -1
  355. data/src/core/lib/iomgr/unix_sockets_posix_noop.cc +5 -2
  356. data/src/core/lib/json/json.h +3 -2
  357. data/src/core/lib/json/json_reader.cc +25 -26
  358. data/src/core/lib/json/json_writer.cc +13 -12
  359. data/src/core/lib/security/credentials/composite/composite_credentials.cc +12 -0
  360. data/src/core/lib/security/credentials/composite/composite_credentials.h +6 -3
  361. data/src/core/lib/security/credentials/credentials.cc +0 -84
  362. data/src/core/lib/security/credentials/credentials.h +13 -62
  363. data/src/core/lib/security/credentials/fake/fake_credentials.h +4 -0
  364. data/src/core/lib/security/credentials/google_default/credentials_generic.cc +8 -6
  365. data/src/core/lib/security/credentials/google_default/google_default_credentials.cc +15 -17
  366. data/src/core/lib/security/credentials/iam/iam_credentials.cc +8 -6
  367. data/src/core/lib/security/credentials/iam/iam_credentials.h +4 -0
  368. data/src/core/lib/security/credentials/jwt/json_token.cc +1 -1
  369. data/src/core/lib/security/credentials/jwt/json_token.h +2 -5
  370. data/src/core/lib/security/credentials/jwt/jwt_credentials.cc +7 -4
  371. data/src/core/lib/security/credentials/jwt/jwt_credentials.h +12 -0
  372. data/src/core/lib/security/credentials/jwt/jwt_verifier.cc +8 -15
  373. data/src/core/lib/security/credentials/jwt/jwt_verifier.h +2 -3
  374. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +73 -54
  375. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.h +9 -3
  376. data/src/core/lib/security/credentials/plugin/plugin_credentials.cc +19 -6
  377. data/src/core/lib/security/credentials/plugin/plugin_credentials.h +2 -0
  378. data/src/core/lib/security/credentials/ssl/ssl_credentials.cc +20 -0
  379. data/src/core/lib/security/credentials/ssl/ssl_credentials.h +10 -0
  380. data/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc +23 -13
  381. data/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h +48 -11
  382. data/src/core/lib/security/security_connector/alts/alts_security_connector.cc +21 -6
  383. data/src/core/lib/security/security_connector/fake/fake_security_connector.cc +17 -17
  384. data/src/core/lib/security/security_connector/load_system_roots_linux.cc +3 -2
  385. data/src/core/lib/security/security_connector/local/local_security_connector.cc +1 -1
  386. data/src/core/lib/security/security_connector/security_connector.cc +2 -0
  387. data/src/core/lib/security/security_connector/security_connector.h +2 -2
  388. data/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc +38 -36
  389. data/src/core/lib/security/security_connector/ssl/ssl_security_connector.h +8 -5
  390. data/src/core/lib/security/security_connector/ssl_utils.cc +89 -21
  391. data/src/core/lib/security/security_connector/ssl_utils.h +18 -12
  392. data/src/core/lib/security/security_connector/tls/tls_security_connector.cc +101 -72
  393. data/src/core/lib/security/security_connector/tls/tls_security_connector.h +27 -5
  394. data/src/core/lib/security/transport/auth_filters.h +0 -5
  395. data/src/core/lib/security/transport/client_auth_filter.cc +11 -11
  396. data/src/core/lib/security/util/json_util.cc +12 -13
  397. data/src/core/lib/slice/slice.cc +38 -1
  398. data/src/core/lib/slice/slice_intern.cc +2 -3
  399. data/src/core/lib/slice/slice_internal.h +15 -0
  400. data/src/core/lib/slice/slice_utils.h +9 -0
  401. data/src/core/lib/surface/byte_buffer_reader.cc +2 -47
  402. data/src/core/lib/surface/call.cc +42 -44
  403. data/src/core/lib/surface/call_log_batch.cc +50 -58
  404. data/src/core/lib/surface/channel.cc +53 -31
  405. data/src/core/lib/surface/channel.h +35 -4
  406. data/src/core/lib/surface/channel_ping.cc +2 -3
  407. data/src/core/lib/surface/completion_queue.cc +304 -47
  408. data/src/core/lib/surface/completion_queue.h +8 -0
  409. data/src/core/lib/surface/event_string.cc +18 -25
  410. data/src/core/lib/surface/event_string.h +3 -1
  411. data/src/core/lib/surface/init.cc +2 -0
  412. data/src/core/lib/surface/init_secure.cc +1 -4
  413. data/src/core/lib/surface/server.cc +971 -837
  414. data/src/core/lib/surface/server.h +66 -12
  415. data/src/core/lib/surface/version.cc +2 -2
  416. data/src/core/lib/transport/byte_stream.h +7 -2
  417. data/src/core/lib/transport/connectivity_state.cc +7 -6
  418. data/src/core/lib/transport/connectivity_state.h +5 -3
  419. data/src/core/lib/transport/metadata.cc +3 -3
  420. data/src/core/lib/transport/metadata_batch.h +2 -3
  421. data/src/core/lib/transport/static_metadata.h +1 -1
  422. data/src/core/lib/transport/status_conversion.cc +6 -14
  423. data/src/core/lib/transport/transport.cc +2 -3
  424. data/src/core/lib/transport/transport.h +9 -2
  425. data/src/core/lib/transport/transport_op_string.cc +61 -102
  426. data/src/core/lib/uri/uri_parser.cc +8 -15
  427. data/src/core/lib/uri/uri_parser.h +2 -3
  428. data/src/core/plugin_registry/grpc_plugin_registry.cc +24 -4
  429. data/src/core/tsi/alts/crypt/aes_gcm.cc +0 -2
  430. data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +31 -14
  431. data/src/core/tsi/alts/handshaker/alts_handshaker_client.h +8 -4
  432. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +34 -2
  433. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.h +9 -1
  434. data/src/core/tsi/alts/handshaker/transport_security_common_api.cc +2 -0
  435. data/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.h +2 -3
  436. data/src/core/tsi/fake_transport_security.cc +10 -15
  437. data/src/core/tsi/ssl/session_cache/ssl_session.h +0 -2
  438. data/src/core/tsi/ssl/session_cache/ssl_session_cache.h +0 -2
  439. data/src/core/tsi/ssl_transport_security.cc +154 -50
  440. data/src/core/tsi/ssl_transport_security.h +22 -10
  441. data/src/core/tsi/ssl_types.h +0 -2
  442. data/src/core/tsi/transport_security.h +6 -9
  443. data/src/core/tsi/transport_security_grpc.h +2 -3
  444. data/src/core/tsi/transport_security_interface.h +8 -3
  445. data/src/ruby/ext/grpc/extconf.rb +5 -2
  446. data/src/ruby/ext/grpc/rb_call.c +12 -3
  447. data/src/ruby/ext/grpc/rb_call.h +4 -0
  448. data/src/ruby/ext/grpc/rb_call_credentials.c +57 -12
  449. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +4 -0
  450. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +6 -0
  451. data/src/ruby/lib/grpc/errors.rb +103 -42
  452. data/src/ruby/lib/grpc/generic/active_call.rb +2 -3
  453. data/src/ruby/lib/grpc/generic/interceptors.rb +5 -5
  454. data/src/ruby/lib/grpc/generic/rpc_server.rb +9 -10
  455. data/src/ruby/lib/grpc/generic/service.rb +5 -4
  456. data/src/ruby/lib/grpc/structs.rb +1 -1
  457. data/src/ruby/lib/grpc/version.rb +1 -1
  458. data/src/ruby/pb/generate_proto_ruby.sh +5 -3
  459. data/src/ruby/pb/src/proto/grpc/testing/messages_pb.rb +11 -0
  460. data/src/ruby/pb/src/proto/grpc/testing/test_services_pb.rb +16 -0
  461. data/src/ruby/spec/debug_message_spec.rb +134 -0
  462. data/src/ruby/spec/generic/service_spec.rb +2 -0
  463. data/src/ruby/spec/pb/codegen/grpc/testing/package_options_import2.proto +23 -0
  464. data/src/ruby/spec/pb/codegen/grpc/testing/package_options_ruby_style.proto +7 -0
  465. data/src/ruby/spec/pb/codegen/package_option_spec.rb +7 -1
  466. data/src/ruby/spec/support/services.rb +10 -4
  467. data/src/ruby/spec/testdata/ca.pem +18 -13
  468. data/src/ruby/spec/testdata/client.key +26 -14
  469. data/src/ruby/spec/testdata/client.pem +18 -12
  470. data/src/ruby/spec/testdata/server1.key +26 -14
  471. data/src/ruby/spec/testdata/server1.pem +20 -14
  472. data/third_party/abseil-cpp/absl/time/civil_time.cc +175 -0
  473. data/third_party/abseil-cpp/absl/time/civil_time.h +538 -0
  474. data/third_party/abseil-cpp/absl/time/clock.cc +569 -0
  475. data/third_party/abseil-cpp/absl/time/clock.h +74 -0
  476. data/third_party/abseil-cpp/absl/time/duration.cc +922 -0
  477. data/third_party/abseil-cpp/absl/time/format.cc +153 -0
  478. data/third_party/abseil-cpp/absl/time/internal/cctz/include/cctz/civil_time.h +332 -0
  479. data/third_party/abseil-cpp/absl/time/internal/cctz/include/cctz/civil_time_detail.h +622 -0
  480. data/third_party/abseil-cpp/absl/time/internal/cctz/include/cctz/time_zone.h +384 -0
  481. data/third_party/abseil-cpp/absl/time/internal/cctz/include/cctz/zone_info_source.h +102 -0
  482. data/third_party/abseil-cpp/absl/time/internal/cctz/src/civil_time_detail.cc +94 -0
  483. data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_fixed.cc +140 -0
  484. data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_fixed.h +52 -0
  485. data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_format.cc +922 -0
  486. data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_if.cc +45 -0
  487. data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_if.h +76 -0
  488. data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_impl.cc +121 -0
  489. data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_impl.h +93 -0
  490. data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_info.cc +958 -0
  491. data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_info.h +138 -0
  492. data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_libc.cc +308 -0
  493. data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_libc.h +55 -0
  494. data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup.cc +187 -0
  495. data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_posix.cc +159 -0
  496. data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_posix.h +132 -0
  497. data/third_party/abseil-cpp/absl/time/internal/cctz/src/tzfile.h +122 -0
  498. data/third_party/abseil-cpp/absl/time/internal/cctz/src/zone_info_source.cc +115 -0
  499. data/third_party/abseil-cpp/absl/time/internal/get_current_time_chrono.inc +31 -0
  500. data/third_party/abseil-cpp/absl/time/internal/get_current_time_posix.inc +24 -0
  501. data/third_party/abseil-cpp/absl/time/time.cc +499 -0
  502. data/third_party/abseil-cpp/absl/time/time.h +1584 -0
  503. data/third_party/boringssl-with-bazel/err_data.c +335 -297
  504. data/third_party/boringssl-with-bazel/src/crypto/asn1/a_bitstr.c +3 -3
  505. data/third_party/boringssl-with-bazel/src/crypto/asn1/a_enum.c +3 -3
  506. data/third_party/boringssl-with-bazel/src/crypto/asn1/a_int.c +1 -1
  507. data/third_party/boringssl-with-bazel/src/crypto/asn1/a_object.c +3 -3
  508. data/third_party/boringssl-with-bazel/src/crypto/asn1/a_time.c +2 -2
  509. data/third_party/boringssl-with-bazel/src/crypto/asn1/a_type.c +1 -1
  510. data/third_party/boringssl-with-bazel/src/crypto/asn1/asn1_lib.c +1 -1
  511. data/third_party/boringssl-with-bazel/src/crypto/asn1/asn_pack.c +1 -1
  512. data/third_party/boringssl-with-bazel/src/crypto/asn1/f_enum.c +1 -1
  513. data/third_party/boringssl-with-bazel/src/crypto/asn1/f_int.c +1 -1
  514. data/third_party/boringssl-with-bazel/src/crypto/asn1/f_string.c +1 -1
  515. data/third_party/boringssl-with-bazel/src/crypto/cipher_extra/derive_key.c +1 -1
  516. data/third_party/boringssl-with-bazel/src/crypto/cipher_extra/tls_cbc.c +1 -0
  517. data/third_party/boringssl-with-bazel/src/crypto/cpu-arm-linux.c +7 -5
  518. data/third_party/boringssl-with-bazel/src/crypto/cpu-intel.c +13 -4
  519. data/third_party/boringssl-with-bazel/src/crypto/crypto.c +11 -0
  520. data/third_party/boringssl-with-bazel/src/{third_party/fiat → crypto/curve25519}/curve25519.c +18 -26
  521. data/third_party/boringssl-with-bazel/src/{third_party/fiat → crypto/curve25519}/curve25519_tables.h +13 -21
  522. data/third_party/boringssl-with-bazel/src/{third_party/fiat → crypto/curve25519}/internal.h +14 -22
  523. data/third_party/boringssl-with-bazel/src/crypto/curve25519/spake25519.c +1 -1
  524. data/third_party/boringssl-with-bazel/src/crypto/dh/dh.c +15 -0
  525. data/third_party/boringssl-with-bazel/src/crypto/dsa/dsa.c +10 -0
  526. data/third_party/boringssl-with-bazel/src/crypto/ec_extra/hash_to_curve.c +385 -0
  527. data/third_party/boringssl-with-bazel/src/crypto/ec_extra/internal.h +56 -0
  528. data/third_party/boringssl-with-bazel/src/crypto/ecdh_extra/ecdh_extra.c +2 -2
  529. data/third_party/boringssl-with-bazel/src/crypto/err/err.c +33 -32
  530. data/third_party/boringssl-with-bazel/src/crypto/evp/evp_asn1.c +143 -0
  531. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/aes/aes_nohw.c +1 -1
  532. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/aes/mode_wrappers.c +17 -1
  533. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/bcm.c +2 -1
  534. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/exponentiation.c +3 -3
  535. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/internal.h +25 -12
  536. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/montgomery.c +8 -8
  537. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/mul.c +30 -154
  538. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/digest/digests.c +16 -0
  539. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/ec.c +289 -117
  540. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/ec_key.c +13 -27
  541. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/ec_montgomery.c +96 -55
  542. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/felem.c +25 -7
  543. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/internal.h +434 -161
  544. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/oct.c +63 -71
  545. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/p224-64.c +18 -25
  546. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/p256-x86_64-table.h +9481 -9485
  547. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/p256-x86_64.c +104 -122
  548. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/p256.c +740 -0
  549. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/p256_table.h +297 -0
  550. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/scalar.c +90 -11
  551. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/simple.c +125 -148
  552. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/simple_mul.c +189 -3
  553. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/util.c +3 -3
  554. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/wnaf.c +61 -18
  555. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ecdh/ecdh.c +2 -2
  556. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ecdsa/ecdsa.c +20 -5
  557. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/rand/fork_detect.c +137 -0
  558. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/rand/fork_detect.h +49 -0
  559. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/rand/getrandom_fillin.h +64 -0
  560. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/rand/internal.h +41 -5
  561. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/rand/rand.c +32 -17
  562. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/rand/urandom.c +24 -114
  563. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/rsa/blinding.c +4 -0
  564. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/rsa/internal.h +1 -0
  565. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/rsa/rsa.c +51 -38
  566. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/rsa/rsa_impl.c +15 -1
  567. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/self_check/self_check.c +62 -0
  568. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/sha/sha512.c +44 -35
  569. data/third_party/boringssl-with-bazel/src/crypto/mem.c +47 -16
  570. data/third_party/boringssl-with-bazel/src/crypto/obj/obj_dat.h +15 -1
  571. data/third_party/boringssl-with-bazel/src/crypto/pkcs8/internal.h +7 -0
  572. data/third_party/boringssl-with-bazel/src/crypto/pkcs8/pkcs8_x509.c +36 -5
  573. data/third_party/boringssl-with-bazel/src/crypto/rand_extra/deterministic.c +6 -10
  574. data/third_party/boringssl-with-bazel/src/crypto/rand_extra/windows.c +16 -0
  575. data/third_party/boringssl-with-bazel/src/crypto/thread_pthread.c +4 -0
  576. data/third_party/boringssl-with-bazel/src/crypto/thread_win.c +4 -0
  577. data/third_party/boringssl-with-bazel/src/crypto/trust_token/internal.h +249 -0
  578. data/third_party/boringssl-with-bazel/src/crypto/trust_token/pmbtoken.c +1227 -0
  579. data/third_party/boringssl-with-bazel/src/crypto/trust_token/trust_token.c +682 -0
  580. data/third_party/boringssl-with-bazel/src/crypto/x509/a_strex.c +4 -4
  581. data/third_party/boringssl-with-bazel/src/crypto/x509/algorithm.c +8 -0
  582. data/third_party/boringssl-with-bazel/src/crypto/x509/asn1_gen.c +4 -4
  583. data/third_party/boringssl-with-bazel/src/crypto/x509/x509.c +0 -67
  584. data/third_party/boringssl-with-bazel/src/crypto/x509/x509_cmp.c +13 -6
  585. data/third_party/boringssl-with-bazel/src/crypto/x509/x509_req.c +10 -0
  586. data/third_party/boringssl-with-bazel/src/crypto/x509/x509_set.c +57 -0
  587. data/third_party/boringssl-with-bazel/src/crypto/x509/x509_trs.c +4 -1
  588. data/third_party/boringssl-with-bazel/src/crypto/x509/x509_vfy.c +33 -9
  589. data/third_party/boringssl-with-bazel/src/crypto/x509/x509cset.c +25 -0
  590. data/third_party/boringssl-with-bazel/src/crypto/x509/x509name.c +4 -3
  591. data/third_party/boringssl-with-bazel/src/crypto/x509/x_crl.c +35 -13
  592. data/third_party/boringssl-with-bazel/src/crypto/x509/x_pubkey.c +0 -154
  593. data/third_party/boringssl-with-bazel/src/crypto/x509/x_x509.c +28 -6
  594. data/third_party/boringssl-with-bazel/src/crypto/x509v3/internal.h +5 -0
  595. data/third_party/boringssl-with-bazel/src/crypto/x509v3/v3_purp.c +74 -35
  596. data/third_party/boringssl-with-bazel/src/include/openssl/aes.h +16 -4
  597. data/third_party/boringssl-with-bazel/src/include/openssl/asn1.h +22 -22
  598. data/third_party/boringssl-with-bazel/src/include/openssl/base.h +6 -2
  599. data/third_party/boringssl-with-bazel/src/include/openssl/crypto.h +9 -4
  600. data/third_party/boringssl-with-bazel/src/include/openssl/dh.h +20 -0
  601. data/third_party/boringssl-with-bazel/src/include/openssl/digest.h +1 -0
  602. data/third_party/boringssl-with-bazel/src/include/openssl/dsa.h +16 -0
  603. data/third_party/boringssl-with-bazel/src/include/openssl/ecdsa.h +6 -0
  604. data/third_party/boringssl-with-bazel/src/include/openssl/err.h +2 -0
  605. data/third_party/boringssl-with-bazel/src/include/openssl/evp.h +69 -0
  606. data/third_party/boringssl-with-bazel/src/include/openssl/nid.h +5 -0
  607. data/third_party/boringssl-with-bazel/src/include/openssl/rand.h +3 -17
  608. data/third_party/boringssl-with-bazel/src/include/openssl/rsa.h +31 -0
  609. data/third_party/boringssl-with-bazel/src/include/openssl/sha.h +26 -0
  610. data/third_party/boringssl-with-bazel/src/include/openssl/ssl.h +191 -79
  611. data/third_party/boringssl-with-bazel/src/include/openssl/tls1.h +1 -0
  612. data/third_party/boringssl-with-bazel/src/include/openssl/trust_token.h +282 -0
  613. data/third_party/boringssl-with-bazel/src/include/openssl/x509.h +791 -715
  614. data/third_party/boringssl-with-bazel/src/include/openssl/x509_vfy.h +1 -0
  615. data/third_party/boringssl-with-bazel/src/ssl/d1_both.cc +0 -4
  616. data/third_party/boringssl-with-bazel/src/ssl/d1_lib.cc +3 -3
  617. data/third_party/boringssl-with-bazel/src/ssl/dtls_method.cc +13 -4
  618. data/third_party/boringssl-with-bazel/src/ssl/handoff.cc +146 -57
  619. data/third_party/boringssl-with-bazel/src/ssl/handshake.cc +23 -5
  620. data/third_party/boringssl-with-bazel/src/ssl/handshake_client.cc +30 -22
  621. data/third_party/boringssl-with-bazel/src/ssl/handshake_server.cc +21 -4
  622. data/third_party/boringssl-with-bazel/src/ssl/internal.h +74 -54
  623. data/third_party/boringssl-with-bazel/src/ssl/s3_both.cc +10 -10
  624. data/third_party/boringssl-with-bazel/src/ssl/s3_lib.cc +2 -2
  625. data/third_party/boringssl-with-bazel/src/ssl/s3_pkt.cc +21 -21
  626. data/third_party/boringssl-with-bazel/src/ssl/ssl_asn1.cc +29 -0
  627. data/third_party/boringssl-with-bazel/src/ssl/ssl_cert.cc +4 -0
  628. data/third_party/boringssl-with-bazel/src/ssl/ssl_lib.cc +34 -1
  629. data/third_party/boringssl-with-bazel/src/ssl/ssl_privkey.cc +13 -2
  630. data/third_party/boringssl-with-bazel/src/ssl/ssl_session.cc +44 -5
  631. data/third_party/boringssl-with-bazel/src/ssl/ssl_stat.cc +6 -0
  632. data/third_party/boringssl-with-bazel/src/ssl/ssl_versions.cc +5 -5
  633. data/third_party/boringssl-with-bazel/src/ssl/t1_enc.cc +51 -26
  634. data/third_party/boringssl-with-bazel/src/ssl/t1_lib.cc +47 -53
  635. data/third_party/boringssl-with-bazel/src/ssl/tls13_both.cc +1 -1
  636. data/third_party/boringssl-with-bazel/src/ssl/tls13_client.cc +129 -48
  637. data/third_party/boringssl-with-bazel/src/ssl/tls13_enc.cc +23 -75
  638. data/third_party/boringssl-with-bazel/src/ssl/tls13_server.cc +55 -22
  639. data/third_party/boringssl-with-bazel/src/ssl/tls_method.cc +63 -25
  640. data/third_party/boringssl-with-bazel/src/third_party/fiat/curve25519_32.h +245 -175
  641. data/third_party/boringssl-with-bazel/src/third_party/fiat/curve25519_64.h +135 -75
  642. data/third_party/boringssl-with-bazel/src/third_party/fiat/p256_32.h +1593 -1672
  643. data/third_party/boringssl-with-bazel/src/third_party/fiat/p256_64.h +512 -503
  644. data/third_party/upb/upb/decode.c +467 -504
  645. data/third_party/upb/upb/encode.c +163 -121
  646. data/third_party/upb/upb/msg.c +130 -64
  647. data/third_party/upb/upb/msg.h +418 -14
  648. data/third_party/upb/upb/port_def.inc +35 -6
  649. data/third_party/upb/upb/port_undef.inc +8 -1
  650. data/third_party/upb/upb/table.c +53 -75
  651. data/third_party/upb/upb/table.int.h +11 -43
  652. data/third_party/upb/upb/upb.c +148 -124
  653. data/third_party/upb/upb/upb.h +65 -147
  654. data/third_party/upb/upb/upb.hpp +86 -0
  655. metadata +122 -41
  656. data/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +0 -1908
  657. data/src/core/lib/gprpp/string_view.h +0 -60
  658. data/src/core/tsi/grpc_shadow_boringssl.h +0 -3311
  659. data/third_party/boringssl-with-bazel/src/third_party/fiat/p256.c +0 -1063
  660. data/third_party/upb/upb/generated_util.h +0 -105
@@ -23,9 +23,10 @@
23
23
  #include <string>
24
24
  #include <vector>
25
25
 
26
+ #include "absl/container/inlined_vector.h"
27
+
26
28
  #include <grpc/impl/codegen/slice.h>
27
29
 
28
- #include "src/core/lib/gprpp/inlined_vector.h"
29
30
  #include "src/core/lib/gprpp/map.h"
30
31
  #include "src/core/lib/gprpp/memory.h"
31
32
  #include "src/core/lib/iomgr/error.h"
@@ -33,6 +34,8 @@
33
34
 
34
35
  namespace grpc_core {
35
36
 
37
+ class XdsClient;
38
+
36
39
  class XdsBootstrap {
37
40
  public:
38
41
  struct Node {
@@ -51,12 +54,14 @@ class XdsBootstrap {
51
54
 
52
55
  struct XdsServer {
53
56
  std::string server_uri;
54
- InlinedVector<ChannelCreds, 1> channel_creds;
57
+ absl::InlinedVector<ChannelCreds, 1> channel_creds;
55
58
  };
56
59
 
57
60
  // If *error is not GRPC_ERROR_NONE after returning, then there was an
58
61
  // error reading the file.
59
- static std::unique_ptr<XdsBootstrap> ReadFromFile(grpc_error** error);
62
+ static std::unique_ptr<XdsBootstrap> ReadFromFile(XdsClient* client,
63
+ TraceFlag* tracer,
64
+ grpc_error** error);
60
65
 
61
66
  // Do not instantiate directly -- use ReadFromFile() above instead.
62
67
  XdsBootstrap(Json json, grpc_error** error);
@@ -74,7 +79,7 @@ class XdsBootstrap {
74
79
  grpc_error* ParseNode(Json* json);
75
80
  grpc_error* ParseLocality(Json* json);
76
81
 
77
- InlinedVector<XdsServer, 1> servers_;
82
+ absl::InlinedVector<XdsServer, 1> servers_;
78
83
  std::unique_ptr<Node> node_;
79
84
  };
80
85
 
@@ -22,6 +22,8 @@
22
22
 
23
23
  #include <string.h>
24
24
 
25
+ #include "absl/container/inlined_vector.h"
26
+
25
27
  #include <grpc/grpc_security.h>
26
28
  #include <grpc/support/alloc.h>
27
29
  #include <grpc/support/string_util.h>
@@ -39,8 +41,8 @@
39
41
  namespace grpc_core {
40
42
 
41
43
  grpc_channel_args* ModifyXdsChannelArgs(grpc_channel_args* args) {
42
- InlinedVector<const char*, 1> args_to_remove;
43
- InlinedVector<grpc_arg, 2> args_to_add;
44
+ absl::InlinedVector<const char*, 1> args_to_remove;
45
+ absl::InlinedVector<grpc_arg, 2> args_to_add;
44
46
  // Substitute the channel credentials with a version without call
45
47
  // credentials: the load balancer is not necessarily trusted to handle
46
48
  // bearer token credentials.
@@ -22,10 +22,14 @@
22
22
  #include <limits.h>
23
23
  #include <string.h>
24
24
 
25
+ #include "absl/container/inlined_vector.h"
26
+ #include "absl/strings/str_format.h"
27
+ #include "absl/strings/str_join.h"
28
+ #include "absl/strings/string_view.h"
29
+
25
30
  #include <grpc/byte_buffer_reader.h>
26
31
  #include <grpc/grpc.h>
27
32
  #include <grpc/support/alloc.h>
28
- #include <grpc/support/string_util.h>
29
33
  #include <grpc/support/time.h>
30
34
 
31
35
  #include "src/core/ext/filters/client_channel/client_channel.h"
@@ -46,10 +50,10 @@
46
50
  #include "src/core/lib/gprpp/orphanable.h"
47
51
  #include "src/core/lib/gprpp/ref_counted_ptr.h"
48
52
  #include "src/core/lib/gprpp/sync.h"
49
- #include "src/core/lib/iomgr/combiner.h"
50
53
  #include "src/core/lib/iomgr/sockaddr.h"
51
54
  #include "src/core/lib/iomgr/sockaddr_utils.h"
52
55
  #include "src/core/lib/iomgr/timer.h"
56
+ #include "src/core/lib/iomgr/work_serializer.h"
53
57
  #include "src/core/lib/slice/slice_hash_table.h"
54
58
  #include "src/core/lib/slice/slice_internal.h"
55
59
  #include "src/core/lib/slice/slice_string_helpers.h"
@@ -93,7 +97,7 @@ class XdsClient::ChannelState::RetryableCall
93
97
  void StartNewCallLocked();
94
98
  void StartRetryTimerLocked();
95
99
  static void OnRetryTimer(void* arg, grpc_error* error);
96
- static void OnRetryTimerLocked(void* arg, grpc_error* error);
100
+ void OnRetryTimerLocked(grpc_error* error);
97
101
 
98
102
  // The wrapped xds call that talks to the xds server. It's instantiated
99
103
  // every time we start a new call. It's null during call retry backoff.
@@ -126,7 +130,8 @@ class XdsClient::ChannelState::AdsCallState
126
130
  bool seen_response() const { return seen_response_; }
127
131
 
128
132
  void Subscribe(const std::string& type_url, const std::string& name);
129
- void Unsubscribe(const std::string& type_url, const std::string& name);
133
+ void Unsubscribe(const std::string& type_url, const std::string& name,
134
+ bool delay_unsubscription);
130
135
 
131
136
  bool HasSubscribedResources() const;
132
137
 
@@ -166,51 +171,46 @@ class XdsClient::ChannelState::AdsCallState
166
171
  private:
167
172
  static void OnTimer(void* arg, grpc_error* error) {
168
173
  ResourceState* self = static_cast<ResourceState*>(arg);
169
- self->ads_calld_->xds_client()->combiner_->Run(
170
- GRPC_CLOSURE_INIT(&self->timer_callback_, OnTimerLocked, self,
171
- nullptr),
172
- GRPC_ERROR_REF(error));
174
+ GRPC_ERROR_REF(error); // ref owned by lambda
175
+ self->ads_calld_->xds_client()->work_serializer_->Run(
176
+ [self, error]() { self->OnTimerLocked(error); }, DEBUG_LOCATION);
173
177
  }
174
178
 
175
- static void OnTimerLocked(void* arg, grpc_error* error) {
176
- ResourceState* self = static_cast<ResourceState*>(arg);
177
- if (error == GRPC_ERROR_NONE && self->timer_pending_) {
178
- self->timer_pending_ = false;
179
- char* msg;
180
- gpr_asprintf(
181
- &msg,
182
- "timeout obtaining resource {type=%s name=%s} from xds server",
183
- self->type_url_.c_str(), self->name_.c_str());
184
- grpc_error* error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
185
- gpr_free(msg);
179
+ void OnTimerLocked(grpc_error* error) {
180
+ if (error == GRPC_ERROR_NONE && timer_pending_) {
181
+ timer_pending_ = false;
182
+ grpc_error* watcher_error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(
183
+ absl::StrFormat(
184
+ "timeout obtaining resource {type=%s name=%s} from xds server",
185
+ type_url_, name_)
186
+ .c_str());
186
187
  if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
187
- gpr_log(GPR_INFO, "[xds_client %p] %s",
188
- self->ads_calld_->xds_client(), grpc_error_string(error));
188
+ gpr_log(GPR_INFO, "[xds_client %p] %s", ads_calld_->xds_client(),
189
+ grpc_error_string(watcher_error));
189
190
  }
190
- if (self->type_url_ == XdsApi::kLdsTypeUrl ||
191
- self->type_url_ == XdsApi::kRdsTypeUrl) {
192
- self->ads_calld_->xds_client()->service_config_watcher_->OnError(
193
- error);
194
- } else if (self->type_url_ == XdsApi::kCdsTypeUrl) {
195
- ClusterState& state =
196
- self->ads_calld_->xds_client()->cluster_map_[self->name_];
191
+ if (type_url_ == XdsApi::kLdsTypeUrl ||
192
+ type_url_ == XdsApi::kRdsTypeUrl) {
193
+ ads_calld_->xds_client()->service_config_watcher_->OnError(
194
+ watcher_error);
195
+ } else if (type_url_ == XdsApi::kCdsTypeUrl) {
196
+ ClusterState& state = ads_calld_->xds_client()->cluster_map_[name_];
197
197
  for (const auto& p : state.watchers) {
198
- p.first->OnError(GRPC_ERROR_REF(error));
198
+ p.first->OnError(GRPC_ERROR_REF(watcher_error));
199
199
  }
200
- GRPC_ERROR_UNREF(error);
201
- } else if (self->type_url_ == XdsApi::kEdsTypeUrl) {
202
- EndpointState& state =
203
- self->ads_calld_->xds_client()->endpoint_map_[self->name_];
200
+ GRPC_ERROR_UNREF(watcher_error);
201
+ } else if (type_url_ == XdsApi::kEdsTypeUrl) {
202
+ EndpointState& state = ads_calld_->xds_client()->endpoint_map_[name_];
204
203
  for (const auto& p : state.watchers) {
205
- p.first->OnError(GRPC_ERROR_REF(error));
204
+ p.first->OnError(GRPC_ERROR_REF(watcher_error));
206
205
  }
207
- GRPC_ERROR_UNREF(error);
206
+ GRPC_ERROR_UNREF(watcher_error);
208
207
  } else {
209
208
  GPR_UNREACHABLE_CODE(return );
210
209
  }
211
210
  }
212
- self->ads_calld_.reset();
213
- self->Unref();
211
+ ads_calld_.reset();
212
+ Unref();
213
+ GRPC_ERROR_UNREF(error);
214
214
  }
215
215
 
216
216
  const std::string type_url_;
@@ -238,22 +238,22 @@ class XdsClient::ChannelState::AdsCallState
238
238
 
239
239
  void SendMessageLocked(const std::string& type_url);
240
240
 
241
- void AcceptLdsUpdate(XdsApi::LdsUpdate lds_update);
242
- void AcceptRdsUpdate(XdsApi::RdsUpdate rds_update);
241
+ void AcceptLdsUpdate(absl::optional<XdsApi::LdsUpdate> lds_update);
242
+ void AcceptRdsUpdate(absl::optional<XdsApi::RdsUpdate> rds_update);
243
243
  void AcceptCdsUpdate(XdsApi::CdsUpdateMap cds_update_map);
244
244
  void AcceptEdsUpdate(XdsApi::EdsUpdateMap eds_update_map);
245
245
 
246
246
  static void OnRequestSent(void* arg, grpc_error* error);
247
- static void OnRequestSentLocked(void* arg, grpc_error* error);
247
+ void OnRequestSentLocked(grpc_error* error);
248
248
  static void OnResponseReceived(void* arg, grpc_error* error);
249
- static void OnResponseReceivedLocked(void* arg, grpc_error* error);
249
+ void OnResponseReceivedLocked();
250
250
  static void OnStatusReceived(void* arg, grpc_error* error);
251
- static void OnStatusReceivedLocked(void* arg, grpc_error* error);
251
+ void OnStatusReceivedLocked(grpc_error* error);
252
252
 
253
253
  bool IsCurrentCallOnChannel() const;
254
254
 
255
- std::set<StringView> ClusterNamesForRequest();
256
- std::set<StringView> EdsServiceNamesForRequest();
255
+ std::set<absl::string_view> ResourceNamesForRequest(
256
+ const std::string& type_url);
257
257
 
258
258
  // The owning RetryableCall<>.
259
259
  RefCountedPtr<RetryableCall<AdsCallState>> parent_;
@@ -299,7 +299,6 @@ class XdsClient::ChannelState::LrsCallState
299
299
  void Orphan() override;
300
300
 
301
301
  void MaybeStartReportingLocked();
302
- bool ShouldSendLoadReports(const StringView& cluster_name) const;
303
302
 
304
303
  RetryableCall<LrsCallState>* parent() { return parent_.get(); }
305
304
  ChannelState* chand() const { return parent_->chand(); }
@@ -312,6 +311,10 @@ class XdsClient::ChannelState::LrsCallState
312
311
  public:
313
312
  Reporter(RefCountedPtr<LrsCallState> parent, grpc_millis report_interval)
314
313
  : parent_(std::move(parent)), report_interval_(report_interval) {
314
+ GRPC_CLOSURE_INIT(&on_next_report_timer_, OnNextReportTimer, this,
315
+ grpc_schedule_on_exec_ctx);
316
+ GRPC_CLOSURE_INIT(&on_report_done_, OnReportDone, this,
317
+ grpc_schedule_on_exec_ctx);
315
318
  ScheduleNextReportLocked();
316
319
  }
317
320
 
@@ -320,10 +323,10 @@ class XdsClient::ChannelState::LrsCallState
320
323
  private:
321
324
  void ScheduleNextReportLocked();
322
325
  static void OnNextReportTimer(void* arg, grpc_error* error);
323
- static void OnNextReportTimerLocked(void* arg, grpc_error* error);
326
+ void OnNextReportTimerLocked(grpc_error* error);
324
327
  void SendReportLocked();
325
328
  static void OnReportDone(void* arg, grpc_error* error);
326
- static void OnReportDoneLocked(void* arg, grpc_error* error);
329
+ void OnReportDoneLocked(grpc_error* error);
327
330
 
328
331
  bool IsCurrentReporterOnCall() const {
329
332
  return this == parent_->reporter_.get();
@@ -343,11 +346,11 @@ class XdsClient::ChannelState::LrsCallState
343
346
  };
344
347
 
345
348
  static void OnInitialRequestSent(void* arg, grpc_error* error);
349
+ void OnInitialRequestSentLocked();
346
350
  static void OnResponseReceived(void* arg, grpc_error* error);
351
+ void OnResponseReceivedLocked();
347
352
  static void OnStatusReceived(void* arg, grpc_error* error);
348
- static void OnInitialRequestSentLocked(void* arg, grpc_error* error);
349
- static void OnResponseReceivedLocked(void* arg, grpc_error* error);
350
- static void OnStatusReceivedLocked(void* arg, grpc_error* error);
353
+ void OnStatusReceivedLocked(grpc_error* error);
351
354
 
352
355
  bool IsCurrentCallOnChannel() const;
353
356
 
@@ -376,6 +379,7 @@ class XdsClient::ChannelState::LrsCallState
376
379
  grpc_closure on_status_received_;
377
380
 
378
381
  // Load reporting state.
382
+ bool send_all_clusters_ = false;
379
383
  std::set<std::string> cluster_names_; // Asked for by the LRS server.
380
384
  grpc_millis load_reporting_interval_ = 0;
381
385
  OrphanablePtr<Reporter> reporter_;
@@ -389,7 +393,8 @@ class XdsClient::ChannelState::StateWatcher
389
393
  : public AsyncConnectivityStateWatcherInterface {
390
394
  public:
391
395
  explicit StateWatcher(RefCountedPtr<ChannelState> parent)
392
- : AsyncConnectivityStateWatcherInterface(parent->xds_client()->combiner_),
396
+ : AsyncConnectivityStateWatcherInterface(
397
+ parent->xds_client()->work_serializer_),
393
398
  parent_(std::move(parent)) {}
394
399
 
395
400
  private:
@@ -442,7 +447,7 @@ grpc_channel_args* BuildXdsChannelArgs(const grpc_channel_args& args) {
442
447
  GRPC_ARG_KEEPALIVE_TIME_MS,
443
448
  };
444
449
  // Channel args to add.
445
- InlinedVector<grpc_arg, 3> args_to_add;
450
+ absl::InlinedVector<grpc_arg, 3> args_to_add;
446
451
  // Keepalive interval.
447
452
  args_to_add.emplace_back(grpc_channel_arg_integer_create(
448
453
  const_cast<char*>(GRPC_ARG_KEEPALIVE_TIME_MS), 5000));
@@ -555,9 +560,10 @@ void XdsClient::ChannelState::Subscribe(const std::string& type_url,
555
560
  }
556
561
 
557
562
  void XdsClient::ChannelState::Unsubscribe(const std::string& type_url,
558
- const std::string& name) {
563
+ const std::string& name,
564
+ bool delay_unsubscription) {
559
565
  if (ads_calld_ != nullptr) {
560
- ads_calld_->calld()->Unsubscribe(type_url, name);
566
+ ads_calld_->calld()->Unsubscribe(type_url, name, delay_unsubscription);
561
567
  if (!ads_calld_->calld()->HasSubscribedResources()) ads_calld_.reset();
562
568
  }
563
569
  }
@@ -577,6 +583,9 @@ XdsClient::ChannelState::RetryableCall::RetryableCall(
577
583
  .set_multiplier(GRPC_XDS_RECONNECT_BACKOFF_MULTIPLIER)
578
584
  .set_jitter(GRPC_XDS_RECONNECT_JITTER)
579
585
  .set_max_backoff(GRPC_XDS_RECONNECT_MAX_BACKOFF_SECONDS * 1000)) {
586
+ // Closure Initialization
587
+ GRPC_CLOSURE_INIT(&on_retry_timer_, OnRetryTimer, this,
588
+ grpc_schedule_on_exec_ctx);
580
589
  StartNewCallLocked();
581
590
  }
582
591
 
@@ -630,8 +639,6 @@ void XdsClient::ChannelState::RetryableCall::StartRetryTimerLocked() {
630
639
  chand()->xds_client(), chand(), timeout);
631
640
  }
632
641
  this->Ref(DEBUG_LOCATION, "RetryableCall+retry_timer_start").release();
633
- GRPC_CLOSURE_INIT(&on_retry_timer_, OnRetryTimer, this,
634
- grpc_schedule_on_exec_ctx);
635
642
  grpc_timer_init(&retry_timer_, next_attempt_time, &on_retry_timer_);
636
643
  retry_timer_callback_pending_ = true;
637
644
  }
@@ -640,27 +647,26 @@ template
640
647
  void XdsClient::ChannelState::RetryableCall<T>::OnRetryTimer(
641
648
  void* arg, grpc_error* error) {
642
649
  RetryableCall* calld = static_cast<RetryableCall*>(arg);
643
- calld->chand_->xds_client()->combiner_->Run(
644
- GRPC_CLOSURE_INIT(&calld->on_retry_timer_, OnRetryTimerLocked, calld,
645
- nullptr),
646
- GRPC_ERROR_REF(error));
650
+ GRPC_ERROR_REF(error); // ref owned by lambda
651
+ calld->chand_->xds_client()->work_serializer_->Run(
652
+ [calld, error]() { calld->OnRetryTimerLocked(error); }, DEBUG_LOCATION);
647
653
  }
648
654
 
649
655
  template <typename T>
650
656
  void XdsClient::ChannelState::RetryableCall<T>::OnRetryTimerLocked(
651
- void* arg, grpc_error* error) {
652
- RetryableCall* calld = static_cast<RetryableCall*>(arg);
653
- calld->retry_timer_callback_pending_ = false;
654
- if (!calld->shutting_down_ && error == GRPC_ERROR_NONE) {
657
+ grpc_error* error) {
658
+ retry_timer_callback_pending_ = false;
659
+ if (!shutting_down_ && error == GRPC_ERROR_NONE) {
655
660
  if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
656
661
  gpr_log(
657
662
  GPR_INFO,
658
663
  "[xds_client %p] Retry timer fires (chand: %p, retryable call: %p)",
659
- calld->chand()->xds_client(), calld->chand(), calld);
664
+ chand()->xds_client(), chand(), this);
660
665
  }
661
- calld->StartNewCallLocked();
666
+ StartNewCallLocked();
662
667
  }
663
- calld->Unref(DEBUG_LOCATION, "RetryableCall+retry_timer_done");
668
+ this->Unref(DEBUG_LOCATION, "RetryableCall+retry_timer_done");
669
+ GRPC_ERROR_UNREF(error);
664
670
  }
665
671
 
666
672
  //
@@ -701,7 +707,8 @@ XdsClient::ChannelState::AdsCallState::AdsCallState(
701
707
  grpc_op* op = ops;
702
708
  op->op = GRPC_OP_SEND_INITIAL_METADATA;
703
709
  op->data.send_initial_metadata.count = 0;
704
- op->flags = 0;
710
+ op->flags = GRPC_INITIAL_METADATA_WAIT_FOR_READY |
711
+ GRPC_INITIAL_METADATA_WAIT_FOR_READY_EXPLICITLY_SET;
705
712
  op->reserved = nullptr;
706
713
  op++;
707
714
  call_error = grpc_call_start_batch_and_execute(call_, ops, (size_t)(op - ops),
@@ -712,6 +719,11 @@ XdsClient::ChannelState::AdsCallState::AdsCallState(
712
719
  grpc_schedule_on_exec_ctx);
713
720
  if (xds_client()->service_config_watcher_ != nullptr) {
714
721
  Subscribe(XdsApi::kLdsTypeUrl, xds_client()->server_name_);
722
+ if (xds_client()->lds_result_.has_value() &&
723
+ !xds_client()->lds_result_->route_config_name.empty()) {
724
+ Subscribe(XdsApi::kRdsTypeUrl,
725
+ xds_client()->lds_result_->route_config_name);
726
+ }
715
727
  }
716
728
  for (const auto& p : xds_client()->cluster_map_) {
717
729
  Subscribe(XdsApi::kCdsTypeUrl, std::string(p.first));
@@ -788,33 +800,27 @@ void XdsClient::ChannelState::AdsCallState::SendMessageLocked(
788
800
  return;
789
801
  }
790
802
  auto& state = state_map_[type_url];
791
- grpc_error* error = state.error;
792
- state.error = GRPC_ERROR_NONE;
793
803
  grpc_slice request_payload_slice;
794
- if (type_url == XdsApi::kLdsTypeUrl) {
795
- request_payload_slice = xds_client()->api_.CreateLdsRequest(
796
- xds_client()->server_name_, state.version, state.nonce, error,
797
- !sent_initial_message_);
798
- state.subscribed_resources[xds_client()->server_name_]->Start(Ref());
799
- } else if (type_url == XdsApi::kRdsTypeUrl) {
800
- request_payload_slice = xds_client()->api_.CreateRdsRequest(
801
- xds_client()->route_config_name_, state.version, state.nonce, error,
802
- !sent_initial_message_);
803
- state.subscribed_resources[xds_client()->route_config_name_]->Start(Ref());
804
- } else if (type_url == XdsApi::kCdsTypeUrl) {
805
- request_payload_slice = xds_client()->api_.CreateCdsRequest(
806
- ClusterNamesForRequest(), state.version, state.nonce, error,
807
- !sent_initial_message_);
808
- } else if (type_url == XdsApi::kEdsTypeUrl) {
809
- request_payload_slice = xds_client()->api_.CreateEdsRequest(
810
- EdsServiceNamesForRequest(), state.version, state.nonce, error,
811
- !sent_initial_message_);
812
- } else {
813
- request_payload_slice = xds_client()->api_.CreateUnsupportedTypeNackRequest(
814
- type_url, state.nonce, state.error);
804
+ std::set<absl::string_view> resource_names =
805
+ ResourceNamesForRequest(type_url);
806
+ request_payload_slice = xds_client()->api_.CreateAdsRequest(
807
+ type_url, resource_names, state.version, state.nonce,
808
+ GRPC_ERROR_REF(state.error), !sent_initial_message_);
809
+ if (type_url != XdsApi::kLdsTypeUrl && type_url != XdsApi::kRdsTypeUrl &&
810
+ type_url != XdsApi::kCdsTypeUrl && type_url != XdsApi::kEdsTypeUrl) {
815
811
  state_map_.erase(type_url);
816
812
  }
817
813
  sent_initial_message_ = true;
814
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
815
+ gpr_log(GPR_INFO,
816
+ "[xds_client %p] sending ADS request: type=%s version=%s nonce=%s "
817
+ "error=%s resources=%s",
818
+ xds_client(), type_url.c_str(), state.version.c_str(),
819
+ state.nonce.c_str(), grpc_error_string(state.error),
820
+ absl::StrJoin(resource_names, " ").c_str());
821
+ }
822
+ GRPC_ERROR_UNREF(state.error);
823
+ state.error = GRPC_ERROR_NONE;
818
824
  // Create message payload.
819
825
  send_message_payload_ =
820
826
  grpc_raw_byte_buffer_create(&request_payload_slice, 1);
@@ -847,9 +853,10 @@ void XdsClient::ChannelState::AdsCallState::Subscribe(
847
853
  }
848
854
 
849
855
  void XdsClient::ChannelState::AdsCallState::Unsubscribe(
850
- const std::string& type_url, const std::string& name) {
856
+ const std::string& type_url, const std::string& name,
857
+ bool delay_unsubscription) {
851
858
  state_map_[type_url].subscribed_resources.erase(name);
852
- SendMessageLocked(type_url);
859
+ if (!delay_unsubscription) SendMessageLocked(type_url);
853
860
  }
854
861
 
855
862
  bool XdsClient::ChannelState::AdsCallState::HasSubscribedResources() const {
@@ -860,25 +867,44 @@ bool XdsClient::ChannelState::AdsCallState::HasSubscribedResources() const {
860
867
  }
861
868
 
862
869
  void XdsClient::ChannelState::AdsCallState::AcceptLdsUpdate(
863
- XdsApi::LdsUpdate lds_update) {
864
- const std::string& cluster_name =
865
- lds_update.rds_update.has_value()
866
- ? lds_update.rds_update.value().cluster_name
867
- : "";
870
+ absl::optional<XdsApi::LdsUpdate> lds_update) {
871
+ if (!lds_update.has_value()) {
872
+ gpr_log(GPR_INFO,
873
+ "[xds_client %p] LDS update does not include requested resource",
874
+ xds_client());
875
+ if (xds_client()->lds_result_.has_value() &&
876
+ !xds_client()->lds_result_->route_config_name.empty()) {
877
+ Unsubscribe(XdsApi::kRdsTypeUrl,
878
+ xds_client()->lds_result_->route_config_name,
879
+ /*delay_unsubscription=*/false);
880
+ xds_client()->rds_result_.reset();
881
+ }
882
+ xds_client()->lds_result_.reset();
883
+ xds_client()->service_config_watcher_->OnResourceDoesNotExist();
884
+ return;
885
+ }
868
886
  if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
869
887
  gpr_log(GPR_INFO,
870
- "[xds_client %p] LDS update received: "
871
- "route_config_name=%s, "
872
- "cluster_name=%s (empty if RDS is needed to obtain it)",
873
- xds_client(), lds_update.route_config_name.c_str(),
874
- cluster_name.c_str());
888
+ "[xds_client %p] LDS update received: route_config_name=%s",
889
+ xds_client(),
890
+ (!lds_update->route_config_name.empty()
891
+ ? lds_update->route_config_name.c_str()
892
+ : "<inlined>"));
893
+ if (lds_update->rds_update.has_value()) {
894
+ gpr_log(GPR_INFO, "RouteConfiguration contains %" PRIuPTR " routes",
895
+ lds_update->rds_update.value().routes.size());
896
+ for (size_t i = 0; i < lds_update->rds_update.value().routes.size();
897
+ ++i) {
898
+ gpr_log(GPR_INFO, "Route %" PRIuPTR ":\n%s", i,
899
+ lds_update->rds_update.value().routes[i].ToString().c_str());
900
+ }
901
+ }
875
902
  }
876
903
  auto& lds_state = state_map_[XdsApi::kLdsTypeUrl];
877
904
  auto& state = lds_state.subscribed_resources[xds_client()->server_name_];
878
905
  if (state != nullptr) state->Finish();
879
906
  // Ignore identical update.
880
- if (xds_client()->route_config_name_ == lds_update.route_config_name &&
881
- xds_client()->cluster_name_ == cluster_name) {
907
+ if (xds_client()->lds_result_ == lds_update) {
882
908
  if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
883
909
  gpr_log(GPR_INFO,
884
910
  "[xds_client %p] LDS update identical to current, ignoring.",
@@ -886,15 +912,20 @@ void XdsClient::ChannelState::AdsCallState::AcceptLdsUpdate(
886
912
  }
887
913
  return;
888
914
  }
889
- xds_client()->route_config_name_ = std::move(lds_update.route_config_name);
890
- if (lds_update.rds_update.has_value()) {
891
- // If cluster_name was found inlined in LDS response, notify the watcher
892
- // immediately.
893
- xds_client()->cluster_name_ =
894
- std::move(lds_update.rds_update.value().cluster_name);
915
+ if (xds_client()->lds_result_.has_value() &&
916
+ !xds_client()->lds_result_->route_config_name.empty()) {
917
+ Unsubscribe(
918
+ XdsApi::kRdsTypeUrl, xds_client()->lds_result_->route_config_name,
919
+ /*delay_unsubscription=*/!lds_update->route_config_name.empty());
920
+ xds_client()->rds_result_.reset();
921
+ }
922
+ xds_client()->lds_result_ = std::move(lds_update);
923
+ if (xds_client()->lds_result_->rds_update.has_value()) {
924
+ // If the RouteConfiguration was found inlined in LDS response, notify
925
+ // the watcher immediately.
895
926
  RefCountedPtr<ServiceConfig> service_config;
896
927
  grpc_error* error = xds_client()->CreateServiceConfig(
897
- xds_client()->cluster_name_, &service_config);
928
+ xds_client()->lds_result_->rds_update.value(), &service_config);
898
929
  if (error == GRPC_ERROR_NONE) {
899
930
  xds_client()->service_config_watcher_->OnServiceConfigChanged(
900
931
  std::move(service_config));
@@ -903,24 +934,38 @@ void XdsClient::ChannelState::AdsCallState::AcceptLdsUpdate(
903
934
  }
904
935
  } else {
905
936
  // Send RDS request for dynamic resolution.
906
- Subscribe(XdsApi::kRdsTypeUrl, xds_client()->route_config_name_);
937
+ Subscribe(XdsApi::kRdsTypeUrl,
938
+ xds_client()->lds_result_->route_config_name);
907
939
  }
908
940
  }
909
941
 
910
942
  void XdsClient::ChannelState::AdsCallState::AcceptRdsUpdate(
911
- XdsApi::RdsUpdate rds_update) {
943
+ absl::optional<XdsApi::RdsUpdate> rds_update) {
944
+ if (!rds_update.has_value()) {
945
+ gpr_log(GPR_INFO,
946
+ "[xds_client %p] RDS update does not include requested resource",
947
+ xds_client());
948
+ xds_client()->rds_result_.reset();
949
+ xds_client()->service_config_watcher_->OnResourceDoesNotExist();
950
+ return;
951
+ }
912
952
  if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
913
953
  gpr_log(GPR_INFO,
914
- "[xds_client %p] RDS update received: "
915
- "cluster_name=%s",
916
- xds_client(), rds_update.cluster_name.c_str());
954
+ "[xds_client %p] RDS update received; RouteConfiguration contains "
955
+ "%" PRIuPTR " routes",
956
+ this, rds_update.value().routes.size());
957
+ for (size_t i = 0; i < rds_update.value().routes.size(); ++i) {
958
+ gpr_log(GPR_INFO, "Route %" PRIuPTR ":\n%s", i,
959
+ rds_update.value().routes[i].ToString().c_str());
960
+ }
917
961
  }
918
962
  auto& rds_state = state_map_[XdsApi::kRdsTypeUrl];
919
963
  auto& state =
920
- rds_state.subscribed_resources[xds_client()->route_config_name_];
964
+ rds_state
965
+ .subscribed_resources[xds_client()->lds_result_->route_config_name];
921
966
  if (state != nullptr) state->Finish();
922
967
  // Ignore identical update.
923
- if (xds_client()->cluster_name_ == rds_update.cluster_name) {
968
+ if (xds_client()->rds_result_ == rds_update) {
924
969
  if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
925
970
  gpr_log(GPR_INFO,
926
971
  "[xds_client %p] RDS update identical to current, ignoring.",
@@ -928,11 +973,11 @@ void XdsClient::ChannelState::AdsCallState::AcceptRdsUpdate(
928
973
  }
929
974
  return;
930
975
  }
931
- xds_client()->cluster_name_ = std::move(rds_update.cluster_name);
976
+ xds_client()->rds_result_ = std::move(rds_update);
932
977
  // Notify the watcher.
933
978
  RefCountedPtr<ServiceConfig> service_config;
934
979
  grpc_error* error = xds_client()->CreateServiceConfig(
935
- xds_client()->cluster_name_, &service_config);
980
+ xds_client()->rds_result_.value(), &service_config);
936
981
  if (error == GRPC_ERROR_NONE) {
937
982
  xds_client()->service_config_watcher_->OnServiceConfigChanged(
938
983
  std::move(service_config));
@@ -944,6 +989,7 @@ void XdsClient::ChannelState::AdsCallState::AcceptRdsUpdate(
944
989
  void XdsClient::ChannelState::AdsCallState::AcceptCdsUpdate(
945
990
  XdsApi::CdsUpdateMap cds_update_map) {
946
991
  auto& cds_state = state_map_[XdsApi::kCdsTypeUrl];
992
+ std::set<std::string> eds_resource_names_seen;
947
993
  for (auto& p : cds_update_map) {
948
994
  const char* cluster_name = p.first.c_str();
949
995
  XdsApi::CdsUpdate& cds_update = p.second;
@@ -952,21 +998,22 @@ void XdsClient::ChannelState::AdsCallState::AcceptCdsUpdate(
952
998
  if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
953
999
  gpr_log(GPR_INFO,
954
1000
  "[xds_client %p] CDS update (cluster=%s) received: "
955
- "eds_service_name=%s, "
956
- "lrs_load_reporting_server_name=%s",
1001
+ "eds_service_name=%s, lrs_load_reporting_server_name=%s",
957
1002
  xds_client(), cluster_name, cds_update.eds_service_name.c_str(),
958
1003
  cds_update.lrs_load_reporting_server_name.has_value()
959
1004
  ? cds_update.lrs_load_reporting_server_name.value().c_str()
960
1005
  : "(N/A)");
961
1006
  }
962
- ClusterState& cluster_state = xds_client()->cluster_map_[cluster_name];
1007
+ // Record the EDS resource names seen.
1008
+ eds_resource_names_seen.insert(cds_update.eds_service_name.empty()
1009
+ ? cluster_name
1010
+ : cds_update.eds_service_name);
963
1011
  // Ignore identical update.
1012
+ ClusterState& cluster_state = xds_client()->cluster_map_[cluster_name];
964
1013
  if (cluster_state.update.has_value() &&
965
- cds_update.eds_service_name ==
966
- cluster_state.update.value().eds_service_name &&
967
- cds_update.lrs_load_reporting_server_name.value() ==
968
- cluster_state.update.value()
969
- .lrs_load_reporting_server_name.value()) {
1014
+ cds_update.eds_service_name == cluster_state.update->eds_service_name &&
1015
+ cds_update.lrs_load_reporting_server_name ==
1016
+ cluster_state.update->lrs_load_reporting_server_name) {
970
1017
  if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
971
1018
  gpr_log(GPR_INFO,
972
1019
  "[xds_client %p] CDS update identical to current, ignoring.",
@@ -975,12 +1022,40 @@ void XdsClient::ChannelState::AdsCallState::AcceptCdsUpdate(
975
1022
  continue;
976
1023
  }
977
1024
  // Update the cluster state.
978
- cluster_state.update.emplace(std::move(cds_update));
1025
+ cluster_state.update = std::move(cds_update);
979
1026
  // Notify all watchers.
980
1027
  for (const auto& p : cluster_state.watchers) {
981
1028
  p.first->OnClusterChanged(cluster_state.update.value());
982
1029
  }
983
1030
  }
1031
+ // For any subscribed resource that is not present in the update,
1032
+ // remove it from the cache and notify watchers that it does not exist.
1033
+ for (const auto& p : cds_state.subscribed_resources) {
1034
+ const std::string& cluster_name = p.first;
1035
+ if (cds_update_map.find(cluster_name) == cds_update_map.end()) {
1036
+ ClusterState& cluster_state = xds_client()->cluster_map_[cluster_name];
1037
+ cluster_state.update.reset();
1038
+ for (const auto& p : cluster_state.watchers) {
1039
+ p.first->OnResourceDoesNotExist();
1040
+ }
1041
+ }
1042
+ }
1043
+ // For any EDS resource that is no longer referred to by any CDS
1044
+ // resources, remove it from the cache and notify watchers that it
1045
+ // does not exist.
1046
+ auto& eds_state = state_map_[XdsApi::kEdsTypeUrl];
1047
+ for (const auto& p : eds_state.subscribed_resources) {
1048
+ const std::string& eds_resource_name = p.first;
1049
+ if (eds_resource_names_seen.find(eds_resource_name) ==
1050
+ eds_resource_names_seen.end()) {
1051
+ EndpointState& endpoint_state =
1052
+ xds_client()->endpoint_map_[eds_resource_name];
1053
+ endpoint_state.update.reset();
1054
+ for (const auto& p : endpoint_state.watchers) {
1055
+ p.first->OnResourceDoesNotExist();
1056
+ }
1057
+ }
1058
+ }
984
1059
  }
985
1060
 
986
1061
  void XdsClient::ChannelState::AdsCallState::AcceptEdsUpdate(
@@ -998,7 +1073,7 @@ void XdsClient::ChannelState::AdsCallState::AcceptEdsUpdate(
998
1073
  " drop categories received (drop_all=%d)",
999
1074
  xds_client(), eds_update.priority_list_update.size(),
1000
1075
  eds_update.drop_config->drop_category_list().size(),
1001
- eds_update.drop_all);
1076
+ eds_update.drop_config->drop_all());
1002
1077
  for (size_t priority = 0;
1003
1078
  priority < eds_update.priority_list_update.size(); ++priority) {
1004
1079
  const auto* locality_map_update = eds_update.priority_list_update.Find(
@@ -1014,18 +1089,17 @@ void XdsClient::ChannelState::AdsCallState::AcceptEdsUpdate(
1014
1089
  "[xds_client %p] Priority %" PRIuPTR ", locality %" PRIuPTR
1015
1090
  " %s has weight %d, contains %" PRIuPTR " server addresses",
1016
1091
  xds_client(), priority, locality_count,
1017
- locality.name->AsHumanReadableString(), locality.lb_weight,
1018
- locality.serverlist.size());
1092
+ locality.name->AsHumanReadableString().c_str(),
1093
+ locality.lb_weight, locality.serverlist.size());
1019
1094
  for (size_t i = 0; i < locality.serverlist.size(); ++i) {
1020
- char* ipport;
1021
- grpc_sockaddr_to_string(&ipport, &locality.serverlist[i].address(),
1022
- false);
1095
+ std::string ipport = grpc_sockaddr_to_string(
1096
+ &locality.serverlist[i].address(), false);
1023
1097
  gpr_log(GPR_INFO,
1024
1098
  "[xds_client %p] Priority %" PRIuPTR ", locality %" PRIuPTR
1025
1099
  " %s, server address %" PRIuPTR ": %s",
1026
1100
  xds_client(), priority, locality_count,
1027
- locality.name->AsHumanReadableString(), i, ipport);
1028
- gpr_free(ipport);
1101
+ locality.name->AsHumanReadableString().c_str(), i,
1102
+ ipport.c_str());
1029
1103
  }
1030
1104
  ++locality_count;
1031
1105
  }
@@ -1043,25 +1117,27 @@ void XdsClient::ChannelState::AdsCallState::AcceptEdsUpdate(
1043
1117
  EndpointState& endpoint_state =
1044
1118
  xds_client()->endpoint_map_[eds_service_name];
1045
1119
  // Ignore identical update.
1046
- const XdsApi::EdsUpdate& prev_update = endpoint_state.update;
1047
- const bool priority_list_changed =
1048
- prev_update.priority_list_update != eds_update.priority_list_update;
1049
- const bool drop_config_changed =
1050
- prev_update.drop_config == nullptr ||
1051
- *prev_update.drop_config != *eds_update.drop_config;
1052
- if (!priority_list_changed && !drop_config_changed) {
1053
- if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
1054
- gpr_log(GPR_INFO,
1055
- "[xds_client %p] EDS update identical to current, ignoring.",
1056
- xds_client());
1120
+ if (endpoint_state.update.has_value()) {
1121
+ const XdsApi::EdsUpdate& prev_update = endpoint_state.update.value();
1122
+ const bool priority_list_changed =
1123
+ prev_update.priority_list_update != eds_update.priority_list_update;
1124
+ const bool drop_config_changed =
1125
+ prev_update.drop_config == nullptr ||
1126
+ *prev_update.drop_config != *eds_update.drop_config;
1127
+ if (!priority_list_changed && !drop_config_changed) {
1128
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
1129
+ gpr_log(GPR_INFO,
1130
+ "[xds_client %p] EDS update identical to current, ignoring.",
1131
+ xds_client());
1132
+ }
1133
+ continue;
1057
1134
  }
1058
- continue;
1059
1135
  }
1060
1136
  // Update the cluster state.
1061
1137
  endpoint_state.update = std::move(eds_update);
1062
1138
  // Notify all watchers.
1063
1139
  for (const auto& p : endpoint_state.watchers) {
1064
- p.first->OnEndpointChanged(endpoint_state.update);
1140
+ p.first->OnEndpointChanged(endpoint_state.update.value());
1065
1141
  }
1066
1142
  }
1067
1143
  }
@@ -1069,19 +1145,18 @@ void XdsClient::ChannelState::AdsCallState::AcceptEdsUpdate(
1069
1145
  void XdsClient::ChannelState::AdsCallState::OnRequestSent(void* arg,
1070
1146
  grpc_error* error) {
1071
1147
  AdsCallState* ads_calld = static_cast<AdsCallState*>(arg);
1072
- ads_calld->xds_client()->combiner_->Run(
1073
- GRPC_CLOSURE_INIT(&ads_calld->on_request_sent_, OnRequestSentLocked,
1074
- ads_calld, nullptr),
1075
- GRPC_ERROR_REF(error));
1148
+ GRPC_ERROR_REF(error); // ref owned by lambda
1149
+ ads_calld->xds_client()->work_serializer_->Run(
1150
+ [ads_calld, error]() { ads_calld->OnRequestSentLocked(error); },
1151
+ DEBUG_LOCATION);
1076
1152
  }
1077
1153
 
1078
1154
  void XdsClient::ChannelState::AdsCallState::OnRequestSentLocked(
1079
- void* arg, grpc_error* error) {
1080
- AdsCallState* self = static_cast<AdsCallState*>(arg);
1081
- if (self->IsCurrentCallOnChannel() && error == GRPC_ERROR_NONE) {
1155
+ grpc_error* error) {
1156
+ if (IsCurrentCallOnChannel() && error == GRPC_ERROR_NONE) {
1082
1157
  // Clean up the sent message.
1083
- grpc_byte_buffer_destroy(self->send_message_payload_);
1084
- self->send_message_payload_ = nullptr;
1158
+ grpc_byte_buffer_destroy(send_message_payload_);
1159
+ send_message_payload_ = nullptr;
1085
1160
  // Continue to send another pending message if any.
1086
1161
  // TODO(roth): The current code to handle buffered messages has the
1087
1162
  // advantage of sending only the most recent list of resource names for
@@ -1091,41 +1166,36 @@ void XdsClient::ChannelState::AdsCallState::OnRequestSentLocked(
1091
1166
  // order of resource types. We need to fix this if we are seeing some
1092
1167
  // resource type(s) starved due to frequent requests of other resource
1093
1168
  // type(s).
1094
- auto it = self->buffered_requests_.begin();
1095
- if (it != self->buffered_requests_.end()) {
1096
- self->SendMessageLocked(*it);
1097
- self->buffered_requests_.erase(it);
1169
+ auto it = buffered_requests_.begin();
1170
+ if (it != buffered_requests_.end()) {
1171
+ SendMessageLocked(*it);
1172
+ buffered_requests_.erase(it);
1098
1173
  }
1099
1174
  }
1100
- self->Unref(DEBUG_LOCATION, "ADS+OnRequestSentLocked");
1175
+ Unref(DEBUG_LOCATION, "ADS+OnRequestSentLocked");
1176
+ GRPC_ERROR_UNREF(error);
1101
1177
  }
1102
1178
 
1103
1179
  void XdsClient::ChannelState::AdsCallState::OnResponseReceived(
1104
- void* arg, grpc_error* error) {
1180
+ void* arg, grpc_error* /* error */) {
1105
1181
  AdsCallState* ads_calld = static_cast<AdsCallState*>(arg);
1106
- ads_calld->xds_client()->combiner_->Run(
1107
- GRPC_CLOSURE_INIT(&ads_calld->on_response_received_,
1108
- OnResponseReceivedLocked, ads_calld, nullptr),
1109
- GRPC_ERROR_REF(error));
1182
+ ads_calld->xds_client()->work_serializer_->Run(
1183
+ [ads_calld]() { ads_calld->OnResponseReceivedLocked(); }, DEBUG_LOCATION);
1110
1184
  }
1111
1185
 
1112
- void XdsClient::ChannelState::AdsCallState::OnResponseReceivedLocked(
1113
- void* arg, grpc_error* /*error*/) {
1114
- AdsCallState* ads_calld = static_cast<AdsCallState*>(arg);
1115
- XdsClient* xds_client = ads_calld->xds_client();
1186
+ void XdsClient::ChannelState::AdsCallState::OnResponseReceivedLocked() {
1116
1187
  // Empty payload means the call was cancelled.
1117
- if (!ads_calld->IsCurrentCallOnChannel() ||
1118
- ads_calld->recv_message_payload_ == nullptr) {
1119
- ads_calld->Unref(DEBUG_LOCATION, "ADS+OnResponseReceivedLocked");
1188
+ if (!IsCurrentCallOnChannel() || recv_message_payload_ == nullptr) {
1189
+ Unref(DEBUG_LOCATION, "ADS+OnResponseReceivedLocked");
1120
1190
  return;
1121
1191
  }
1122
1192
  // Read the response.
1123
1193
  grpc_byte_buffer_reader bbr;
1124
- grpc_byte_buffer_reader_init(&bbr, ads_calld->recv_message_payload_);
1194
+ grpc_byte_buffer_reader_init(&bbr, recv_message_payload_);
1125
1195
  grpc_slice response_slice = grpc_byte_buffer_reader_readall(&bbr);
1126
1196
  grpc_byte_buffer_reader_destroy(&bbr);
1127
- grpc_byte_buffer_destroy(ads_calld->recv_message_payload_);
1128
- ads_calld->recv_message_payload_ = nullptr;
1197
+ grpc_byte_buffer_destroy(recv_message_payload_);
1198
+ recv_message_payload_ = nullptr;
1129
1199
  // TODO(juanlishen): When we convert this to use the xds protocol, the
1130
1200
  // balancer will send us a fallback timeout such that we should go into
1131
1201
  // fallback mode if we have lost contact with the balancer after a certain
@@ -1135,114 +1205,113 @@ void XdsClient::ChannelState::AdsCallState::OnResponseReceivedLocked(
1135
1205
  // mode. We will also need to cancel the timer when we receive a serverlist
1136
1206
  // from the balancer.
1137
1207
  // Parse the response.
1138
- XdsApi::LdsUpdate lds_update;
1139
- XdsApi::RdsUpdate rds_update;
1208
+ absl::optional<XdsApi::LdsUpdate> lds_update;
1209
+ absl::optional<XdsApi::RdsUpdate> rds_update;
1140
1210
  XdsApi::CdsUpdateMap cds_update_map;
1141
1211
  XdsApi::EdsUpdateMap eds_update_map;
1142
1212
  std::string version;
1143
1213
  std::string nonce;
1144
1214
  std::string type_url;
1145
1215
  // Note that ParseAdsResponse() also validates the response.
1146
- grpc_error* parse_error = xds_client->api_.ParseAdsResponse(
1147
- response_slice, xds_client->server_name_, xds_client->route_config_name_,
1148
- ads_calld->EdsServiceNamesForRequest(), &lds_update, &rds_update,
1216
+ grpc_error* parse_error = xds_client()->api_.ParseAdsResponse(
1217
+ response_slice, xds_client()->server_name_,
1218
+ ResourceNamesForRequest(XdsApi::kRdsTypeUrl),
1219
+ ResourceNamesForRequest(XdsApi::kCdsTypeUrl),
1220
+ ResourceNamesForRequest(XdsApi::kEdsTypeUrl), &lds_update, &rds_update,
1149
1221
  &cds_update_map, &eds_update_map, &version, &nonce, &type_url);
1150
1222
  grpc_slice_unref_internal(response_slice);
1151
1223
  if (type_url.empty()) {
1152
1224
  // Ignore unparsable response.
1153
- gpr_log(GPR_ERROR, "[xds_client %p] No type_url found. error=%s",
1154
- xds_client, grpc_error_string(parse_error));
1225
+ gpr_log(GPR_ERROR,
1226
+ "[xds_client %p] Error parsing ADS response (%s) -- ignoring",
1227
+ xds_client(), grpc_error_string(parse_error));
1155
1228
  GRPC_ERROR_UNREF(parse_error);
1156
1229
  } else {
1157
1230
  // Update nonce.
1158
- auto& state = ads_calld->state_map_[type_url];
1231
+ auto& state = state_map_[type_url];
1159
1232
  state.nonce = std::move(nonce);
1160
1233
  // NACK or ACK the response.
1161
1234
  if (parse_error != GRPC_ERROR_NONE) {
1162
1235
  GRPC_ERROR_UNREF(state.error);
1163
1236
  state.error = parse_error;
1164
1237
  // NACK unacceptable update.
1165
- gpr_log(
1166
- GPR_ERROR,
1167
- "[xds_client %p] ADS response can't be accepted, NACKing. error=%s",
1168
- xds_client, grpc_error_string(parse_error));
1169
- ads_calld->SendMessageLocked(type_url);
1238
+ gpr_log(GPR_ERROR,
1239
+ "[xds_client %p] ADS response invalid for resource type %s "
1240
+ "version %s, will NACK: nonce=%s error=%s",
1241
+ xds_client(), type_url.c_str(), version.c_str(),
1242
+ state.nonce.c_str(), grpc_error_string(parse_error));
1243
+ SendMessageLocked(type_url);
1170
1244
  } else {
1171
- ads_calld->seen_response_ = true;
1245
+ seen_response_ = true;
1172
1246
  // Accept the ADS response according to the type_url.
1173
1247
  if (type_url == XdsApi::kLdsTypeUrl) {
1174
- ads_calld->AcceptLdsUpdate(std::move(lds_update));
1248
+ AcceptLdsUpdate(std::move(lds_update));
1175
1249
  } else if (type_url == XdsApi::kRdsTypeUrl) {
1176
- ads_calld->AcceptRdsUpdate(std::move(rds_update));
1250
+ AcceptRdsUpdate(std::move(rds_update));
1177
1251
  } else if (type_url == XdsApi::kCdsTypeUrl) {
1178
- ads_calld->AcceptCdsUpdate(std::move(cds_update_map));
1252
+ AcceptCdsUpdate(std::move(cds_update_map));
1179
1253
  } else if (type_url == XdsApi::kEdsTypeUrl) {
1180
- ads_calld->AcceptEdsUpdate(std::move(eds_update_map));
1254
+ AcceptEdsUpdate(std::move(eds_update_map));
1181
1255
  }
1182
1256
  state.version = std::move(version);
1183
1257
  // ACK the update.
1184
- ads_calld->SendMessageLocked(type_url);
1258
+ SendMessageLocked(type_url);
1185
1259
  // Start load reporting if needed.
1186
- auto& lrs_call = ads_calld->chand()->lrs_calld_;
1260
+ auto& lrs_call = chand()->lrs_calld_;
1187
1261
  if (lrs_call != nullptr) {
1188
1262
  LrsCallState* lrs_calld = lrs_call->calld();
1189
1263
  if (lrs_calld != nullptr) lrs_calld->MaybeStartReportingLocked();
1190
1264
  }
1191
1265
  }
1192
1266
  }
1193
- if (xds_client->shutting_down_) {
1194
- ads_calld->Unref(DEBUG_LOCATION,
1195
- "ADS+OnResponseReceivedLocked+xds_shutdown");
1267
+ if (xds_client()->shutting_down_) {
1268
+ Unref(DEBUG_LOCATION, "ADS+OnResponseReceivedLocked+xds_shutdown");
1196
1269
  return;
1197
1270
  }
1198
1271
  // Keep listening for updates.
1199
1272
  grpc_op op;
1200
1273
  memset(&op, 0, sizeof(op));
1201
1274
  op.op = GRPC_OP_RECV_MESSAGE;
1202
- op.data.recv_message.recv_message = &ads_calld->recv_message_payload_;
1275
+ op.data.recv_message.recv_message = &recv_message_payload_;
1203
1276
  op.flags = 0;
1204
1277
  op.reserved = nullptr;
1205
- GPR_ASSERT(ads_calld->call_ != nullptr);
1278
+ GPR_ASSERT(call_ != nullptr);
1206
1279
  // Reuse the "ADS+OnResponseReceivedLocked" ref taken in ctor.
1207
- GRPC_CLOSURE_INIT(&ads_calld->on_response_received_, OnResponseReceived,
1208
- ads_calld, grpc_schedule_on_exec_ctx);
1209
- const grpc_call_error call_error = grpc_call_start_batch_and_execute(
1210
- ads_calld->call_, &op, 1, &ads_calld->on_response_received_);
1280
+ const grpc_call_error call_error =
1281
+ grpc_call_start_batch_and_execute(call_, &op, 1, &on_response_received_);
1211
1282
  GPR_ASSERT(GRPC_CALL_OK == call_error);
1212
1283
  }
1213
1284
 
1214
1285
  void XdsClient::ChannelState::AdsCallState::OnStatusReceived(
1215
1286
  void* arg, grpc_error* error) {
1216
1287
  AdsCallState* ads_calld = static_cast<AdsCallState*>(arg);
1217
- ads_calld->xds_client()->combiner_->Run(
1218
- GRPC_CLOSURE_INIT(&ads_calld->on_status_received_, OnStatusReceivedLocked,
1219
- ads_calld, nullptr),
1220
- GRPC_ERROR_REF(error));
1288
+ GRPC_ERROR_REF(error); // ref owned by lambda
1289
+ ads_calld->xds_client()->work_serializer_->Run(
1290
+ [ads_calld, error]() { ads_calld->OnStatusReceivedLocked(error); },
1291
+ DEBUG_LOCATION);
1221
1292
  }
1222
1293
 
1223
1294
  void XdsClient::ChannelState::AdsCallState::OnStatusReceivedLocked(
1224
- void* arg, grpc_error* error) {
1225
- AdsCallState* ads_calld = static_cast<AdsCallState*>(arg);
1226
- ChannelState* chand = ads_calld->chand();
1227
- XdsClient* xds_client = ads_calld->xds_client();
1295
+ grpc_error* error) {
1228
1296
  if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
1229
- char* status_details = grpc_slice_to_c_string(ads_calld->status_details_);
1297
+ char* status_details = grpc_slice_to_c_string(status_details_);
1230
1298
  gpr_log(GPR_INFO,
1231
1299
  "[xds_client %p] ADS call status received. Status = %d, details "
1232
1300
  "= '%s', (chand: %p, ads_calld: %p, call: %p), error '%s'",
1233
- xds_client, ads_calld->status_code_, status_details, chand,
1234
- ads_calld, ads_calld->call_, grpc_error_string(error));
1301
+ xds_client(), status_code_, status_details, chand(), this, call_,
1302
+ grpc_error_string(error));
1235
1303
  gpr_free(status_details);
1236
1304
  }
1237
1305
  // Ignore status from a stale call.
1238
- if (ads_calld->IsCurrentCallOnChannel()) {
1306
+ if (IsCurrentCallOnChannel()) {
1239
1307
  // Try to restart the call.
1240
- ads_calld->parent_->OnCallFinishedLocked();
1308
+ parent_->OnCallFinishedLocked();
1241
1309
  // Send error to all watchers.
1242
- xds_client->NotifyOnError(
1310
+ xds_client()->NotifyOnError(
1243
1311
  GRPC_ERROR_CREATE_FROM_STATIC_STRING("xds call failed"));
1244
1312
  }
1245
- ads_calld->Unref(DEBUG_LOCATION, "ADS+OnStatusReceivedLocked");
1313
+ Unref(DEBUG_LOCATION, "ADS+OnStatusReceivedLocked");
1314
+ GRPC_ERROR_UNREF(error);
1246
1315
  }
1247
1316
 
1248
1317
  bool XdsClient::ChannelState::AdsCallState::IsCurrentCallOnChannel() const {
@@ -1252,26 +1321,19 @@ bool XdsClient::ChannelState::AdsCallState::IsCurrentCallOnChannel() const {
1252
1321
  return this == chand()->ads_calld_->calld();
1253
1322
  }
1254
1323
 
1255
- std::set<StringView>
1256
- XdsClient::ChannelState::AdsCallState::ClusterNamesForRequest() {
1257
- std::set<StringView> cluster_names;
1258
- for (auto& p : state_map_[XdsApi::kCdsTypeUrl].subscribed_resources) {
1259
- cluster_names.insert(p.first);
1260
- OrphanablePtr<ResourceState>& state = p.second;
1261
- state->Start(Ref());
1262
- }
1263
- return cluster_names;
1264
- }
1265
-
1266
- std::set<StringView>
1267
- XdsClient::ChannelState::AdsCallState::EdsServiceNamesForRequest() {
1268
- std::set<StringView> eds_names;
1269
- for (auto& p : state_map_[XdsApi::kEdsTypeUrl].subscribed_resources) {
1270
- eds_names.insert(p.first);
1271
- OrphanablePtr<ResourceState>& state = p.second;
1272
- state->Start(Ref());
1324
+ std::set<absl::string_view>
1325
+ XdsClient::ChannelState::AdsCallState::ResourceNamesForRequest(
1326
+ const std::string& type_url) {
1327
+ std::set<absl::string_view> resource_names;
1328
+ auto it = state_map_.find(type_url);
1329
+ if (it != state_map_.end()) {
1330
+ for (auto& p : it->second.subscribed_resources) {
1331
+ resource_names.insert(p.first);
1332
+ OrphanablePtr<ResourceState>& state = p.second;
1333
+ state->Start(Ref());
1334
+ }
1273
1335
  }
1274
- return eds_names;
1336
+ return resource_names;
1275
1337
  }
1276
1338
 
1277
1339
  //
@@ -1287,8 +1349,6 @@ void XdsClient::ChannelState::LrsCallState::Reporter::Orphan() {
1287
1349
  void XdsClient::ChannelState::LrsCallState::Reporter::
1288
1350
  ScheduleNextReportLocked() {
1289
1351
  const grpc_millis next_report_time = ExecCtx::Get()->Now() + report_interval_;
1290
- GRPC_CLOSURE_INIT(&on_next_report_timer_, OnNextReportTimer, this,
1291
- grpc_schedule_on_exec_ctx);
1292
1352
  grpc_timer_init(&next_report_timer_, next_report_time,
1293
1353
  &on_next_report_timer_);
1294
1354
  next_report_timer_callback_pending_ = true;
@@ -1297,21 +1357,21 @@ void XdsClient::ChannelState::LrsCallState::Reporter::
1297
1357
  void XdsClient::ChannelState::LrsCallState::Reporter::OnNextReportTimer(
1298
1358
  void* arg, grpc_error* error) {
1299
1359
  Reporter* self = static_cast<Reporter*>(arg);
1300
- self->xds_client()->combiner_->Run(
1301
- GRPC_CLOSURE_INIT(&self->on_next_report_timer_, OnNextReportTimerLocked,
1302
- self, nullptr),
1303
- GRPC_ERROR_REF(error));
1360
+ GRPC_ERROR_REF(error); // ref owned by lambda
1361
+ self->xds_client()->work_serializer_->Run(
1362
+ [self, error]() { self->OnNextReportTimerLocked(error); },
1363
+ DEBUG_LOCATION);
1304
1364
  }
1305
1365
 
1306
1366
  void XdsClient::ChannelState::LrsCallState::Reporter::OnNextReportTimerLocked(
1307
- void* arg, grpc_error* error) {
1308
- Reporter* self = static_cast<Reporter*>(arg);
1309
- self->next_report_timer_callback_pending_ = false;
1310
- if (error != GRPC_ERROR_NONE || !self->IsCurrentReporterOnCall()) {
1311
- self->Unref(DEBUG_LOCATION, "Reporter+timer");
1312
- return;
1367
+ grpc_error* error) {
1368
+ next_report_timer_callback_pending_ = false;
1369
+ if (error != GRPC_ERROR_NONE || !IsCurrentReporterOnCall()) {
1370
+ Unref(DEBUG_LOCATION, "Reporter+timer");
1371
+ } else {
1372
+ SendReportLocked();
1313
1373
  }
1314
- self->SendReportLocked();
1374
+ GRPC_ERROR_UNREF(error);
1315
1375
  }
1316
1376
 
1317
1377
  namespace {
@@ -1334,8 +1394,8 @@ bool LoadReportCountersAreZero(const XdsApi::ClusterLoadReportMap& snapshot) {
1334
1394
 
1335
1395
  void XdsClient::ChannelState::LrsCallState::Reporter::SendReportLocked() {
1336
1396
  // Construct snapshot from all reported stats.
1337
- XdsApi::ClusterLoadReportMap snapshot =
1338
- xds_client()->BuildLoadReportSnapshot();
1397
+ XdsApi::ClusterLoadReportMap snapshot = xds_client()->BuildLoadReportSnapshot(
1398
+ parent_->send_all_clusters_, parent_->cluster_names_);
1339
1399
  // Skip client load report if the counters were all zero in the last
1340
1400
  // report and they are still zero in this one.
1341
1401
  const bool old_val = last_report_counters_were_zero_;
@@ -1355,8 +1415,6 @@ void XdsClient::ChannelState::LrsCallState::Reporter::SendReportLocked() {
1355
1415
  memset(&op, 0, sizeof(op));
1356
1416
  op.op = GRPC_OP_SEND_MESSAGE;
1357
1417
  op.data.send_message.send_message = parent_->send_message_payload_;
1358
- GRPC_CLOSURE_INIT(&on_report_done_, OnReportDone, this,
1359
- grpc_schedule_on_exec_ctx);
1360
1418
  grpc_call_error call_error = grpc_call_start_batch_and_execute(
1361
1419
  parent_->call_, &op, 1, &on_report_done_);
1362
1420
  if (GPR_UNLIKELY(call_error != GRPC_CALL_OK)) {
@@ -1370,27 +1428,32 @@ void XdsClient::ChannelState::LrsCallState::Reporter::SendReportLocked() {
1370
1428
  void XdsClient::ChannelState::LrsCallState::Reporter::OnReportDone(
1371
1429
  void* arg, grpc_error* error) {
1372
1430
  Reporter* self = static_cast<Reporter*>(arg);
1373
- self->xds_client()->combiner_->Run(
1374
- GRPC_CLOSURE_INIT(&self->on_report_done_, OnReportDoneLocked, self,
1375
- nullptr),
1376
- GRPC_ERROR_REF(error));
1431
+ GRPC_ERROR_REF(error); // ref owned by lambda
1432
+ self->xds_client()->work_serializer_->Run(
1433
+ [self, error]() { self->OnReportDoneLocked(error); }, DEBUG_LOCATION);
1377
1434
  }
1378
1435
 
1379
1436
  void XdsClient::ChannelState::LrsCallState::Reporter::OnReportDoneLocked(
1380
- void* arg, grpc_error* error) {
1381
- Reporter* self = static_cast<Reporter*>(arg);
1382
- grpc_byte_buffer_destroy(self->parent_->send_message_payload_);
1383
- self->parent_->send_message_payload_ = nullptr;
1384
- if (error != GRPC_ERROR_NONE || !self->IsCurrentReporterOnCall()) {
1437
+ grpc_error* error) {
1438
+ grpc_byte_buffer_destroy(parent_->send_message_payload_);
1439
+ parent_->send_message_payload_ = nullptr;
1440
+ // If there are no more registered stats to report, cancel the call.
1441
+ if (xds_client()->load_report_map_.empty()) {
1442
+ parent_->chand()->StopLrsCall();
1443
+ Unref(DEBUG_LOCATION, "Reporter+report_done+no_more_reporters");
1444
+ return;
1445
+ }
1446
+ if (error != GRPC_ERROR_NONE || !IsCurrentReporterOnCall()) {
1385
1447
  // If this reporter is no longer the current one on the call, the reason
1386
1448
  // might be that it was orphaned for a new one due to config update.
1387
- if (!self->IsCurrentReporterOnCall()) {
1388
- self->parent_->MaybeStartReportingLocked();
1449
+ if (!IsCurrentReporterOnCall()) {
1450
+ parent_->MaybeStartReportingLocked();
1389
1451
  }
1390
- self->Unref(DEBUG_LOCATION, "Reporter+report_done");
1391
- return;
1452
+ Unref(DEBUG_LOCATION, "Reporter+report_done");
1453
+ } else {
1454
+ ScheduleNextReportLocked();
1392
1455
  }
1393
- self->ScheduleNextReportLocked();
1456
+ GRPC_ERROR_UNREF(error);
1394
1457
  }
1395
1458
 
1396
1459
  //
@@ -1436,7 +1499,8 @@ XdsClient::ChannelState::LrsCallState::LrsCallState(
1436
1499
  grpc_op* op = ops;
1437
1500
  op->op = GRPC_OP_SEND_INITIAL_METADATA;
1438
1501
  op->data.send_initial_metadata.count = 0;
1439
- op->flags = 0;
1502
+ op->flags = GRPC_INITIAL_METADATA_WAIT_FOR_READY |
1503
+ GRPC_INITIAL_METADATA_WAIT_FOR_READY_EXPLICITLY_SET;
1440
1504
  op->reserved = nullptr;
1441
1505
  op++;
1442
1506
  // Op: send request message.
@@ -1524,90 +1588,81 @@ void XdsClient::ChannelState::LrsCallState::MaybeStartReportingLocked() {
1524
1588
  // Don't start if the ADS call hasn't received any valid response. Note that
1525
1589
  // this must be the first channel because it is the current channel but its
1526
1590
  // ADS call hasn't seen any response.
1527
- AdsCallState* ads_calld = chand()->ads_calld_->calld();
1528
- if (ads_calld == nullptr || !ads_calld->seen_response()) return;
1591
+ if (chand()->ads_calld_ == nullptr ||
1592
+ chand()->ads_calld_->calld() == nullptr ||
1593
+ !chand()->ads_calld_->calld()->seen_response()) {
1594
+ return;
1595
+ }
1529
1596
  // Start reporting.
1530
1597
  reporter_ = MakeOrphanable<Reporter>(
1531
1598
  Ref(DEBUG_LOCATION, "LRS+load_report+start"), load_reporting_interval_);
1532
1599
  }
1533
1600
 
1534
- bool XdsClient::ChannelState::LrsCallState::ShouldSendLoadReports(
1535
- const StringView& cluster_name) const {
1536
- // Only send load reports for the clusters that are asked for by the LRS
1537
- // server.
1538
- return cluster_names_.find(std::string(cluster_name)) != cluster_names_.end();
1539
- }
1540
-
1541
1601
  void XdsClient::ChannelState::LrsCallState::OnInitialRequestSent(
1542
- void* arg, grpc_error* error) {
1602
+ void* arg, grpc_error* /*error*/) {
1543
1603
  LrsCallState* lrs_calld = static_cast<LrsCallState*>(arg);
1544
- lrs_calld->xds_client()->combiner_->Run(
1545
- GRPC_CLOSURE_INIT(&lrs_calld->on_initial_request_sent_,
1546
- OnInitialRequestSentLocked, lrs_calld, nullptr),
1547
- GRPC_ERROR_REF(error));
1604
+ lrs_calld->xds_client()->work_serializer_->Run(
1605
+ [lrs_calld]() { lrs_calld->OnInitialRequestSentLocked(); },
1606
+ DEBUG_LOCATION);
1548
1607
  }
1549
1608
 
1550
- void XdsClient::ChannelState::LrsCallState::OnInitialRequestSentLocked(
1551
- void* arg, grpc_error* /*error*/) {
1552
- LrsCallState* lrs_calld = static_cast<LrsCallState*>(arg);
1609
+ void XdsClient::ChannelState::LrsCallState::OnInitialRequestSentLocked() {
1553
1610
  // Clear the send_message_payload_.
1554
- grpc_byte_buffer_destroy(lrs_calld->send_message_payload_);
1555
- lrs_calld->send_message_payload_ = nullptr;
1556
- lrs_calld->MaybeStartReportingLocked();
1557
- lrs_calld->Unref(DEBUG_LOCATION, "LRS+OnInitialRequestSentLocked");
1611
+ grpc_byte_buffer_destroy(send_message_payload_);
1612
+ send_message_payload_ = nullptr;
1613
+ MaybeStartReportingLocked();
1614
+ Unref(DEBUG_LOCATION, "LRS+OnInitialRequestSentLocked");
1558
1615
  }
1559
1616
 
1560
1617
  void XdsClient::ChannelState::LrsCallState::OnResponseReceived(
1561
- void* arg, grpc_error* error) {
1618
+ void* arg, grpc_error* /*error*/) {
1562
1619
  LrsCallState* lrs_calld = static_cast<LrsCallState*>(arg);
1563
- lrs_calld->xds_client()->combiner_->Run(
1564
- GRPC_CLOSURE_INIT(&lrs_calld->on_response_received_,
1565
- OnResponseReceivedLocked, lrs_calld, nullptr),
1566
- GRPC_ERROR_REF(error));
1620
+ lrs_calld->xds_client()->work_serializer_->Run(
1621
+ [lrs_calld]() { lrs_calld->OnResponseReceivedLocked(); }, DEBUG_LOCATION);
1567
1622
  }
1568
1623
 
1569
- void XdsClient::ChannelState::LrsCallState::OnResponseReceivedLocked(
1570
- void* arg, grpc_error* /*error*/) {
1571
- LrsCallState* lrs_calld = static_cast<LrsCallState*>(arg);
1572
- XdsClient* xds_client = lrs_calld->xds_client();
1624
+ void XdsClient::ChannelState::LrsCallState::OnResponseReceivedLocked() {
1573
1625
  // Empty payload means the call was cancelled.
1574
- if (!lrs_calld->IsCurrentCallOnChannel() ||
1575
- lrs_calld->recv_message_payload_ == nullptr) {
1576
- lrs_calld->Unref(DEBUG_LOCATION, "LRS+OnResponseReceivedLocked");
1626
+ if (!IsCurrentCallOnChannel() || recv_message_payload_ == nullptr) {
1627
+ Unref(DEBUG_LOCATION, "LRS+OnResponseReceivedLocked");
1577
1628
  return;
1578
1629
  }
1579
1630
  // Read the response.
1580
1631
  grpc_byte_buffer_reader bbr;
1581
- grpc_byte_buffer_reader_init(&bbr, lrs_calld->recv_message_payload_);
1632
+ grpc_byte_buffer_reader_init(&bbr, recv_message_payload_);
1582
1633
  grpc_slice response_slice = grpc_byte_buffer_reader_readall(&bbr);
1583
1634
  grpc_byte_buffer_reader_destroy(&bbr);
1584
- grpc_byte_buffer_destroy(lrs_calld->recv_message_payload_);
1585
- lrs_calld->recv_message_payload_ = nullptr;
1635
+ grpc_byte_buffer_destroy(recv_message_payload_);
1636
+ recv_message_payload_ = nullptr;
1586
1637
  // This anonymous lambda is a hack to avoid the usage of goto.
1587
1638
  [&]() {
1588
1639
  // Parse the response.
1640
+ bool send_all_clusters = false;
1589
1641
  std::set<std::string> new_cluster_names;
1590
1642
  grpc_millis new_load_reporting_interval;
1591
- grpc_error* parse_error = xds_client->api_.ParseLrsResponse(
1592
- response_slice, &new_cluster_names, &new_load_reporting_interval);
1643
+ grpc_error* parse_error = xds_client()->api_.ParseLrsResponse(
1644
+ response_slice, &send_all_clusters, &new_cluster_names,
1645
+ &new_load_reporting_interval);
1593
1646
  if (parse_error != GRPC_ERROR_NONE) {
1594
1647
  gpr_log(GPR_ERROR,
1595
1648
  "[xds_client %p] LRS response parsing failed. error=%s",
1596
- xds_client, grpc_error_string(parse_error));
1649
+ xds_client(), grpc_error_string(parse_error));
1597
1650
  GRPC_ERROR_UNREF(parse_error);
1598
1651
  return;
1599
1652
  }
1600
- lrs_calld->seen_response_ = true;
1653
+ seen_response_ = true;
1601
1654
  if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
1602
- gpr_log(GPR_INFO,
1603
- "[xds_client %p] LRS response received, %" PRIuPTR
1604
- " cluster names, load_report_interval=%" PRId64 "ms",
1605
- xds_client, new_cluster_names.size(),
1606
- new_load_reporting_interval);
1655
+ gpr_log(
1656
+ GPR_INFO,
1657
+ "[xds_client %p] LRS response received, %" PRIuPTR
1658
+ " cluster names, send_all_clusters=%d, load_report_interval=%" PRId64
1659
+ "ms",
1660
+ xds_client(), new_cluster_names.size(), send_all_clusters,
1661
+ new_load_reporting_interval);
1607
1662
  size_t i = 0;
1608
1663
  for (const auto& name : new_cluster_names) {
1609
1664
  gpr_log(GPR_INFO, "[xds_client %p] cluster_name %" PRIuPTR ": %s",
1610
- xds_client, i++, name.c_str());
1665
+ xds_client(), i++, name.c_str());
1611
1666
  }
1612
1667
  }
1613
1668
  if (new_load_reporting_interval <
@@ -1618,81 +1673,78 @@ void XdsClient::ChannelState::LrsCallState::OnResponseReceivedLocked(
1618
1673
  gpr_log(GPR_INFO,
1619
1674
  "[xds_client %p] Increased load_report_interval to minimum "
1620
1675
  "value %dms",
1621
- xds_client, GRPC_XDS_MIN_CLIENT_LOAD_REPORTING_INTERVAL_MS);
1676
+ xds_client(), GRPC_XDS_MIN_CLIENT_LOAD_REPORTING_INTERVAL_MS);
1622
1677
  }
1623
1678
  }
1624
1679
  // Ignore identical update.
1625
- if (lrs_calld->cluster_names_ == new_cluster_names &&
1626
- lrs_calld->load_reporting_interval_ == new_load_reporting_interval) {
1680
+ if (send_all_clusters == send_all_clusters_ &&
1681
+ cluster_names_ == new_cluster_names &&
1682
+ load_reporting_interval_ == new_load_reporting_interval) {
1627
1683
  if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
1628
1684
  gpr_log(GPR_INFO,
1629
1685
  "[xds_client %p] Incoming LRS response identical to current, "
1630
1686
  "ignoring.",
1631
- xds_client);
1687
+ xds_client());
1632
1688
  }
1633
1689
  return;
1634
1690
  }
1635
1691
  // Stop current load reporting (if any) to adopt the new config.
1636
- lrs_calld->reporter_.reset();
1692
+ reporter_.reset();
1637
1693
  // Record the new config.
1638
- lrs_calld->cluster_names_ = std::move(new_cluster_names);
1639
- lrs_calld->load_reporting_interval_ = new_load_reporting_interval;
1694
+ send_all_clusters_ = send_all_clusters;
1695
+ cluster_names_ = std::move(new_cluster_names);
1696
+ load_reporting_interval_ = new_load_reporting_interval;
1640
1697
  // Try starting sending load report.
1641
- lrs_calld->MaybeStartReportingLocked();
1698
+ MaybeStartReportingLocked();
1642
1699
  }();
1643
1700
  grpc_slice_unref_internal(response_slice);
1644
- if (xds_client->shutting_down_) {
1645
- lrs_calld->Unref(DEBUG_LOCATION,
1646
- "LRS+OnResponseReceivedLocked+xds_shutdown");
1701
+ if (xds_client()->shutting_down_) {
1702
+ Unref(DEBUG_LOCATION, "LRS+OnResponseReceivedLocked+xds_shutdown");
1647
1703
  return;
1648
1704
  }
1649
1705
  // Keep listening for LRS config updates.
1650
1706
  grpc_op op;
1651
1707
  memset(&op, 0, sizeof(op));
1652
1708
  op.op = GRPC_OP_RECV_MESSAGE;
1653
- op.data.recv_message.recv_message = &lrs_calld->recv_message_payload_;
1709
+ op.data.recv_message.recv_message = &recv_message_payload_;
1654
1710
  op.flags = 0;
1655
1711
  op.reserved = nullptr;
1656
- GPR_ASSERT(lrs_calld->call_ != nullptr);
1712
+ GPR_ASSERT(call_ != nullptr);
1657
1713
  // Reuse the "OnResponseReceivedLocked" ref taken in ctor.
1658
- GRPC_CLOSURE_INIT(&lrs_calld->on_response_received_, OnResponseReceived,
1659
- lrs_calld, grpc_schedule_on_exec_ctx);
1660
- const grpc_call_error call_error = grpc_call_start_batch_and_execute(
1661
- lrs_calld->call_, &op, 1, &lrs_calld->on_response_received_);
1714
+ const grpc_call_error call_error =
1715
+ grpc_call_start_batch_and_execute(call_, &op, 1, &on_response_received_);
1662
1716
  GPR_ASSERT(GRPC_CALL_OK == call_error);
1663
1717
  }
1664
1718
 
1665
1719
  void XdsClient::ChannelState::LrsCallState::OnStatusReceived(
1666
1720
  void* arg, grpc_error* error) {
1667
1721
  LrsCallState* lrs_calld = static_cast<LrsCallState*>(arg);
1668
- lrs_calld->xds_client()->combiner_->Run(
1669
- GRPC_CLOSURE_INIT(&lrs_calld->on_status_received_, OnStatusReceivedLocked,
1670
- lrs_calld, nullptr),
1671
- GRPC_ERROR_REF(error));
1722
+ GRPC_ERROR_REF(error); // ref owned by lambda
1723
+ lrs_calld->xds_client()->work_serializer_->Run(
1724
+ [lrs_calld, error]() { lrs_calld->OnStatusReceivedLocked(error); },
1725
+ DEBUG_LOCATION);
1672
1726
  }
1673
1727
 
1674
1728
  void XdsClient::ChannelState::LrsCallState::OnStatusReceivedLocked(
1675
- void* arg, grpc_error* error) {
1676
- LrsCallState* lrs_calld = static_cast<LrsCallState*>(arg);
1677
- XdsClient* xds_client = lrs_calld->xds_client();
1678
- ChannelState* chand = lrs_calld->chand();
1679
- GPR_ASSERT(lrs_calld->call_ != nullptr);
1729
+ grpc_error* error) {
1730
+ GPR_ASSERT(call_ != nullptr);
1680
1731
  if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
1681
- char* status_details = grpc_slice_to_c_string(lrs_calld->status_details_);
1732
+ char* status_details = grpc_slice_to_c_string(status_details_);
1682
1733
  gpr_log(GPR_INFO,
1683
1734
  "[xds_client %p] LRS call status received. Status = %d, details "
1684
1735
  "= '%s', (chand: %p, calld: %p, call: %p), error '%s'",
1685
- xds_client, lrs_calld->status_code_, status_details, chand,
1686
- lrs_calld, lrs_calld->call_, grpc_error_string(error));
1736
+ xds_client(), status_code_, status_details, chand(), this, call_,
1737
+ grpc_error_string(error));
1687
1738
  gpr_free(status_details);
1688
1739
  }
1689
1740
  // Ignore status from a stale call.
1690
- if (lrs_calld->IsCurrentCallOnChannel()) {
1691
- GPR_ASSERT(!xds_client->shutting_down_);
1741
+ if (IsCurrentCallOnChannel()) {
1742
+ GPR_ASSERT(!xds_client()->shutting_down_);
1692
1743
  // Try to restart the call.
1693
- lrs_calld->parent_->OnCallFinishedLocked();
1744
+ parent_->OnCallFinishedLocked();
1694
1745
  }
1695
- lrs_calld->Unref(DEBUG_LOCATION, "LRS+OnStatusReceivedLocked");
1746
+ Unref(DEBUG_LOCATION, "LRS+OnStatusReceivedLocked");
1747
+ GRPC_ERROR_UNREF(error);
1696
1748
  }
1697
1749
 
1698
1750
  bool XdsClient::ChannelState::LrsCallState::IsCurrentCallOnChannel() const {
@@ -1716,18 +1768,24 @@ grpc_millis GetRequestTimeout(const grpc_channel_args& args) {
1716
1768
 
1717
1769
  } // namespace
1718
1770
 
1719
- XdsClient::XdsClient(Combiner* combiner, grpc_pollset_set* interested_parties,
1720
- StringView server_name,
1771
+ XdsClient::XdsClient(std::shared_ptr<WorkSerializer> work_serializer,
1772
+ grpc_pollset_set* interested_parties,
1773
+ absl::string_view server_name,
1721
1774
  std::unique_ptr<ServiceConfigWatcherInterface> watcher,
1722
1775
  const grpc_channel_args& channel_args, grpc_error** error)
1723
1776
  : InternallyRefCounted<XdsClient>(&grpc_xds_client_trace),
1724
1777
  request_timeout_(GetRequestTimeout(channel_args)),
1725
- combiner_(GRPC_COMBINER_REF(combiner, "xds_client")),
1778
+ work_serializer_(std::move(work_serializer)),
1726
1779
  interested_parties_(interested_parties),
1727
- bootstrap_(XdsBootstrap::ReadFromFile(error)),
1728
- api_(bootstrap_ == nullptr ? nullptr : bootstrap_->node()),
1780
+ bootstrap_(
1781
+ XdsBootstrap::ReadFromFile(this, &grpc_xds_client_trace, error)),
1782
+ api_(this, &grpc_xds_client_trace,
1783
+ bootstrap_ == nullptr ? nullptr : bootstrap_->node()),
1729
1784
  server_name_(server_name),
1730
1785
  service_config_watcher_(std::move(watcher)) {
1786
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
1787
+ gpr_log(GPR_INFO, "[xds_client %p] creating xds client", this);
1788
+ }
1731
1789
  if (*error != GRPC_ERROR_NONE) {
1732
1790
  gpr_log(GPR_ERROR, "[xds_client %p] failed to read bootstrap file: %s",
1733
1791
  this, grpc_error_string(*error));
@@ -1752,9 +1810,16 @@ XdsClient::XdsClient(Combiner* combiner, grpc_pollset_set* interested_parties,
1752
1810
  }
1753
1811
  }
1754
1812
 
1755
- XdsClient::~XdsClient() { GRPC_COMBINER_UNREF(combiner_, "xds_client"); }
1813
+ XdsClient::~XdsClient() {
1814
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
1815
+ gpr_log(GPR_INFO, "[xds_client %p] destroying xds client", this);
1816
+ }
1817
+ }
1756
1818
 
1757
1819
  void XdsClient::Orphan() {
1820
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
1821
+ gpr_log(GPR_INFO, "[xds_client %p] shutting down xds client", this);
1822
+ }
1758
1823
  shutting_down_ = true;
1759
1824
  chand_.reset();
1760
1825
  // We do not clear cluster_map_ and endpoint_map_ if the xds client was
@@ -1771,7 +1836,8 @@ void XdsClient::Orphan() {
1771
1836
  }
1772
1837
 
1773
1838
  void XdsClient::WatchClusterData(
1774
- StringView cluster_name, std::unique_ptr<ClusterWatcherInterface> watcher) {
1839
+ absl::string_view cluster_name,
1840
+ std::unique_ptr<ClusterWatcherInterface> watcher) {
1775
1841
  std::string cluster_name_str = std::string(cluster_name);
1776
1842
  ClusterState& cluster_state = cluster_map_[cluster_name_str];
1777
1843
  ClusterWatcherInterface* w = watcher.get();
@@ -1779,13 +1845,18 @@ void XdsClient::WatchClusterData(
1779
1845
  // If we've already received an CDS update, notify the new watcher
1780
1846
  // immediately.
1781
1847
  if (cluster_state.update.has_value()) {
1848
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
1849
+ gpr_log(GPR_INFO, "[xds_client %p] returning cached cluster data for %s",
1850
+ this, cluster_name_str.c_str());
1851
+ }
1782
1852
  w->OnClusterChanged(cluster_state.update.value());
1783
1853
  }
1784
1854
  chand_->Subscribe(XdsApi::kCdsTypeUrl, cluster_name_str);
1785
1855
  }
1786
1856
 
1787
- void XdsClient::CancelClusterDataWatch(StringView cluster_name,
1788
- ClusterWatcherInterface* watcher) {
1857
+ void XdsClient::CancelClusterDataWatch(absl::string_view cluster_name,
1858
+ ClusterWatcherInterface* watcher,
1859
+ bool delay_unsubscription) {
1789
1860
  if (shutting_down_) return;
1790
1861
  std::string cluster_name_str = std::string(cluster_name);
1791
1862
  ClusterState& cluster_state = cluster_map_[cluster_name_str];
@@ -1794,13 +1865,14 @@ void XdsClient::CancelClusterDataWatch(StringView cluster_name,
1794
1865
  cluster_state.watchers.erase(it);
1795
1866
  if (cluster_state.watchers.empty()) {
1796
1867
  cluster_map_.erase(cluster_name_str);
1797
- chand_->Unsubscribe(XdsApi::kCdsTypeUrl, cluster_name_str);
1868
+ chand_->Unsubscribe(XdsApi::kCdsTypeUrl, cluster_name_str,
1869
+ delay_unsubscription);
1798
1870
  }
1799
1871
  }
1800
1872
  }
1801
1873
 
1802
1874
  void XdsClient::WatchEndpointData(
1803
- StringView eds_service_name,
1875
+ absl::string_view eds_service_name,
1804
1876
  std::unique_ptr<EndpointWatcherInterface> watcher) {
1805
1877
  std::string eds_service_name_str = std::string(eds_service_name);
1806
1878
  EndpointState& endpoint_state = endpoint_map_[eds_service_name_str];
@@ -1808,14 +1880,19 @@ void XdsClient::WatchEndpointData(
1808
1880
  endpoint_state.watchers[w] = std::move(watcher);
1809
1881
  // If we've already received an EDS update, notify the new watcher
1810
1882
  // immediately.
1811
- if (!endpoint_state.update.priority_list_update.empty()) {
1812
- w->OnEndpointChanged(endpoint_state.update);
1883
+ if (endpoint_state.update.has_value()) {
1884
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
1885
+ gpr_log(GPR_INFO, "[xds_client %p] returning cached endpoint data for %s",
1886
+ this, eds_service_name_str.c_str());
1887
+ }
1888
+ w->OnEndpointChanged(endpoint_state.update.value());
1813
1889
  }
1814
1890
  chand_->Subscribe(XdsApi::kEdsTypeUrl, eds_service_name_str);
1815
1891
  }
1816
1892
 
1817
- void XdsClient::CancelEndpointDataWatch(StringView eds_service_name,
1818
- EndpointWatcherInterface* watcher) {
1893
+ void XdsClient::CancelEndpointDataWatch(absl::string_view eds_service_name,
1894
+ EndpointWatcherInterface* watcher,
1895
+ bool delay_unsubscription) {
1819
1896
  if (shutting_down_) return;
1820
1897
  std::string eds_service_name_str = std::string(eds_service_name);
1821
1898
  EndpointState& endpoint_state = endpoint_map_[eds_service_name_str];
@@ -1824,19 +1901,20 @@ void XdsClient::CancelEndpointDataWatch(StringView eds_service_name,
1824
1901
  endpoint_state.watchers.erase(it);
1825
1902
  if (endpoint_state.watchers.empty()) {
1826
1903
  endpoint_map_.erase(eds_service_name_str);
1827
- chand_->Unsubscribe(XdsApi::kEdsTypeUrl, eds_service_name_str);
1904
+ chand_->Unsubscribe(XdsApi::kEdsTypeUrl, eds_service_name_str,
1905
+ delay_unsubscription);
1828
1906
  }
1829
1907
  }
1830
1908
  }
1831
1909
 
1832
1910
  RefCountedPtr<XdsClusterDropStats> XdsClient::AddClusterDropStats(
1833
- StringView lrs_server, StringView cluster_name,
1834
- StringView eds_service_name) {
1911
+ absl::string_view lrs_server, absl::string_view cluster_name,
1912
+ absl::string_view eds_service_name) {
1835
1913
  // TODO(roth): When we add support for direct federation, use the
1836
1914
  // server name specified in lrs_server.
1837
1915
  auto key =
1838
1916
  std::make_pair(std::string(cluster_name), std::string(eds_service_name));
1839
- // We jump through some hoops here to make sure that the StringViews
1917
+ // We jump through some hoops here to make sure that the absl::string_views
1840
1918
  // stored in the XdsClusterDropStats object point to the strings
1841
1919
  // in the load_report_map_ key, so that they have the same lifetime.
1842
1920
  auto it = load_report_map_
@@ -1851,38 +1929,35 @@ RefCountedPtr XdsClient::AddClusterDropStats(
1851
1929
  }
1852
1930
 
1853
1931
  void XdsClient::RemoveClusterDropStats(
1854
- StringView /*lrs_server*/, StringView cluster_name,
1855
- StringView eds_service_name, XdsClusterDropStats* cluster_drop_stats) {
1932
+ absl::string_view /*lrs_server*/, absl::string_view cluster_name,
1933
+ absl::string_view eds_service_name,
1934
+ XdsClusterDropStats* cluster_drop_stats) {
1856
1935
  auto load_report_it = load_report_map_.find(
1857
1936
  std::make_pair(std::string(cluster_name), std::string(eds_service_name)));
1858
1937
  if (load_report_it == load_report_map_.end()) return;
1859
1938
  LoadReportState& load_report_state = load_report_it->second;
1860
1939
  // TODO(roth): When we add support for direct federation, use the
1861
1940
  // server name specified in lrs_server.
1862
- // TODO(roth): In principle, we should try to send a final load report
1863
- // containing whatever final stats have been accumulated since the
1864
- // last load report.
1865
1941
  auto it = load_report_state.drop_stats.find(cluster_drop_stats);
1866
1942
  if (it != load_report_state.drop_stats.end()) {
1867
- load_report_state.drop_stats.erase(it);
1868
- if (load_report_state.drop_stats.empty() &&
1869
- load_report_state.locality_stats.empty()) {
1870
- load_report_map_.erase(load_report_it);
1871
- if (chand_ != nullptr && load_report_map_.empty()) {
1872
- chand_->StopLrsCall();
1873
- }
1943
+ // Record final drop stats in deleted_drop_stats, which will be
1944
+ // added to the next load report.
1945
+ for (const auto& p : cluster_drop_stats->GetSnapshotAndReset()) {
1946
+ load_report_state.deleted_drop_stats[p.first] += p.second;
1874
1947
  }
1948
+ load_report_state.drop_stats.erase(it);
1875
1949
  }
1876
1950
  }
1877
1951
 
1878
1952
  RefCountedPtr<XdsClusterLocalityStats> XdsClient::AddClusterLocalityStats(
1879
- StringView lrs_server, StringView cluster_name, StringView eds_service_name,
1953
+ absl::string_view lrs_server, absl::string_view cluster_name,
1954
+ absl::string_view eds_service_name,
1880
1955
  RefCountedPtr<XdsLocalityName> locality) {
1881
1956
  // TODO(roth): When we add support for direct federation, use the
1882
1957
  // server name specified in lrs_server.
1883
1958
  auto key =
1884
1959
  std::make_pair(std::string(cluster_name), std::string(eds_service_name));
1885
- // We jump through some hoops here to make sure that the StringViews
1960
+ // We jump through some hoops here to make sure that the absl::string_views
1886
1961
  // stored in the XdsClusterLocalityStats object point to the strings
1887
1962
  // in the load_report_map_ key, so that they have the same lifetime.
1888
1963
  auto it = load_report_map_
@@ -1892,15 +1967,16 @@ RefCountedPtr XdsClient::AddClusterLocalityStats(
1892
1967
  Ref(DEBUG_LOCATION, "LocalityStats"), lrs_server,
1893
1968
  it->first.first /*cluster_name*/, it->first.second /*eds_service_name*/,
1894
1969
  locality);
1895
- it->second.locality_stats[std::move(locality)].insert(
1970
+ it->second.locality_stats[std::move(locality)].locality_stats.insert(
1896
1971
  cluster_locality_stats.get());
1897
1972
  chand_->MaybeStartLrsCall();
1898
1973
  return cluster_locality_stats;
1899
1974
  }
1900
1975
 
1901
1976
  void XdsClient::RemoveClusterLocalityStats(
1902
- StringView /*lrs_server*/, StringView cluster_name,
1903
- StringView eds_service_name, const RefCountedPtr<XdsLocalityName>& locality,
1977
+ absl::string_view /*lrs_server*/, absl::string_view cluster_name,
1978
+ absl::string_view eds_service_name,
1979
+ const RefCountedPtr<XdsLocalityName>& locality,
1904
1980
  XdsClusterLocalityStats* cluster_locality_stats) {
1905
1981
  auto load_report_it = load_report_map_.find(
1906
1982
  std::make_pair(std::string(cluster_name), std::string(eds_service_name)));
@@ -1908,25 +1984,16 @@ void XdsClient::RemoveClusterLocalityStats(
1908
1984
  LoadReportState& load_report_state = load_report_it->second;
1909
1985
  // TODO(roth): When we add support for direct federation, use the
1910
1986
  // server name specified in lrs_server.
1911
- // TODO(roth): In principle, we should try to send a final load report
1912
- // containing whatever final stats have been accumulated since the
1913
- // last load report.
1914
1987
  auto locality_it = load_report_state.locality_stats.find(locality);
1915
1988
  if (locality_it == load_report_state.locality_stats.end()) return;
1916
- auto& locality_set = locality_it->second;
1989
+ auto& locality_set = locality_it->second.locality_stats;
1917
1990
  auto it = locality_set.find(cluster_locality_stats);
1918
1991
  if (it != locality_set.end()) {
1992
+ // Record final snapshot in deleted_locality_stats, which will be
1993
+ // added to the next load report.
1994
+ locality_it->second.deleted_locality_stats.emplace_back(
1995
+ cluster_locality_stats->GetSnapshotAndReset());
1919
1996
  locality_set.erase(it);
1920
- if (locality_set.empty()) {
1921
- load_report_state.locality_stats.erase(locality_it);
1922
- if (load_report_state.locality_stats.empty() &&
1923
- load_report_state.drop_stats.empty()) {
1924
- load_report_map_.erase(load_report_it);
1925
- if (chand_ != nullptr && load_report_map_.empty()) {
1926
- chand_->StopLrsCall();
1927
- }
1928
- }
1929
- }
1930
1997
  }
1931
1998
  }
1932
1999
 
@@ -1936,51 +2003,386 @@ void XdsClient::ResetBackoff() {
1936
2003
  }
1937
2004
  }
1938
2005
 
2006
+ namespace {
2007
+ std::string CreateServiceConfigActionCluster(const std::string& cluster_name) {
2008
+ return absl::StrFormat(
2009
+ " \"cds:%s\":{\n"
2010
+ " \"childPolicy\":[ {\n"
2011
+ " \"cds_experimental\":{\n"
2012
+ " \"cluster\": \"%s\"\n"
2013
+ " }\n"
2014
+ " } ]\n"
2015
+ " }",
2016
+ cluster_name, cluster_name);
2017
+ }
2018
+
2019
+ std::string CreateServiceConfigRoute(const std::string& action_name,
2020
+ const XdsApi::RdsUpdate::RdsRoute& route) {
2021
+ std::vector<std::string> headers;
2022
+ for (const auto& header : route.matchers.header_matchers) {
2023
+ std::string header_matcher;
2024
+ switch (header.type) {
2025
+ case XdsApi::RdsUpdate::RdsRoute::Matchers::HeaderMatcher::
2026
+ HeaderMatcherType::EXACT:
2027
+ header_matcher = absl::StrFormat(" \"exact_match\": \"%s\"",
2028
+ header.string_matcher);
2029
+ break;
2030
+ case XdsApi::RdsUpdate::RdsRoute::Matchers::HeaderMatcher::
2031
+ HeaderMatcherType::REGEX:
2032
+ header_matcher = absl::StrFormat(" \"regex_match\": \"%s\"",
2033
+ header.regex_match->pattern());
2034
+ break;
2035
+ case XdsApi::RdsUpdate::RdsRoute::Matchers::HeaderMatcher::
2036
+ HeaderMatcherType::RANGE:
2037
+ header_matcher = absl::StrFormat(
2038
+ " \"range_match\":{\n"
2039
+ " \"start\":%d,\n"
2040
+ " \"end\":%d\n"
2041
+ " }",
2042
+ header.range_start, header.range_end);
2043
+ break;
2044
+ case XdsApi::RdsUpdate::RdsRoute::Matchers::HeaderMatcher::
2045
+ HeaderMatcherType::PRESENT:
2046
+ header_matcher =
2047
+ absl::StrFormat(" \"present_match\": %s",
2048
+ header.present_match ? "true" : "false");
2049
+ break;
2050
+ case XdsApi::RdsUpdate::RdsRoute::Matchers::HeaderMatcher::
2051
+ HeaderMatcherType::PREFIX:
2052
+ header_matcher = absl::StrFormat(
2053
+ " \"prefix_match\": \"%s\"", header.string_matcher);
2054
+ break;
2055
+ case XdsApi::RdsUpdate::RdsRoute::Matchers::HeaderMatcher::
2056
+ HeaderMatcherType::SUFFIX:
2057
+ header_matcher = absl::StrFormat(
2058
+ " \"suffix_match\": \"%s\"", header.string_matcher);
2059
+ break;
2060
+ default:
2061
+ break;
2062
+ }
2063
+ std::vector<std::string> header_parts;
2064
+ header_parts.push_back(
2065
+ absl::StrFormat(" { \n"
2066
+ " \"name\": \"%s\",\n",
2067
+ header.name));
2068
+ header_parts.push_back(header_matcher);
2069
+ if (header.invert_match) {
2070
+ header_parts.push_back(
2071
+ absl::StrFormat(",\n"
2072
+ " \"invert_match\": true"));
2073
+ }
2074
+ header_parts.push_back(
2075
+ absl::StrFormat("\n"
2076
+ " }"));
2077
+ headers.push_back(absl::StrJoin(header_parts, ""));
2078
+ }
2079
+ std::vector<std::string> headers_service_config;
2080
+ if (!headers.empty()) {
2081
+ headers_service_config.push_back("\"headers\":[\n");
2082
+ headers_service_config.push_back(absl::StrJoin(headers, ","));
2083
+ headers_service_config.push_back(" ],\n");
2084
+ }
2085
+ std::string path_match_str;
2086
+ switch (route.matchers.path_matcher.type) {
2087
+ case XdsApi::RdsUpdate::RdsRoute::Matchers::PathMatcher::PathMatcherType::
2088
+ PREFIX:
2089
+ path_match_str = absl::StrFormat(
2090
+ "\"prefix\": \"%s\",\n", route.matchers.path_matcher.string_matcher);
2091
+ break;
2092
+ case XdsApi::RdsUpdate::RdsRoute::Matchers::PathMatcher::PathMatcherType::
2093
+ PATH:
2094
+ path_match_str = absl::StrFormat(
2095
+ "\"path\": \"%s\",\n", route.matchers.path_matcher.string_matcher);
2096
+ break;
2097
+ case XdsApi::RdsUpdate::RdsRoute::Matchers::PathMatcher::PathMatcherType::
2098
+ REGEX:
2099
+ path_match_str =
2100
+ absl::StrFormat("\"regex\": \"%s\",\n",
2101
+ route.matchers.path_matcher.regex_matcher->pattern());
2102
+ break;
2103
+ }
2104
+ return absl::StrFormat(
2105
+ " { \n"
2106
+ " %s"
2107
+ " %s"
2108
+ " %s"
2109
+ " \"action\": \"%s\"\n"
2110
+ " }",
2111
+ path_match_str, absl::StrJoin(headers_service_config, ""),
2112
+ route.matchers.fraction_per_million.has_value()
2113
+ ? absl::StrFormat("\"match_fraction\":%d,\n",
2114
+ route.matchers.fraction_per_million.value())
2115
+ : "",
2116
+ action_name);
2117
+ }
2118
+
2119
+ // Create the service config for one weighted cluster.
2120
+ std::string CreateServiceConfigActionWeightedCluster(
2121
+ const std::string& name,
2122
+ const std::vector<XdsApi::RdsUpdate::RdsRoute::ClusterWeight>& clusters) {
2123
+ std::vector<std::string> config_parts;
2124
+ config_parts.push_back(
2125
+ absl::StrFormat(" \"weighted:%s\":{\n"
2126
+ " \"childPolicy\":[ {\n"
2127
+ " \"weighted_target_experimental\":{\n"
2128
+ " \"targets\":{\n",
2129
+ name));
2130
+ std::vector<std::string> weighted_targets;
2131
+ weighted_targets.reserve(clusters.size());
2132
+ for (const auto& cluster_weight : clusters) {
2133
+ weighted_targets.push_back(absl::StrFormat(
2134
+ " \"%s\":{\n"
2135
+ " \"weight\":%d,\n"
2136
+ " \"childPolicy\":[ {\n"
2137
+ " \"cds_experimental\":{\n"
2138
+ " \"cluster\": \"%s\"\n"
2139
+ " }\n"
2140
+ " } ]\n"
2141
+ " }",
2142
+ cluster_weight.name, cluster_weight.weight, cluster_weight.name));
2143
+ }
2144
+ config_parts.push_back(absl::StrJoin(weighted_targets, ",\n"));
2145
+ config_parts.push_back(
2146
+ " }\n"
2147
+ " }\n"
2148
+ " } ]\n"
2149
+ " }");
2150
+ return absl::StrJoin(config_parts, "");
2151
+ }
2152
+
2153
+ struct WeightedClustersKeys {
2154
+ std::string cluster_names_key;
2155
+ std::string cluster_weights_key;
2156
+ };
2157
+
2158
+ // Returns the cluster names and weights key or the cluster names only key.
2159
+ WeightedClustersKeys GetWeightedClustersKey(
2160
+ const std::vector<XdsApi::RdsUpdate::RdsRoute::ClusterWeight>&
2161
+ weighted_clusters) {
2162
+ std::set<std::string> cluster_names;
2163
+ std::set<std::string> cluster_weights;
2164
+ for (const auto& cluster_weight : weighted_clusters) {
2165
+ cluster_names.emplace(absl::StrFormat("%s", cluster_weight.name));
2166
+ cluster_weights.emplace(
2167
+ absl::StrFormat("%s_%d", cluster_weight.name, cluster_weight.weight));
2168
+ }
2169
+ return {absl::StrJoin(cluster_names, "_"),
2170
+ absl::StrJoin(cluster_weights, "_")};
2171
+ }
2172
+
2173
+ } // namespace
2174
+
2175
+ std::string XdsClient::WeightedClustersActionName(
2176
+ const std::vector<XdsApi::RdsUpdate::RdsRoute::ClusterWeight>&
2177
+ weighted_clusters) {
2178
+ WeightedClustersKeys keys = GetWeightedClustersKey(weighted_clusters);
2179
+ auto cluster_names_map_it =
2180
+ weighted_cluster_index_map_.find(keys.cluster_names_key);
2181
+ GPR_ASSERT(cluster_names_map_it != weighted_cluster_index_map_.end());
2182
+ const auto& cluster_weights_map =
2183
+ cluster_names_map_it->second.cluster_weights_map;
2184
+ auto cluster_weights_map_it =
2185
+ cluster_weights_map.find(keys.cluster_weights_key);
2186
+ GPR_ASSERT(cluster_weights_map_it != cluster_weights_map.end());
2187
+ return absl::StrFormat("%s_%d", keys.cluster_names_key,
2188
+ cluster_weights_map_it->second);
2189
+ }
2190
+
2191
+ void XdsClient::UpdateWeightedClusterIndexMap(
2192
+ const XdsApi::RdsUpdate& rds_update) {
2193
+ // Construct a list of unique WeightedCluster
2194
+ // actions which we need to process: to find action names
2195
+ std::map<std::string /* cluster_weights_key */,
2196
+ std::string /* cluster_names_key */>
2197
+ actions_to_process;
2198
+ for (const auto& route : rds_update.routes) {
2199
+ if (!route.weighted_clusters.empty()) {
2200
+ WeightedClustersKeys keys =
2201
+ GetWeightedClustersKey(route.weighted_clusters);
2202
+ auto action_it = actions_to_process.find(keys.cluster_weights_key);
2203
+ if (action_it == actions_to_process.end()) {
2204
+ actions_to_process[std::move(keys.cluster_weights_key)] =
2205
+ std::move(keys.cluster_names_key);
2206
+ }
2207
+ }
2208
+ }
2209
+ // First pass of all unique WeightedCluster actions: if the exact same
2210
+ // weighted target policy (same clusters and weights) appears in the old map,
2211
+ // then that old action name is taken again and should be moved to the new
2212
+ // map; any other action names from the old set of actions are candidates for
2213
+ // reuse.
2214
+ XdsClient::WeightedClusterIndexMap new_weighted_cluster_index_map;
2215
+ for (auto action_it = actions_to_process.begin();
2216
+ action_it != actions_to_process.end();) {
2217
+ const std::string& cluster_names_key = action_it->second;
2218
+ const std::string& cluster_weights_key = action_it->first;
2219
+ auto old_cluster_names_map_it =
2220
+ weighted_cluster_index_map_.find(cluster_names_key);
2221
+ if (old_cluster_names_map_it != weighted_cluster_index_map_.end()) {
2222
+ // Add cluster_names_key to the new map and copy next_index.
2223
+ auto& new_cluster_names_info =
2224
+ new_weighted_cluster_index_map[cluster_names_key];
2225
+ new_cluster_names_info.next_index =
2226
+ old_cluster_names_map_it->second.next_index;
2227
+ // Lookup cluster_weights_key in old map.
2228
+ auto& old_cluster_weights_map =
2229
+ old_cluster_names_map_it->second.cluster_weights_map;
2230
+ auto old_cluster_weights_map_it =
2231
+ old_cluster_weights_map.find(cluster_weights_key);
2232
+ if (old_cluster_weights_map_it != old_cluster_weights_map.end()) {
2233
+ // same policy found, move from old map to new map.
2234
+ new_cluster_names_info.cluster_weights_map[cluster_weights_key] =
2235
+ old_cluster_weights_map_it->second;
2236
+ old_cluster_weights_map.erase(old_cluster_weights_map_it);
2237
+ // This action has been added to new map, so no need to process it
2238
+ // again.
2239
+ action_it = actions_to_process.erase(action_it);
2240
+ continue;
2241
+ }
2242
+ }
2243
+ ++action_it;
2244
+ }
2245
+ // Second pass of all remaining unique WeightedCluster actions: if clusters
2246
+ // for a new action are the same as an old unused action, reuse the name. If
2247
+ // clusters differ, use a brand new name.
2248
+ for (const auto& action : actions_to_process) {
2249
+ const std::string& cluster_names_key = action.second;
2250
+ const std::string& cluster_weights_key = action.first;
2251
+ auto& new_cluster_names_info =
2252
+ new_weighted_cluster_index_map[cluster_names_key];
2253
+ auto& old_cluster_weights_map =
2254
+ weighted_cluster_index_map_[cluster_names_key].cluster_weights_map;
2255
+ auto old_cluster_weights_it = old_cluster_weights_map.begin();
2256
+ if (old_cluster_weights_it != old_cluster_weights_map.end()) {
2257
+ // There is something to reuse: this action uses the same set
2258
+ // of clusters as a previous action and that action name is not
2259
+ // already taken.
2260
+ new_cluster_names_info.cluster_weights_map[cluster_weights_key] =
2261
+ old_cluster_weights_it->second;
2262
+ // Remove the name from being able to reuse again.
2263
+ old_cluster_weights_map.erase(old_cluster_weights_it);
2264
+ } else {
2265
+ // There is nothing to reuse, take the next index to use and
2266
+ // increment.
2267
+ new_cluster_names_info.cluster_weights_map[cluster_weights_key] =
2268
+ new_cluster_names_info.next_index++;
2269
+ }
2270
+ }
2271
+ weighted_cluster_index_map_ = std::move(new_weighted_cluster_index_map);
2272
+ }
2273
+
1939
2274
  grpc_error* XdsClient::CreateServiceConfig(
1940
- const std::string& cluster_name,
1941
- RefCountedPtr<ServiceConfig>* service_config) const {
1942
- char* json;
1943
- gpr_asprintf(&json,
1944
- "{\n"
1945
- " \"loadBalancingConfig\":[\n"
1946
- " { \"cds_experimental\":{\n"
1947
- " \"cluster\": \"%s\"\n"
1948
- " } }\n"
1949
- " ]\n"
1950
- "}",
1951
- cluster_name.c_str());
2275
+ const XdsApi::RdsUpdate& rds_update,
2276
+ RefCountedPtr<ServiceConfig>* service_config) {
2277
+ UpdateWeightedClusterIndexMap(rds_update);
2278
+ std::vector<std::string> actions_vector;
2279
+ std::vector<std::string> route_table;
2280
+ std::set<std::string> actions_set;
2281
+ for (const auto& route : rds_update.routes) {
2282
+ const std::string action_name =
2283
+ route.weighted_clusters.empty()
2284
+ ? route.cluster_name
2285
+ : WeightedClustersActionName(route.weighted_clusters);
2286
+ if (actions_set.find(action_name) == actions_set.end()) {
2287
+ actions_set.emplace(action_name);
2288
+ actions_vector.push_back(
2289
+ route.weighted_clusters.empty()
2290
+ ? CreateServiceConfigActionCluster(action_name)
2291
+ : CreateServiceConfigActionWeightedCluster(
2292
+ action_name, route.weighted_clusters));
2293
+ }
2294
+ route_table.push_back(CreateServiceConfigRoute(
2295
+ absl::StrFormat("%s:%s",
2296
+ route.weighted_clusters.empty() ? "cds" : "weighted",
2297
+ action_name),
2298
+ route));
2299
+ }
2300
+ std::vector<std::string> config_parts;
2301
+ config_parts.push_back(
2302
+ "{\n"
2303
+ " \"loadBalancingConfig\":[\n"
2304
+ " { \"xds_routing_experimental\":{\n"
2305
+ " \"actions\":{\n");
2306
+ config_parts.push_back(absl::StrJoin(actions_vector, ",\n"));
2307
+ config_parts.push_back(
2308
+ " },\n"
2309
+ " \"routes\":[\n");
2310
+ config_parts.push_back(absl::StrJoin(route_table, ",\n"));
2311
+ config_parts.push_back(
2312
+ " ]\n"
2313
+ " } }\n"
2314
+ " ]\n"
2315
+ "}");
2316
+ std::string json = absl::StrJoin(config_parts, "");
1952
2317
  grpc_error* error = GRPC_ERROR_NONE;
1953
- *service_config = ServiceConfig::Create(json, &error);
1954
- gpr_free(json);
2318
+ *service_config = ServiceConfig::Create(json.c_str(), &error);
1955
2319
  return error;
1956
2320
  }
1957
2321
 
1958
- XdsApi::ClusterLoadReportMap XdsClient::BuildLoadReportSnapshot() {
2322
+ XdsApi::ClusterLoadReportMap XdsClient::BuildLoadReportSnapshot(
2323
+ bool send_all_clusters, const std::set<std::string>& clusters) {
1959
2324
  XdsApi::ClusterLoadReportMap snapshot_map;
1960
- for (auto& p : load_report_map_) {
1961
- const auto& cluster_key = p.first; // cluster and EDS service name
1962
- LoadReportState& load_report = p.second;
1963
- XdsApi::ClusterLoadReport& snapshot = snapshot_map[cluster_key];
2325
+ for (auto load_report_it = load_report_map_.begin();
2326
+ load_report_it != load_report_map_.end();) {
2327
+ // Cluster key is cluster and EDS service name.
2328
+ const auto& cluster_key = load_report_it->first;
2329
+ LoadReportState& load_report = load_report_it->second;
2330
+ // If the CDS response for a cluster indicates to use LRS but the
2331
+ // LRS server does not say that it wants reports for this cluster,
2332
+ // then we'll have stats objects here whose data we're not going to
2333
+ // include in the load report. However, we still need to clear out
2334
+ // the data from the stats objects, so that if the LRS server starts
2335
+ // asking for the data in the future, we don't incorrectly include
2336
+ // data from previous reporting intervals in that future report.
2337
+ const bool record_stats =
2338
+ send_all_clusters || clusters.find(cluster_key.first) != clusters.end();
2339
+ XdsApi::ClusterLoadReport snapshot;
1964
2340
  // Aggregate drop stats.
2341
+ snapshot.dropped_requests = std::move(load_report.deleted_drop_stats);
1965
2342
  for (auto& drop_stats : load_report.drop_stats) {
1966
2343
  for (const auto& p : drop_stats->GetSnapshotAndReset()) {
1967
2344
  snapshot.dropped_requests[p.first] += p.second;
1968
2345
  }
1969
2346
  }
1970
2347
  // Aggregate locality stats.
1971
- for (auto& p : load_report.locality_stats) {
1972
- XdsLocalityName* locality_name = p.first.get();
1973
- auto& locality_stats_set = p.second;
2348
+ for (auto it = load_report.locality_stats.begin();
2349
+ it != load_report.locality_stats.end();) {
2350
+ const RefCountedPtr<XdsLocalityName>& locality_name = it->first;
2351
+ auto& locality_state = it->second;
1974
2352
  XdsClusterLocalityStats::Snapshot& locality_snapshot =
1975
2353
  snapshot.locality_stats[locality_name];
1976
- for (auto& locality_stats : locality_stats_set) {
2354
+ for (auto& locality_stats : locality_state.locality_stats) {
1977
2355
  locality_snapshot += locality_stats->GetSnapshotAndReset();
1978
2356
  }
2357
+ // Add final snapshots from recently deleted locality stats objects.
2358
+ for (auto& deleted_locality_stats :
2359
+ locality_state.deleted_locality_stats) {
2360
+ locality_snapshot += deleted_locality_stats;
2361
+ }
2362
+ locality_state.deleted_locality_stats.clear();
2363
+ // If the only thing left in this entry was final snapshots from
2364
+ // deleted locality stats objects, remove the entry.
2365
+ if (locality_state.locality_stats.empty()) {
2366
+ it = load_report.locality_stats.erase(it);
2367
+ } else {
2368
+ ++it;
2369
+ }
2370
+ }
2371
+ if (record_stats) {
2372
+ // Compute load report interval.
2373
+ const grpc_millis now = ExecCtx::Get()->Now();
2374
+ snapshot.load_report_interval = now - load_report.last_report_time;
2375
+ load_report.last_report_time = now;
2376
+ // Record snapshot.
2377
+ snapshot_map[cluster_key] = std::move(snapshot);
2378
+ }
2379
+ // If the only thing left in this entry was final snapshots from
2380
+ // deleted stats objects, remove the entry.
2381
+ if (load_report.locality_stats.empty() && load_report.drop_stats.empty()) {
2382
+ load_report_it = load_report_map_.erase(load_report_it);
2383
+ } else {
2384
+ ++load_report_it;
1979
2385
  }
1980
- // Compute load report interval.
1981
- const grpc_millis now = ExecCtx::Get()->Now();
1982
- snapshot.load_report_interval = now - load_report.last_report_time;
1983
- load_report.last_report_time = now;
1984
2386
  }
1985
2387
  return snapshot_map;
1986
2388
  }
@@ -2035,4 +2437,10 @@ RefCountedPtr XdsClient::GetFromChannelArgs(
2035
2437
  return nullptr;
2036
2438
  }
2037
2439
 
2440
+ grpc_channel_args* XdsClient::RemoveFromChannelArgs(
2441
+ const grpc_channel_args& args) {
2442
+ const char* arg_name = GRPC_ARG_XDS_CLIENT;
2443
+ return grpc_channel_args_copy_and_remove(&args, &arg_name, 1);
2444
+ }
2445
+
2038
2446
  } // namespace grpc_core