grpc 1.76.0 → 1.78.0.pre1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (763) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +11 -5
  3. data/include/grpc/credentials.h +6 -1
  4. data/include/grpc/event_engine/memory_allocator.h +2 -0
  5. data/include/grpc/impl/channel_arg_names.h +5 -0
  6. data/include/grpc/support/metrics.h +7 -1
  7. data/src/core/call/call_filters.cc +1 -1
  8. data/src/core/call/call_filters.h +175 -1
  9. data/src/core/call/call_spine.cc +1 -1
  10. data/src/core/call/call_spine.h +27 -5
  11. data/src/core/call/channelz_context.h +30 -0
  12. data/src/core/call/client_call.cc +43 -5
  13. data/src/core/call/client_call.h +6 -3
  14. data/src/core/call/filter_fusion.h +4 -4
  15. data/src/core/call/interception_chain.h +7 -6
  16. data/src/core/call/metadata_batch.cc +49 -55
  17. data/src/core/call/metadata_batch.h +7 -6
  18. data/src/core/call/metadata_info.cc +1 -1
  19. data/src/core/call/parsed_metadata.h +2 -2
  20. data/src/core/call/request_buffer.cc +1 -1
  21. data/src/core/call/security_context.cc +1 -1
  22. data/src/core/call/security_context.h +1 -1
  23. data/src/core/call/server_call.cc +1 -1
  24. data/src/core/call/server_call.h +5 -3
  25. data/src/core/call/simple_slice_based_metadata.h +1 -1
  26. data/src/core/call/status_util.cc +1 -1
  27. data/src/core/channelz/channel_trace.cc +1 -1
  28. data/src/core/channelz/channel_trace.h +3 -3
  29. data/src/core/channelz/channelz.cc +13 -11
  30. data/src/core/channelz/channelz.h +41 -6
  31. data/src/core/channelz/channelz_registry.cc +2 -2
  32. data/src/core/channelz/channelz_registry.h +42 -2
  33. data/src/core/channelz/property_list.h +6 -4
  34. data/src/core/channelz/v2tov1/convert.cc +6 -6
  35. data/src/core/channelz/v2tov1/legacy_api.cc +4 -5
  36. data/src/core/channelz/v2tov1/property_list.cc +1 -1
  37. data/src/core/channelz/ztrace_collector.h +14 -2
  38. data/src/core/client_channel/backup_poller.cc +2 -2
  39. data/src/core/client_channel/buffered_call.cc +140 -0
  40. data/src/core/client_channel/buffered_call.h +104 -0
  41. data/src/core/client_channel/client_channel.cc +124 -71
  42. data/src/core/client_channel/client_channel.h +8 -11
  43. data/src/core/client_channel/client_channel_factory.h +1 -1
  44. data/src/core/client_channel/client_channel_filter.cc +393 -663
  45. data/src/core/client_channel/client_channel_filter.h +57 -150
  46. data/src/core/client_channel/client_channel_internal.h +5 -1
  47. data/src/core/client_channel/client_channel_service_config.cc +43 -3
  48. data/src/core/client_channel/client_channel_service_config.h +12 -1
  49. data/src/core/client_channel/config_selector.h +2 -2
  50. data/src/core/client_channel/connector.h +2 -0
  51. data/src/core/client_channel/dynamic_filters.cc +2 -2
  52. data/src/core/client_channel/global_subchannel_pool.h +1 -1
  53. data/src/core/client_channel/lb_metadata.h +1 -1
  54. data/src/core/client_channel/load_balanced_call_destination.cc +3 -5
  55. data/src/core/client_channel/load_balanced_call_destination.h +1 -1
  56. data/src/core/client_channel/retry_filter.cc +2 -2
  57. data/src/core/client_channel/retry_filter_legacy_call_data.cc +6 -7
  58. data/src/core/client_channel/retry_filter_legacy_call_data.h +6 -8
  59. data/src/core/client_channel/retry_service_config.cc +3 -3
  60. data/src/core/client_channel/retry_service_config.h +1 -1
  61. data/src/core/client_channel/subchannel.cc +106 -17
  62. data/src/core/client_channel/subchannel.h +24 -8
  63. data/src/core/client_channel/subchannel_pool_interface.cc +2 -2
  64. data/src/core/client_channel/subchannel_pool_interface.h +1 -1
  65. data/src/core/client_channel/subchannel_stream_client.cc +1 -1
  66. data/src/core/client_channel/subchannel_stream_client.h +3 -3
  67. data/src/core/config/config_vars.cc +8 -2
  68. data/src/core/config/config_vars.h +5 -0
  69. data/src/core/config/core_configuration.h +1 -1
  70. data/src/core/config/load_config.cc +1 -1
  71. data/src/core/credentials/call/call_credentials.h +2 -2
  72. data/src/core/credentials/call/call_creds_registry.h +1 -1
  73. data/src/core/credentials/call/call_creds_registry_init.cc +2 -2
  74. data/src/core/credentials/call/call_creds_util.cc +3 -3
  75. data/src/core/credentials/call/composite/composite_call_credentials.cc +2 -2
  76. data/src/core/credentials/call/composite/composite_call_credentials.h +1 -1
  77. data/src/core/credentials/call/external/aws_external_account_credentials.cc +6 -6
  78. data/src/core/credentials/call/external/aws_external_account_credentials.h +1 -1
  79. data/src/core/credentials/call/external/external_account_credentials.cc +12 -12
  80. data/src/core/credentials/call/external/external_account_credentials.h +1 -1
  81. data/src/core/credentials/call/external/file_external_account_credentials.cc +3 -3
  82. data/src/core/credentials/call/external/file_external_account_credentials.h +1 -1
  83. data/src/core/credentials/call/external/url_external_account_credentials.cc +6 -6
  84. data/src/core/credentials/call/external/url_external_account_credentials.h +1 -1
  85. data/src/core/credentials/call/gcp_service_account_identity/gcp_service_account_identity_credentials.cc +24 -71
  86. data/src/core/credentials/call/gcp_service_account_identity/gcp_service_account_identity_credentials.h +1 -8
  87. data/src/core/credentials/call/iam/iam_credentials.cc +2 -2
  88. data/src/core/credentials/call/iam/iam_credentials.h +1 -1
  89. data/src/core/credentials/call/json_util.cc +1 -1
  90. data/src/core/credentials/call/jwt/json_token.cc +4 -4
  91. data/src/core/credentials/call/jwt/jwt_credentials.cc +3 -3
  92. data/src/core/credentials/call/jwt/jwt_credentials.h +4 -4
  93. data/src/core/credentials/call/jwt/jwt_verifier.cc +5 -5
  94. data/src/core/credentials/call/jwt_token_file/jwt_token_file_call_credentials.cc +2 -2
  95. data/src/core/credentials/call/jwt_token_file/jwt_token_file_call_credentials.h +3 -3
  96. data/src/core/credentials/call/jwt_util.cc +3 -3
  97. data/src/core/credentials/call/jwt_util.h +1 -1
  98. data/src/core/credentials/call/oauth2/oauth2_credentials.cc +29 -60
  99. data/src/core/credentials/call/oauth2/oauth2_credentials.h +3 -9
  100. data/src/core/credentials/call/plugin/plugin_credentials.cc +4 -4
  101. data/src/core/credentials/call/plugin/plugin_credentials.h +2 -2
  102. data/src/core/credentials/call/token_fetcher/token_fetcher_credentials.cc +46 -0
  103. data/src/core/credentials/call/token_fetcher/token_fetcher_credentials.h +32 -3
  104. data/src/core/credentials/transport/alts/alts_credentials.cc +3 -3
  105. data/src/core/credentials/transport/alts/alts_security_connector.cc +3 -3
  106. data/src/core/credentials/transport/alts/check_gcp_environment_no_op.cc +1 -1
  107. data/src/core/credentials/transport/alts/grpc_alts_credentials_client_options.cc +1 -1
  108. data/src/core/credentials/transport/alts/grpc_alts_credentials_options.h +1 -1
  109. data/src/core/credentials/transport/channel_creds_registry.h +1 -1
  110. data/src/core/credentials/transport/channel_creds_registry_init.cc +1 -1
  111. data/src/core/credentials/transport/composite/composite_channel_credentials.cc +2 -2
  112. data/src/core/credentials/transport/composite/composite_channel_credentials.h +1 -1
  113. data/src/core/credentials/transport/fake/fake_credentials.cc +1 -1
  114. data/src/core/credentials/transport/fake/fake_credentials.h +1 -1
  115. data/src/core/credentials/transport/fake/fake_security_connector.cc +5 -5
  116. data/src/core/credentials/transport/google_default/credentials_generic.cc +2 -2
  117. data/src/core/credentials/transport/google_default/google_default_credentials.cc +5 -11
  118. data/src/core/credentials/transport/google_default/google_default_credentials.h +0 -2
  119. data/src/core/credentials/transport/insecure/insecure_security_connector.h +2 -2
  120. data/src/core/credentials/transport/local/local_security_connector.cc +5 -5
  121. data/src/core/credentials/transport/security_connector.cc +1 -1
  122. data/src/core/credentials/transport/security_connector.h +2 -2
  123. data/src/core/credentials/transport/ssl/ssl_credentials.cc +1 -1
  124. data/src/core/credentials/transport/ssl/ssl_security_connector.cc +5 -5
  125. data/src/core/credentials/transport/tls/certificate_provider_factory.h +1 -1
  126. data/src/core/credentials/transport/tls/certificate_provider_registry.cc +1 -1
  127. data/src/core/credentials/transport/tls/certificate_provider_registry.h +1 -1
  128. data/src/core/credentials/transport/tls/grpc_tls_certificate_distributor.cc +1 -1
  129. data/src/core/credentials/transport/tls/grpc_tls_certificate_distributor.h +2 -2
  130. data/src/core/credentials/transport/tls/grpc_tls_certificate_match.cc +1 -1
  131. data/src/core/credentials/transport/tls/grpc_tls_certificate_provider.cc +3 -3
  132. data/src/core/credentials/transport/tls/grpc_tls_certificate_provider.h +3 -3
  133. data/src/core/credentials/transport/tls/grpc_tls_certificate_verifier.cc +1 -1
  134. data/src/core/credentials/transport/tls/grpc_tls_certificate_verifier.h +2 -2
  135. data/src/core/credentials/transport/tls/grpc_tls_credentials_options.cc +1 -1
  136. data/src/core/credentials/transport/tls/grpc_tls_crl_provider.cc +5 -5
  137. data/src/core/credentials/transport/tls/grpc_tls_crl_provider.h +3 -3
  138. data/src/core/credentials/transport/tls/load_system_roots_supported.cc +1 -1
  139. data/src/core/credentials/transport/tls/spiffe_utils.cc +10 -8
  140. data/src/core/credentials/transport/tls/spiffe_utils.h +2 -2
  141. data/src/core/credentials/transport/tls/ssl_utils.cc +4 -4
  142. data/src/core/credentials/transport/tls/ssl_utils.h +2 -2
  143. data/src/core/credentials/transport/tls/tls_credentials.cc +1 -1
  144. data/src/core/credentials/transport/tls/tls_security_connector.cc +4 -4
  145. data/src/core/credentials/transport/tls/tls_security_connector.h +3 -3
  146. data/src/core/credentials/transport/transport_credentials.cc +1 -1
  147. data/src/core/credentials/transport/transport_credentials.h +2 -2
  148. data/src/core/credentials/transport/xds/xds_credentials.h +1 -1
  149. data/src/core/ext/filters/backend_metrics/backend_metric_filter.cc +2 -2
  150. data/src/core/ext/filters/backend_metrics/backend_metric_filter.h +4 -1
  151. data/src/core/ext/filters/channel_idle/legacy_channel_idle_filter.cc +5 -5
  152. data/src/core/ext/filters/channel_idle/legacy_channel_idle_filter.h +2 -2
  153. data/src/core/ext/filters/fault_injection/fault_injection_filter.cc +7 -7
  154. data/src/core/ext/filters/fault_injection/fault_injection_filter.h +6 -3
  155. data/src/core/ext/filters/fault_injection/fault_injection_service_config_parser.h +1 -1
  156. data/src/core/ext/filters/gcp_authentication/gcp_authentication_filter.cc +1 -1
  157. data/src/core/ext/filters/gcp_authentication/gcp_authentication_filter.h +6 -3
  158. data/src/core/ext/filters/gcp_authentication/gcp_authentication_service_config_parser.h +1 -1
  159. data/src/core/ext/filters/http/client/http_client_filter.cc +6 -6
  160. data/src/core/ext/filters/http/client/http_client_filter.h +4 -1
  161. data/src/core/ext/filters/http/client_authority_filter.cc +2 -2
  162. data/src/core/ext/filters/http/client_authority_filter.h +4 -1
  163. data/src/core/ext/filters/http/http_filters_plugin.cc +1 -1
  164. data/src/core/ext/filters/http/message_compress/compression_filter.cc +3 -3
  165. data/src/core/ext/filters/http/message_compress/compression_filter.h +21 -2
  166. data/src/core/ext/filters/http/server/http_server_filter.cc +3 -3
  167. data/src/core/ext/filters/http/server/http_server_filter.h +4 -1
  168. data/src/core/ext/filters/message_size/message_size_filter.cc +2 -2
  169. data/src/core/ext/filters/message_size/message_size_filter.h +8 -2
  170. data/src/core/ext/filters/rbac/rbac_filter.cc +1 -1
  171. data/src/core/ext/filters/rbac/rbac_filter.h +4 -1
  172. data/src/core/ext/filters/rbac/rbac_service_config_parser.cc +3 -3
  173. data/src/core/ext/filters/rbac/rbac_service_config_parser.h +1 -1
  174. data/src/core/ext/filters/stateful_session/stateful_session_filter.cc +7 -7
  175. data/src/core/ext/filters/stateful_session/stateful_session_filter.h +13 -2
  176. data/src/core/ext/filters/stateful_session/stateful_session_service_config_parser.h +1 -1
  177. data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +50 -37
  178. data/src/core/ext/transport/chttp2/client/chttp2_connector.h +2 -3
  179. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +15 -17
  180. data/src/core/ext/transport/chttp2/server/chttp2_server.h +1 -2
  181. data/src/core/ext/transport/chttp2/transport/bin_decoder.cc +2 -2
  182. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +210 -60
  183. data/src/core/ext/transport/chttp2/transport/chttp2_transport.h +10 -2
  184. data/src/core/ext/transport/chttp2/transport/flow_control.cc +39 -4
  185. data/src/core/ext/transport/chttp2/transport/flow_control.h +213 -78
  186. data/src/core/ext/transport/chttp2/transport/flow_control_manager.h +46 -1
  187. data/src/core/ext/transport/chttp2/transport/frame.cc +147 -21
  188. data/src/core/ext/transport/chttp2/transport/frame.h +44 -10
  189. data/src/core/ext/transport/chttp2/transport/frame_data.cc +2 -2
  190. data/src/core/ext/transport/chttp2/transport/frame_data.h +1 -1
  191. data/src/core/ext/transport/chttp2/transport/frame_goaway.cc +2 -2
  192. data/src/core/ext/transport/chttp2/transport/frame_ping.cc +4 -4
  193. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +5 -5
  194. data/src/core/ext/transport/chttp2/transport/frame_security.cc +1 -1
  195. data/src/core/ext/transport/chttp2/transport/frame_settings.cc +7 -15
  196. data/src/core/ext/transport/chttp2/transport/frame_window_update.cc +3 -3
  197. data/src/core/ext/transport/chttp2/transport/goaway.cc +129 -0
  198. data/src/core/ext/transport/chttp2/transport/goaway.h +350 -0
  199. data/src/core/ext/transport/chttp2/transport/header_assembler.h +175 -51
  200. data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +1 -1
  201. data/src/core/ext/transport/chttp2/transport/hpack_encoder.h +4 -4
  202. data/src/core/ext/transport/chttp2/transport/hpack_parse_result.cc +1 -1
  203. data/src/core/ext/transport/chttp2/transport/hpack_parse_result.h +3 -3
  204. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +7 -7
  205. data/src/core/ext/transport/chttp2/transport/hpack_parser.h +4 -4
  206. data/src/core/ext/transport/chttp2/transport/hpack_parser_table.cc +4 -4
  207. data/src/core/ext/transport/chttp2/transport/hpack_parser_table.h +1 -1
  208. data/src/core/ext/transport/chttp2/transport/http2_client_transport.cc +1177 -511
  209. data/src/core/ext/transport/chttp2/transport/http2_client_transport.h +264 -174
  210. data/src/core/ext/transport/chttp2/transport/http2_settings.cc +1 -1
  211. data/src/core/ext/transport/chttp2/transport/http2_settings.h +6 -4
  212. data/src/core/ext/transport/chttp2/transport/http2_settings_manager.cc +4 -6
  213. data/src/core/ext/transport/chttp2/transport/http2_settings_manager.h +6 -16
  214. data/src/core/ext/transport/chttp2/transport/http2_settings_promises.h +320 -82
  215. data/src/core/ext/transport/chttp2/transport/http2_status.h +7 -1
  216. data/src/core/ext/transport/chttp2/transport/http2_transport.cc +286 -7
  217. data/src/core/ext/transport/chttp2/transport/http2_transport.h +187 -19
  218. data/src/core/ext/transport/chttp2/transport/http2_ztrace_collector.h +57 -1
  219. data/src/core/ext/transport/chttp2/transport/incoming_metadata_tracker.h +128 -0
  220. data/src/core/ext/transport/chttp2/transport/internal.h +25 -5
  221. data/src/core/ext/transport/chttp2/transport/keepalive.cc +12 -5
  222. data/src/core/ext/transport/chttp2/transport/keepalive.h +14 -10
  223. data/src/core/ext/transport/chttp2/transport/message_assembler.h +24 -15
  224. data/src/core/ext/transport/chttp2/transport/parsing.cc +8 -8
  225. data/src/core/ext/transport/chttp2/transport/ping_callbacks.cc +1 -1
  226. data/src/core/ext/transport/chttp2/transport/ping_callbacks.h +3 -3
  227. data/src/core/ext/transport/chttp2/transport/ping_promise.cc +11 -5
  228. data/src/core/ext/transport/chttp2/transport/ping_promise.h +7 -3
  229. data/src/core/ext/transport/chttp2/transport/ping_rate_policy.cc +1 -1
  230. data/src/core/ext/transport/chttp2/transport/security_frame.cc +31 -0
  231. data/src/core/ext/transport/chttp2/transport/security_frame.h +32 -0
  232. data/src/core/ext/transport/chttp2/transport/stream.h +139 -59
  233. data/src/core/ext/transport/chttp2/transport/stream_data_queue.h +225 -98
  234. data/src/core/ext/transport/chttp2/transport/stream_lists.cc +1 -1
  235. data/src/core/ext/transport/chttp2/transport/transport_common.cc +1 -1
  236. data/src/core/ext/transport/chttp2/transport/transport_common.h +5 -0
  237. data/src/core/ext/transport/chttp2/transport/writable_streams.h +27 -11
  238. data/src/core/ext/transport/chttp2/transport/writing.cc +3 -3
  239. data/src/core/ext/transport/inproc/inproc_transport.cc +8 -2
  240. data/src/core/ext/transport/inproc/legacy_inproc_transport.cc +8 -5
  241. data/src/core/filter/auth/auth_filters.h +7 -1
  242. data/src/core/filter/auth/client_auth_filter.cc +2 -2
  243. data/src/core/filter/auth/server_auth_filter.cc +3 -3
  244. data/src/core/filter/blackboard.h +2 -2
  245. data/src/core/filter/filter_args.h +40 -2
  246. data/src/core/handshaker/endpoint_info/endpoint_info_handshaker.cc +2 -2
  247. data/src/core/handshaker/handshaker.cc +5 -5
  248. data/src/core/handshaker/handshaker.h +2 -2
  249. data/src/core/handshaker/http_connect/http_connect_handshaker.cc +5 -5
  250. data/src/core/handshaker/http_connect/http_proxy_mapper.cc +11 -11
  251. data/src/core/handshaker/http_connect/http_proxy_mapper.h +1 -1
  252. data/src/core/handshaker/http_connect/xds_http_proxy_mapper.cc +1 -1
  253. data/src/core/handshaker/http_connect/xds_http_proxy_mapper.h +1 -1
  254. data/src/core/handshaker/proxy_mapper.h +1 -1
  255. data/src/core/handshaker/proxy_mapper_registry.h +1 -1
  256. data/src/core/handshaker/security/legacy_secure_endpoint.cc +4 -4
  257. data/src/core/handshaker/security/pipelined_secure_endpoint.cc +7 -7
  258. data/src/core/handshaker/security/secure_endpoint.cc +15 -5
  259. data/src/core/handshaker/security/security_handshaker.cc +8 -5
  260. data/src/core/handshaker/security/security_handshaker.h +1 -1
  261. data/src/core/handshaker/tcp_connect/tcp_connect_handshaker.cc +4 -4
  262. data/src/core/lib/address_utils/parse_address.cc +5 -5
  263. data/src/core/lib/address_utils/parse_address.h +2 -2
  264. data/src/core/lib/address_utils/sockaddr_utils.cc +4 -4
  265. data/src/core/lib/address_utils/sockaddr_utils.h +1 -1
  266. data/src/core/lib/channel/channel_args.cc +1 -1
  267. data/src/core/lib/channel/channel_args.h +2 -2
  268. data/src/core/lib/channel/channel_stack.cc +22 -21
  269. data/src/core/lib/channel/channel_stack.h +5 -3
  270. data/src/core/lib/channel/channel_stack_builder.cc +8 -4
  271. data/src/core/lib/channel/channel_stack_builder.h +10 -9
  272. data/src/core/lib/channel/channel_stack_builder_impl.cc +7 -13
  273. data/src/core/lib/channel/channel_stack_builder_impl.h +1 -1
  274. data/src/core/lib/channel/connected_channel.cc +2 -2
  275. data/src/core/lib/channel/promise_based_filter.cc +63 -8
  276. data/src/core/lib/channel/promise_based_filter.h +23 -8
  277. data/src/core/lib/compression/compression_internal.cc +4 -4
  278. data/src/core/lib/compression/compression_internal.h +1 -1
  279. data/src/core/lib/compression/message_compress.cc +1 -1
  280. data/src/core/lib/debug/trace.cc +2 -5
  281. data/src/core/lib/debug/trace.h +10 -0
  282. data/src/core/lib/debug/trace_flags.cc +2 -2
  283. data/src/core/lib/debug/trace_flags.h +1 -1
  284. data/src/core/lib/event_engine/ares_resolver.cc +8 -8
  285. data/src/core/lib/event_engine/ares_resolver.h +4 -4
  286. data/src/core/lib/event_engine/cf_engine/cf_engine.cc +1 -1
  287. data/src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc +2 -2
  288. data/src/core/lib/event_engine/cf_engine/cfstream_endpoint.h +1 -1
  289. data/src/core/lib/event_engine/cf_engine/dns_service_resolver.cc +2 -2
  290. data/src/core/lib/event_engine/cf_engine/dns_service_resolver.h +1 -1
  291. data/src/core/lib/event_engine/channel_args_endpoint_config.h +1 -1
  292. data/src/core/lib/event_engine/default_event_engine.cc +1 -1
  293. data/src/core/lib/event_engine/event_engine.cc +1 -1
  294. data/src/core/lib/event_engine/extensions/channelz.h +1 -1
  295. data/src/core/lib/event_engine/extensions/chaotic_good_extension.h +1 -1
  296. data/src/core/lib/event_engine/extensions/tcp_trace.h +8 -1
  297. data/src/core/lib/event_engine/grpc_polled_fd.h +1 -1
  298. data/src/core/lib/event_engine/memory_allocator_factory.h +1 -1
  299. data/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc +4 -4
  300. data/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.h +5 -5
  301. data/src/core/lib/event_engine/posix_engine/ev_poll_posix.cc +5 -5
  302. data/src/core/lib/event_engine/posix_engine/ev_poll_posix.h +3 -3
  303. data/src/core/lib/event_engine/posix_engine/event_poller.h +2 -2
  304. data/src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc +2 -2
  305. data/src/core/lib/event_engine/posix_engine/file_descriptor_collection.cc +1 -1
  306. data/src/core/lib/event_engine/posix_engine/file_descriptor_collection.h +1 -1
  307. data/src/core/lib/event_engine/posix_engine/grpc_polled_fd_posix.h +4 -4
  308. data/src/core/lib/event_engine/posix_engine/internal_errqueue.cc +1 -1
  309. data/src/core/lib/event_engine/posix_engine/lockfree_event.cc +1 -1
  310. data/src/core/lib/event_engine/posix_engine/lockfree_event.h +1 -1
  311. data/src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc +3 -3
  312. data/src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.h +1 -1
  313. data/src/core/lib/event_engine/posix_engine/posix_endpoint.cc +5 -5
  314. data/src/core/lib/event_engine/posix_engine/posix_endpoint.h +6 -6
  315. data/src/core/lib/event_engine/posix_engine/posix_engine.cc +7 -7
  316. data/src/core/lib/event_engine/posix_engine/posix_engine.h +7 -7
  317. data/src/core/lib/event_engine/posix_engine/posix_engine_listener.cc +7 -4
  318. data/src/core/lib/event_engine/posix_engine/posix_engine_listener.h +4 -4
  319. data/src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.cc +4 -4
  320. data/src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.h +1 -1
  321. data/src/core/lib/event_engine/posix_engine/posix_interface.h +1 -1
  322. data/src/core/lib/event_engine/posix_engine/posix_interface_posix.cc +5 -5
  323. data/src/core/lib/event_engine/posix_engine/posix_write_event_sink.h +1 -1
  324. data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.h +1 -1
  325. data/src/core/lib/event_engine/posix_engine/timer.h +1 -1
  326. data/src/core/lib/event_engine/posix_engine/timer_manager.cc +2 -2
  327. data/src/core/lib/event_engine/posix_engine/timer_manager.h +1 -1
  328. data/src/core/lib/event_engine/posix_engine/traced_buffer_list.cc +2 -2
  329. data/src/core/lib/event_engine/posix_engine/traced_buffer_list.h +2 -2
  330. data/src/core/lib/event_engine/posix_engine/wakeup_fd_eventfd.cc +1 -1
  331. data/src/core/lib/event_engine/posix_engine/wakeup_fd_eventfd.h +2 -2
  332. data/src/core/lib/event_engine/posix_engine/wakeup_fd_pipe.cc +1 -1
  333. data/src/core/lib/event_engine/posix_engine/wakeup_fd_pipe.h +2 -2
  334. data/src/core/lib/event_engine/posix_engine/wakeup_fd_posix.h +1 -1
  335. data/src/core/lib/event_engine/posix_engine/wakeup_fd_posix_default.cc +2 -2
  336. data/src/core/lib/event_engine/posix_engine/wakeup_fd_posix_default.h +1 -1
  337. data/src/core/lib/event_engine/ref_counted_dns_resolver_interface.h +1 -1
  338. data/src/core/lib/event_engine/tcp_socket_utils.cc +4 -4
  339. data/src/core/lib/event_engine/thread_pool/thread_count.cc +1 -1
  340. data/src/core/lib/event_engine/thread_pool/thread_count.h +1 -1
  341. data/src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.cc +4 -4
  342. data/src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.h +3 -3
  343. data/src/core/lib/event_engine/utils.cc +3 -3
  344. data/src/core/lib/event_engine/utils.h +1 -1
  345. data/src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc +1 -1
  346. data/src/core/lib/event_engine/windows/grpc_polled_fd_windows.h +2 -2
  347. data/src/core/lib/event_engine/windows/iocp.cc +1 -1
  348. data/src/core/lib/event_engine/windows/iocp.h +1 -1
  349. data/src/core/lib/event_engine/windows/native_windows_dns_resolver.cc +5 -2
  350. data/src/core/lib/event_engine/windows/win_socket.cc +1 -1
  351. data/src/core/lib/event_engine/windows/win_socket.h +2 -2
  352. data/src/core/lib/event_engine/windows/windows_endpoint.cc +5 -5
  353. data/src/core/lib/event_engine/windows/windows_engine.cc +4 -4
  354. data/src/core/lib/event_engine/windows/windows_engine.h +3 -3
  355. data/src/core/lib/event_engine/windows/windows_listener.cc +3 -3
  356. data/src/core/lib/event_engine/windows/windows_listener.h +2 -2
  357. data/src/core/lib/event_engine/work_queue/basic_work_queue.h +2 -2
  358. data/src/core/lib/experiments/config.cc +4 -4
  359. data/src/core/lib/experiments/experiments.cc +174 -48
  360. data/src/core/lib/experiments/experiments.h +76 -24
  361. data/src/core/lib/iomgr/buffer_list.cc +1 -1
  362. data/src/core/lib/iomgr/call_combiner.cc +1 -1
  363. data/src/core/lib/iomgr/call_combiner.h +2 -2
  364. data/src/core/lib/iomgr/cfstream_handle.cc +1 -1
  365. data/src/core/lib/iomgr/closure.h +2 -2
  366. data/src/core/lib/iomgr/combiner.cc +2 -2
  367. data/src/core/lib/iomgr/endpoint.h +1 -1
  368. data/src/core/lib/iomgr/endpoint_cfstream.cc +1 -1
  369. data/src/core/lib/iomgr/endpoint_pair_posix.cc +1 -1
  370. data/src/core/lib/iomgr/endpoint_pair_windows.cc +1 -1
  371. data/src/core/lib/iomgr/error.cc +1 -1
  372. data/src/core/lib/iomgr/error.h +2 -2
  373. data/src/core/lib/iomgr/error_cfstream.cc +1 -1
  374. data/src/core/lib/iomgr/ev_apple.cc +1 -1
  375. data/src/core/lib/iomgr/ev_epoll1_linux.cc +4 -4
  376. data/src/core/lib/iomgr/ev_poll_posix.cc +3 -3
  377. data/src/core/lib/iomgr/ev_posix.cc +3 -3
  378. data/src/core/lib/iomgr/event_engine_shims/closure.cc +3 -3
  379. data/src/core/lib/iomgr/event_engine_shims/closure.h +1 -1
  380. data/src/core/lib/iomgr/event_engine_shims/endpoint.cc +5 -5
  381. data/src/core/lib/iomgr/event_engine_shims/tcp_client.cc +2 -2
  382. data/src/core/lib/iomgr/exec_ctx.cc +3 -3
  383. data/src/core/lib/iomgr/exec_ctx.h +1 -1
  384. data/src/core/lib/iomgr/fork_posix.cc +1 -1
  385. data/src/core/lib/iomgr/internal_errqueue.cc +1 -1
  386. data/src/core/lib/iomgr/iocp_windows.cc +1 -1
  387. data/src/core/lib/iomgr/iomgr.cc +1 -1
  388. data/src/core/lib/iomgr/lockfree_event.cc +1 -1
  389. data/src/core/lib/iomgr/polling_entity.cc +1 -1
  390. data/src/core/lib/iomgr/resolve_address.cc +1 -1
  391. data/src/core/lib/iomgr/resolve_address.h +2 -2
  392. data/src/core/lib/iomgr/resolve_address_posix.cc +4 -4
  393. data/src/core/lib/iomgr/resolve_address_windows.cc +1 -1
  394. data/src/core/lib/iomgr/sockaddr_utils_posix.cc +1 -1
  395. data/src/core/lib/iomgr/socket_utils_common_posix.cc +2 -2
  396. data/src/core/lib/iomgr/socket_windows.cc +2 -2
  397. data/src/core/lib/iomgr/tcp_client_cfstream.cc +1 -1
  398. data/src/core/lib/iomgr/tcp_client_posix.cc +3 -3
  399. data/src/core/lib/iomgr/tcp_posix.cc +5 -5
  400. data/src/core/lib/iomgr/tcp_server_posix.cc +20 -9
  401. data/src/core/lib/iomgr/tcp_server_utils_posix.h +1 -1
  402. data/src/core/lib/iomgr/tcp_server_utils_posix_common.cc +2 -2
  403. data/src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.cc +2 -2
  404. data/src/core/lib/iomgr/tcp_server_windows.cc +2 -2
  405. data/src/core/lib/iomgr/tcp_windows.cc +1 -1
  406. data/src/core/lib/iomgr/timer_generic.cc +3 -3
  407. data/src/core/lib/iomgr/timer_manager.cc +1 -1
  408. data/src/core/lib/iomgr/unix_sockets_posix.cc +1 -1
  409. data/src/core/lib/iomgr/unix_sockets_posix.h +1 -1
  410. data/src/core/lib/iomgr/vsock.cc +1 -1
  411. data/src/core/lib/iomgr/vsock.h +1 -1
  412. data/src/core/lib/iomgr/wakeup_fd_pipe.cc +1 -1
  413. data/src/core/lib/promise/activity.cc +2 -2
  414. data/src/core/lib/promise/activity.h +5 -4
  415. data/src/core/lib/promise/all_ok.h +3 -3
  416. data/src/core/lib/promise/arena_promise.h +47 -6
  417. data/src/core/lib/promise/context.h +1 -1
  418. data/src/core/lib/promise/detail/join_state.h +1 -1
  419. data/src/core/lib/promise/detail/promise_factory.h +1 -1
  420. data/src/core/lib/promise/detail/promise_like.h +1 -1
  421. data/src/core/lib/promise/detail/seq_state.h +3 -3
  422. data/src/core/lib/promise/detail/status.h +1 -1
  423. data/src/core/lib/promise/exec_ctx_wakeup_scheduler.h +1 -1
  424. data/src/core/lib/promise/for_each.h +3 -3
  425. data/src/core/lib/promise/if.h +1 -1
  426. data/src/core/lib/promise/inter_activity_latch.h +3 -3
  427. data/src/core/lib/promise/inter_activity_mutex.h +1 -1
  428. data/src/core/lib/promise/interceptor_list.h +3 -3
  429. data/src/core/lib/promise/latch.h +2 -2
  430. data/src/core/lib/promise/loop.h +2 -2
  431. data/src/core/lib/promise/map.h +2 -2
  432. data/src/core/lib/promise/mpsc.cc +5 -4
  433. data/src/core/lib/promise/observable.h +2 -2
  434. data/src/core/lib/promise/party.cc +14 -8
  435. data/src/core/lib/promise/party.h +11 -4
  436. data/src/core/lib/promise/pipe.h +16 -2
  437. data/src/core/lib/promise/poll.h +2 -2
  438. data/src/core/lib/promise/promise.h +2 -2
  439. data/src/core/lib/promise/sleep.h +1 -1
  440. data/src/core/lib/promise/status_flag.h +2 -2
  441. data/src/core/lib/promise/try_join.h +3 -3
  442. data/src/core/lib/promise/try_seq.h +3 -3
  443. data/src/core/lib/promise/wait_set.h +2 -2
  444. data/src/core/lib/resource_quota/api.cc +1 -1
  445. data/src/core/lib/resource_quota/arena.cc +1 -1
  446. data/src/core/lib/resource_quota/connection_quota.h +1 -1
  447. data/src/core/lib/resource_quota/memory_quota.cc +3 -3
  448. data/src/core/lib/resource_quota/memory_quota.h +9 -5
  449. data/src/core/lib/resource_quota/periodic_update.h +1 -1
  450. data/src/core/lib/resource_quota/resource_quota.cc +8 -0
  451. data/src/core/lib/resource_quota/resource_quota.h +2 -1
  452. data/src/core/lib/resource_quota/stream_quota.cc +22 -0
  453. data/src/core/lib/resource_quota/stream_quota.h +31 -0
  454. data/src/core/lib/resource_quota/telemetry.h +1 -0
  455. data/src/core/lib/resource_quota/thread_quota.h +1 -1
  456. data/src/core/lib/security/authorization/audit_logging.cc +3 -3
  457. data/src/core/lib/security/authorization/audit_logging.h +1 -1
  458. data/src/core/lib/security/authorization/authorization_policy_provider.h +1 -1
  459. data/src/core/lib/security/authorization/evaluate_args.cc +5 -5
  460. data/src/core/lib/security/authorization/evaluate_args.h +1 -1
  461. data/src/core/lib/security/authorization/grpc_server_authz_filter.cc +3 -3
  462. data/src/core/lib/security/authorization/grpc_server_authz_filter.h +4 -1
  463. data/src/core/lib/security/authorization/matchers.cc +2 -2
  464. data/src/core/lib/security/authorization/stdout_logger.cc +1 -1
  465. data/src/core/lib/slice/percent_encoding.cc +1 -1
  466. data/src/core/lib/slice/slice.cc +1 -1
  467. data/src/core/lib/slice/slice.h +2 -2
  468. data/src/core/lib/slice/slice_buffer.cc +1 -1
  469. data/src/core/lib/slice/slice_internal.h +1 -1
  470. data/src/core/lib/surface/call.cc +42 -14
  471. data/src/core/lib/surface/call.h +12 -5
  472. data/src/core/lib/surface/call_log_batch.cc +2 -2
  473. data/src/core/lib/surface/call_utils.cc +5 -5
  474. data/src/core/lib/surface/call_utils.h +83 -18
  475. data/src/core/lib/surface/channel.cc +2 -1
  476. data/src/core/lib/surface/channel.h +13 -3
  477. data/src/core/lib/surface/channel_create.cc +2 -2
  478. data/src/core/lib/surface/channel_create.h +1 -1
  479. data/src/core/lib/surface/channel_init.cc +5 -5
  480. data/src/core/lib/surface/channel_init.h +4 -2
  481. data/src/core/lib/surface/completion_queue.cc +4 -4
  482. data/src/core/lib/surface/filter_stack_call.cc +13 -8
  483. data/src/core/lib/surface/filter_stack_call.h +3 -3
  484. data/src/core/lib/surface/init.cc +4 -4
  485. data/src/core/lib/surface/lame_client.cc +2 -2
  486. data/src/core/lib/surface/lame_client.h +3 -3
  487. data/src/core/lib/surface/legacy_channel.cc +3 -3
  488. data/src/core/lib/surface/legacy_channel.h +1 -1
  489. data/src/core/lib/surface/validate_metadata.cc +2 -2
  490. data/src/core/lib/surface/validate_metadata.h +1 -1
  491. data/src/core/lib/surface/version.cc +2 -2
  492. data/src/core/lib/transport/bdp_estimator.cc +1 -1
  493. data/src/core/lib/transport/bdp_estimator.h +2 -2
  494. data/src/core/lib/transport/connectivity_state.cc +1 -1
  495. data/src/core/lib/transport/connectivity_state.h +2 -2
  496. data/src/core/lib/transport/error_utils.h +1 -1
  497. data/src/core/lib/transport/promise_endpoint.cc +1 -1
  498. data/src/core/lib/transport/promise_endpoint.h +3 -3
  499. data/src/core/lib/transport/timeout_encoding.cc +1 -1
  500. data/src/core/lib/transport/transport.cc +3 -3
  501. data/src/core/lib/transport/transport.h +62 -4
  502. data/src/core/lib/transport/transport_framing_endpoint_extension.h +1 -1
  503. data/src/core/lib/transport/transport_op_string.cc +2 -2
  504. data/src/core/load_balancing/address_filtering.cc +1 -1
  505. data/src/core/load_balancing/address_filtering.h +2 -2
  506. data/src/core/load_balancing/backend_metric_parser.cc +1 -1
  507. data/src/core/load_balancing/backend_metric_parser.h +1 -1
  508. data/src/core/load_balancing/child_policy_handler.cc +4 -4
  509. data/src/core/load_balancing/child_policy_handler.h +2 -2
  510. data/src/core/load_balancing/delegating_helper.h +2 -2
  511. data/src/core/load_balancing/endpoint_list.cc +4 -4
  512. data/src/core/load_balancing/endpoint_list.h +2 -2
  513. data/src/core/load_balancing/grpclb/client_load_reporting_filter.cc +7 -5
  514. data/src/core/load_balancing/grpclb/client_load_reporting_filter.h +5 -1
  515. data/src/core/load_balancing/grpclb/grpclb.cc +13 -24
  516. data/src/core/load_balancing/grpclb/grpclb_client_stats.h +2 -2
  517. data/src/core/load_balancing/grpclb/load_balancer_api.cc +1 -1
  518. data/src/core/load_balancing/grpclb/load_balancer_api.h +1 -1
  519. data/src/core/load_balancing/health_check_client.cc +9 -5
  520. data/src/core/load_balancing/health_check_client_internal.h +3 -3
  521. data/src/core/load_balancing/lb_policy.h +11 -8
  522. data/src/core/load_balancing/lb_policy_factory.h +2 -2
  523. data/src/core/load_balancing/lb_policy_registry.cc +2 -2
  524. data/src/core/load_balancing/lb_policy_registry.h +2 -2
  525. data/src/core/load_balancing/oob_backend_metric.cc +7 -3
  526. data/src/core/load_balancing/oob_backend_metric_internal.h +2 -2
  527. data/src/core/load_balancing/outlier_detection/outlier_detection.cc +7 -15
  528. data/src/core/load_balancing/pick_first/pick_first.cc +48 -18
  529. data/src/core/load_balancing/priority/priority.cc +6 -6
  530. data/src/core/load_balancing/ring_hash/ring_hash.cc +8 -8
  531. data/src/core/load_balancing/rls/rls.cc +10 -10
  532. data/src/core/load_balancing/round_robin/round_robin.cc +7 -7
  533. data/src/core/load_balancing/subchannel_interface.h +2 -2
  534. data/src/core/load_balancing/weighted_round_robin/static_stride_scheduler.cc +1 -1
  535. data/src/core/load_balancing/weighted_round_robin/weighted_round_robin.cc +9 -15
  536. data/src/core/load_balancing/weighted_target/weighted_target.cc +9 -9
  537. data/src/core/load_balancing/xds/cds.cc +5 -5
  538. data/src/core/load_balancing/xds/xds_cluster_impl.cc +22 -39
  539. data/src/core/load_balancing/xds/xds_cluster_manager.cc +6 -6
  540. data/src/core/load_balancing/xds/xds_override_host.cc +10 -10
  541. data/src/core/load_balancing/xds/xds_override_host.h +1 -1
  542. data/src/core/load_balancing/xds/xds_wrr_locality.cc +5 -5
  543. data/src/core/resolver/dns/c_ares/dns_resolver_ares.cc +8 -8
  544. data/src/core/resolver/dns/c_ares/dns_resolver_ares.h +1 -1
  545. data/src/core/resolver/dns/c_ares/grpc_ares_ev_driver.h +1 -1
  546. data/src/core/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc +2 -2
  547. data/src/core/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +2 -2
  548. data/src/core/resolver/dns/c_ares/grpc_ares_wrapper.cc +6 -6
  549. data/src/core/resolver/dns/c_ares/grpc_ares_wrapper.h +2 -2
  550. data/src/core/resolver/dns/dns_resolver_plugin.cc +2 -2
  551. data/src/core/resolver/dns/event_engine/event_engine_client_channel_resolver.cc +8 -8
  552. data/src/core/resolver/dns/event_engine/event_engine_client_channel_resolver.h +1 -1
  553. data/src/core/resolver/dns/event_engine/service_config_helper.cc +2 -2
  554. data/src/core/resolver/dns/native/dns_resolver.cc +7 -7
  555. data/src/core/resolver/endpoint_addresses.cc +4 -4
  556. data/src/core/resolver/endpoint_addresses.h +1 -1
  557. data/src/core/resolver/fake/fake_resolver.cc +1 -1
  558. data/src/core/resolver/fake/fake_resolver.h +3 -3
  559. data/src/core/resolver/google_c2p/google_c2p_resolver.cc +5 -5
  560. data/src/core/resolver/polling_resolver.cc +5 -5
  561. data/src/core/resolver/polling_resolver.h +1 -1
  562. data/src/core/resolver/resolver.h +2 -2
  563. data/src/core/resolver/resolver_factory.h +2 -2
  564. data/src/core/resolver/resolver_registry.cc +1 -1
  565. data/src/core/resolver/resolver_registry.h +1 -1
  566. data/src/core/resolver/sockaddr/sockaddr_resolver.cc +4 -4
  567. data/src/core/resolver/xds/xds_config.cc +1 -1
  568. data/src/core/resolver/xds/xds_config.h +3 -3
  569. data/src/core/resolver/xds/xds_dependency_manager.cc +2 -2
  570. data/src/core/resolver/xds/xds_dependency_manager.h +3 -3
  571. data/src/core/resolver/xds/xds_resolver.cc +16 -13
  572. data/src/core/resolver/xds/xds_resolver_attributes.h +1 -1
  573. data/src/core/server/add_port.cc +2 -2
  574. data/src/core/server/server.cc +9 -5
  575. data/src/core/server/server.h +8 -7
  576. data/src/core/server/server_call_tracer_filter.cc +1 -1
  577. data/src/core/server/server_call_tracer_filter.h +5 -1
  578. data/src/core/server/server_config_selector.h +2 -2
  579. data/src/core/server/server_config_selector_filter.cc +3 -3
  580. data/src/core/server/xds_channel_stack_modifier.cc +3 -2
  581. data/src/core/server/xds_channel_stack_modifier.h +1 -1
  582. data/src/core/server/xds_server_config_fetcher.cc +10 -10
  583. data/src/core/service_config/service_config.h +1 -1
  584. data/src/core/service_config/service_config_channel_arg_filter.h +4 -1
  585. data/src/core/service_config/service_config_impl.cc +3 -3
  586. data/src/core/service_config/service_config_impl.h +2 -2
  587. data/src/core/service_config/service_config_parser.h +1 -1
  588. data/src/core/telemetry/call_tracer.h +2 -2
  589. data/src/core/telemetry/default_tcp_tracer.h +3 -3
  590. data/src/core/telemetry/histogram.h +1 -1
  591. data/src/core/telemetry/instrument.cc +550 -270
  592. data/src/core/telemetry/instrument.h +301 -128
  593. data/src/core/telemetry/metrics.cc +2 -0
  594. data/src/core/telemetry/metrics.h +33 -4
  595. data/src/core/telemetry/stats.h +2 -2
  596. data/src/core/telemetry/stats_data.cc +1 -1
  597. data/src/core/telemetry/stats_data.h +2 -2
  598. data/src/core/transport/auth_context.cc +1 -1
  599. data/src/core/transport/auth_context.h +2 -1
  600. data/src/core/transport/auth_context_comparator_registry.h +1 -1
  601. data/src/core/tsi/alts/crypt/aes_gcm.cc +1 -1
  602. data/src/core/tsi/alts/frame_protector/alts_frame_protector.cc +2 -2
  603. data/src/core/tsi/alts/frame_protector/frame_handler.cc +1 -1
  604. data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +3 -3
  605. data/src/core/tsi/alts/handshaker/alts_handshaker_client.h +1 -1
  606. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +9 -7
  607. data/src/core/tsi/alts/handshaker/alts_tsi_utils.cc +1 -1
  608. data/src/core/tsi/alts/handshaker/transport_security_common_api.cc +1 -1
  609. data/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.cc +1 -1
  610. data/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.cc +11 -3
  611. data/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol.h +10 -0
  612. data/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.cc +9 -1
  613. data/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.h +3 -0
  614. data/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc +15 -2
  615. data/src/core/tsi/fake_transport_security.cc +2 -1
  616. data/src/core/tsi/local_transport_security.cc +1 -1
  617. data/src/core/tsi/ssl/key_logging/ssl_key_logging.cc +1 -1
  618. data/src/core/tsi/ssl/key_logging/ssl_key_logging.h +1 -1
  619. data/src/core/tsi/ssl/session_cache/ssl_session_cache.cc +1 -1
  620. data/src/core/tsi/ssl/session_cache/ssl_session_openssl.cc +1 -1
  621. data/src/core/tsi/ssl_transport_security.cc +6 -6
  622. data/src/core/tsi/ssl_transport_security.h +1 -1
  623. data/src/core/tsi/ssl_transport_security_utils.cc +2 -2
  624. data/src/core/tsi/ssl_transport_security_utils.h +2 -2
  625. data/src/core/tsi/transport_security_grpc.cc +8 -0
  626. data/src/core/tsi/transport_security_grpc.h +15 -0
  627. data/src/core/util/alloc.cc +1 -1
  628. data/src/core/util/backoff.h +1 -1
  629. data/src/core/util/crash.h +1 -1
  630. data/src/core/util/dual_ref_counted.h +2 -2
  631. data/src/core/util/event_log.cc +1 -1
  632. data/src/core/util/event_log.h +3 -3
  633. data/src/core/util/gcp_metadata_query.cc +5 -5
  634. data/src/core/util/gcp_metadata_query.h +2 -2
  635. data/src/core/util/grpc_check.cc +2 -0
  636. data/src/core/util/grpc_check.h +1 -1
  637. data/src/core/util/grpc_if_nametoindex_posix.cc +1 -1
  638. data/src/core/util/grpc_if_nametoindex_unsupported.cc +1 -1
  639. data/src/core/util/http_client/format_request.cc +1 -1
  640. data/src/core/util/http_client/httpcli.cc +3 -3
  641. data/src/core/util/http_client/httpcli.h +4 -4
  642. data/src/core/util/http_client/httpcli_security_connector.cc +4 -4
  643. data/src/core/util/http_client/parser.cc +1 -1
  644. data/src/core/util/json/json_channel_args.h +1 -1
  645. data/src/core/util/json/json_object_loader.h +6 -6
  646. data/src/core/util/json/json_reader.cc +2 -2
  647. data/src/core/util/json/json_reader.h +1 -1
  648. data/src/core/util/json/json_util.h +3 -3
  649. data/src/core/util/json/json_writer.cc +1 -1
  650. data/src/core/util/latent_see.cc +45 -24
  651. data/src/core/util/latent_see.h +192 -24
  652. data/src/core/util/linux/cpu.cc +1 -1
  653. data/src/core/util/load_file.cc +1 -1
  654. data/src/core/util/load_file.h +1 -1
  655. data/src/core/util/log.cc +3 -3
  656. data/src/core/util/lru_cache.h +1 -1
  657. data/src/core/util/matchers.h +1 -1
  658. data/src/core/util/memory_usage.h +3 -3
  659. data/src/core/util/mpscq.h +1 -1
  660. data/src/core/util/notification.h +1 -1
  661. data/src/core/util/posix/cpu.cc +1 -1
  662. data/src/core/util/posix/stat.cc +2 -2
  663. data/src/core/util/posix/thd.cc +2 -2
  664. data/src/core/util/posix/tmpfile.cc +2 -2
  665. data/src/core/util/ref_counted.h +2 -2
  666. data/src/core/util/ref_counted_ptr.h +1 -1
  667. data/src/core/util/ref_counted_string.h +1 -1
  668. data/src/core/util/single_set_ptr.h +3 -1
  669. data/src/core/util/status_helper.cc +8 -8
  670. data/src/core/util/status_helper.h +1 -1
  671. data/src/core/util/string.cc +2 -2
  672. data/src/core/util/sync_abseil.cc +1 -1
  673. data/src/core/util/table.h +1 -1
  674. data/src/core/util/time.cc +1 -1
  675. data/src/core/util/time_precise.cc +1 -1
  676. data/src/core/util/unique_ptr_with_bitset.h +1 -1
  677. data/src/core/util/unique_type_name.h +1 -1
  678. data/src/core/util/upb_utils.h +6 -1
  679. data/src/core/util/validation_errors.cc +2 -2
  680. data/src/core/util/validation_errors.h +2 -3
  681. data/src/core/util/wait_for_single_owner.h +2 -2
  682. data/src/core/util/windows/directory_reader.cc +1 -1
  683. data/src/core/util/windows/stat.cc +2 -2
  684. data/src/core/util/windows/thd.cc +2 -2
  685. data/src/core/util/windows/time.cc +1 -1
  686. data/src/core/util/work_serializer.cc +3 -3
  687. data/src/core/util/work_serializer.h +2 -2
  688. data/src/core/xds/grpc/certificate_provider_store.cc +2 -2
  689. data/src/core/xds/grpc/certificate_provider_store.h +2 -2
  690. data/src/core/xds/grpc/file_watcher_certificate_provider_factory.cc +3 -3
  691. data/src/core/xds/grpc/file_watcher_certificate_provider_factory.h +1 -1
  692. data/src/core/xds/grpc/xds_audit_logger_registry.cc +3 -3
  693. data/src/core/xds/grpc/xds_audit_logger_registry.h +1 -1
  694. data/src/core/xds/grpc/xds_bootstrap_grpc.cc +7 -7
  695. data/src/core/xds/grpc/xds_bootstrap_grpc.h +2 -2
  696. data/src/core/xds/grpc/xds_certificate_provider.cc +1 -1
  697. data/src/core/xds/grpc/xds_certificate_provider.h +2 -2
  698. data/src/core/xds/grpc/xds_client_grpc.cc +5 -5
  699. data/src/core/xds/grpc/xds_client_grpc.h +2 -2
  700. data/src/core/xds/grpc/xds_cluster.cc +2 -2
  701. data/src/core/xds/grpc/xds_cluster.h +1 -1
  702. data/src/core/xds/grpc/xds_cluster_parser.cc +5 -5
  703. data/src/core/xds/grpc/xds_cluster_parser.h +1 -1
  704. data/src/core/xds/grpc/xds_cluster_specifier_plugin.cc +2 -2
  705. data/src/core/xds/grpc/xds_cluster_specifier_plugin.h +1 -1
  706. data/src/core/xds/grpc/xds_common_types.cc +1 -1
  707. data/src/core/xds/grpc/xds_common_types.h +1 -1
  708. data/src/core/xds/grpc/xds_common_types_parser.cc +5 -5
  709. data/src/core/xds/grpc/xds_endpoint.h +2 -2
  710. data/src/core/xds/grpc/xds_endpoint_parser.cc +5 -5
  711. data/src/core/xds/grpc/xds_endpoint_parser.h +1 -1
  712. data/src/core/xds/grpc/xds_health_status.cc +1 -1
  713. data/src/core/xds/grpc/xds_health_status.h +1 -1
  714. data/src/core/xds/grpc/xds_http_fault_filter.cc +4 -4
  715. data/src/core/xds/grpc/xds_http_fault_filter.h +2 -2
  716. data/src/core/xds/grpc/xds_http_filter.h +3 -3
  717. data/src/core/xds/grpc/xds_http_filter_registry.h +2 -2
  718. data/src/core/xds/grpc/xds_http_gcp_authn_filter.cc +3 -3
  719. data/src/core/xds/grpc/xds_http_gcp_authn_filter.h +2 -2
  720. data/src/core/xds/grpc/xds_http_rbac_filter.cc +4 -4
  721. data/src/core/xds/grpc/xds_http_rbac_filter.h +2 -2
  722. data/src/core/xds/grpc/xds_http_stateful_session_filter.cc +3 -3
  723. data/src/core/xds/grpc/xds_http_stateful_session_filter.h +2 -2
  724. data/src/core/xds/grpc/xds_lb_policy_registry.cc +1 -1
  725. data/src/core/xds/grpc/xds_lb_policy_registry.h +1 -1
  726. data/src/core/xds/grpc/xds_listener.cc +2 -2
  727. data/src/core/xds/grpc/xds_listener_parser.cc +6 -6
  728. data/src/core/xds/grpc/xds_listener_parser.h +1 -1
  729. data/src/core/xds/grpc/xds_matcher.cc +1 -1
  730. data/src/core/xds/grpc/xds_matcher.h +3 -3
  731. data/src/core/xds/grpc/xds_matcher_input.h +1 -1
  732. data/src/core/xds/grpc/xds_metadata.cc +1 -1
  733. data/src/core/xds/grpc/xds_metadata.h +3 -3
  734. data/src/core/xds/grpc/xds_metadata_parser.cc +2 -2
  735. data/src/core/xds/grpc/xds_route_config.cc +3 -3
  736. data/src/core/xds/grpc/xds_route_config_parser.cc +8 -8
  737. data/src/core/xds/grpc/xds_route_config_parser.h +1 -1
  738. data/src/core/xds/grpc/xds_routing.cc +4 -4
  739. data/src/core/xds/grpc/xds_routing.h +2 -2
  740. data/src/core/xds/grpc/xds_server_grpc.cc +2 -2
  741. data/src/core/xds/grpc/xds_transport_grpc.cc +1 -1
  742. data/src/core/xds/grpc/xds_transport_grpc.h +2 -2
  743. data/src/core/xds/xds_client/lrs_client.cc +3 -3
  744. data/src/core/xds/xds_client/lrs_client.h +4 -4
  745. data/src/core/xds/xds_client/xds_api.h +1 -1
  746. data/src/core/xds/xds_client/xds_backend_metric_propagation.cc +1 -1
  747. data/src/core/xds/xds_client/xds_backend_metric_propagation.h +1 -1
  748. data/src/core/xds/xds_client/xds_client.cc +8 -8
  749. data/src/core/xds/xds_client/xds_client.h +5 -5
  750. data/src/core/xds/xds_client/xds_locality.h +2 -2
  751. data/src/core/xds/xds_client/xds_resource_type.h +2 -2
  752. data/src/core/xds/xds_client/xds_resource_type_impl.h +1 -1
  753. data/src/core/xds/xds_client/xds_transport.h +2 -2
  754. data/src/ruby/ext/grpc/extconf.rb +14 -12
  755. data/src/ruby/ext/grpc/rb_call.c +0 -1
  756. data/src/ruby/ext/grpc/rb_channel_args.c +0 -1
  757. data/src/ruby/ext/grpc/rb_channel_credentials.c +0 -1
  758. data/src/ruby/ext/grpc/rb_compression_options.c +0 -1
  759. data/src/ruby/ext/grpc/rb_server_credentials.c +0 -1
  760. data/src/ruby/ext/grpc/rb_xds_channel_credentials.c +0 -1
  761. data/src/ruby/ext/grpc/rb_xds_server_credentials.c +0 -1
  762. data/src/ruby/lib/grpc/version.rb +1 -1
  763. metadata +16 -6
