grpc 1.49.1 → 1.50.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 (270) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +54 -153
  3. data/include/grpc/event_engine/endpoint_config.h +11 -5
  4. data/include/grpc/event_engine/event_engine.h +1 -1
  5. data/include/grpc/impl/codegen/atm_gcc_atomic.h +19 -28
  6. data/include/grpc/impl/codegen/atm_gcc_sync.h +0 -2
  7. data/include/grpc/impl/codegen/atm_windows.h +0 -2
  8. data/include/grpc/impl/codegen/grpc_types.h +6 -0
  9. data/src/core/ext/filters/channel_idle/channel_idle_filter.cc +3 -3
  10. data/src/core/ext/filters/client_channel/backup_poller.cc +4 -6
  11. data/src/core/ext/filters/client_channel/client_channel.cc +33 -22
  12. data/src/core/ext/filters/client_channel/client_channel.h +1 -1
  13. data/src/core/ext/filters/client_channel/client_channel_plugin.cc +0 -16
  14. data/src/core/ext/filters/client_channel/http_proxy.cc +12 -19
  15. data/src/core/ext/filters/client_channel/http_proxy.h +3 -2
  16. data/src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc +6 -4
  17. data/src/core/ext/filters/client_channel/lb_policy/child_policy_handler.h +5 -4
  18. data/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc +0 -2
  19. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +112 -96
  20. data/src/core/ext/filters/client_channel/lb_policy/oob_backend_metric.cc +20 -11
  21. data/src/core/ext/filters/client_channel/lb_policy/outlier_detection/outlier_detection.cc +106 -108
  22. data/src/core/ext/filters/client_channel/lb_policy/outlier_detection/outlier_detection.h +16 -0
  23. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +20 -13
  24. data/src/core/ext/filters/client_channel/lb_policy/priority/priority.cc +165 -257
  25. data/src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.cc +218 -231
  26. data/src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.h +10 -6
  27. data/src/core/ext/filters/client_channel/lb_policy/rls/rls.cc +389 -444
  28. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +16 -16
  29. data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +8 -13
  30. data/src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc +84 -96
  31. data/src/core/ext/filters/client_channel/lb_policy/xds/cds.cc +38 -37
  32. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc +106 -186
  33. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc +106 -93
  34. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc +170 -218
  35. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +2 -2
  36. data/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +1 -1
  37. data/src/core/ext/filters/client_channel/resolver/google_c2p/google_c2p_resolver.cc +13 -15
  38. data/src/core/ext/filters/client_channel/resolver/polling_resolver.cc +84 -37
  39. data/src/core/ext/filters/client_channel/resolver/polling_resolver.h +11 -0
  40. data/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc +1 -0
  41. data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc +5 -3
  42. data/src/core/ext/filters/client_channel/resolver_result_parsing.cc +5 -4
  43. data/src/core/ext/filters/client_channel/retry_filter.cc +25 -29
  44. data/src/core/ext/filters/client_channel/subchannel.cc +38 -33
  45. data/src/core/ext/filters/client_channel/subchannel.h +12 -3
  46. data/src/core/ext/filters/client_channel/subchannel_stream_client.cc +1 -2
  47. data/src/core/ext/filters/fault_injection/fault_injection_filter.cc +23 -16
  48. data/src/core/ext/filters/fault_injection/fault_injection_filter.h +8 -0
  49. data/src/core/ext/filters/http/client/http_client_filter.cc +1 -2
  50. data/src/core/ext/filters/http/message_compress/message_compress_filter.cc +2 -4
  51. data/src/core/ext/filters/http/message_compress/message_decompress_filter.cc +0 -2
  52. data/src/core/ext/filters/http/server/http_server_filter.cc +1 -2
  53. data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +12 -8
  54. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +32 -26
  55. data/src/core/ext/transport/chttp2/transport/bin_encoder.cc +1 -1
  56. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +25 -130
  57. data/src/core/ext/transport/chttp2/transport/decode_huff.cc +287 -0
  58. data/src/core/ext/transport/chttp2/transport/decode_huff.h +1018 -0
  59. data/src/core/ext/transport/chttp2/transport/flow_control.cc +83 -51
  60. data/src/core/ext/transport/chttp2/transport/flow_control.h +11 -6
  61. data/src/core/ext/transport/chttp2/transport/frame_ping.cc +1 -2
  62. data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +2 -20
  63. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +28 -28
  64. data/src/core/ext/transport/chttp2/transport/hpack_parser_table.cc +1 -10
  65. data/src/core/ext/transport/chttp2/transport/hpack_parser_table.h +11 -6
  66. data/src/core/ext/transport/chttp2/transport/internal.h +2 -0
  67. data/src/core/ext/transport/chttp2/transport/parsing.cc +44 -0
  68. data/src/core/ext/transport/chttp2/transport/writing.cc +3 -14
  69. data/src/core/ext/transport/inproc/inproc_transport.cc +1 -3
  70. data/src/core/ext/xds/certificate_provider_store.cc +63 -3
  71. data/src/core/ext/xds/certificate_provider_store.h +9 -1
  72. data/src/core/ext/xds/file_watcher_certificate_provider_factory.cc +5 -5
  73. data/src/core/ext/xds/file_watcher_certificate_provider_factory.h +1 -1
  74. data/src/core/ext/xds/xds_api.cc +21 -17
  75. data/src/core/ext/xds/xds_api.h +7 -0
  76. data/src/core/ext/xds/xds_bootstrap.cc +5 -537
  77. data/src/core/ext/xds/xds_bootstrap.h +39 -111
  78. data/src/core/ext/xds/xds_bootstrap_grpc.cc +370 -0
  79. data/src/core/ext/xds/xds_bootstrap_grpc.h +169 -0
  80. data/src/core/ext/xds/xds_client.cc +219 -145
  81. data/src/core/ext/xds/xds_client.h +19 -17
  82. data/src/core/ext/xds/xds_client_grpc.cc +18 -80
  83. data/src/core/ext/xds/xds_client_grpc.h +2 -25
  84. data/src/core/ext/xds/xds_client_stats.cc +4 -4
  85. data/src/core/ext/xds/xds_cluster.cc +87 -79
  86. data/src/core/ext/xds/xds_cluster.h +5 -5
  87. data/src/core/ext/xds/xds_cluster_specifier_plugin.cc +3 -1
  88. data/src/core/ext/xds/xds_common_types.cc +13 -5
  89. data/src/core/ext/xds/xds_endpoint.cc +8 -6
  90. data/src/core/ext/xds/xds_endpoint.h +3 -4
  91. data/src/core/ext/xds/xds_lb_policy_registry.cc +4 -2
  92. data/src/core/ext/xds/xds_listener.cc +25 -20
  93. data/src/core/ext/xds/xds_listener.h +3 -4
  94. data/src/core/ext/xds/xds_resource_type.h +11 -8
  95. data/src/core/ext/xds/xds_route_config.cc +15 -16
  96. data/src/core/ext/xds/xds_route_config.h +3 -3
  97. data/src/core/ext/xds/xds_server_config_fetcher.cc +7 -5
  98. data/src/core/ext/xds/xds_transport_grpc.cc +15 -7
  99. data/src/core/lib/backoff/backoff.cc +2 -4
  100. data/src/core/lib/channel/call_finalization.h +1 -3
  101. data/src/core/lib/channel/channel_args.h +114 -14
  102. data/src/core/lib/channel/channel_trace.cc +3 -4
  103. data/src/core/lib/channel/promise_based_filter.cc +18 -19
  104. data/src/core/lib/channel/status_util.cc +27 -0
  105. data/src/core/lib/channel/status_util.h +10 -0
  106. data/src/core/lib/config/core_configuration.cc +5 -1
  107. data/src/core/lib/config/core_configuration.h +33 -0
  108. data/src/core/lib/debug/stats.cc +26 -30
  109. data/src/core/lib/debug/stats.h +2 -12
  110. data/src/core/lib/debug/stats_data.cc +118 -614
  111. data/src/core/lib/debug/stats_data.h +67 -465
  112. data/src/core/lib/debug/trace.cc +0 -2
  113. data/src/core/lib/event_engine/channel_args_endpoint_config.cc +12 -20
  114. data/src/core/lib/event_engine/channel_args_endpoint_config.h +13 -7
  115. data/src/core/lib/event_engine/forkable.cc +1 -1
  116. data/src/core/lib/event_engine/poller.h +14 -12
  117. data/src/core/lib/event_engine/posix_engine/timer_manager.cc +53 -32
  118. data/src/core/lib/event_engine/posix_engine/timer_manager.h +23 -1
  119. data/src/core/lib/event_engine/thread_pool.cc +131 -94
  120. data/src/core/lib/event_engine/thread_pool.h +56 -23
  121. data/src/core/lib/event_engine/time_util.cc +30 -0
  122. data/src/core/lib/event_engine/time_util.h +32 -0
  123. data/src/core/lib/event_engine/utils.cc +0 -5
  124. data/src/core/lib/event_engine/utils.h +0 -4
  125. data/src/core/lib/event_engine/windows/iocp.cc +13 -7
  126. data/src/core/lib/event_engine/windows/iocp.h +2 -1
  127. data/src/core/lib/event_engine/windows/win_socket.cc +1 -1
  128. data/src/core/lib/experiments/config.cc +146 -0
  129. data/src/core/lib/experiments/config.h +43 -0
  130. data/src/core/lib/experiments/experiments.cc +75 -0
  131. data/src/core/lib/experiments/experiments.h +56 -0
  132. data/src/core/lib/gpr/alloc.cc +1 -9
  133. data/src/core/lib/gpr/log_windows.cc +0 -1
  134. data/src/core/lib/gpr/string_util_windows.cc +3 -30
  135. data/src/core/lib/gpr/sync_abseil.cc +0 -14
  136. data/src/core/lib/gpr/sync_posix.cc +0 -14
  137. data/src/core/lib/gpr/time_posix.cc +0 -6
  138. data/src/core/lib/gpr/time_precise.h +1 -1
  139. data/src/core/lib/gpr/tmpfile_windows.cc +5 -7
  140. data/src/core/lib/gpr/useful.h +11 -0
  141. data/src/core/lib/{gpr → gprpp}/env.h +25 -12
  142. data/src/core/lib/{gpr → gprpp}/env_linux.cc +20 -15
  143. data/src/core/lib/{gpr → gprpp}/env_posix.cc +11 -10
  144. data/src/core/lib/gprpp/env_windows.cc +56 -0
  145. data/src/core/lib/gprpp/fork.cc +14 -22
  146. data/src/core/lib/gprpp/fork.h +0 -8
  147. data/src/core/lib/gprpp/global_config_env.cc +7 -6
  148. data/src/core/lib/gprpp/notification.h +67 -0
  149. data/src/core/lib/gprpp/packed_table.h +40 -0
  150. data/src/core/lib/gprpp/ref_counted_ptr.h +20 -33
  151. data/src/core/lib/gprpp/sorted_pack.h +98 -0
  152. data/src/core/lib/gprpp/status_helper.h +6 -0
  153. data/src/core/lib/gprpp/table.h +9 -1
  154. data/src/core/lib/gprpp/tchar.cc +49 -0
  155. data/src/core/lib/gprpp/tchar.h +33 -0
  156. data/src/core/lib/gprpp/time.cc +21 -0
  157. data/src/core/lib/gprpp/time.h +55 -0
  158. data/src/core/lib/gprpp/validation_errors.cc +61 -0
  159. data/src/core/lib/gprpp/validation_errors.h +110 -0
  160. data/src/core/{ext/filters/client_channel → lib/handshaker}/proxy_mapper.h +3 -3
  161. data/src/core/{ext/filters/client_channel → lib/handshaker}/proxy_mapper_registry.cc +14 -36
  162. data/src/core/lib/handshaker/proxy_mapper_registry.h +75 -0
  163. data/src/core/lib/iomgr/call_combiner.cc +0 -8
  164. data/src/core/lib/iomgr/closure.h +0 -1
  165. data/src/core/lib/iomgr/endpoint_pair_posix.cc +14 -10
  166. data/src/core/lib/iomgr/endpoint_pair_windows.cc +2 -2
  167. data/src/core/lib/iomgr/ev_epoll1_linux.cc +1 -38
  168. data/src/core/lib/iomgr/ev_poll_posix.cc +2 -17
  169. data/src/core/lib/iomgr/exec_ctx.cc +0 -10
  170. data/src/core/lib/iomgr/exec_ctx.h +7 -31
  171. data/src/core/lib/iomgr/iocp_windows.cc +1 -2
  172. data/src/core/lib/iomgr/iomgr.cc +6 -8
  173. data/src/core/lib/iomgr/iomgr_fwd.h +1 -0
  174. data/src/core/lib/iomgr/pollset.h +1 -1
  175. data/src/core/lib/iomgr/pollset_set.h +0 -1
  176. data/src/core/lib/iomgr/resolve_address.h +1 -0
  177. data/src/core/lib/iomgr/resolve_address_impl.h +1 -0
  178. data/src/core/lib/iomgr/resolve_address_posix.cc +1 -0
  179. data/src/core/lib/iomgr/resolve_address_windows.cc +1 -0
  180. data/src/core/lib/iomgr/sockaddr_utils_posix.cc +2 -1
  181. data/src/core/lib/iomgr/socket_utils_common_posix.cc +12 -34
  182. data/src/core/lib/iomgr/socket_utils_posix.cc +83 -1
  183. data/src/core/lib/iomgr/socket_utils_posix.h +98 -6
  184. data/src/core/lib/iomgr/tcp_client.cc +6 -7
  185. data/src/core/lib/iomgr/tcp_client.h +11 -11
  186. data/src/core/lib/iomgr/tcp_client_cfstream.cc +6 -6
  187. data/src/core/lib/iomgr/tcp_client_posix.cc +33 -29
  188. data/src/core/lib/iomgr/tcp_client_posix.h +12 -9
  189. data/src/core/lib/iomgr/tcp_client_windows.cc +6 -6
  190. data/src/core/lib/iomgr/tcp_posix.cc +131 -114
  191. data/src/core/lib/iomgr/tcp_posix.h +3 -1
  192. data/src/core/lib/iomgr/tcp_server.cc +5 -4
  193. data/src/core/lib/iomgr/tcp_server.h +9 -6
  194. data/src/core/lib/iomgr/tcp_server_posix.cc +17 -28
  195. data/src/core/lib/iomgr/tcp_server_utils_posix.h +2 -2
  196. data/src/core/lib/iomgr/tcp_server_utils_posix_common.cc +3 -3
  197. data/src/core/lib/iomgr/tcp_server_windows.cc +6 -7
  198. data/src/core/lib/iomgr/tcp_windows.cc +0 -1
  199. data/src/core/lib/iomgr/tcp_windows.h +0 -1
  200. data/src/core/lib/iomgr/timer_generic.cc +4 -4
  201. data/src/core/lib/iomgr/timer_manager.cc +1 -2
  202. data/src/core/lib/iomgr/wakeup_fd_eventfd.cc +0 -2
  203. data/src/core/lib/json/json_object_loader.cc +21 -52
  204. data/src/core/lib/json/json_object_loader.h +56 -76
  205. data/src/core/lib/json/json_util.cc +2 -1
  206. data/src/core/lib/load_balancing/lb_policy.h +5 -5
  207. data/src/core/lib/load_balancing/lb_policy_registry.cc +29 -55
  208. data/src/core/lib/load_balancing/lb_policy_registry.h +23 -11
  209. data/src/core/lib/promise/activity.h +2 -3
  210. data/src/core/lib/promise/context.h +1 -1
  211. data/src/core/lib/promise/sleep.cc +16 -4
  212. data/src/core/lib/promise/sleep.h +8 -2
  213. data/src/core/lib/resolver/resolver.h +13 -3
  214. data/src/core/lib/resource_quota/api.cc +9 -0
  215. data/src/core/lib/resource_quota/api.h +6 -0
  216. data/src/core/lib/resource_quota/arena.cc +1 -3
  217. data/src/core/lib/resource_quota/memory_quota.cc +8 -24
  218. data/src/core/lib/resource_quota/memory_quota.h +6 -19
  219. data/src/core/lib/resource_quota/periodic_update.cc +2 -3
  220. data/src/core/{ext/xds → lib/security/certificate_provider}/certificate_provider_factory.h +3 -3
  221. data/src/core/lib/security/certificate_provider/certificate_provider_registry.cc +60 -0
  222. data/src/core/lib/security/certificate_provider/certificate_provider_registry.h +70 -0
  223. data/src/core/lib/security/credentials/channel_creds_registry_init.cc +1 -0
  224. data/src/core/lib/security/credentials/external/aws_external_account_credentials.cc +15 -16
  225. data/src/core/lib/security/credentials/external/external_account_credentials.cc +2 -1
  226. data/src/core/lib/security/credentials/google_default/credentials_generic.cc +5 -8
  227. data/src/core/lib/security/credentials/google_default/google_default_credentials.cc +6 -6
  228. data/src/core/lib/security/credentials/jwt/jwt_verifier.cc +3 -2
  229. data/src/core/lib/security/credentials/jwt/jwt_verifier.h +1 -1
  230. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +1 -2
  231. data/src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc +4 -3
  232. data/src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h +4 -2
  233. data/src/core/lib/security/credentials/tls/tls_utils.cc +3 -1
  234. data/src/core/lib/security/transport/client_auth_filter.cc +12 -1
  235. data/src/core/lib/security/transport/secure_endpoint.cc +0 -4
  236. data/src/core/lib/surface/call.cc +1 -11
  237. data/src/core/lib/surface/channel.cc +3 -2
  238. data/src/core/lib/surface/completion_queue.cc +16 -28
  239. data/src/core/lib/surface/completion_queue.h +1 -1
  240. data/src/core/lib/surface/completion_queue_factory.cc +5 -0
  241. data/src/core/lib/surface/init.cc +16 -11
  242. data/src/core/lib/surface/init_internally.cc +24 -0
  243. data/src/core/lib/surface/init_internally.h +28 -0
  244. data/src/core/lib/surface/server.cc +1 -7
  245. data/src/core/lib/surface/server.h +4 -6
  246. data/src/core/lib/surface/version.cc +2 -2
  247. data/src/core/lib/transport/bdp_estimator.cc +1 -3
  248. data/src/core/lib/transport/metadata_batch.cc +2 -3
  249. data/src/core/lib/transport/metadata_batch.h +9 -7
  250. data/src/core/lib/transport/parsed_metadata.h +4 -2
  251. data/src/core/lib/transport/status_conversion.cc +1 -3
  252. data/src/core/lib/transport/tcp_connect_handshaker.cc +9 -5
  253. data/src/core/lib/transport/transport.h +0 -1
  254. data/src/core/lib/transport/transport_impl.h +0 -1
  255. data/src/core/plugin_registry/grpc_plugin_registry.cc +23 -46
  256. data/src/core/plugin_registry/grpc_plugin_registry_extra.cc +13 -25
  257. data/src/ruby/lib/grpc/version.rb +1 -1
  258. data/src/ruby/spec/channel_spec.rb +5 -0
  259. data/src/ruby/spec/generic/server_interceptors_spec.rb +1 -1
  260. data/src/ruby/spec/user_agent_spec.rb +1 -1
  261. metadata +33 -19
  262. data/src/core/ext/filters/client_channel/proxy_mapper_registry.h +0 -56
  263. data/src/core/ext/xds/certificate_provider_registry.cc +0 -103
  264. data/src/core/ext/xds/certificate_provider_registry.h +0 -59
  265. data/src/core/lib/event_engine/promise.h +0 -78
  266. data/src/core/lib/gpr/env_windows.cc +0 -74
  267. data/src/core/lib/gpr/string_windows.h +0 -32
  268. data/src/core/lib/profiling/basic_timers.cc +0 -295
  269. data/src/core/lib/profiling/stap_timers.cc +0 -50
  270. data/src/core/lib/profiling/timers.h +0 -94