@@ -37,15 +37,6 @@
37
37
  #include <variant>
38
38
  #include <vector>
39
39
 
40
- #include "absl/cleanup/cleanup.h"
41
- #include "absl/log/log.h"
42
- #include "absl/status/status.h"
43
- #include "absl/status/statusor.h"
44
- #include "absl/strings/cord.h"
45
- #include "absl/strings/numbers.h"
46
- #include "absl/strings/str_cat.h"
47
- #include "absl/strings/str_join.h"
48
- #include "absl/strings/string_view.h"
49
40
  #include "src/core/call/metadata_batch.h"
50
41
  #include "src/core/call/status_util.h"
51
42
  #include "src/core/channelz/channel_trace.h"
@@ -103,6 +94,15 @@
103
94
  #include "src/core/util/unique_type_name.h"
104
95
  #include "src/core/util/useful.h"
105
96
  #include "src/core/util/work_serializer.h"
97
+ #include "absl/cleanup/cleanup.h"
98
+ #include "absl/log/log.h"
99
+ #include "absl/status/status.h"
100
+ #include "absl/status/statusor.h"
101
+ #include "absl/strings/cord.h"
102
+ #include "absl/strings/numbers.h"
103
+ #include "absl/strings/str_cat.h"
104
+ #include "absl/strings/str_join.h"
105
+ #include "absl/strings/string_view.h"
106
106
 
107
107
  //
108
108
  // Client channel filter
@@ -118,6 +118,15 @@ using internal::ClientChannelMethodParsedConfig;
118
118
 
119
119
  class ClientChannelFilter::CallData {
120
120
  public:
121
+ static grpc_error_handle Init(grpc_call_element* elem,
122
+ const grpc_call_element_args* args);
123
+ static void Destroy(grpc_call_element* elem,
124
+ const grpc_call_final_info* final_info,
125
+ grpc_closure* then_schedule_closure);
126
+ static void StartTransportStreamOpBatch(
127
+ grpc_call_element* elem, grpc_transport_stream_op_batch* batch);
128
+ static void SetPollent(grpc_call_element* elem, grpc_polling_entity* pollent);
129
+
121
130
  // Removes the call from the channel's list of calls queued
122
131
  // for name resolution.
123
132
  void RemoveCallFromResolverQueuedCallsLocked()
@@ -125,16 +134,21 @@ class ClientChannelFilter::CallData {
125
134
 
126
135
  // Called by the channel for each queued call when a new resolution
127
136
  // result becomes available.
128
- virtual void RetryCheckResolutionLocked()
129
- ABSL_EXCLUSIVE_LOCKS_REQUIRED(&ClientChannelFilter::resolution_mu_) = 0;
137
+ void RetryCheckResolutionLocked()
138
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(&ClientChannelFilter::resolution_mu_);
139
+
140
+ private:
141
+ class ResolverQueuedCallCanceller;
142
+
143
+ CallData(grpc_call_element* elem, const grpc_call_element_args& args);
130
144
 
131
- RefCountedPtr<DynamicFilters> dynamic_filters() const {
132
- return dynamic_filters_;
145
+ ClientChannelFilter* chand() const {
146
+ return static_cast<ClientChannelFilter*>(elem_->channel_data);
133
147
  }
134
148
 
135
- protected:
136
- CallData() = default;
137
- virtual ~CallData() = default;
149
+ grpc_metadata_batch* send_initial_metadata() {
150
+ return buffered_call_.send_initial_metadata();
151
+ }
138
152
 
139
153
  // Checks whether a resolver result is available. The following
140
154
  // outcomes are possible:
@@ -148,13 +162,6 @@ class ClientChannelFilter::CallData {
148
162
  // stored in the call context and an OK status will be returned.
149
163
  std::optional<absl::Status> CheckResolution(bool was_queued);
150
164
 
151
- private:
152
- // Accessors for data stored in the subclass.
153
- virtual ClientChannelFilter* chand() const = 0;
154
- virtual Arena* arena() const = 0;
155
- virtual grpc_polling_entity* pollent() = 0;
156
- virtual grpc_metadata_batch* send_initial_metadata() = 0;
157
-
158
165
  // Helper function for CheckResolution(). Returns true if the call
159
166
  // can continue (i.e., there is a valid resolution result, or there is
160
167
  // an invalid resolution result but the call is not wait_for_ready).
@@ -166,10 +173,6 @@ class ClientChannelFilter::CallData {
166
173
  void AddCallToResolverQueuedCallsLocked()
167
174
  ABSL_EXCLUSIVE_LOCKS_REQUIRED(&ClientChannelFilter::resolution_mu_);
168
175
 
169
- // Called when adding the call to the resolver queue.
170
- virtual void OnAddToQueueLocked()
171
- ABSL_EXCLUSIVE_LOCKS_REQUIRED(&ClientChannelFilter::resolution_mu_) {}
172
-
173
176
  // Applies service config to the call. Must be invoked once we know
174
177
  // that the resolver has returned results to the channel.
175
178
  // If an error is returned, the error indicates the status with which
@@ -179,90 +182,19 @@ class ClientChannelFilter::CallData {
179
182
 
180
183
  // Called to reset the deadline based on the service config obtained
181
184
  // from the resolver.
182
- virtual void ResetDeadline(Duration timeout) = 0;
183
-
184
- RefCountedPtr<DynamicFilters> dynamic_filters_;
185
- };
186
-
187
- class ClientChannelFilter::FilterBasedCallData final
188
- : public ClientChannelFilter::CallData {
189
- public:
190
- static grpc_error_handle Init(grpc_call_element* elem,
191
- const grpc_call_element_args* args);
192
- static void Destroy(grpc_call_element* elem,
193
- const grpc_call_final_info* final_info,
194
- grpc_closure* then_schedule_closure);
195
- static void StartTransportStreamOpBatch(
196
- grpc_call_element* elem, grpc_transport_stream_op_batch* batch);
197
- static void SetPollent(grpc_call_element* elem, grpc_polling_entity* pollent);
198
-
199
- private:
200
- class ResolverQueuedCallCanceller;
201
-
202
- FilterBasedCallData(grpc_call_element* elem,
203
- const grpc_call_element_args& args);
204
- ~FilterBasedCallData() override;
205
-
206
- grpc_call_element* elem() const { return elem_; }
207
- grpc_call_stack* owning_call() const { return owning_call_; }
208
- CallCombiner* call_combiner() const { return call_combiner_; }
209
-
210
- ClientChannelFilter* chand() const override {
211
- return static_cast<ClientChannelFilter*>(elem()->channel_data);
212
- }
213
- Arena* arena() const override { return arena_; }
214
- grpc_polling_entity* pollent() override { return pollent_; }
215
- grpc_metadata_batch* send_initial_metadata() override {
216
- return pending_batches_[0]
217
- ->payload->send_initial_metadata.send_initial_metadata;
218
- }
219
-
220
- // Returns the index into pending_batches_ to be used for batch.
221
- static size_t GetBatchIndex(grpc_transport_stream_op_batch* batch);
222
- void PendingBatchesAdd(grpc_transport_stream_op_batch* batch);
223
- static void FailPendingBatchInCallCombiner(void* arg,
224
- grpc_error_handle error);
225
- // A predicate type and some useful implementations for PendingBatchesFail().
226
- typedef bool (*YieldCallCombinerPredicate)(
227
- const CallCombinerClosureList& closures);
228
- static bool YieldCallCombiner(const CallCombinerClosureList& /*closures*/) {
229
- return true;
230
- }
231
- static bool NoYieldCallCombiner(const CallCombinerClosureList& /*closures*/) {
232
- return false;
185
+ void ResetDeadline(Duration timeout) {
186
+ const Timestamp per_method_deadline =
187
+ Timestamp::FromCycleCounterRoundUp(call_start_time_) + timeout;
188
+ arena_->GetContext<Call>()
189
+ ->UpdateDeadline(per_method_deadline)
190
+ .IgnoreError();
233
191
  }
234
- static bool YieldCallCombinerIfPendingBatchesFound(
235
- const CallCombinerClosureList& closures) {
236
- return closures.size() > 0;
237
- }
238
- // Fails all pending batches.
239
- // If yield_call_combiner_predicate returns true, assumes responsibility for
240
- // yielding the call combiner.
241
- void PendingBatchesFail(
242
- grpc_error_handle error,
243
- YieldCallCombinerPredicate yield_call_combiner_predicate);
244
- static void ResumePendingBatchInCallCombiner(void* arg,
245
- grpc_error_handle ignored);
246
- // Resumes all pending batches on dynamic_call_.
247
- void PendingBatchesResume();
248
192
 
249
193
  // Called to check for a resolution result, both when the call is
250
194
  // initially started and when it is queued and the channel gets a new
251
195
  // resolution result.
252
196
  void TryCheckResolution(bool was_queued);
253
197
 
254
- void OnAddToQueueLocked() override
255
- ABSL_EXCLUSIVE_LOCKS_REQUIRED(&ClientChannelFilter::resolution_mu_);
256
-
257
- void RetryCheckResolutionLocked() override
258
- ABSL_EXCLUSIVE_LOCKS_REQUIRED(&ClientChannelFilter::resolution_mu_);
259
-
260
- void ResetDeadline(Duration timeout) override {
261
- const Timestamp per_method_deadline =
262
- Timestamp::FromCycleCounterRoundUp(call_start_time_) + timeout;
263
- arena_->GetContext<Call>()->UpdateDeadline(per_method_deadline);
264
- }
265
-
266
198
  void CreateDynamicCall();
267
199
 
268
200
  static void RecvTrailingMetadataReadyForConfigSelectorCommitCallback(
@@ -285,14 +217,10 @@ class ClientChannelFilter::FilterBasedCallData final
285
217
  grpc_closure* original_recv_trailing_metadata_ready_ = nullptr;
286
218
  grpc_closure recv_trailing_metadata_ready_;
287
219
 
220
+ RefCountedPtr<DynamicFilters> dynamic_filters_;
288
221
  RefCountedPtr<DynamicFilters::Call> dynamic_call_;
289
222
 
290
- // Batches are added to this list when received from above.
291
- // They are removed when we are done handling the batch (i.e., when
292
- // either we have invoked all of the batch's callbacks or we have
293
- // passed the batch down to the LB call and are not intercepting any of
294
- // its callbacks).
295
- grpc_transport_stream_op_batch* pending_batches_[MAX_PENDING_BATCHES] = {};
223
+ BufferedCall buffered_call_;
296
224
 
297
225
  // Set when we get a cancel_stream op.
298
226
  grpc_error_handle cancel_error_;
@@ -303,12 +231,12 @@ class ClientChannelFilter::FilterBasedCallData final
303
231
  //
304
232
 
305
233
  const grpc_channel_filter ClientChannelFilter::kFilter = {
306
- ClientChannelFilter::FilterBasedCallData::StartTransportStreamOpBatch,
234
+ ClientChannelFilter::CallData::StartTransportStreamOpBatch,
307
235
  ClientChannelFilter::StartTransportOp,
308
- sizeof(ClientChannelFilter::FilterBasedCallData),
309
- ClientChannelFilter::FilterBasedCallData::Init,
310
- ClientChannelFilter::FilterBasedCallData::SetPollent,
311
- ClientChannelFilter::FilterBasedCallData::Destroy,
236
+ sizeof(ClientChannelFilter::CallData),
237
+ ClientChannelFilter::CallData::Init,
238
+ ClientChannelFilter::CallData::SetPollent,
239
+ ClientChannelFilter::CallData::Destroy,
312
240
  sizeof(ClientChannelFilter),
313
241
  ClientChannelFilter::Init,
314
242
  grpc_channel_stack_no_post_init,
@@ -421,7 +349,7 @@ class DynamicTerminationFilter::CallData final {
421
349
  grpc_call_stack* owning_call_;
422
350
  CallCombiner* call_combiner_;
423
351
 
424
- OrphanablePtr<ClientChannelFilter::FilterBasedLoadBalancedCall> lb_call_;
352
+ OrphanablePtr<ClientChannelFilter::LoadBalancedCall> lb_call_;
425
353
  };
426
354
 
427
355
  const grpc_channel_filter DynamicTerminationFilter::kFilterVtable = {
@@ -483,32 +411,31 @@ class ClientChannelFilter::SubchannelWrapper final
483
411
  : public SubchannelInterface {
484
412
  public:
485
413
  SubchannelWrapper(ClientChannelFilter* chand,
486
- RefCountedPtr<Subchannel> subchannel)
414
+ RefCountedPtr<Subchannel> subchannel,
415
+ uint32_t max_connections_per_subchannel)
487
416
  : SubchannelInterface(GRPC_TRACE_FLAG_ENABLED(client_channel)
488
417
  ? "SubchannelWrapper"
489
418
  : nullptr),
490
419
  chand_(chand),
491
- subchannel_(std::move(subchannel)) {
420
+ subchannel_(std::move(subchannel)),
421
+ max_connections_per_subchannel_(max_connections_per_subchannel) {
492
422
  GRPC_TRACE_LOG(client_channel, INFO)
493
423
  << "chand=" << chand << ": creating subchannel wrapper " << this
494
- << " for subchannel " << subchannel_.get();
424
+ << " for subchannel " << subchannel_.get()
425
+ << ", max_connections_per_subchannel="
426
+ << max_connections_per_subchannel;
495
427
  GRPC_CHANNEL_STACK_REF(chand_->owning_stack_, "SubchannelWrapper");
496
428
  #ifndef NDEBUG
497
429
  GRPC_DCHECK(chand_->work_serializer_->RunningInWorkSerializer());
498
430
  #endif
499
- if (chand_->channelz_node_ != nullptr) {
431
+ auto& subchannel_wrappers = chand_->subchannel_map_[subchannel_.get()];
432
+ if (subchannel_wrappers.empty() && chand_->channelz_node_ != nullptr) {
500
433
  auto* subchannel_node = subchannel_->channelz_node();
501
434
  if (subchannel_node != nullptr) {
502
- auto it = chand_->subchannel_refcount_map_.find(subchannel_.get());
503
- if (it == chand_->subchannel_refcount_map_.end()) {
504
- subchannel_node->AddParent(chand_->channelz_node_);
505
- it = chand_->subchannel_refcount_map_.emplace(subchannel_.get(), 0)
506
- .first;
507
- }
508
- ++it->second;
435
+ subchannel_node->AddParent(chand_->channelz_node_);
509
436
  }
510
437
  }
511
- chand_->subchannel_wrappers_.insert(this);
438
+ subchannel_wrappers.insert(this);
512
439
  }
513
440
 
514
441
  ~SubchannelWrapper() override {
@@ -523,37 +450,37 @@ class ClientChannelFilter::SubchannelWrapper final
523
450
  // WorkSerializer.
524
451
  // Ref held by callback.
525
452
  WeakRef(DEBUG_LOCATION, "subchannel map cleanup").release();
526
- chand_->work_serializer_->Run([this]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(
527
- *chand_->work_serializer_) {
528
- chand_->subchannel_wrappers_.erase(this);
529
- if (chand_->channelz_node_ != nullptr) {
530
- auto* subchannel_node = subchannel_->channelz_node();
531
- if (subchannel_node != nullptr) {
532
- auto it = chand_->subchannel_refcount_map_.find(subchannel_.get());
533
- GRPC_CHECK(it != chand_->subchannel_refcount_map_.end());
534
- --it->second;
535
- if (it->second == 0) {
536
- subchannel_node->RemoveParent(chand_->channelz_node_);
537
- chand_->subchannel_refcount_map_.erase(it);
453
+ chand_->work_serializer_->Run(
454
+ [this]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*chand_->work_serializer_) {
455
+ auto it = chand_->subchannel_map_.find(subchannel_.get());
456
+ GRPC_CHECK(it != chand_->subchannel_map_.end());
457
+ auto& subchannel_wrappers = it->second;
458
+ subchannel_wrappers.erase(this);
459
+ if (subchannel_wrappers.empty()) {
460
+ if (chand_->channelz_node_ != nullptr) {
461
+ auto* subchannel_node = subchannel_->channelz_node();
462
+ if (subchannel_node != nullptr) {
463
+ subchannel_node->RemoveParent(chand_->channelz_node_);
464
+ }
465
+ }
466
+ chand_->subchannel_map_.erase(it);
538
467
  }
539
- }
540
- }
541
- if (IsSubchannelWrapperCleanupOnOrphanEnabled()) {
542
- // We need to make sure that the internal subchannel gets unreffed
543
- // inside of the WorkSerializer, so that updates to the local
544
- // subchannel pool are properly synchronized. To that end, we
545
- // drop our ref to the internal subchannel here. We also cancel
546
- // any watchers that were not properly cancelled, in case any of
547
- // them are holding a ref to the internal subchannel.
548
- for (const auto& [_, watcher] : watcher_map_) {
549
- subchannel_->CancelConnectivityStateWatch(watcher);
550
- }
551
- watcher_map_.clear();
552
- data_watchers_.clear();
553
- subchannel_.reset();
554
- }
555
- WeakUnref(DEBUG_LOCATION, "subchannel map cleanup");
556
- });
468
+ if (IsSubchannelWrapperCleanupOnOrphanEnabled()) {
469
+ // We need to make sure that the internal subchannel gets unreffed
470
+ // inside of the WorkSerializer, so that updates to the local
471
+ // subchannel pool are properly synchronized. To that end, we
472
+ // drop our ref to the internal subchannel here. We also cancel
473
+ // any watchers that were not properly cancelled, in case any of
474
+ // them are holding a ref to the internal subchannel.
475
+ for (const auto& [_, watcher] : watcher_map_) {
476
+ subchannel_->CancelConnectivityStateWatch(watcher);
477
+ }
478
+ watcher_map_.clear();
479
+ data_watchers_.clear();
480
+ subchannel_.reset();
481
+ }
482
+ WeakUnref(DEBUG_LOCATION, "subchannel map cleanup");
483
+ });
557
484
  }
558
485
 
559
486
  void WatchConnectivityState(
@@ -598,10 +525,6 @@ class ClientChannelFilter::SubchannelWrapper final
598
525
  if (it != data_watchers_.end()) data_watchers_.erase(it);
599
526
  }
600
527
 
601
- void ThrottleKeepaliveTime(int new_keepalive_time) {
602
- subchannel_->ThrottleKeepaliveTime(new_keepalive_time);
603
- }
604
-
605
528
  std::string address() const override { return subchannel_->address(); }
606
529
 
607
530
  private:
@@ -644,6 +567,23 @@ class ClientChannelFilter::SubchannelWrapper final
644
567
  });
645
568
  }
646
569
 
570
+ void OnKeepaliveUpdate(Duration new_keepalive_time) override {
571
+ GRPC_TRACE_LOG(client_channel, INFO)
572
+ << "chand=" << parent_->chand_
573
+ << ": keepalive update for subchannel wrapper " << parent_.get()
574
+ << "hopping into work_serializer";
575
+ auto self = RefAsSubclass<WatcherWrapper>();
576
+ parent_->chand_->work_serializer_->Run(
577
+ [self, new_keepalive_time]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(
578
+ *self->parent_->chand_->work_serializer_) {
579
+ self->ApplyKeepaliveThrottlingInWorkSerializer(new_keepalive_time);
580
+ });
581
+ }
582
+
583
+ uint32_t max_connections_per_subchannel() const override {
584
+ return parent_->max_connections_per_subchannel_;
585
+ }
586
+
647
587
  grpc_pollset_set* interested_parties() override {
648
588
  return watcher_->interested_parties();
649
589
  }
@@ -659,29 +599,33 @@ class ClientChannelFilter::SubchannelWrapper final
659
599
  << parent_.get() << " subchannel " << parent_->subchannel_.get()
660
600
  << " watcher=" << watcher_.get()
661
601
  << " state=" << ConnectivityStateName(state) << " status=" << status;
662
- auto keepalive_throttling = status.GetPayload(kKeepaliveThrottlingKey);
663
- if (keepalive_throttling.has_value()) {
664
- int new_keepalive_time = -1;
665
- if (absl::SimpleAtoi(std::string(keepalive_throttling.value()),
666
- &new_keepalive_time)) {
667
- if (new_keepalive_time > parent_->chand_->keepalive_time_) {
668
- parent_->chand_->keepalive_time_ = new_keepalive_time;
669
- GRPC_TRACE_LOG(client_channel, INFO)
670
- << "chand=" << parent_->chand_
671
- << ": throttling keepalive time to "
672
- << parent_->chand_->keepalive_time_;
673
- // Propagate the new keepalive time to all subchannels. This is so
674
- // that new transports created by any subchannel (and not just the
675
- // subchannel that received the GOAWAY), use the new keepalive time.
676
- for (auto* subchannel_wrapper :
677
- parent_->chand_->subchannel_wrappers_) {
678
- subchannel_wrapper->ThrottleKeepaliveTime(new_keepalive_time);
602
+ if (!IsTransportStateWatcherEnabled()) {
603
+ auto keepalive_throttling = status.GetPayload(kKeepaliveThrottlingKey);
604
+ if (keepalive_throttling.has_value()) {
605
+ int new_keepalive_time_ms = -1;
606
+ if (absl::SimpleAtoi(std::string(keepalive_throttling.value()),
607
+ &new_keepalive_time_ms)) {
608
+ Duration new_keepalive_time =
609
+ Duration::Milliseconds(new_keepalive_time_ms);
610
+ if (new_keepalive_time > parent_->chand_->keepalive_time_) {
611
+ parent_->chand_->keepalive_time_ = new_keepalive_time;
612
+ GRPC_TRACE_LOG(client_channel, INFO)
613
+ << "chand=" << parent_->chand_
614
+ << ": throttling keepalive time to "
615
+ << parent_->chand_->keepalive_time_;
616
+ // Propagate the new keepalive time to all subchannels. This is
617
+ // so that new transports created by any subchannel (and not
618
+ // just the subchannel that received the GOAWAY), use the new
619
+ // keepalive time.
620
+ for (auto& [subchannel, _] : parent_->chand_->subchannel_map_) {
621
+ subchannel->ThrottleKeepaliveTime(new_keepalive_time);
622
+ }
679
623
  }
624
+ } else {
625
+ LOG(ERROR) << "chand=" << parent_->chand_
626
+ << ": Illegal keepalive throttling value "
627
+ << std::string(keepalive_throttling.value());
680
628
  }
681
- } else {
682
- LOG(ERROR) << "chand=" << parent_->chand_
683
- << ": Illegal keepalive throttling value "
684
- << std::string(keepalive_throttling.value());
685
629
  }
686
630
  }
687
631
  // Propagate status only in state TF.
@@ -693,6 +637,23 @@ class ClientChannelFilter::SubchannelWrapper final
693
637
  state == GRPC_CHANNEL_TRANSIENT_FAILURE ? status : absl::OkStatus());
694
638
  }
695
639
 
640
+ void ApplyKeepaliveThrottlingInWorkSerializer(Duration new_keepalive_time)
641
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(*parent_->chand_->work_serializer_) {
642
+ if (new_keepalive_time > parent_->chand_->keepalive_time_) {
643
+ parent_->chand_->keepalive_time_ = new_keepalive_time;
644
+ GRPC_TRACE_LOG(client_channel, INFO)
645
+ << "chand=" << parent_->chand_ << ": throttling keepalive time to "
646
+ << parent_->chand_->keepalive_time_;
647
+ // Propagate the new keepalive time to all subchannels. This is so
648
+ // that new transports created by any subchannel (and not just the
649
+ // subchannel that received the GOAWAY), use the new keepalive time.
650
+ for (auto& [subchannel, _] : parent_->chand_->subchannel_map_) {
651
+ if (parent_->subchannel_ == subchannel) continue;
652
+ subchannel->ThrottleKeepaliveTime(new_keepalive_time);
653
+ }
654
+ }
655
+ }
656
+
696
657
  std::unique_ptr<SubchannelInterface::ConnectivityStateWatcherInterface>
697
658
  watcher_;
698
659
  WeakRefCountedPtr<SubchannelWrapper> parent_;
@@ -718,6 +679,7 @@ class ClientChannelFilter::SubchannelWrapper final
718
679
 
719
680
  ClientChannelFilter* chand_;
720
681
  RefCountedPtr<Subchannel> subchannel_;
682
+ const uint32_t max_connections_per_subchannel_;
721
683
  // Maps from the address of the watcher passed to us by the LB policy
722
684
  // to the address of the WrapperWatcher that we passed to the underlying
723
685
  // subchannel. This is needed so that when the LB policy calls
@@ -929,6 +891,17 @@ class ClientChannelFilter::ClientChannelControlHelper final
929
891
  const ChannelArgs& args) override
930
892
  ABSL_EXCLUSIVE_LOCKS_REQUIRED(*chand_->work_serializer_) {
931
893
  if (chand_->resolver_ == nullptr) return nullptr; // Shutting down.
894
+ // Determine max_connections_per_subchannel.
895
+ const uint32_t cap =
896
+ args.GetInt(GRPC_ARG_MAX_CONNECTIONS_PER_SUBCHANNEL_CAP).value_or(10);
897
+ uint32_t max_connections_per_subchannel =
898
+ args.GetInt(GRPC_ARG_MAX_CONNECTIONS_PER_SUBCHANNEL)
899
+ .value_or(
900
+ per_address_args.GetInt(GRPC_ARG_MAX_CONNECTIONS_PER_SUBCHANNEL)
901
+ .value_or(1));
902
+ max_connections_per_subchannel =
903
+ std::min(max_connections_per_subchannel, cap);
904
+ // Modify args for subchannel.
932
905
  ChannelArgs subchannel_args = Subchannel::MakeSubchannelArgs(
933
906
  args, per_address_args, chand_->subchannel_pool_,
934
907
  chand_->default_authority_);
@@ -940,7 +913,8 @@ class ClientChannelFilter::ClientChannelControlHelper final
940
913
  // Make sure the subchannel has updated keepalive time.
941
914
  subchannel->ThrottleKeepaliveTime(chand_->keepalive_time_);
942
915
  // Create and return wrapper for the subchannel.
943
- return MakeRefCounted<SubchannelWrapper>(chand_, std::move(subchannel));
916
+ return MakeRefCounted<SubchannelWrapper>(chand_, std::move(subchannel),
917
+ max_connections_per_subchannel);
944
918
  }
945
919
 
946
920
  void UpdateState(grpc_connectivity_state state, const absl::Status& status,
@@ -1098,9 +1072,7 @@ ClientChannelFilter::ClientChannelFilter(grpc_channel_element_args* args,
1098
1072
  // Set initial keepalive time.
1099
1073
  auto keepalive_arg = channel_args_.GetInt(GRPC_ARG_KEEPALIVE_TIME_MS);
1100
1074
  if (keepalive_arg.has_value()) {
1101
- keepalive_time_ = Clamp(*keepalive_arg, 1, INT_MAX);
1102
- } else {
1103
- keepalive_time_ = -1; // unset
1075
+ keepalive_time_ = Duration::Milliseconds(Clamp(*keepalive_arg, 1, INT_MAX));
1104
1076
  }
1105
1077
  // Set default authority.
1106
1078
  std::optional<std::string> default_authority =
@@ -1125,16 +1097,15 @@ ClientChannelFilter::~ClientChannelFilter() {
1125
1097
  grpc_pollset_set_destroy(interested_parties_);
1126
1098
  }
1127
1099
 
1128
- OrphanablePtr<ClientChannelFilter::FilterBasedLoadBalancedCall>
1100
+ OrphanablePtr<ClientChannelFilter::LoadBalancedCall>
1129
1101
  ClientChannelFilter::CreateLoadBalancedCall(
1130
1102
  const grpc_call_element_args& args, grpc_polling_entity* pollent,
1131
1103
  grpc_closure* on_call_destruction_complete,
1132
1104
  absl::AnyInvocable<void()> on_commit, bool is_transparent_retry) {
1133
1105
  promise_detail::Context<Arena> arena_ctx(args.arena);
1134
- return OrphanablePtr<FilterBasedLoadBalancedCall>(
1135
- args.arena->New<FilterBasedLoadBalancedCall>(
1136
- this, args, pollent, on_call_destruction_complete,
1137
- std::move(on_commit), is_transparent_retry));
1106
+ return OrphanablePtr<LoadBalancedCall>(args.arena->New<LoadBalancedCall>(
1107
+ this, args, pollent, on_call_destruction_complete, std::move(on_commit),
1108
+ is_transparent_retry));
1138
1109
  }
1139
1110
 
1140
1111
  void ClientChannelFilter::ReprocessQueuedResolverCalls() {
@@ -1289,6 +1260,12 @@ void ClientChannelFilter::OnResolverResultChangedLocked(
1289
1260
  static_cast<const internal::ClientChannelGlobalParsedConfig*>(
1290
1261
  service_config->GetGlobalParsedConfig(
1291
1262
  service_config_parser_index_));
1263
+ // Set max_connections_per_subchannel from service config.
1264
+ if (parsed_service_config->max_connections_per_subchannel() != 0) {
1265
+ result.args = result.args.Set(
1266
+ GRPC_ARG_MAX_CONNECTIONS_PER_SUBCHANNEL,
1267
+ parsed_service_config->max_connections_per_subchannel());
1268
+ }
1292
1269
  // Choose LB policy config.
1293
1270
  RefCountedPtr<LoadBalancingPolicy::Config> lb_policy_config =
1294
1271
  ChooseLbPolicy(result, parsed_service_config);
@@ -1781,6 +1758,52 @@ void ClientChannelFilter::RemoveConnectivityWatcher(
1781
1758
  new ConnectivityWatcherRemover(this, watcher);
1782
1759
  }
1783
1760
 
1761
+ //
1762
+ // ClientChannelFilter::CallData::ResolverQueuedCallCanceller
1763
+ //
1764
+
1765
+ // A class to handle the call combiner cancellation callback for a
1766
+ // queued pick.
1767
+ class ClientChannelFilter::CallData::ResolverQueuedCallCanceller final {
1768
+ public:
1769
+ explicit ResolverQueuedCallCanceller(CallData* calld) : calld_(calld) {
1770
+ GRPC_CALL_STACK_REF(calld->owning_call_, "ResolverQueuedCallCanceller");
1771
+ GRPC_CLOSURE_INIT(&closure_, &CancelLocked, this,
1772
+ grpc_schedule_on_exec_ctx);
1773
+ calld->call_combiner_->SetNotifyOnCancel(&closure_);
1774
+ }
1775
+
1776
+ private:
1777
+ static void CancelLocked(void* arg, grpc_error_handle error) {
1778
+ auto* self = static_cast<ResolverQueuedCallCanceller*>(arg);
1779
+ auto* calld = self->calld_;
1780
+ auto* chand = calld->chand();
1781
+ {
1782
+ MutexLock lock(&chand->resolution_mu_);
1783
+ GRPC_TRACE_LOG(client_channel_call, INFO)
1784
+ << "chand=" << chand << " calld=" << calld
1785
+ << ": cancelling resolver queued pick: "
1786
+ "error="
1787
+ << StatusToString(error) << " self=" << self
1788
+ << " calld->resolver_pick_canceller="
1789
+ << calld->resolver_call_canceller_;
1790
+ if (calld->resolver_call_canceller_ == self && !error.ok()) {
1791
+ // Remove pick from list of queued picks.
1792
+ calld->RemoveCallFromResolverQueuedCallsLocked();
1793
+ chand->resolver_queued_calls_.erase(calld);
1794
+ // Fail pending batches on the call.
1795
+ calld->buffered_call_.Fail(
1796
+ error, BufferedCall::YieldCallCombinerIfPendingBatchesFound);
1797
+ }
1798
+ }
1799
+ GRPC_CALL_STACK_UNREF(calld->owning_call_, "ResolvingQueuedCallCanceller");
1800
+ delete self;
1801
+ }
1802
+
1803
+ CallData* calld_;
1804
+ grpc_closure closure_;
1805
+ };
1806
+
1784
1807
  //
1785
1808
  // CallData implementation
1786
1809
  //
@@ -1790,7 +1813,7 @@ void ClientChannelFilter::CallData::RemoveCallFromResolverQueuedCallsLocked() {
1790
1813
  << "chand=" << chand() << " calld=" << this
1791
1814
  << ": removing from resolver queued picks list";
1792
1815
  // Remove call's pollent from channel's interested_parties.
1793
- grpc_polling_entity_del_from_pollset_set(pollent(),
1816
+ grpc_polling_entity_del_from_pollset_set(pollent_,
1794
1817
  chand()->interested_parties_);
1795
1818
  // Note: There's no need to actually remove the call from the queue
1796
1819
  // here, because that will be done in
@@ -1802,14 +1825,15 @@ void ClientChannelFilter::CallData::AddCallToResolverQueuedCallsLocked() {
1802
1825
  GRPC_TRACE_LOG(client_channel_call, INFO)
1803
1826
  << "chand=" << chand() << " calld=" << this
1804
1827
  << ": adding to resolver queued picks list; pollent="
1805
- << grpc_polling_entity_string(pollent());
1828
+ << grpc_polling_entity_string(pollent_);
1806
1829
  // Add call's pollent to channel's interested_parties, so that I/O
1807
1830
  // can be done under the call's CQ.
1808
- grpc_polling_entity_add_to_pollset_set(pollent(),
1831
+ grpc_polling_entity_add_to_pollset_set(pollent_,
1809
1832
  chand()->interested_parties_);
1810
1833
  // Add to queue.
1811
1834
  chand()->resolver_queued_calls_.insert(this);
1812
- OnAddToQueueLocked();
1835
+ // Register call combiner cancellation callback.
1836
+ resolver_call_canceller_ = new ResolverQueuedCallCanceller(this);
1813
1837
  }
1814
1838
 
1815
1839
  grpc_error_handle ClientChannelFilter::CallData::ApplyServiceConfigToCallLocked(
@@ -1824,12 +1848,12 @@ grpc_error_handle ClientChannelFilter::CallData::ApplyServiceConfigToCallLocked(
1824
1848
  // itself in the call context, so that it can be accessed by filters
1825
1849
  // below us in the stack, and it will be cleaned up when the call ends.
1826
1850
  auto* service_config_call_data =
1827
- arena()->New<ClientChannelServiceConfigCallData>(arena());
1851
+ arena_->New<ClientChannelServiceConfigCallData>(arena_);
1828
1852
  // Use the ConfigSelector to determine the config for the call.
1829
1853
  absl::Status call_config_status =
1830
1854
  (*config_selector)
1831
1855
  ->GetCallConfig(
1832
- {send_initial_metadata(), arena(), service_config_call_data});
1856
+ {send_initial_metadata(), arena_, service_config_call_data});
1833
1857
  if (!call_config_status.ok()) {
1834
1858
  return absl_status_to_grpc_error(
1835
1859
  MaybeRewriteIllegalStatusCode(call_config_status, "ConfigSelector"));
@@ -1880,7 +1904,7 @@ std::optional<absl::Status> ClientChannelFilter::CallData::CheckResolution(
1880
1904
  }
1881
1905
  // If the call was queued, add trace annotation.
1882
1906
  if (was_queued) {
1883
- auto* call_tracer = arena()->GetContext<CallSpan>();
1907
+ auto* call_tracer = arena_->GetContext<CallSpan>();
1884
1908
  if (call_tracer != nullptr) {
1885
1909
  call_tracer->RecordAnnotation("Delayed name resolution complete.");
1886
1910
  }
@@ -1918,42 +1942,32 @@ bool ClientChannelFilter::CallData::CheckResolutionLocked(
1918
1942
  return true;
1919
1943
  }
1920
1944
 
1921
- //
1922
- // FilterBasedCallData implementation
1923
- //
1924
-
1925
- ClientChannelFilter::FilterBasedCallData::FilterBasedCallData(
1926
- grpc_call_element* elem, const grpc_call_element_args& args)
1945
+ ClientChannelFilter::CallData::CallData(grpc_call_element* elem,
1946
+ const grpc_call_element_args& args)
1927
1947
  : call_start_time_(args.start_time),
1928
1948
  deadline_(args.deadline),
1929
1949
  arena_(args.arena),
1930
1950
  elem_(elem),
1931
1951
  owning_call_(args.call_stack),
1932
- call_combiner_(args.call_combiner) {
1952
+ call_combiner_(args.call_combiner),
1953
+ buffered_call_(call_combiner_, &client_channel_call_trace) {
1933
1954
  GRPC_TRACE_LOG(client_channel_call, INFO)
1934
1955
  << "chand=" << chand() << " calld=" << this << ": created call";
1935
1956
  }
1936
1957
 
1937
- ClientChannelFilter::FilterBasedCallData::~FilterBasedCallData() {
1938
- // Make sure there are no remaining pending batches.
1939
- for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches_); ++i) {
1940
- GRPC_CHECK_EQ(pending_batches_[i], nullptr);
1941
- }
1942
- }
1943
-
1944
- grpc_error_handle ClientChannelFilter::FilterBasedCallData::Init(
1958
+ grpc_error_handle ClientChannelFilter::CallData::Init(
1945
1959
  grpc_call_element* elem, const grpc_call_element_args* args) {
1946
- new (elem->call_data) FilterBasedCallData(elem, *args);
1960
+ new (elem->call_data) CallData(elem, *args);
1947
1961
  return absl::OkStatus();
1948
1962
  }
1949
1963
 
1950
- void ClientChannelFilter::FilterBasedCallData::Destroy(
1964
+ void ClientChannelFilter::CallData::Destroy(
1951
1965
  grpc_call_element* elem, const grpc_call_final_info* /*final_info*/,
1952
1966
  grpc_closure* then_schedule_closure) {
1953
- auto* calld = static_cast<FilterBasedCallData*>(elem->call_data);
1967
+ auto* calld = static_cast<CallData*>(elem->call_data);
1954
1968
  RefCountedPtr<DynamicFilters::Call> dynamic_call =
1955
1969
  std::move(calld->dynamic_call_);
1956
- calld->~FilterBasedCallData();
1970
+ calld->~CallData();
1957
1971
  if (GPR_LIKELY(dynamic_call != nullptr)) {
1958
1972
  dynamic_call->SetAfterCallStackDestroy(then_schedule_closure);
1959
1973
  } else {
@@ -1962,9 +1976,9 @@ void ClientChannelFilter::FilterBasedCallData::Destroy(
1962
1976
  }
1963
1977
  }
1964
1978
 
1965
- void ClientChannelFilter::FilterBasedCallData::StartTransportStreamOpBatch(
1979
+ void ClientChannelFilter::CallData::StartTransportStreamOpBatch(
1966
1980
  grpc_call_element* elem, grpc_transport_stream_op_batch* batch) {
1967
- auto* calld = static_cast<FilterBasedCallData*>(elem->call_data);
1981
+ auto* calld = static_cast<CallData*>(elem->call_data);
1968
1982
  auto* chand = static_cast<ClientChannelFilter*>(elem->channel_data);
1969
1983
  if (GRPC_TRACE_FLAG_ENABLED(client_channel_call) &&
1970
1984
  !GRPC_TRACE_FLAG_ENABLED(channel)) {
@@ -2003,7 +2017,7 @@ void ClientChannelFilter::FilterBasedCallData::StartTransportStreamOpBatch(
2003
2017
  << StatusToString(calld->cancel_error_);
2004
2018
  // Note: This will release the call combiner.
2005
2019
  grpc_transport_stream_op_batch_finish_with_failure(
2006
- batch, calld->cancel_error_, calld->call_combiner());
2020
+ batch, calld->cancel_error_, calld->call_combiner_);
2007
2021
  return;
2008
2022
  }
2009
2023
  // Handle cancellation.
@@ -2018,14 +2032,15 @@ void ClientChannelFilter::FilterBasedCallData::StartTransportStreamOpBatch(
2018
2032
  << "chand=" << chand << " calld=" << calld
2019
2033
  << ": recording cancel_error=" << StatusToString(calld->cancel_error_);
2020
2034
  // Fail all pending batches.
2021
- calld->PendingBatchesFail(calld->cancel_error_, NoYieldCallCombiner);
2035
+ calld->buffered_call_.Fail(calld->cancel_error_,
2036
+ BufferedCall::NoYieldCallCombiner);
2022
2037
  // Note: This will release the call combiner.
2023
2038
  grpc_transport_stream_op_batch_finish_with_failure(
2024
- batch, calld->cancel_error_, calld->call_combiner());
2039
+ batch, calld->cancel_error_, calld->call_combiner_);
2025
2040
  return;
2026
2041
  }
2027
2042
  // Add the batch to the pending list.
2028
- calld->PendingBatchesAdd(batch);
2043
+ calld->buffered_call_.EnqueueBatch(batch);
2029
2044
  // For batches containing a send_initial_metadata op, acquire the
2030
2045
  // channel's resolution mutex to apply the service config to the call,
2031
2046
  // after which we will create a dynamic call.
@@ -2053,188 +2068,29 @@ void ClientChannelFilter::FilterBasedCallData::StartTransportStreamOpBatch(
2053
2068
  GRPC_TRACE_LOG(client_channel_call, INFO)
2054
2069
  << "chand=" << chand << " calld=" << calld
2055
2070
  << ": saved batch, yielding call combiner";
2056
- GRPC_CALL_COMBINER_STOP(calld->call_combiner(),
2071
+ GRPC_CALL_COMBINER_STOP(calld->call_combiner_,
2057
2072
  "batch does not include send_initial_metadata");
2058
2073
  }
2059
2074
  }
2060
2075
 
2061
- void ClientChannelFilter::FilterBasedCallData::SetPollent(
2062
- grpc_call_element* elem, grpc_polling_entity* pollent) {
2063
- auto* calld = static_cast<FilterBasedCallData*>(elem->call_data);
2076
+ void ClientChannelFilter::CallData::SetPollent(grpc_call_element* elem,
2077
+ grpc_polling_entity* pollent) {
2078
+ auto* calld = static_cast<CallData*>(elem->call_data);
2064
2079
  calld->pollent_ = pollent;
2065
2080
  }
2066
2081
 
2067
- size_t ClientChannelFilter::FilterBasedCallData::GetBatchIndex(
2068
- grpc_transport_stream_op_batch* batch) {
2069
- // Note: It is important the send_initial_metadata be the first entry
2070
- // here, since the code in CheckResolution() assumes it will be.
2071
- if (batch->send_initial_metadata) return 0;
2072
- if (batch->send_message) return 1;
2073
- if (batch->send_trailing_metadata) return 2;
2074
- if (batch->recv_initial_metadata) return 3;
2075
- if (batch->recv_message) return 4;
2076
- if (batch->recv_trailing_metadata) return 5;
2077
- GPR_UNREACHABLE_CODE(return (size_t)-1);
2078
- }
2079
-
2080
- // This is called via the call combiner, so access to calld is synchronized.
2081
- void ClientChannelFilter::FilterBasedCallData::PendingBatchesAdd(
2082
- grpc_transport_stream_op_batch* batch) {
2083
- const size_t idx = GetBatchIndex(batch);
2084
- GRPC_TRACE_LOG(client_channel_call, INFO)
2085
- << "chand=" << chand() << " calld=" << this
2086
- << ": adding pending batch at index " << idx;
2087
- grpc_transport_stream_op_batch*& pending = pending_batches_[idx];
2088
- GRPC_CHECK_EQ(pending, nullptr);
2089
- pending = batch;
2090
- }
2091
-
2092
- // This is called via the call combiner, so access to calld is synchronized.
2093
- void ClientChannelFilter::FilterBasedCallData::FailPendingBatchInCallCombiner(
2094
- void* arg, grpc_error_handle error) {
2095
- grpc_transport_stream_op_batch* batch =
2096
- static_cast<grpc_transport_stream_op_batch*>(arg);
2097
- auto* calld =
2098
- static_cast<FilterBasedCallData*>(batch->handler_private.extra_arg);
2099
- // Note: This will release the call combiner.
2100
- grpc_transport_stream_op_batch_finish_with_failure(batch, error,
2101
- calld->call_combiner());
2102
- }
2103
-
2104
- // This is called via the call combiner, so access to calld is synchronized.
2105
- void ClientChannelFilter::FilterBasedCallData::PendingBatchesFail(
2106
- grpc_error_handle error,
2107
- YieldCallCombinerPredicate yield_call_combiner_predicate) {
2108
- GRPC_CHECK(!error.ok());
2109
- if (GRPC_TRACE_FLAG_ENABLED(client_channel_call)) {
2110
- size_t num_batches = 0;
2111
- for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches_); ++i) {
2112
- if (pending_batches_[i] != nullptr) ++num_batches;
2113
- }
2114
- LOG(INFO) << "chand=" << chand() << " calld=" << this << ": failing "
2115
- << num_batches << " pending batches: " << StatusToString(error);
2116
- }
2117
- CallCombinerClosureList closures;
2118
- for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches_); ++i) {
2119
- grpc_transport_stream_op_batch*& batch = pending_batches_[i];
2120
- if (batch != nullptr) {
2121
- batch->handler_private.extra_arg = this;
2122
- GRPC_CLOSURE_INIT(&batch->handler_private.closure,
2123
- FailPendingBatchInCallCombiner, batch,
2124
- grpc_schedule_on_exec_ctx);
2125
- closures.Add(&batch->handler_private.closure, error,
2126
- "PendingBatchesFail");
2127
- batch = nullptr;
2128
- }
2129
- }
2130
- if (yield_call_combiner_predicate(closures)) {
2131
- closures.RunClosures(call_combiner());
2132
- } else {
2133
- closures.RunClosuresWithoutYielding(call_combiner());
2134
- }
2135
- }
2136
-
2137
- // This is called via the call combiner, so access to calld is synchronized.
2138
- void ClientChannelFilter::FilterBasedCallData::ResumePendingBatchInCallCombiner(
2139
- void* arg, grpc_error_handle /*ignored*/) {
2140
- grpc_transport_stream_op_batch* batch =
2141
- static_cast<grpc_transport_stream_op_batch*>(arg);
2142
- auto* calld =
2143
- static_cast<FilterBasedCallData*>(batch->handler_private.extra_arg);
2144
- // Note: This will release the call combiner.
2145
- calld->dynamic_call_->StartTransportStreamOpBatch(batch);
2146
- }
2147
-
2148
- // This is called via the call combiner, so access to calld is synchronized.
2149
- void ClientChannelFilter::FilterBasedCallData::PendingBatchesResume() {
2150
- // Retries not enabled; send down batches as-is.
2151
- if (GRPC_TRACE_FLAG_ENABLED(client_channel_call)) {
2152
- size_t num_batches = 0;
2153
- for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches_); ++i) {
2154
- if (pending_batches_[i] != nullptr) ++num_batches;
2155
- }
2156
- LOG(INFO) << "chand=" << chand() << " calld=" << this << ": starting "
2157
- << num_batches
2158
- << " pending batches on dynamic_call=" << dynamic_call_.get();
2159
- }
2160
- CallCombinerClosureList closures;
2161
- for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches_); ++i) {
2162
- grpc_transport_stream_op_batch*& batch = pending_batches_[i];
2163
- if (batch != nullptr) {
2164
- batch->handler_private.extra_arg = this;
2165
- GRPC_CLOSURE_INIT(&batch->handler_private.closure,
2166
- ResumePendingBatchInCallCombiner, batch, nullptr);
2167
- closures.Add(&batch->handler_private.closure, absl::OkStatus(),
2168
- "resuming pending batch from client channel call");
2169
- batch = nullptr;
2170
- }
2171
- }
2172
- // Note: This will release the call combiner.
2173
- closures.RunClosures(call_combiner());
2174
- }
2175
-
2176
- // A class to handle the call combiner cancellation callback for a
2177
- // queued pick.
2178
- class ClientChannelFilter::FilterBasedCallData::ResolverQueuedCallCanceller
2179
- final {
2180
- public:
2181
- explicit ResolverQueuedCallCanceller(FilterBasedCallData* calld)
2182
- : calld_(calld) {
2183
- GRPC_CALL_STACK_REF(calld->owning_call(), "ResolverQueuedCallCanceller");
2184
- GRPC_CLOSURE_INIT(&closure_, &CancelLocked, this,
2185
- grpc_schedule_on_exec_ctx);
2186
- calld->call_combiner()->SetNotifyOnCancel(&closure_);
2187
- }
2188
-
2189
- private:
2190
- static void CancelLocked(void* arg, grpc_error_handle error) {
2191
- auto* self = static_cast<ResolverQueuedCallCanceller*>(arg);
2192
- auto* calld = self->calld_;
2193
- auto* chand = calld->chand();
2194
- {
2195
- MutexLock lock(&chand->resolution_mu_);
2196
- GRPC_TRACE_LOG(client_channel_call, INFO)
2197
- << "chand=" << chand << " calld=" << calld
2198
- << ": cancelling resolver queued pick: "
2199
- "error="
2200
- << StatusToString(error) << " self=" << self
2201
- << " calld->resolver_pick_canceller="
2202
- << calld->resolver_call_canceller_;
2203
- if (calld->resolver_call_canceller_ == self && !error.ok()) {
2204
- // Remove pick from list of queued picks.
2205
- calld->RemoveCallFromResolverQueuedCallsLocked();
2206
- chand->resolver_queued_calls_.erase(calld);
2207
- // Fail pending batches on the call.
2208
- calld->PendingBatchesFail(error,
2209
- YieldCallCombinerIfPendingBatchesFound);
2210
- }
2211
- }
2212
- GRPC_CALL_STACK_UNREF(calld->owning_call(), "ResolvingQueuedCallCanceller");
2213
- delete self;
2214
- }
2215
-
2216
- FilterBasedCallData* calld_;
2217
- grpc_closure closure_;
2218
- };
2219
-
2220
- void ClientChannelFilter::FilterBasedCallData::TryCheckResolution(
2221
- bool was_queued) {
2082
+ void ClientChannelFilter::CallData::TryCheckResolution(bool was_queued) {
2222
2083
  auto result = CheckResolution(was_queued);
2223
2084
  if (result.has_value()) {
2224
2085
  if (!result->ok()) {
2225
- PendingBatchesFail(*result, YieldCallCombiner);
2086
+ buffered_call_.Fail(*result, BufferedCall::YieldCallCombiner);
2226
2087
  return;
2227
2088
  }
2228
2089
  CreateDynamicCall();
2229
2090
  }
2230
2091
  }
2231
2092
 
2232
- void ClientChannelFilter::FilterBasedCallData::OnAddToQueueLocked() {
2233
- // Register call combiner cancellation callback.
2234
- resolver_call_canceller_ = new ResolverQueuedCallCanceller(this);
2235
- }
2236
-
2237
- void ClientChannelFilter::FilterBasedCallData::RetryCheckResolutionLocked() {
2093
+ void ClientChannelFilter::CallData::RetryCheckResolutionLocked() {
2238
2094
  // Lame the call combiner canceller.
2239
2095
  resolver_call_canceller_ = nullptr;
2240
2096
  // Do an async callback to resume call processing, so that we're not
@@ -2245,10 +2101,10 @@ void ClientChannelFilter::FilterBasedCallData::RetryCheckResolutionLocked() {
2245
2101
  });
2246
2102
  }
2247
2103
 
2248
- void ClientChannelFilter::FilterBasedCallData::CreateDynamicCall() {
2249
- DynamicFilters::Call::Args args = {dynamic_filters(), pollent_,
2250
- call_start_time_, deadline_,
2251
- arena(), call_combiner()};
2104
+ void ClientChannelFilter::CallData::CreateDynamicCall() {
2105
+ DynamicFilters::Call::Args args = {dynamic_filters_, pollent_,
2106
+ call_start_time_, deadline_,
2107
+ arena_, call_combiner_};
2252
2108
  grpc_error_handle error;
2253
2109
  DynamicFilters* channel_stack = args.channel_stack.get();
2254
2110
  GRPC_TRACE_LOG(client_channel_call, INFO)
@@ -2259,18 +2115,21 @@ void ClientChannelFilter::FilterBasedCallData::CreateDynamicCall() {
2259
2115
  GRPC_TRACE_LOG(client_channel_call, INFO)
2260
2116
  << "chand=" << chand() << " calld=" << this
2261
2117
  << ": failed to create dynamic call: error=" << StatusToString(error);
2262
- PendingBatchesFail(error, YieldCallCombiner);
2118
+ buffered_call_.Fail(error, BufferedCall::YieldCallCombiner);
2263
2119
  return;
2264
2120
  }
2265
- PendingBatchesResume();
2121
+ buffered_call_.Resume(
2122
+ [dynamic_call = dynamic_call_](grpc_transport_stream_op_batch* batch) {
2123
+ dynamic_call->StartTransportStreamOpBatch(batch);
2124
+ });
2266
2125
  }
2267
2126
 
2268
- void ClientChannelFilter::FilterBasedCallData::
2127
+ void ClientChannelFilter::CallData::
2269
2128
  RecvTrailingMetadataReadyForConfigSelectorCommitCallback(
2270
2129
  void* arg, grpc_error_handle error) {
2271
- auto* calld = static_cast<FilterBasedCallData*>(arg);
2130
+ auto* calld = static_cast<CallData*>(arg);
2272
2131
  auto* chand = calld->chand();
2273
- auto* service_config_call_data = GetServiceConfigCallData(calld->arena());
2132
+ auto* service_config_call_data = GetServiceConfigCallData(calld->arena_);
2274
2133
  GRPC_TRACE_LOG(client_channel_call, INFO)
2275
2134
  << "chand=" << chand << " calld=" << calld
2276
2135
  << ": got recv_trailing_metadata_ready: error=" << StatusToString(error)
@@ -2319,7 +2178,7 @@ ClientChannelFilter::LoadBalancedCall::LbCallState::GetCallAttribute(
2319
2178
  CallAttemptTracer*
2320
2179
  ClientChannelFilter::LoadBalancedCall::LbCallState::GetCallAttemptTracer()
2321
2180
  const {
2322
- return lb_call_->call_attempt_tracer();
2181
+ return lb_call_->call_attempt_tracer_;
2323
2182
  }
2324
2183
 
2325
2184
  //
@@ -2367,6 +2226,61 @@ class ClientChannelFilter::LoadBalancedCall::BackendMetricAccessor final
2367
2226
  grpc_metadata_batch* recv_trailing_metadata_;
2368
2227
  };
2369
2228
 
2229
+ //
2230
+ // ClientChannelFilter::LoadBalancedCall::LbQueuedCallCanceller
2231
+ //
2232
+
2233
+ // A class to handle the call combiner cancellation callback for a
2234
+ // queued pick.
2235
+ // TODO(roth): When we implement hedging support, we won't be able to
2236
+ // register a call combiner cancellation closure for each LB pick,
2237
+ // because there may be multiple LB picks happening in parallel.
2238
+ // Instead, we will probably need to maintain a list in the CallData
2239
+ // object of pending LB picks to be cancelled when the closure runs.
2240
+ class ClientChannelFilter::LoadBalancedCall::LbQueuedCallCanceller final {
2241
+ public:
2242
+ explicit LbQueuedCallCanceller(RefCountedPtr<LoadBalancedCall> lb_call)
2243
+ : lb_call_(std::move(lb_call)) {
2244
+ GRPC_CALL_STACK_REF(lb_call_->owning_call_, "LbQueuedCallCanceller");
2245
+ GRPC_CLOSURE_INIT(&closure_, &CancelLocked, this, nullptr);
2246
+ lb_call_->call_combiner_->SetNotifyOnCancel(&closure_);
2247
+ }
2248
+
2249
+ private:
2250
+ static void CancelLocked(void* arg, grpc_error_handle error) {
2251
+ auto* self = static_cast<LbQueuedCallCanceller*>(arg);
2252
+ auto* lb_call = self->lb_call_.get();
2253
+ auto* chand = lb_call->chand_;
2254
+ {
2255
+ MutexLock lock(&chand->lb_mu_);
2256
+ GRPC_TRACE_LOG(client_channel_lb_call, INFO)
2257
+ << "chand=" << chand << " lb_call=" << lb_call
2258
+ << ": cancelling queued pick: error=" << StatusToString(error)
2259
+ << " self=" << self
2260
+ << " calld->pick_canceller=" << lb_call->lb_call_canceller_;
2261
+ if (lb_call->lb_call_canceller_ == self && !error.ok()) {
2262
+ lb_call->Commit();
2263
+ // Remove pick from list of queued picks.
2264
+ lb_call->RemoveCallFromLbQueuedCallsLocked();
2265
+ // Remove from queued picks list.
2266
+ chand->lb_queued_calls_.erase(self->lb_call_);
2267
+ // Fail pending batches on the call.
2268
+ lb_call->buffered_call_.Fail(
2269
+ error, BufferedCall::YieldCallCombinerIfPendingBatchesFound);
2270
+ }
2271
+ }
2272
+ // Unref lb_call before unreffing the call stack, since unreffing
2273
+ // the call stack may destroy the arena in which lb_call is allocated.
2274
+ auto* owning_call = lb_call->owning_call_;
2275
+ self->lb_call_.reset();
2276
+ GRPC_CALL_STACK_UNREF(owning_call, "LbQueuedCallCanceller");
2277
+ delete self;
2278
+ }
2279
+
2280
+ RefCountedPtr<LoadBalancedCall> lb_call_;
2281
+ grpc_closure closure_;
2282
+ };
2283
+
2370
2284
  //
2371
2285
  // ClientChannelFilter::LoadBalancedCall
2372
2286
  //
@@ -2386,16 +2300,22 @@ CallAttemptTracer* CreateCallAttemptTracer(Arena* arena,
2386
2300
  } // namespace
2387
2301
 
2388
2302
  ClientChannelFilter::LoadBalancedCall::LoadBalancedCall(
2389
- ClientChannelFilter* chand, Arena* arena,
2303
+ ClientChannelFilter* chand, const grpc_call_element_args& args,
2304
+ grpc_polling_entity* pollent, grpc_closure* on_call_destruction_complete,
2390
2305
  absl::AnyInvocable<void()> on_commit, bool is_transparent_retry)
2391
2306
  : InternallyRefCounted(GRPC_TRACE_FLAG_ENABLED(client_channel_lb_call)
2392
2307
  ? "LoadBalancedCall"
2393
2308
  : nullptr),
2394
2309
  chand_(chand),
2395
2310
  call_attempt_tracer_(
2396
- CreateCallAttemptTracer(arena, is_transparent_retry)),
2311
+ CreateCallAttemptTracer(args.arena, is_transparent_retry)),
2312
+ owning_call_(args.call_stack),
2313
+ call_combiner_(args.call_combiner),
2314
+ pollent_(pollent),
2315
+ on_call_destruction_complete_(on_call_destruction_complete),
2316
+ arena_(args.arena),
2397
2317
  on_commit_(std::move(on_commit)),
2398
- arena_(arena) {
2318
+ buffered_call_(call_combiner_, &client_channel_lb_call_trace) {
2399
2319
  GRPC_TRACE_LOG(client_channel_lb_call, INFO)
2400
2320
  << "chand=" << chand_ << " lb_call=" << this << ": created";
2401
2321
  }
@@ -2404,6 +2324,22 @@ ClientChannelFilter::LoadBalancedCall::~LoadBalancedCall() {
2404
2324
  if (backend_metric_data_ != nullptr) {
2405
2325
  backend_metric_data_->BackendMetricData::~BackendMetricData();
2406
2326
  }
2327
+ if (on_call_destruction_complete_ != nullptr) {
2328
+ ExecCtx::Run(DEBUG_LOCATION, on_call_destruction_complete_,
2329
+ absl::OkStatus());
2330
+ }
2331
+ }
2332
+
2333
+ void ClientChannelFilter::LoadBalancedCall::Orphan() {
2334
+ // If the recv_trailing_metadata op was never started, then notify
2335
+ // about call completion here, as best we can. We assume status
2336
+ // CANCELLED in this case.
2337
+ if (recv_trailing_metadata_ == nullptr) {
2338
+ RecordCallCompletion(absl::CancelledError("call cancelled"), nullptr,
2339
+ nullptr, "");
2340
+ }
2341
+ RecordLatency();
2342
+ Unref();
2407
2343
  }
2408
2344
 
2409
2345
  void ClientChannelFilter::LoadBalancedCall::RecordCallCompletion(
@@ -2411,8 +2347,8 @@ void ClientChannelFilter::LoadBalancedCall::RecordCallCompletion(
2411
2347
  grpc_transport_stream_stats* transport_stream_stats,
2412
2348
  absl::string_view peer_address) {
2413
2349
  // If we have a tracer, notify it.
2414
- if (call_attempt_tracer() != nullptr) {
2415
- call_attempt_tracer()->RecordReceivedTrailingMetadata(
2350
+ if (call_attempt_tracer_ != nullptr) {
2351
+ call_attempt_tracer_->RecordReceivedTrailingMetadata(
2416
2352
  status, recv_trailing_metadata, transport_stream_stats);
2417
2353
  }
2418
2354
  // If the LB policy requested a callback for trailing metadata, invoke
@@ -2429,8 +2365,8 @@ void ClientChannelFilter::LoadBalancedCall::RecordCallCompletion(
2429
2365
 
2430
2366
  void ClientChannelFilter::LoadBalancedCall::RecordLatency() {
2431
2367
  // Compute latency and report it to the tracer.
2432
- if (call_attempt_tracer() != nullptr) {
2433
- call_attempt_tracer()->RecordEnd();
2368
+ if (call_attempt_tracer_ != nullptr) {
2369
+ call_attempt_tracer_->RecordEnd();
2434
2370
  }
2435
2371
  }
2436
2372
 
@@ -2440,7 +2376,7 @@ void ClientChannelFilter::LoadBalancedCall::
2440
2376
  << "chand=" << chand_ << " lb_call=" << this
2441
2377
  << ": removing from queued picks list";
2442
2378
  // Remove pollset_set linkage.
2443
- grpc_polling_entity_del_from_pollset_set(pollent(),
2379
+ grpc_polling_entity_del_from_pollset_set(pollent_,
2444
2380
  chand_->interested_parties_);
2445
2381
  // Note: There's no need to actually remove the call from the queue
2446
2382
  // here, because that will be done in either
@@ -2454,11 +2390,12 @@ void ClientChannelFilter::LoadBalancedCall::AddCallToLbQueuedCallsLocked() {
2454
2390
  << ": adding to queued picks list";
2455
2391
  // Add call's pollent to channel's interested_parties, so that I/O
2456
2392
  // can be done under the call's CQ.
2457
- grpc_polling_entity_add_to_pollset_set(pollent(),
2458
- chand_->interested_parties_);
2393
+ grpc_polling_entity_add_to_pollset_set(pollent_, chand_->interested_parties_);
2459
2394
  // Add to queue.
2460
2395
  chand_->lb_queued_calls_.insert(Ref());
2461
- OnAddToQueueLocked();
2396
+ // Register call combiner cancellation callback.
2397
+ lb_call_canceller_ =
2398
+ new LbQueuedCallCanceller(RefAsSubclass<LoadBalancedCall>());
2462
2399
  }
2463
2400
 
2464
2401
  std::optional<absl::Status>
@@ -2506,8 +2443,8 @@ ClientChannelFilter::LoadBalancedCall::PickSubchannel(bool was_queued) {
2506
2443
  }
2507
2444
  // Pick is complete.
2508
2445
  // If it was queued, add a trace annotation.
2509
- if (was_queued && call_attempt_tracer() != nullptr) {
2510
- call_attempt_tracer()->RecordAnnotation("Delayed LB pick complete.");
2446
+ if (was_queued && call_attempt_tracer_ != nullptr) {
2447
+ call_attempt_tracer_->RecordAnnotation("Delayed LB pick complete.");
2511
2448
  }
2512
2449
  // If the pick failed, fail the call.
2513
2450
  if (!error.ok()) {
@@ -2562,9 +2499,6 @@ bool ClientChannelFilter::LoadBalancedCall::PickSubchannelImpl(
2562
2499
  }
2563
2500
  lb_subchannel_call_tracker_ =
2564
2501
  std::move(complete_pick->subchannel_call_tracker);
2565
- if (lb_subchannel_call_tracker_ != nullptr) {
2566
- lb_subchannel_call_tracker_->Start();
2567
- }
2568
2502
  // Handle metadata mutations.
2569
2503
  MetadataMutationHandler::Apply(complete_pick->metadata_mutations,
2570
2504
  send_initial_metadata());
@@ -2609,177 +2543,28 @@ bool ClientChannelFilter::LoadBalancedCall::PickSubchannelImpl(
2609
2543
  });
2610
2544
  }
2611
2545
 
2612
- //
2613
- // ClientChannelFilter::FilterBasedLoadBalancedCall
2614
- //
2615
-
2616
- ClientChannelFilter::FilterBasedLoadBalancedCall::FilterBasedLoadBalancedCall(
2617
- ClientChannelFilter* chand, const grpc_call_element_args& args,
2618
- grpc_polling_entity* pollent, grpc_closure* on_call_destruction_complete,
2619
- absl::AnyInvocable<void()> on_commit, bool is_transparent_retry)
2620
- : LoadBalancedCall(chand, args.arena, std::move(on_commit),
2621
- is_transparent_retry),
2622
- owning_call_(args.call_stack),
2623
- call_combiner_(args.call_combiner),
2624
- pollent_(pollent),
2625
- on_call_destruction_complete_(on_call_destruction_complete) {}
2626
-
2627
- ClientChannelFilter::FilterBasedLoadBalancedCall::
2628
- ~FilterBasedLoadBalancedCall() {
2629
- // Make sure there are no remaining pending batches.
2630
- for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches_); ++i) {
2631
- GRPC_CHECK_EQ(pending_batches_[i], nullptr);
2632
- }
2633
- if (on_call_destruction_complete_ != nullptr) {
2634
- ExecCtx::Run(DEBUG_LOCATION, on_call_destruction_complete_,
2635
- absl::OkStatus());
2636
- }
2637
- }
2638
-
2639
- void ClientChannelFilter::FilterBasedLoadBalancedCall::Orphan() {
2640
- // If the recv_trailing_metadata op was never started, then notify
2641
- // about call completion here, as best we can. We assume status
2642
- // CANCELLED in this case.
2643
- if (recv_trailing_metadata_ == nullptr) {
2644
- RecordCallCompletion(absl::CancelledError("call cancelled"), nullptr,
2645
- nullptr, "");
2646
- }
2647
- RecordLatency();
2648
- // Delegate to parent.
2649
- LoadBalancedCall::Orphan();
2650
- }
2651
-
2652
- size_t ClientChannelFilter::FilterBasedLoadBalancedCall::GetBatchIndex(
2653
- grpc_transport_stream_op_batch* batch) {
2654
- // Note: It is important the send_initial_metadata be the first entry
2655
- // here, since the code in PickSubchannelImpl() assumes it will be.
2656
- if (batch->send_initial_metadata) return 0;
2657
- if (batch->send_message) return 1;
2658
- if (batch->send_trailing_metadata) return 2;
2659
- if (batch->recv_initial_metadata) return 3;
2660
- if (batch->recv_message) return 4;
2661
- if (batch->recv_trailing_metadata) return 5;
2662
- GPR_UNREACHABLE_CODE(return (size_t)-1);
2663
- }
2664
-
2665
- // This is called via the call combiner, so access to calld is synchronized.
2666
- void ClientChannelFilter::FilterBasedLoadBalancedCall::PendingBatchesAdd(
2546
+ void ClientChannelFilter::LoadBalancedCall::StartTransportStreamOpBatch(
2667
2547
  grpc_transport_stream_op_batch* batch) {
2668
- const size_t idx = GetBatchIndex(batch);
2669
- GRPC_TRACE_LOG(client_channel_lb_call, INFO)
2670
- << "chand=" << chand() << " lb_call=" << this
2671
- << ": adding pending batch at index " << idx;
2672
- GRPC_CHECK_EQ(pending_batches_[idx], nullptr);
2673
- pending_batches_[idx] = batch;
2674
- }
2675
-
2676
- // This is called via the call combiner, so access to calld is synchronized.
2677
- void ClientChannelFilter::FilterBasedLoadBalancedCall::
2678
- FailPendingBatchInCallCombiner(void* arg, grpc_error_handle error) {
2679
- grpc_transport_stream_op_batch* batch =
2680
- static_cast<grpc_transport_stream_op_batch*>(arg);
2681
- auto* self = static_cast<FilterBasedLoadBalancedCall*>(
2682
- batch->handler_private.extra_arg);
2683
- // Note: This will release the call combiner.
2684
- grpc_transport_stream_op_batch_finish_with_failure(batch, error,
2685
- self->call_combiner_);
2686
- }
2687
-
2688
- // This is called via the call combiner, so access to calld is synchronized.
2689
- void ClientChannelFilter::FilterBasedLoadBalancedCall::PendingBatchesFail(
2690
- grpc_error_handle error,
2691
- YieldCallCombinerPredicate yield_call_combiner_predicate) {
2692
- GRPC_CHECK(!error.ok());
2693
- failure_error_ = error;
2694
- if (GRPC_TRACE_FLAG_ENABLED(client_channel_lb_call)) {
2695
- size_t num_batches = 0;
2696
- for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches_); ++i) {
2697
- if (pending_batches_[i] != nullptr) ++num_batches;
2698
- }
2699
- LOG(INFO) << "chand=" << chand() << " lb_call=" << this << ": failing "
2700
- << num_batches << " pending batches: " << StatusToString(error);
2701
- }
2702
- CallCombinerClosureList closures;
2703
- for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches_); ++i) {
2704
- grpc_transport_stream_op_batch*& batch = pending_batches_[i];
2705
- if (batch != nullptr) {
2706
- batch->handler_private.extra_arg = this;
2707
- GRPC_CLOSURE_INIT(&batch->handler_private.closure,
2708
- FailPendingBatchInCallCombiner, batch,
2709
- grpc_schedule_on_exec_ctx);
2710
- closures.Add(&batch->handler_private.closure, error,
2711
- "PendingBatchesFail");
2712
- batch = nullptr;
2713
- }
2714
- }
2715
- if (yield_call_combiner_predicate(closures)) {
2716
- closures.RunClosures(call_combiner_);
2717
- } else {
2718
- closures.RunClosuresWithoutYielding(call_combiner_);
2719
- }
2720
- }
2721
-
2722
- // This is called via the call combiner, so access to calld is synchronized.
2723
- void ClientChannelFilter::FilterBasedLoadBalancedCall::
2724
- ResumePendingBatchInCallCombiner(void* arg, grpc_error_handle /*ignored*/) {
2725
- grpc_transport_stream_op_batch* batch =
2726
- static_cast<grpc_transport_stream_op_batch*>(arg);
2727
- SubchannelCall* subchannel_call =
2728
- static_cast<SubchannelCall*>(batch->handler_private.extra_arg);
2729
- // Note: This will release the call combiner.
2730
- subchannel_call->StartTransportStreamOpBatch(batch);
2731
- }
2732
-
2733
- // This is called via the call combiner, so access to calld is synchronized.
2734
- void ClientChannelFilter::FilterBasedLoadBalancedCall::PendingBatchesResume() {
2735
- if (GRPC_TRACE_FLAG_ENABLED(client_channel_lb_call)) {
2736
- size_t num_batches = 0;
2737
- for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches_); ++i) {
2738
- if (pending_batches_[i] != nullptr) ++num_batches;
2739
- }
2740
- LOG(INFO) << "chand=" << chand() << " lb_call=" << this << ": starting "
2741
- << num_batches << " pending batches on subchannel_call="
2742
- << subchannel_call_.get();
2743
- }
2744
- CallCombinerClosureList closures;
2745
- for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches_); ++i) {
2746
- grpc_transport_stream_op_batch*& batch = pending_batches_[i];
2747
- if (batch != nullptr) {
2748
- batch->handler_private.extra_arg = subchannel_call_.get();
2749
- GRPC_CLOSURE_INIT(&batch->handler_private.closure,
2750
- ResumePendingBatchInCallCombiner, batch,
2751
- grpc_schedule_on_exec_ctx);
2752
- closures.Add(&batch->handler_private.closure, absl::OkStatus(),
2753
- "resuming pending batch from LB call");
2754
- batch = nullptr;
2755
- }
2756
- }
2757
- // Note: This will release the call combiner.
2758
- closures.RunClosures(call_combiner_);
2759
- }
2760
-
2761
- void ClientChannelFilter::FilterBasedLoadBalancedCall::
2762
- StartTransportStreamOpBatch(grpc_transport_stream_op_batch* batch) {
2763
2548
  if (GRPC_TRACE_FLAG_ENABLED(client_channel_lb_call) ||
2764
2549
  GRPC_TRACE_FLAG_ENABLED(channel)) {
2765
- LOG(INFO) << "chand=" << chand() << " lb_call=" << this
2550
+ LOG(INFO) << "chand=" << chand_ << " lb_call=" << this
2766
2551
  << ": batch started from above: "
2767
2552
  << grpc_transport_stream_op_batch_string(batch, false)
2768
- << ", call_attempt_tracer()=" << call_attempt_tracer();
2553
+ << ", call_attempt_tracer_=" << call_attempt_tracer_;
2769
2554
  }
2770
2555
  // Handle call tracing.
2771
- if (call_attempt_tracer() != nullptr) {
2556
+ if (call_attempt_tracer_ != nullptr) {
2772
2557
  // Record send ops in tracer.
2773
2558
  if (batch->cancel_stream) {
2774
- call_attempt_tracer()->RecordCancel(
2559
+ call_attempt_tracer_->RecordCancel(
2775
2560
  batch->payload->cancel_stream.cancel_error);
2776
2561
  }
2777
2562
  if (batch->send_initial_metadata) {
2778
- call_attempt_tracer()->RecordSendInitialMetadata(
2563
+ call_attempt_tracer_->RecordSendInitialMetadata(
2779
2564
  batch->payload->send_initial_metadata.send_initial_metadata);
2780
2565
  }
2781
2566
  if (batch->send_trailing_metadata) {
2782
- call_attempt_tracer()->RecordSendTrailingMetadata(
2567
+ call_attempt_tracer_->RecordSendTrailingMetadata(
2783
2568
  batch->payload->send_trailing_metadata.send_trailing_metadata);
2784
2569
  }
2785
2570
  // Intercept recv ops.
@@ -2814,7 +2599,7 @@ void ClientChannelFilter::FilterBasedLoadBalancedCall::
2814
2599
  // streaming calls).
2815
2600
  if (subchannel_call_ != nullptr) {
2816
2601
  GRPC_TRACE_LOG(client_channel_lb_call, INFO)
2817
- << "chand=" << chand() << " lb_call=" << this
2602
+ << "chand=" << chand_ << " lb_call=" << this
2818
2603
  << ": starting batch on subchannel_call=" << subchannel_call_.get();
2819
2604
  subchannel_call_->StartTransportStreamOpBatch(batch);
2820
2605
  return;
@@ -2824,7 +2609,7 @@ void ClientChannelFilter::FilterBasedLoadBalancedCall::
2824
2609
  // If we've previously been cancelled, immediately fail any new batches.
2825
2610
  if (GPR_UNLIKELY(!cancel_error_.ok())) {
2826
2611
  GRPC_TRACE_LOG(client_channel_lb_call, INFO)
2827
- << "chand=" << chand() << " lb_call=" << this
2612
+ << "chand=" << chand_ << " lb_call=" << this
2828
2613
  << ": failing batch with error: " << StatusToString(cancel_error_);
2829
2614
  // Note: This will release the call combiner.
2830
2615
  grpc_transport_stream_op_batch_finish_with_failure(batch, cancel_error_,
@@ -2840,17 +2625,17 @@ void ClientChannelFilter::FilterBasedLoadBalancedCall::
2840
2625
  // error to the caller when the first batch does get passed down.
2841
2626
  cancel_error_ = batch->payload->cancel_stream.cancel_error;
2842
2627
  GRPC_TRACE_LOG(client_channel_lb_call, INFO)
2843
- << "chand=" << chand() << " lb_call=" << this
2628
+ << "chand=" << chand_ << " lb_call=" << this
2844
2629
  << ": recording cancel_error=" << StatusToString(cancel_error_).c_str();
2845
2630
  // Fail all pending batches.
2846
- PendingBatchesFail(cancel_error_, NoYieldCallCombiner);
2631
+ buffered_call_.Fail(cancel_error_, BufferedCall::NoYieldCallCombiner);
2847
2632
  // Note: This will release the call combiner.
2848
2633
  grpc_transport_stream_op_batch_finish_with_failure(batch, cancel_error_,
2849
2634
  call_combiner_);
2850
2635
  return;
2851
2636
  }
2852
2637
  // Add the batch to the pending list.
2853
- PendingBatchesAdd(batch);
2638
+ buffered_call_.EnqueueBatch(batch);
2854
2639
  // For batches containing a send_initial_metadata op, acquire the
2855
2640
  // channel's LB mutex to pick a subchannel.
2856
2641
  if (GPR_LIKELY(batch->send_initial_metadata)) {
@@ -2858,22 +2643,22 @@ void ClientChannelFilter::FilterBasedLoadBalancedCall::
2858
2643
  } else {
2859
2644
  // For all other batches, release the call combiner.
2860
2645
  GRPC_TRACE_LOG(client_channel_lb_call, INFO)
2861
- << "chand=" << chand() << " lb_call=" << this
2646
+ << "chand=" << chand_ << " lb_call=" << this
2862
2647
  << ": saved batch, yielding call combiner";
2863
2648
  GRPC_CALL_COMBINER_STOP(call_combiner_,
2864
2649
  "batch does not include send_initial_metadata");
2865
2650
  }
2866
2651
  }
2867
2652
 
2868
- void ClientChannelFilter::FilterBasedLoadBalancedCall::RecvInitialMetadataReady(
2653
+ void ClientChannelFilter::LoadBalancedCall::RecvInitialMetadataReady(
2869
2654
  void* arg, grpc_error_handle error) {
2870
- auto* self = static_cast<FilterBasedLoadBalancedCall*>(arg);
2655
+ auto* self = static_cast<LoadBalancedCall*>(arg);
2871
2656
  GRPC_TRACE_LOG(client_channel_lb_call, INFO)
2872
- << "chand=" << self->chand() << " lb_call=" << self
2657
+ << "chand=" << self->chand_ << " lb_call=" << self
2873
2658
  << ": got recv_initial_metadata_ready: error=" << StatusToString(error);
2874
2659
  if (error.ok()) {
2875
2660
  // recv_initial_metadata_flags is not populated for clients
2876
- self->call_attempt_tracer()->RecordReceivedInitialMetadata(
2661
+ self->call_attempt_tracer_->RecordReceivedInitialMetadata(
2877
2662
  self->recv_initial_metadata_);
2878
2663
  auto* peer_string = self->recv_initial_metadata_->get_pointer(PeerString());
2879
2664
  if (peer_string != nullptr) self->peer_string_ = peer_string->Ref();
@@ -2882,27 +2667,28 @@ void ClientChannelFilter::FilterBasedLoadBalancedCall::RecvInitialMetadataReady(
2882
2667
  error);
2883
2668
  }
2884
2669
 
2885
- void ClientChannelFilter::FilterBasedLoadBalancedCall::
2886
- RecvTrailingMetadataReady(void* arg, grpc_error_handle error) {
2887
- auto* self = static_cast<FilterBasedLoadBalancedCall*>(arg);
2670
+ void ClientChannelFilter::LoadBalancedCall::RecvTrailingMetadataReady(
2671
+ void* arg, grpc_error_handle error) {
2672
+ auto* self = static_cast<LoadBalancedCall*>(arg);
2888
2673
  GRPC_TRACE_LOG(client_channel_lb_call, INFO)
2889
- << "chand=" << self->chand() << " lb_call=" << self
2674
+ << "chand=" << self->chand_ << " lb_call=" << self
2890
2675
  << ": got recv_trailing_metadata_ready: error=" << StatusToString(error)
2891
- << " call_attempt_tracer()=" << self->call_attempt_tracer()
2892
- << " lb_subchannel_call_tracker_=" << self->lb_subchannel_call_tracker()
2676
+ << " call_attempt_tracer_=" << self->call_attempt_tracer_
2677
+ << " lb_subchannel_call_tracker_="
2678
+ << self->lb_subchannel_call_tracker_.get()
2893
2679
  << " failure_error_=" << StatusToString(self->failure_error_);
2894
2680
  // Check if we have a tracer or an LB callback to invoke.
2895
- if (self->call_attempt_tracer() != nullptr ||
2896
- self->lb_subchannel_call_tracker() != nullptr) {
2681
+ if (self->call_attempt_tracer_ != nullptr ||
2682
+ self->lb_subchannel_call_tracker_ != nullptr) {
2897
2683
  // Get the call's status.
2898
2684
  absl::Status status;
2899
2685
  if (!error.ok()) {
2900
2686
  // Get status from error.
2901
2687
  grpc_status_code code;
2902
2688
  std::string message;
2903
- grpc_error_get_status(
2904
- error, self->arena()->GetContext<Call>()->deadline(), &code, &message,
2905
- /*http_error=*/nullptr, /*error_string=*/nullptr);
2689
+ grpc_error_get_status(error, self->arena_->GetContext<Call>()->deadline(),
2690
+ &code, &message,
2691
+ /*http_error=*/nullptr, /*error_string=*/nullptr);
2906
2692
  status = absl::Status(static_cast<absl::StatusCode>(code), message);
2907
2693
  } else {
2908
2694
  // Get status from headers.
@@ -2933,78 +2719,18 @@ void ClientChannelFilter::FilterBasedLoadBalancedCall::
2933
2719
  error);
2934
2720
  }
2935
2721
 
2936
- // A class to handle the call combiner cancellation callback for a
2937
- // queued pick.
2938
- // TODO(roth): When we implement hedging support, we won't be able to
2939
- // register a call combiner cancellation closure for each LB pick,
2940
- // because there may be multiple LB picks happening in parallel.
2941
- // Instead, we will probably need to maintain a list in the CallData
2942
- // object of pending LB picks to be cancelled when the closure runs.
2943
- class ClientChannelFilter::FilterBasedLoadBalancedCall::LbQueuedCallCanceller
2944
- final {
2945
- public:
2946
- explicit LbQueuedCallCanceller(
2947
- RefCountedPtr<FilterBasedLoadBalancedCall> lb_call)
2948
- : lb_call_(std::move(lb_call)) {
2949
- GRPC_CALL_STACK_REF(lb_call_->owning_call_, "LbQueuedCallCanceller");
2950
- GRPC_CLOSURE_INIT(&closure_, &CancelLocked, this, nullptr);
2951
- lb_call_->call_combiner_->SetNotifyOnCancel(&closure_);
2952
- }
2953
-
2954
- private:
2955
- static void CancelLocked(void* arg, grpc_error_handle error) {
2956
- auto* self = static_cast<LbQueuedCallCanceller*>(arg);
2957
- auto* lb_call = self->lb_call_.get();
2958
- auto* chand = lb_call->chand();
2959
- {
2960
- MutexLock lock(&chand->lb_mu_);
2961
- GRPC_TRACE_LOG(client_channel_lb_call, INFO)
2962
- << "chand=" << chand << " lb_call=" << lb_call
2963
- << ": cancelling queued pick: error=" << StatusToString(error)
2964
- << " self=" << self
2965
- << " calld->pick_canceller=" << lb_call->lb_call_canceller_;
2966
- if (lb_call->lb_call_canceller_ == self && !error.ok()) {
2967
- lb_call->Commit();
2968
- // Remove pick from list of queued picks.
2969
- lb_call->RemoveCallFromLbQueuedCallsLocked();
2970
- // Remove from queued picks list.
2971
- chand->lb_queued_calls_.erase(self->lb_call_);
2972
- // Fail pending batches on the call.
2973
- lb_call->PendingBatchesFail(error,
2974
- YieldCallCombinerIfPendingBatchesFound);
2975
- }
2976
- }
2977
- // Unref lb_call before unreffing the call stack, since unreffing
2978
- // the call stack may destroy the arena in which lb_call is allocated.
2979
- auto* owning_call = lb_call->owning_call_;
2980
- self->lb_call_.reset();
2981
- GRPC_CALL_STACK_UNREF(owning_call, "LbQueuedCallCanceller");
2982
- delete self;
2983
- }
2984
-
2985
- RefCountedPtr<FilterBasedLoadBalancedCall> lb_call_;
2986
- grpc_closure closure_;
2987
- };
2988
-
2989
- void ClientChannelFilter::FilterBasedLoadBalancedCall::TryPick(
2990
- bool was_queued) {
2722
+ void ClientChannelFilter::LoadBalancedCall::TryPick(bool was_queued) {
2991
2723
  auto result = PickSubchannel(was_queued);
2992
2724
  if (result.has_value()) {
2993
2725
  if (!result->ok()) {
2994
- PendingBatchesFail(*result, YieldCallCombiner);
2726
+ buffered_call_.Fail(*result, BufferedCall::YieldCallCombiner);
2995
2727
  return;
2996
2728
  }
2997
2729
  CreateSubchannelCall();
2998
2730
  }
2999
2731
  }
3000
2732
 
3001
- void ClientChannelFilter::FilterBasedLoadBalancedCall::OnAddToQueueLocked() {
3002
- // Register call combiner cancellation callback.
3003
- lb_call_canceller_ =
3004
- new LbQueuedCallCanceller(RefAsSubclass<FilterBasedLoadBalancedCall>());
3005
- }
3006
-
3007
- void ClientChannelFilter::FilterBasedLoadBalancedCall::RetryPickLocked() {
2733
+ void ClientChannelFilter::LoadBalancedCall::RetryPickLocked() {
3008
2734
  // Lame the call combiner canceller.
3009
2735
  lb_call_canceller_ = nullptr;
3010
2736
  // Do an async callback to resume call processing, so that we're not
@@ -3033,17 +2759,17 @@ void ClientChannelFilter::FilterBasedLoadBalancedCall::RetryPickLocked() {
3033
2759
  absl::OkStatus());
3034
2760
  }
3035
2761
 
3036
- void ClientChannelFilter::FilterBasedLoadBalancedCall::CreateSubchannelCall() {
2762
+ void ClientChannelFilter::LoadBalancedCall::CreateSubchannelCall() {
3037
2763
  SubchannelCall::Args call_args = {
3038
- connected_subchannel()->Ref(), pollent_, /*start_time=*/0,
3039
- arena()->GetContext<Call>()->deadline(),
2764
+ connected_subchannel_->Ref(), pollent_, /*start_time=*/0,
2765
+ arena_->GetContext<Call>()->deadline(),
3040
2766
  // TODO(roth): When we implement hedging support, we will probably
3041
2767
  // need to use a separate call arena for each subchannel call.
3042
- arena(), call_combiner_};
2768
+ arena_, call_combiner_};
3043
2769
  grpc_error_handle error;
3044
2770
  subchannel_call_ = SubchannelCall::Create(std::move(call_args), &error);
3045
2771
  GRPC_TRACE_LOG(client_channel_lb_call, INFO)
3046
- << "chand=" << chand() << " lb_call=" << this
2772
+ << "chand=" << chand_ << " lb_call=" << this
3047
2773
  << ": create subchannel_call=" << subchannel_call_.get()
3048
2774
  << ": error=" << StatusToString(error);
3049
2775
  if (on_call_destruction_complete_ != nullptr) {
@@ -3051,9 +2777,13 @@ void ClientChannelFilter::FilterBasedLoadBalancedCall::CreateSubchannelCall() {
3051
2777
  on_call_destruction_complete_ = nullptr;
3052
2778
  }
3053
2779
  if (GPR_UNLIKELY(!error.ok())) {
3054
- PendingBatchesFail(error, YieldCallCombiner);
2780
+ buffered_call_.Fail(error, BufferedCall::YieldCallCombiner);
3055
2781
  } else {
3056
- PendingBatchesResume();
2782
+ buffered_call_.Resume([subchannel_call = subchannel_call_](
2783
+ grpc_transport_stream_op_batch* batch) {
2784
+ // Note: This will release the call combiner.
2785
+ subchannel_call->StartTransportStreamOpBatch(batch);
2786
+ });
3057
2787
  }
3058
2788
  }
3059
2789