@@ -20,10 +20,13 @@
20
20
 
21
21
  #include <inttypes.h>
22
22
 
23
+ #include <functional>
23
24
  #include <utility>
25
+ #include <vector>
24
26
 
25
27
  #include "absl/status/status.h"
26
28
  #include "absl/status/statusor.h"
29
+ #include "absl/strings/str_cat.h"
27
30
  #include "absl/strings/string_view.h"
28
31
  #include "absl/strings/strip.h"
29
32
 
@@ -36,6 +39,7 @@
36
39
  #include "src/core/lib/gprpp/work_serializer.h"
37
40
  #include "src/core/lib/iomgr/exec_ctx.h"
38
41
  #include "src/core/lib/iomgr/timer.h"
42
+ #include "src/core/lib/service_config/service_config.h"
39
43
  #include "src/core/lib/uri/uri_parser.h"
40
44
 
41
45
  namespace grpc_core {
@@ -69,7 +73,16 @@ void PollingResolver::StartLocked() { MaybeStartResolvingLocked(); }
69
73
 
70
74
  void PollingResolver::RequestReresolutionLocked() {
71
75
  if (request_ == nullptr) {
72
- MaybeStartResolvingLocked();
76
+ // If we're still waiting for a result-health callback from the last
77
+ // result we reported, don't trigger the re-resolution until we get
78
+ // that callback.
79
+ if (result_status_state_ ==
80
+ ResultStatusState::kResultHealthCallbackPending) {
81
+ result_status_state_ =
82
+ ResultStatusState::kReresolutionRequestedWhileCallbackWasPending;
83
+ } else {
84
+ MaybeStartResolvingLocked();
85
+ }
73
86
  }
74
87
  }
75
88
 
@@ -126,44 +139,78 @@ void PollingResolver::OnRequestCompleteLocked(Result result) {
126
139
  }
127
140
  request_.reset();
128
141
  if (!shutdown_) {
129
- if (result.service_config.ok() && result.addresses.ok()) {
130
- // Reset backoff state so that we start from the beginning when the
131
- // next request gets triggered.
132
- backoff_.Reset();
133
- } else {
134
- if (GPR_UNLIKELY(tracer_ != nullptr && tracer_->enabled())) {
135
- gpr_log(GPR_INFO,
136
- "[polling resolver %p] resolution failed (will retry): "
137
- "address status \"%s\"; service config status \"%s\"",
138
- this, result.addresses.status().ToString().c_str(),
139
- result.service_config.status().ToString().c_str());
140
- }
141
- // Set up for retry.
142
- // InvalidateNow to avoid getting stuck re-initializing this timer
143
- // in a loop while draining the currently-held WorkSerializer.
144
- // Also see https://github.com/grpc/grpc/issues/26079.
145
- ExecCtx::Get()->InvalidateNow();
146
- Timestamp next_try = backoff_.NextAttemptTime();
147
- Duration timeout = next_try - ExecCtx::Get()->Now();
148
- GPR_ASSERT(!have_next_resolution_timer_);
149
- have_next_resolution_timer_ = true;
150
- if (GPR_UNLIKELY(tracer_ != nullptr && tracer_->enabled())) {
151
- if (timeout > Duration::Zero()) {
152
- gpr_log(GPR_INFO, "[polling resolver %p] retrying in %" PRId64 " ms",
153
- this, timeout.millis());
154
- } else {
155
- gpr_log(GPR_INFO, "[polling resolver %p] retrying immediately", this);
156
- }
157
- }
158
- Ref(DEBUG_LOCATION, "next_resolution_timer").release();
159
- GRPC_CLOSURE_INIT(&on_next_resolution_, OnNextResolution, this, nullptr);
160
- grpc_timer_init(&next_resolution_timer_, next_try, &on_next_resolution_);
142
+ if (GPR_UNLIKELY(tracer_ != nullptr && tracer_->enabled())) {
143
+ gpr_log(GPR_INFO,
144
+ "[polling resolver %p] returning result: "
145
+ "addresses=%s, service_config=%s",
146
+ this,
147
+ result.addresses.ok()
148
+ ? absl::StrCat("<", result.addresses->size(), " addresses>")
149
+ .c_str()
150
+ : result.addresses.status().ToString().c_str(),
151
+ result.service_config.ok()
152
+ ? (*result.service_config == nullptr
153
+ ? "<null>"
154
+ : std::string((*result.service_config)->json_string())
155
+ .c_str())
156
+ : result.service_config.status().ToString().c_str());
161
157
  }
158
+ GPR_ASSERT(result.result_health_callback == nullptr);
159
+ RefCountedPtr<PollingResolver> self =
160
+ Ref(DEBUG_LOCATION, "result_health_callback");
161
+ result.result_health_callback = [self =
162
+ std::move(self)](absl::Status status) {
163
+ self->GetResultStatus(std::move(status));
164
+ };
165
+ result_status_state_ = ResultStatusState::kResultHealthCallbackPending;
162
166
  result_handler_->ReportResult(std::move(result));
163
167
  }
164
168
  Unref(DEBUG_LOCATION, "OnRequestComplete");
165
169
  }
166
170
 
171
+ void PollingResolver::GetResultStatus(absl::Status status) {
172
+ if (GPR_UNLIKELY(tracer_ != nullptr && tracer_->enabled())) {
173
+ gpr_log(GPR_INFO, "[polling resolver %p] result status from channel: %s",
174
+ this, status.ToString().c_str());
175
+ }
176
+ if (status.ok()) {
177
+ // Reset backoff state so that we start from the beginning when the
178
+ // next request gets triggered.
179
+ backoff_.Reset();
180
+ // If a re-resolution attempt was requested while the result-status
181
+ // callback was pending, trigger a new request now.
182
+ if (std::exchange(result_status_state_, ResultStatusState::kNone) ==
183
+ ResultStatusState::kReresolutionRequestedWhileCallbackWasPending) {
184
+ MaybeStartResolvingLocked();
185
+ }
186
+ } else {
187
+ // Set up for retry.
188
+ // InvalidateNow to avoid getting stuck re-initializing this timer
189
+ // in a loop while draining the currently-held WorkSerializer.
190
+ // Also see https://github.com/grpc/grpc/issues/26079.
191
+ ExecCtx::Get()->InvalidateNow();
192
+ Timestamp next_try = backoff_.NextAttemptTime();
193
+ Duration timeout = next_try - Timestamp::Now();
194
+ GPR_ASSERT(!have_next_resolution_timer_);
195
+ have_next_resolution_timer_ = true;
196
+ if (GPR_UNLIKELY(tracer_ != nullptr && tracer_->enabled())) {
197
+ if (timeout > Duration::Zero()) {
198
+ gpr_log(GPR_INFO, "[polling resolver %p] retrying in %" PRId64 " ms",
199
+ this, timeout.millis());
200
+ } else {
201
+ gpr_log(GPR_INFO, "[polling resolver %p] retrying immediately", this);
202
+ }
203
+ }
204
+ Ref(DEBUG_LOCATION, "next_resolution_timer").release();
205
+ GRPC_CLOSURE_INIT(&on_next_resolution_, OnNextResolution, this, nullptr);
206
+ grpc_timer_init(&next_resolution_timer_, next_try, &on_next_resolution_);
207
+ // Reset result_status_state_. Note that even if re-resolution was
208
+ // requested while the result-health callback was pending, we can
209
+ // ignore it here, because we are in backoff to re-resolve anyway.
210
+ result_status_state_ = ResultStatusState::kNone;
211
+ }
212
+ }
213
+
167
214
  void PollingResolver::MaybeStartResolvingLocked() {
168
215
  // If there is an existing timer, the time it fires is the earliest time we
169
216
  // can start the next resolution.
@@ -176,11 +223,11 @@ void PollingResolver::MaybeStartResolvingLocked() {
176
223
  const Timestamp earliest_next_resolution =
177
224
  *last_resolution_timestamp_ + min_time_between_resolutions_;
178
225
  const Duration time_until_next_resolution =
179
- earliest_next_resolution - ExecCtx::Get()->Now();
226
+ earliest_next_resolution - Timestamp::Now();
180
227
  if (time_until_next_resolution > Duration::Zero()) {
181
228
  if (GPR_UNLIKELY(tracer_ != nullptr && tracer_->enabled())) {
182
229
  const Duration last_resolution_ago =
183
- ExecCtx::Get()->Now() - *last_resolution_timestamp_;
230
+ Timestamp::Now() - *last_resolution_timestamp_;
184
231
  gpr_log(GPR_INFO,
185
232
  "[polling resolver %p] in cooldown from last resolution "
186
233
  "(from %" PRId64 " ms ago); will resolve again in %" PRId64
@@ -192,7 +239,7 @@ void PollingResolver::MaybeStartResolvingLocked() {
192
239
  Ref(DEBUG_LOCATION, "next_resolution_timer_cooldown").release();
193
240
  GRPC_CLOSURE_INIT(&on_next_resolution_, OnNextResolution, this, nullptr);
194
241
  grpc_timer_init(&next_resolution_timer_,
195
- ExecCtx::Get()->Now() + time_until_next_resolution,
242
+ Timestamp::Now() + time_until_next_resolution,
196
243
  &on_next_resolution_);
197
244
  return;
198
245
  }
@@ -202,7 +249,7 @@ void PollingResolver::MaybeStartResolvingLocked() {
202
249
 
203
250
  void PollingResolver::StartResolvingLocked() {
204
251
  request_ = StartRequest();
205
- last_resolution_timestamp_ = ExecCtx::Get()->Now();
252
+ last_resolution_timestamp_ = Timestamp::Now();
206
253
  if (GPR_UNLIKELY(tracer_ != nullptr && tracer_->enabled())) {
207
254
  gpr_log(GPR_INFO, "[polling resolver %p] starting resolution, request_=%p",
208
255
  this, request_.get());
@@ -22,6 +22,7 @@
22
22
  #include <memory>
23
23
  #include <string>
24
24
 
25
+ #include "absl/status/status.h"
25
26
  #include "absl/types/optional.h"
26
27
 
27
28
  #include "src/core/lib/backoff/backoff.h"
@@ -77,6 +78,8 @@ class PollingResolver : public Resolver {
77
78
 
78
79
  void OnRequestCompleteLocked(Result result);
79
80
 
81
+ void GetResultStatus(absl::Status status);
82
+
80
83
  static void OnNextResolution(void* arg, grpc_error_handle error);
81
84
  void OnNextResolutionLocked(grpc_error_handle error);
82
85
 
@@ -105,6 +108,14 @@ class PollingResolver : public Resolver {
105
108
  absl::optional<Timestamp> last_resolution_timestamp_;
106
109
  /// retry backoff state
107
110
  BackOff backoff_;
111
+ /// state for handling interactions between re-resolution requests and
112
+ /// result health callbacks
113
+ enum class ResultStatusState {
114
+ kNone,
115
+ kResultHealthCallbackPending,
116
+ kReresolutionRequestedWhileCallbackWasPending,
117
+ };
118
+ ResultStatusState result_status_state_ = ResultStatusState::kNone;
108
119
  };
109
120
 
110
121
  } // namespace grpc_core
@@ -20,6 +20,7 @@
20
20
  #include <memory>
21
21
  #include <string>
22
22
  #include <utility>
23
+ #include <vector>
23
24
 
24
25
  #include "absl/memory/memory.h"
25
26
  #include "absl/status/statusor.h"
@@ -56,6 +56,7 @@
56
56
  #include "src/core/ext/filters/client_channel/config_selector.h"
57
57
  #include "src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.h"
58
58
  #include "src/core/ext/xds/xds_bootstrap.h"
59
+ #include "src/core/ext/xds/xds_bootstrap_grpc.h"
59
60
  #include "src/core/ext/xds/xds_client.h"
60
61
  #include "src/core/ext/xds/xds_client_grpc.h"
61
62
  #include "src/core/ext/xds/xds_http_filters.h"
@@ -813,7 +814,8 @@ void XdsResolver::StartLocked() {
813
814
  if (!uri_.authority().empty()) {
814
815
  // target_uri.authority is set case
815
816
  const auto* authority_config =
816
- xds_client_->bootstrap().LookupAuthority(uri_.authority());
817
+ static_cast<const GrpcXdsBootstrap::GrpcAuthority*>(
818
+ xds_client_->bootstrap().LookupAuthority(uri_.authority()));
817
819
  if (authority_config == nullptr) {
818
820
  absl::Status status = absl::UnavailableError(
819
821
  absl::StrCat("Invalid target URI -- authority not found for ",
@@ -826,7 +828,7 @@ void XdsResolver::StartLocked() {
826
828
  return;
827
829
  }
828
830
  std::string name_template =
829
- authority_config->client_listener_resource_name_template;
831
+ authority_config->client_listener_resource_name_template();
830
832
  if (name_template.empty()) {
831
833
  name_template = absl::StrCat(
832
834
  "xdstp://", URI::PercentEncodeAuthority(uri_.authority()),
@@ -838,7 +840,7 @@ void XdsResolver::StartLocked() {
838
840
  } else {
839
841
  // target_uri.authority not set
840
842
  absl::string_view name_template =
841
- xds_client_->bootstrap()
843
+ static_cast<const GrpcXdsBootstrap&>(xds_client_->bootstrap())
842
844
  .client_default_listener_resource_name_template();
843
845
  if (name_template.empty()) {
844
846
  name_template = "%s";
@@ -85,12 +85,13 @@ absl::StatusOr<std::unique_ptr<ServiceConfigParser::ParsedConfig>>
85
85
  ClientChannelServiceConfigParser::ParseGlobalParams(const ChannelArgs& /*args*/,
86
86
  const Json& json) {
87
87
  std::vector<grpc_error_handle> error_list;
88
+ const auto& lb_policy_registry =
89
+ CoreConfiguration::Get().lb_policy_registry();
88
90
  // Parse LB config.
89
91
  RefCountedPtr<LoadBalancingPolicy::Config> parsed_lb_config;
90
92
  auto it = json.object_value().find("loadBalancingConfig");
91
93
  if (it != json.object_value().end()) {
92
- auto config =
93
- LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(it->second);
94
+ auto config = lb_policy_registry.ParseLoadBalancingConfig(it->second);
94
95
  if (!config.ok()) {
95
96
  error_list.push_back(GRPC_ERROR_CREATE_FROM_CPP_STRING(absl::StrCat(
96
97
  "field:loadBalancingConfig error:", config.status().message())));
@@ -111,8 +112,8 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const ChannelArgs& /*args*/,
111
112
  lb_policy_name[i] = tolower(lb_policy_name[i]);
112
113
  }
113
114
  bool requires_config = false;
114
- if (!LoadBalancingPolicyRegistry::LoadBalancingPolicyExists(
115
- lb_policy_name.c_str(), &requires_config)) {
115
+ if (!lb_policy_registry.LoadBalancingPolicyExists(lb_policy_name.c_str(),
116
+ &requires_config)) {
116
117
  error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
117
118
  "field:loadBalancingPolicy error:Unknown lb policy"));
118
119
  } else if (requires_config) {
@@ -33,7 +33,6 @@
33
33
  #include "absl/strings/string_view.h"
34
34
  #include "absl/strings/strip.h"
35
35
  #include "absl/types/optional.h"
36
- #include "absl/utility/utility.h"
37
36
 
38
37
  #include <grpc/impl/codegen/grpc_types.h>
39
38
  #include <grpc/slice.h>
@@ -351,7 +350,11 @@ class RetryFilter::CallData {
351
350
  // cancel_stream op.
352
351
  static void OnCompleteForCancelOp(void* arg, grpc_error_handle error);
353
352
 
354
- RefCountedPtr<CallAttempt> call_attempt_;
353
+ // This DOES hold a ref, but it cannot be a RefCountedPtr<>, because
354
+ // our dtor unrefs the owning call, which may delete the arena in
355
+ // which we are allocated, which means that running the dtor of any
356
+ // data members after that would cause a crash.
357
+ CallAttempt* call_attempt_;
355
358
  // The batch to use in the LB call.
356
359
  // Its payload field points to CallAttempt::batch_payload_.
357
360
  grpc_transport_stream_op_batch batch_;
@@ -722,8 +725,7 @@ RetryFilter::CallData::CallAttempt::CallAttempt(CallData* calld,
722
725
  if (calld->retry_policy_ != nullptr &&
723
726
  calld->retry_policy_->per_attempt_recv_timeout().has_value()) {
724
727
  Timestamp per_attempt_recv_deadline =
725
- ExecCtx::Get()->Now() +
726
- *calld->retry_policy_->per_attempt_recv_timeout();
728
+ Timestamp::Now() + *calld->retry_policy_->per_attempt_recv_timeout();
727
729
  if (GRPC_TRACE_FLAG_ENABLED(grpc_retry_trace)) {
728
730
  gpr_log(GPR_INFO,
729
731
  "chand=%p calld=%p attempt=%p: per-attempt timeout in %" PRId64
@@ -1330,11 +1332,11 @@ RetryFilter::CallData::CallAttempt::BatchData::BatchData(
1330
1332
  : RefCounted(
1331
1333
  GRPC_TRACE_FLAG_ENABLED(grpc_retry_trace) ? "BatchData" : nullptr,
1332
1334
  refcount),
1333
- call_attempt_(std::move(attempt)) {
1335
+ call_attempt_(attempt.release()) {
1334
1336
  if (GRPC_TRACE_FLAG_ENABLED(grpc_retry_trace)) {
1335
1337
  gpr_log(GPR_INFO, "chand=%p calld=%p attempt=%p: creating batch %p",
1336
- call_attempt_->calld_->chand_, call_attempt_->calld_,
1337
- call_attempt_.get(), this);
1338
+ call_attempt_->calld_->chand_, call_attempt_->calld_, call_attempt_,
1339
+ this);
1338
1340
  }
1339
1341
  // We hold a ref to the call stack for every batch sent on a call attempt.
1340
1342
  // This is because some batches on the call attempt may not complete
@@ -1354,11 +1356,12 @@ RetryFilter::CallData::CallAttempt::BatchData::BatchData(
1354
1356
  RetryFilter::CallData::CallAttempt::BatchData::~BatchData() {
1355
1357
  if (GRPC_TRACE_FLAG_ENABLED(grpc_retry_trace)) {
1356
1358
  gpr_log(GPR_INFO, "chand=%p calld=%p attempt=%p: destroying batch %p",
1357
- call_attempt_->calld_->chand_, call_attempt_->calld_,
1358
- call_attempt_.get(), this);
1359
+ call_attempt_->calld_->chand_, call_attempt_->calld_, call_attempt_,
1360
+ this);
1359
1361
  }
1360
- GRPC_CALL_STACK_UNREF(call_attempt_->calld_->owning_call_, "Retry BatchData");
1361
- call_attempt_.reset(DEBUG_LOCATION, "~BatchData");
1362
+ CallAttempt* call_attempt = std::exchange(call_attempt_, nullptr);
1363
+ GRPC_CALL_STACK_UNREF(call_attempt->calld_->owning_call_, "Retry BatchData");
1364
+ call_attempt->Unref(DEBUG_LOCATION, "~BatchData");
1362
1365
  }
1363
1366
 
1364
1367
  void RetryFilter::CallData::CallAttempt::BatchData::
@@ -1422,7 +1425,7 @@ void RetryFilter::CallData::CallAttempt::BatchData::
1422
1425
  void RetryFilter::CallData::CallAttempt::BatchData::RecvInitialMetadataReady(
1423
1426
  void* arg, grpc_error_handle error) {
1424
1427
  RefCountedPtr<BatchData> batch_data(static_cast<BatchData*>(arg));
1425
- CallAttempt* call_attempt = batch_data->call_attempt_.get();
1428
+ CallAttempt* call_attempt = batch_data->call_attempt_;
1426
1429
  CallData* calld = call_attempt->calld_;
1427
1430
  if (GRPC_TRACE_FLAG_ENABLED(grpc_retry_trace)) {
1428
1431
  gpr_log(GPR_INFO,
@@ -1524,7 +1527,7 @@ void RetryFilter::CallData::CallAttempt::BatchData::
1524
1527
  void RetryFilter::CallData::CallAttempt::BatchData::RecvMessageReady(
1525
1528
  void* arg, grpc_error_handle error) {
1526
1529
  RefCountedPtr<BatchData> batch_data(static_cast<BatchData*>(arg));
1527
- CallAttempt* call_attempt = batch_data->call_attempt_.get();
1530
+ CallAttempt* call_attempt = batch_data->call_attempt_;
1528
1531
  CallData* calld = call_attempt->calld_;
1529
1532
  if (GRPC_TRACE_FLAG_ENABLED(grpc_retry_trace)) {
1530
1533
  gpr_log(GPR_INFO,
@@ -1722,15 +1725,8 @@ void RetryFilter::CallData::CallAttempt::BatchData::RunClosuresForCompletedCall(
1722
1725
 
1723
1726
  void RetryFilter::CallData::CallAttempt::BatchData::RecvTrailingMetadataReady(
1724
1727
  void* arg, grpc_error_handle error) {
1725
- // Add a ref to the outer call stack. This works around a TSAN reported
1726
- // failure that we do not understand, but since we expect the lifetime of
1727
- // this code to be relatively short we think it's OK to work around for now.
1728
- // TSAN failure:
1729
- // https://source.cloud.google.com/results/invocations/5b122974-4977-4862-beb1-dc1af9fbbd1d/targets/%2F%2Ftest%2Fcore%2Fend2end:h2_census_test@max_concurrent_streams@poller%3Dpoll/log
1730
- RefCountedPtr<grpc_call_stack> owning_call_stack =
1731
- static_cast<BatchData*>(arg)->call_attempt_->calld_->owning_call_->Ref();
1732
1728
  RefCountedPtr<BatchData> batch_data(static_cast<BatchData*>(arg));
1733
- CallAttempt* call_attempt = batch_data->call_attempt_.get();
1729
+ CallAttempt* call_attempt = batch_data->call_attempt_;
1734
1730
  CallData* calld = call_attempt->calld_;
1735
1731
  if (GRPC_TRACE_FLAG_ENABLED(grpc_retry_trace)) {
1736
1732
  gpr_log(GPR_INFO,
@@ -1886,7 +1882,7 @@ void RetryFilter::CallData::CallAttempt::BatchData::
1886
1882
  gpr_log(GPR_INFO,
1887
1883
  "chand=%p calld=%p attempt=%p: starting next batch for pending "
1888
1884
  "send op(s)",
1889
- calld->chand_, calld, call_attempt_.get());
1885
+ calld->chand_, calld, call_attempt_);
1890
1886
  }
1891
1887
  call_attempt_->AddRetriableBatches(closures);
1892
1888
  }
@@ -1895,7 +1891,7 @@ void RetryFilter::CallData::CallAttempt::BatchData::
1895
1891
  void RetryFilter::CallData::CallAttempt::BatchData::OnComplete(
1896
1892
  void* arg, grpc_error_handle error) {
1897
1893
  RefCountedPtr<BatchData> batch_data(static_cast<BatchData*>(arg));
1898
- CallAttempt* call_attempt = batch_data->call_attempt_.get();
1894
+ CallAttempt* call_attempt = batch_data->call_attempt_;
1899
1895
  CallData* calld = call_attempt->calld_;
1900
1896
  if (GRPC_TRACE_FLAG_ENABLED(grpc_retry_trace)) {
1901
1897
  gpr_log(GPR_INFO,
@@ -1971,7 +1967,7 @@ void RetryFilter::CallData::CallAttempt::BatchData::OnComplete(
1971
1967
  void RetryFilter::CallData::CallAttempt::BatchData::OnCompleteForCancelOp(
1972
1968
  void* arg, grpc_error_handle error) {
1973
1969
  RefCountedPtr<BatchData> batch_data(static_cast<BatchData*>(arg));
1974
- CallAttempt* call_attempt = batch_data->call_attempt_.get();
1970
+ CallAttempt* call_attempt = batch_data->call_attempt_;
1975
1971
  CallData* calld = call_attempt->calld_;
1976
1972
  if (GRPC_TRACE_FLAG_ENABLED(grpc_retry_trace)) {
1977
1973
  gpr_log(GPR_INFO,
@@ -2022,7 +2018,7 @@ void RetryFilter::CallData::CallAttempt::BatchData::
2022
2018
  GPR_INFO,
2023
2019
  "chand=%p calld=%p attempt=%p: starting calld->send_messages[%" PRIuPTR
2024
2020
  "]",
2025
- calld->chand_, calld, call_attempt_.get(),
2021
+ calld->chand_, calld, call_attempt_,
2026
2022
  call_attempt_->started_send_message_count_);
2027
2023
  }
2028
2024
  CachedSendMessage cache =
@@ -2367,7 +2363,7 @@ void RetryFilter::CallData::MaybeCacheSendOpsForBatch(PendingBatch* pending) {
2367
2363
  // Set up cache for send_message ops.
2368
2364
  if (batch->send_message) {
2369
2365
  SliceBuffer* cache = arena_->New<SliceBuffer>(std::move(
2370
- *absl::exchange(batch->payload->send_message.send_message, nullptr)));
2366
+ *std::exchange(batch->payload->send_message.send_message, nullptr)));
2371
2367
  send_messages_.push_back({cache, batch->payload->send_message.flags});
2372
2368
  }
2373
2369
  // Save metadata batch for send_trailing_metadata ops.
@@ -2394,7 +2390,7 @@ void RetryFilter::CallData::FreeCachedSendMessage(size_t idx) {
2394
2390
  "chand=%p calld=%p: destroying send_messages[%" PRIuPTR "]",
2395
2391
  chand_, this, idx);
2396
2392
  }
2397
- Destruct(absl::exchange(send_messages_[idx].slices, nullptr));
2393
+ Destruct(std::exchange(send_messages_[idx].slices, nullptr));
2398
2394
  }
2399
2395
  }
2400
2396
 
@@ -2607,7 +2603,7 @@ void RetryFilter::CallData::StartRetryTimer(
2607
2603
  Timestamp next_attempt_time;
2608
2604
  if (server_pushback.has_value()) {
2609
2605
  GPR_ASSERT(*server_pushback >= Duration::Zero());
2610
- next_attempt_time = ExecCtx::Get()->Now() + *server_pushback;
2606
+ next_attempt_time = Timestamp::Now() + *server_pushback;
2611
2607
  retry_backoff_.Reset();
2612
2608
  } else {
2613
2609
  next_attempt_time = retry_backoff_.NextAttemptTime();
@@ -2615,7 +2611,7 @@ void RetryFilter::CallData::StartRetryTimer(
2615
2611
  if (GRPC_TRACE_FLAG_ENABLED(grpc_retry_trace)) {
2616
2612
  gpr_log(GPR_INFO,
2617
2613
  "chand=%p calld=%p: retrying failed call in %" PRId64 " ms", chand_,
2618
- this, (next_attempt_time - ExecCtx::Get()->Now()).millis());
2614
+ this, (next_attempt_time - Timestamp::Now()).millis());
2619
2615
  }
2620
2616
  // Schedule retry after computed delay.
2621
2617
  GRPC_CLOSURE_INIT(&retry_closure_, OnRetryTimer, this, nullptr);
@@ -27,15 +27,16 @@
27
27
  #include <utility>
28
28
 
29
29
  #include "absl/status/statusor.h"
30
+ #include "absl/strings/cord.h"
31
+ #include "absl/strings/str_cat.h"
32
+ #include "absl/strings/string_view.h"
30
33
 
31
- #include <grpc/grpc.h>
32
34
  #include <grpc/impl/codegen/grpc_types.h>
33
35
  #include <grpc/slice.h>
34
36
  #include <grpc/status.h>
35
37
  #include <grpc/support/log.h>
36
38
 
37
39
  #include "src/core/ext/filters/client_channel/health/health_check_client.h"
38
- #include "src/core/ext/filters/client_channel/proxy_mapper_registry.h"
39
40
  #include "src/core/ext/filters/client_channel/subchannel_pool_interface.h"
40
41
  #include "src/core/ext/filters/client_channel/subchannel_stream_client.h"
41
42
  #include "src/core/lib/address_utils/sockaddr_utils.h"
@@ -55,18 +56,15 @@
55
56
  #include "src/core/lib/gprpp/debug_location.h"
56
57
  #include "src/core/lib/gprpp/ref_counted_ptr.h"
57
58
  #include "src/core/lib/gprpp/sync.h"
59
+ #include "src/core/lib/handshaker/proxy_mapper_registry.h"
58
60
  #include "src/core/lib/iomgr/exec_ctx.h"
59
61
  #include "src/core/lib/iomgr/pollset_set.h"
60
- #include "src/core/lib/profiling/timers.h"
61
62
  #include "src/core/lib/surface/channel_init.h"
62
63
  #include "src/core/lib/surface/channel_stack_type.h"
64
+ #include "src/core/lib/surface/init_internally.h"
63
65
  #include "src/core/lib/transport/connectivity_state.h"
64
66
  #include "src/core/lib/transport/error_utils.h"
65
67
 
66
- // Strong and weak refs.
67
- #define INTERNAL_REF_BITS 16
68
- #define STRONG_REF_MASK (~(gpr_atm)((1 << INTERNAL_REF_BITS) - 1))
69
-
70
68
  // Backoff parameters.
71
69
  #define GRPC_SUBCHANNEL_INITIAL_CONNECT_BACKOFF_SECONDS 1
72
70
  #define GRPC_SUBCHANNEL_RECONNECT_BACKOFF_MULTIPLIER 1.6
@@ -175,7 +173,6 @@ SubchannelCall::SubchannelCall(Args args, grpc_error_handle* error)
175
173
 
176
174
  void SubchannelCall::StartTransportStreamOpBatch(
177
175
  grpc_transport_stream_op_batch* batch) {
178
- GPR_TIMER_SCOPE("subchannel_call_process_op", 0);
179
176
  MaybeInterceptRecvTrailingMetadata(batch);
180
177
  grpc_call_stack* call_stack = SUBCHANNEL_CALL_TO_CALL_STACK(this);
181
178
  grpc_call_element* top_elem = grpc_call_stack_element(call_stack, 0);
@@ -214,7 +211,6 @@ void SubchannelCall::Unref(const DebugLocation& /*location*/,
214
211
  }
215
212
 
216
213
  void SubchannelCall::Destroy(void* arg, grpc_error_handle /*error*/) {
217
- GPR_TIMER_SCOPE("subchannel_call_destroy", 0);
218
214
  SubchannelCall* self = static_cast<SubchannelCall*>(arg);
219
215
  // Keep some members before destroying the subchannel call.
220
216
  grpc_closure* after_call_stack_destroy = self->after_call_stack_destroy_;
@@ -640,13 +636,15 @@ Subchannel::Subchannel(SubchannelKey key,
640
636
  // before the last subchannel destruction, then there maybe race conditions
641
637
  // triggering segmentation faults. To prevent this issue, we call a grpc_init
642
638
  // here and a grpc_shutdown in the subchannel destructor.
643
- grpc_init();
639
+ InitInternally();
644
640
  GRPC_STATS_INC_CLIENT_SUBCHANNELS_CREATED();
645
641
  GRPC_CLOSURE_INIT(&on_connecting_finished_, OnConnectingFinished, this,
646
642
  grpc_schedule_on_exec_ctx);
647
643
  // Check proxy mapper to determine address to connect to and channel
648
644
  // args to use.
649
- address_for_connect_ = ProxyMapperRegistry::MapAddress(key_.address(), &args_)
645
+ address_for_connect_ = CoreConfiguration::Get()
646
+ .proxy_mapper_registry()
647
+ .MapAddress(key_.address(), &args_)
650
648
  .value_or(key_.address());
651
649
  // Initialize channelz.
652
650
  const bool channelz_enabled = args_.GetBool(GRPC_ARG_ENABLE_CHANNELZ)
@@ -676,7 +674,7 @@ Subchannel::~Subchannel() {
676
674
  connector_.reset();
677
675
  grpc_pollset_set_destroy(pollset_set_);
678
676
  // grpc_shutdown is called here because grpc_init is called in the ctor.
679
- grpc_shutdown();
677
+ ShutdownInternally();
680
678
  }
681
679
 
682
680
  RefCountedPtr<Subchannel> Subchannel::Create(
@@ -769,7 +767,7 @@ void Subchannel::ResetBackoff() {
769
767
  GetDefaultEventEngine()->Cancel(retry_timer_handle_)) {
770
768
  OnRetryTimerLocked();
771
769
  } else if (state_ == GRPC_CHANNEL_CONNECTING) {
772
- next_attempt_time_ = ExecCtx::Get()->Now();
770
+ next_attempt_time_ = Timestamp::Now();
773
771
  }
774
772
  }
775
773
 
@@ -788,27 +786,20 @@ void Subchannel::Orphan() {
788
786
  health_watcher_map_.ShutdownLocked();
789
787
  }
790
788
 
791
- void Subchannel::AddDataProducer(DataProducerInterface* data_producer) {
789
+ void Subchannel::GetOrAddDataProducer(
790
+ UniqueTypeName type,
791
+ std::function<void(DataProducerInterface**)> get_or_add) {
792
792
  MutexLock lock(&mu_);
793
- auto& entry = data_producer_map_[data_producer->type()];
794
- GPR_ASSERT(entry == nullptr);
795
- entry = data_producer;
793
+ auto it = data_producer_map_.emplace(type, nullptr).first;
794
+ get_or_add(&it->second);
796
795
  }
797
796
 
798
797
  void Subchannel::RemoveDataProducer(DataProducerInterface* data_producer) {
799
798
  MutexLock lock(&mu_);
800
799
  auto it = data_producer_map_.find(data_producer->type());
801
- GPR_ASSERT(it != data_producer_map_.end());
802
- GPR_ASSERT(it->second == data_producer);
803
- data_producer_map_.erase(it);
804
- }
805
-
806
- Subchannel::DataProducerInterface* Subchannel::GetDataProducer(
807
- UniqueTypeName type) {
808
- MutexLock lock(&mu_);
809
- auto it = data_producer_map_.find(type);
810
- if (it == data_producer_map_.end()) return nullptr;
811
- return it->second;
800
+ if (it != data_producer_map_.end() && it->second == data_producer) {
801
+ data_producer_map_.erase(it);
802
+ }
812
803
  }
813
804
 
814
805
  namespace {
@@ -838,7 +829,21 @@ const char* SubchannelConnectivityStateChangeString(
838
829
  void Subchannel::SetConnectivityStateLocked(grpc_connectivity_state state,
839
830
  const absl::Status& status) {
840
831
  state_ = state;
841
- status_ = status;
832
+ if (status.ok()) {
833
+ status_ = status;
834
+ } else {
835
+ // Augment status message to include IP address.
836
+ status_ = absl::Status(status.code(),
837
+ absl::StrCat(grpc_sockaddr_to_uri(&key_.address())
838
+ .value_or("<unknown address type>"),
839
+ ": ", status.message()));
840
+ status.ForEachPayload(
841
+ [this](absl::string_view key, const absl::Cord& value)
842
+ // Want to use ABSL_EXCLUSIVE_LOCKS_REQUIRED(&mu_) here,
843
+ // but that won't work, because we can't pass the lock
844
+ // annotation through absl::Status::ForEachPayload().
845
+ ABSL_NO_THREAD_SAFETY_ANALYSIS { status_.SetPayload(key, value); });
846
+ }
842
847
  if (channelz_node_ != nullptr) {
843
848
  channelz_node_->UpdateConnectivityState(state);
844
849
  channelz_node_->AddTraceEvent(
@@ -847,9 +852,9 @@ void Subchannel::SetConnectivityStateLocked(grpc_connectivity_state state,
847
852
  SubchannelConnectivityStateChangeString(state)));
848
853
  }
849
854
  // Notify non-health watchers.
850
- watcher_list_.NotifyLocked(state, status);
855
+ watcher_list_.NotifyLocked(state, status_);
851
856
  // Notify health watchers.
852
- health_watcher_map_.NotifyLocked(state, status);
857
+ health_watcher_map_.NotifyLocked(state, status_);
853
858
  }
854
859
 
855
860
  void Subchannel::OnRetryTimer() {
@@ -866,7 +871,7 @@ void Subchannel::OnRetryTimerLocked() {
866
871
 
867
872
  void Subchannel::StartConnectingLocked() {
868
873
  // Set next attempt time.
869
- const Timestamp min_deadline = min_connect_timeout_ + ExecCtx::Get()->Now();
874
+ const Timestamp min_deadline = min_connect_timeout_ + Timestamp::Now();
870
875
  next_attempt_time_ = backoff_.NextAttemptTime();
871
876
  // Report CONNECTING.
872
877
  SetConnectivityStateLocked(GRPC_CHANNEL_CONNECTING, absl::OkStatus());
@@ -901,7 +906,7 @@ void Subchannel::OnConnectingFinishedLocked(grpc_error_handle error) {
901
906
  // transition back to IDLE.
902
907
  if (connecting_result_.transport == nullptr || !PublishTransportLocked()) {
903
908
  const Duration time_until_next_attempt =
904
- next_attempt_time_ - ExecCtx::Get()->Now();
909
+ next_attempt_time_ - Timestamp::Now();
905
910
  gpr_log(GPR_INFO,
906
911
  "subchannel %p %s: connect failed (%s), backing off for %" PRId64
907
912
  " ms",
@@ -22,6 +22,7 @@
22
22
  #include <stddef.h>
23
23
 
24
24
  #include <deque>
25
+ #include <functional>
25
26
  #include <map>
26
27
  #include <string>
27
28
 
@@ -278,12 +279,20 @@ class Subchannel : public DualRefCounted<Subchannel> {
278
279
  // We do not hold refs to the data producer; the implementation is
279
280
  // expected to register itself upon construction and remove itself
280
281
  // upon destruction.
281
- void AddDataProducer(DataProducerInterface* data_producer)
282
+ //
283
+ // Looks up the current data producer for type and invokes get_or_add()
284
+ // with a pointer to that producer in the map. The get_or_add() function
285
+ // can modify the pointed-to value to update the map. This provides a
286
+ // way to either re-use an existing producer or register a new one in
287
+ // a non-racy way.
288
+ void GetOrAddDataProducer(
289
+ UniqueTypeName type,
290
+ std::function<void(DataProducerInterface**)> get_or_add)
282
291
  ABSL_LOCKS_EXCLUDED(mu_);
292
+ // Removes the data producer from the map, if the current producer for
293
+ // this type is the specified producer.
283
294
  void RemoveDataProducer(DataProducerInterface* data_producer)
284
295
  ABSL_LOCKS_EXCLUDED(mu_);
285
- DataProducerInterface* GetDataProducer(UniqueTypeName type)
286
- ABSL_LOCKS_EXCLUDED(mu_);
287
296
 
288
297
  private:
289
298
  // A linked list of ConnectivityStateWatcherInterfaces that are monitoring