grpc 1.75.0.pre1 → 1.76.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 (387) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +18 -5
  3. data/include/grpc/credentials.h +21 -5
  4. data/src/core/call/call_filters.cc +4 -4
  5. data/src/core/call/call_filters.h +36 -36
  6. data/src/core/call/call_spine.h +27 -27
  7. data/src/core/call/client_call.cc +6 -5
  8. data/src/core/call/filter_fusion.h +5 -5
  9. data/src/core/call/metadata_batch.h +3 -3
  10. data/src/core/call/security_context.cc +1 -1
  11. data/src/core/call/server_call.cc +4 -4
  12. data/src/core/call/server_call.h +1 -1
  13. data/src/core/channelz/channelz.cc +12 -18
  14. data/src/core/channelz/channelz.h +32 -16
  15. data/src/core/channelz/channelz_registry.h +11 -0
  16. data/src/core/channelz/property_list.cc +18 -0
  17. data/src/core/channelz/property_list.h +10 -1
  18. data/src/core/channelz/text_encode.cc +66 -0
  19. data/src/core/channelz/text_encode.h +29 -0
  20. data/src/core/channelz/v2tov1/convert.cc +11 -0
  21. data/src/core/channelz/v2tov1/legacy_api.cc +15 -8
  22. data/src/core/channelz/ztrace_collector.h +247 -86
  23. data/src/core/client_channel/backup_poller.cc +5 -6
  24. data/src/core/client_channel/client_channel.cc +20 -13
  25. data/src/core/client_channel/client_channel_filter.cc +53 -45
  26. data/src/core/client_channel/client_channel_filter.h +2 -2
  27. data/src/core/client_channel/client_channel_internal.h +3 -4
  28. data/src/core/client_channel/config_selector.h +3 -3
  29. data/src/core/client_channel/dynamic_filters.cc +3 -3
  30. data/src/core/client_channel/global_subchannel_pool.cc +0 -37
  31. data/src/core/client_channel/global_subchannel_pool.h +0 -27
  32. data/src/core/client_channel/load_balanced_call_destination.cc +7 -7
  33. data/src/core/client_channel/local_subchannel_pool.cc +4 -4
  34. data/src/core/client_channel/retry_filter.h +3 -3
  35. data/src/core/client_channel/retry_filter_legacy_call_data.cc +5 -5
  36. data/src/core/client_channel/subchannel.cc +8 -8
  37. data/src/core/client_channel/subchannel_stream_client.cc +4 -4
  38. data/src/core/config/config_vars.cc +30 -1
  39. data/src/core/config/config_vars.h +21 -0
  40. data/src/core/config/core_configuration.cc +5 -5
  41. data/src/core/config/core_configuration.h +7 -7
  42. data/src/core/config/load_config.cc +12 -0
  43. data/src/core/config/load_config.h +2 -0
  44. data/src/core/credentials/call/call_credentials.h +2 -2
  45. data/src/core/credentials/call/call_creds_util.cc +4 -3
  46. data/src/core/credentials/call/composite/composite_call_credentials.cc +4 -4
  47. data/src/core/credentials/call/external/aws_external_account_credentials.cc +3 -3
  48. data/src/core/credentials/call/external/external_account_credentials.cc +1 -1
  49. data/src/core/credentials/call/external/url_external_account_credentials.cc +1 -1
  50. data/src/core/credentials/call/iam/iam_credentials.cc +4 -4
  51. data/src/core/credentials/call/jwt/json_token.cc +3 -3
  52. data/src/core/credentials/call/jwt/jwt_credentials.cc +2 -2
  53. data/src/core/credentials/call/jwt/jwt_verifier.cc +14 -13
  54. data/src/core/credentials/call/oauth2/oauth2_credentials.cc +20 -12
  55. data/src/core/credentials/call/plugin/plugin_credentials.cc +2 -2
  56. data/src/core/credentials/transport/alts/alts_credentials.cc +4 -4
  57. data/src/core/credentials/transport/alts/alts_security_connector.cc +14 -12
  58. data/src/core/credentials/transport/alts/grpc_alts_credentials_client_options.cc +22 -2
  59. data/src/core/credentials/transport/alts/grpc_alts_credentials_options.cc +10 -1
  60. data/src/core/credentials/transport/alts/grpc_alts_credentials_options.h +31 -0
  61. data/src/core/credentials/transport/alts/grpc_alts_credentials_server_options.cc +8 -3
  62. data/src/core/credentials/transport/composite/composite_channel_credentials.cc +5 -5
  63. data/src/core/credentials/transport/fake/fake_security_connector.cc +2 -2
  64. data/src/core/credentials/transport/google_default/google_default_credentials.cc +78 -28
  65. data/src/core/credentials/transport/insecure/insecure_security_connector.cc +3 -3
  66. data/src/core/credentials/transport/local/local_security_connector.cc +8 -8
  67. data/src/core/credentials/transport/security_connector.cc +5 -5
  68. data/src/core/credentials/transport/ssl/ssl_credentials.cc +12 -12
  69. data/src/core/credentials/transport/ssl/ssl_credentials.h +2 -2
  70. data/src/core/credentials/transport/ssl/ssl_security_connector.cc +3 -3
  71. data/src/core/credentials/transport/tls/certificate_provider_registry.cc +2 -2
  72. data/src/core/credentials/transport/tls/grpc_tls_certificate_distributor.cc +24 -24
  73. data/src/core/credentials/transport/tls/grpc_tls_certificate_provider.cc +5 -5
  74. data/src/core/credentials/transport/tls/grpc_tls_certificate_provider.h +2 -2
  75. data/src/core/credentials/transport/tls/grpc_tls_certificate_verifier.cc +2 -2
  76. data/src/core/credentials/transport/tls/grpc_tls_certificate_verifier.h +2 -2
  77. data/src/core/credentials/transport/tls/grpc_tls_credentials_options.cc +17 -17
  78. data/src/core/credentials/transport/tls/ssl_utils.cc +14 -9
  79. data/src/core/credentials/transport/tls/tls_credentials.cc +2 -2
  80. data/src/core/credentials/transport/tls/tls_security_connector.cc +11 -11
  81. data/src/core/credentials/transport/transport_credentials.cc +2 -2
  82. data/src/core/credentials/transport/transport_credentials.h +2 -2
  83. data/src/core/credentials/transport/xds/xds_credentials.cc +5 -5
  84. data/src/core/ext/filters/channel_idle/legacy_channel_idle_filter.cc +2 -0
  85. data/src/core/ext/filters/gcp_authentication/gcp_authentication_filter.cc +1 -1
  86. data/src/core/ext/filters/http/message_compress/compression_filter.cc +8 -8
  87. data/src/core/ext/filters/http/message_compress/compression_filter.h +3 -3
  88. data/src/core/ext/filters/stateful_session/stateful_session_filter.cc +7 -7
  89. data/src/core/ext/transport/chttp2/alpn/alpn.cc +2 -2
  90. data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +10 -9
  91. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +10 -7
  92. data/src/core/ext/transport/chttp2/transport/bin_decoder.cc +5 -5
  93. data/src/core/ext/transport/chttp2/transport/bin_encoder.cc +6 -6
  94. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +96 -88
  95. data/src/core/ext/transport/chttp2/transport/flow_control.cc +3 -3
  96. data/src/core/ext/transport/chttp2/transport/flow_control.h +12 -7
  97. data/src/core/ext/transport/chttp2/transport/flow_control_manager.h +60 -0
  98. data/src/core/ext/transport/chttp2/transport/frame.cc +32 -10
  99. data/src/core/ext/transport/chttp2/transport/frame.h +16 -2
  100. data/src/core/ext/transport/chttp2/transport/frame_data.cc +2 -2
  101. data/src/core/ext/transport/chttp2/transport/frame_goaway.cc +4 -4
  102. data/src/core/ext/transport/chttp2/transport/frame_ping.cc +2 -2
  103. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +2 -2
  104. data/src/core/ext/transport/chttp2/transport/frame_window_update.cc +3 -3
  105. data/src/core/ext/transport/chttp2/transport/header_assembler.h +28 -12
  106. data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +2 -2
  107. data/src/core/ext/transport/chttp2/transport/hpack_encoder.h +4 -2
  108. data/src/core/ext/transport/chttp2/transport/hpack_encoder_table.cc +8 -8
  109. data/src/core/ext/transport/chttp2/transport/hpack_parse_result.cc +2 -2
  110. data/src/core/ext/transport/chttp2/transport/hpack_parse_result.h +2 -2
  111. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +27 -27
  112. data/src/core/ext/transport/chttp2/transport/hpack_parser.h +2 -3
  113. data/src/core/ext/transport/chttp2/transport/hpack_parser_table.cc +4 -4
  114. data/src/core/ext/transport/chttp2/transport/http2_client_transport.cc +543 -366
  115. data/src/core/ext/transport/chttp2/transport/http2_client_transport.h +198 -277
  116. data/src/core/ext/transport/chttp2/transport/http2_settings_manager.cc +3 -0
  117. data/src/core/ext/transport/chttp2/transport/http2_settings_manager.h +11 -0
  118. data/src/core/ext/transport/chttp2/transport/http2_settings_promises.h +179 -0
  119. data/src/core/ext/transport/chttp2/transport/http2_transport.cc +51 -23
  120. data/src/core/ext/transport/chttp2/transport/http2_transport.h +13 -6
  121. data/src/core/ext/transport/chttp2/transport/http2_ztrace_collector.h +115 -71
  122. data/src/core/ext/transport/chttp2/transport/internal.h +6 -14
  123. data/src/core/ext/transport/chttp2/transport/message_assembler.h +7 -7
  124. data/src/core/ext/transport/chttp2/transport/parsing.cc +17 -15
  125. data/src/core/ext/transport/chttp2/transport/ping_callbacks.cc +2 -2
  126. data/src/core/ext/transport/chttp2/transport/ping_promise.cc +62 -26
  127. data/src/core/ext/transport/chttp2/transport/ping_promise.h +58 -22
  128. data/src/core/ext/transport/chttp2/transport/stream.h +207 -0
  129. data/src/core/ext/transport/chttp2/transport/stream_data_queue.h +328 -187
  130. data/src/core/ext/transport/chttp2/transport/stream_lists.cc +7 -7
  131. data/src/core/ext/transport/chttp2/transport/transport_common.cc +17 -1
  132. data/src/core/ext/transport/chttp2/transport/transport_common.h +52 -0
  133. data/src/core/ext/transport/chttp2/transport/varint.h +2 -2
  134. data/src/core/ext/transport/chttp2/transport/writable_streams.h +181 -79
  135. data/src/core/ext/transport/chttp2/transport/write_size_policy.cc +2 -2
  136. data/src/core/ext/transport/chttp2/transport/writing.cc +3 -3
  137. data/src/core/ext/transport/inproc/inproc_transport.cc +1 -1
  138. data/src/core/ext/transport/inproc/legacy_inproc_transport.cc +3 -3
  139. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/service.upb.h +740 -0
  140. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/service.upb_minitable.c +218 -0
  141. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/service.upb_minitable.h +46 -0
  142. data/src/core/ext/upb-gen/src/proto/grpc/gcp/handshaker.upb.h +87 -55
  143. data/src/core/ext/upb-gen/src/proto/grpc/gcp/handshaker.upb_minitable.c +23 -21
  144. data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/channelz.upbdefs.c +80 -0
  145. data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/channelz.upbdefs.h +47 -0
  146. data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/service.upbdefs.c +129 -0
  147. data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/service.upbdefs.h +72 -0
  148. data/src/core/filter/auth/server_auth_filter.cc +2 -2
  149. data/src/core/handshaker/handshaker.cc +3 -3
  150. data/src/core/handshaker/http_connect/http_proxy_mapper.cc +2 -2
  151. data/src/core/handshaker/security/legacy_secure_endpoint.cc +2 -2
  152. data/src/core/handshaker/security/pipelined_secure_endpoint.cc +31 -8
  153. data/src/core/handshaker/security/secure_endpoint.cc +16 -6
  154. data/src/core/handshaker/security/security_handshaker.cc +3 -3
  155. data/src/core/handshaker/tcp_connect/tcp_connect_handshaker.cc +2 -2
  156. data/src/core/lib/channel/channel_stack.cc +8 -5
  157. data/src/core/lib/channel/channel_stack.h +3 -0
  158. data/src/core/lib/channel/channel_stack_builder_impl.cc +1 -0
  159. data/src/core/lib/channel/connected_channel.cc +2 -2
  160. data/src/core/lib/channel/promise_based_filter.cc +69 -64
  161. data/src/core/lib/channel/promise_based_filter.h +16 -15
  162. data/src/core/lib/compression/compression_internal.cc +2 -2
  163. data/src/core/lib/compression/message_compress.cc +7 -7
  164. data/src/core/lib/event_engine/ares_resolver.cc +22 -20
  165. data/src/core/lib/event_engine/cf_engine/cf_engine.cc +2 -2
  166. data/src/core/lib/event_engine/cf_engine/dns_service_resolver.cc +2 -2
  167. data/src/core/lib/event_engine/cf_engine/dns_service_resolver.h +2 -2
  168. data/src/core/lib/event_engine/extensions/channelz.h +2 -2
  169. data/src/core/lib/event_engine/extensions/supports_fd.h +5 -5
  170. data/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc +8 -8
  171. data/src/core/lib/event_engine/posix_engine/ev_poll_posix.cc +10 -10
  172. data/src/core/lib/event_engine/posix_engine/lockfree_event.cc +2 -2
  173. data/src/core/lib/event_engine/posix_engine/posix_endpoint.cc +23 -22
  174. data/src/core/lib/event_engine/posix_engine/posix_endpoint.h +11 -11
  175. data/src/core/lib/event_engine/posix_engine/posix_engine.cc +168 -170
  176. data/src/core/lib/event_engine/posix_engine/posix_engine.h +33 -54
  177. data/src/core/lib/event_engine/posix_engine/posix_engine_listener.cc +4 -3
  178. data/src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.cc +5 -5
  179. data/src/core/lib/event_engine/posix_engine/posix_interface.h +1 -1
  180. data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.cc +1 -1
  181. data/src/core/lib/event_engine/posix_engine/timer_manager.cc +3 -3
  182. data/src/core/lib/event_engine/resolved_address.cc +3 -3
  183. data/src/core/lib/event_engine/shim.cc +8 -11
  184. data/src/core/lib/event_engine/shim.h +2 -1
  185. data/src/core/lib/event_engine/slice.cc +2 -2
  186. data/src/core/lib/event_engine/tcp_socket_utils.cc +11 -11
  187. data/src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.cc +7 -7
  188. data/src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc +31 -31
  189. data/src/core/lib/event_engine/windows/iocp.cc +10 -10
  190. data/src/core/lib/event_engine/windows/win_socket.cc +6 -6
  191. data/src/core/lib/event_engine/windows/windows_endpoint.cc +11 -11
  192. data/src/core/lib/event_engine/windows/windows_engine.cc +16 -14
  193. data/src/core/lib/event_engine/windows/windows_listener.cc +7 -7
  194. data/src/core/lib/experiments/experiments.cc +105 -18
  195. data/src/core/lib/experiments/experiments.h +43 -11
  196. data/src/core/lib/iomgr/call_combiner.cc +3 -3
  197. data/src/core/lib/iomgr/endpoint_cfstream.cc +6 -6
  198. data/src/core/lib/iomgr/endpoint_pair_posix.cc +5 -5
  199. data/src/core/lib/iomgr/endpoint_pair_windows.cc +15 -14
  200. data/src/core/lib/iomgr/ev_epoll1_linux.cc +15 -15
  201. data/src/core/lib/iomgr/ev_poll_posix.cc +11 -11
  202. data/src/core/lib/iomgr/event_engine_shims/endpoint.cc +5 -4
  203. data/src/core/lib/iomgr/event_engine_shims/endpoint.h +1 -1
  204. data/src/core/lib/iomgr/iocp_windows.cc +8 -8
  205. data/src/core/lib/iomgr/iomgr_windows.cc +3 -3
  206. data/src/core/lib/iomgr/lockfree_event.cc +2 -2
  207. data/src/core/lib/iomgr/polling_entity.cc +3 -3
  208. data/src/core/lib/iomgr/socket_utils_common_posix.cc +2 -2
  209. data/src/core/lib/iomgr/socket_windows.cc +4 -4
  210. data/src/core/lib/iomgr/tcp_client_posix.cc +4 -4
  211. data/src/core/lib/iomgr/tcp_client_windows.cc +4 -4
  212. data/src/core/lib/iomgr/tcp_posix.cc +42 -42
  213. data/src/core/lib/iomgr/tcp_server.cc +5 -0
  214. data/src/core/lib/iomgr/tcp_server.h +7 -0
  215. data/src/core/lib/iomgr/tcp_server_posix.cc +47 -27
  216. data/src/core/lib/iomgr/tcp_server_utils_posix.h +3 -0
  217. data/src/core/lib/iomgr/tcp_server_utils_posix_common.cc +5 -5
  218. data/src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.cc +2 -2
  219. data/src/core/lib/iomgr/tcp_server_windows.cc +68 -29
  220. data/src/core/lib/iomgr/tcp_windows.cc +7 -7
  221. data/src/core/lib/iomgr/timer_generic.cc +2 -2
  222. data/src/core/lib/iomgr/timer_manager.cc +2 -2
  223. data/src/core/lib/iomgr/unix_sockets_posix.cc +2 -2
  224. data/src/core/lib/iomgr/unix_sockets_posix_noop.cc +2 -2
  225. data/src/core/lib/promise/activity.cc +2 -2
  226. data/src/core/lib/promise/activity.h +6 -6
  227. data/src/core/lib/promise/context.h +2 -2
  228. data/src/core/lib/promise/detail/join_state.h +9 -9
  229. data/src/core/lib/promise/detail/seq_state.h +13 -13
  230. data/src/core/lib/promise/detail/status.h +2 -2
  231. data/src/core/lib/promise/for_each.h +5 -5
  232. data/src/core/lib/promise/interceptor_list.h +2 -2
  233. data/src/core/lib/promise/latch.h +7 -7
  234. data/src/core/lib/promise/mpsc.cc +26 -26
  235. data/src/core/lib/promise/mpsc.h +2 -2
  236. data/src/core/lib/promise/observable.h +4 -4
  237. data/src/core/lib/promise/party.cc +32 -25
  238. data/src/core/lib/promise/party.h +16 -19
  239. data/src/core/lib/promise/pipe.h +15 -15
  240. data/src/core/lib/promise/poll.h +5 -4
  241. data/src/core/lib/promise/promise.h +0 -2
  242. data/src/core/lib/promise/sleep.cc +3 -1
  243. data/src/core/lib/promise/status_flag.h +7 -7
  244. data/src/core/lib/promise/try_join.h +2 -2
  245. data/src/core/lib/promise/try_seq.h +2 -2
  246. data/src/core/lib/resource_quota/arena.h +15 -2
  247. data/src/core/lib/resource_quota/connection_quota.cc +9 -7
  248. data/src/core/lib/resource_quota/memory_quota.cc +45 -24
  249. data/src/core/lib/resource_quota/memory_quota.h +48 -16
  250. data/src/core/lib/resource_quota/telemetry.h +54 -0
  251. data/src/core/lib/resource_quota/thread_quota.cc +2 -2
  252. data/src/core/lib/resource_tracker/resource_tracker.cc +33 -0
  253. data/src/core/lib/resource_tracker/resource_tracker.h +46 -0
  254. data/src/core/lib/security/authorization/audit_logging.cc +5 -5
  255. data/src/core/lib/security/authorization/grpc_authorization_engine.cc +2 -2
  256. data/src/core/lib/security/authorization/stdout_logger.cc +3 -3
  257. data/src/core/lib/surface/byte_buffer_reader.cc +2 -2
  258. data/src/core/lib/surface/call.cc +16 -14
  259. data/src/core/lib/surface/call.h +1 -1
  260. data/src/core/lib/surface/call_utils.cc +2 -2
  261. data/src/core/lib/surface/call_utils.h +2 -2
  262. data/src/core/lib/surface/channel.cc +4 -4
  263. data/src/core/lib/surface/channel_create.cc +10 -6
  264. data/src/core/lib/surface/channel_init.cc +80 -23
  265. data/src/core/lib/surface/channel_init.h +26 -11
  266. data/src/core/lib/surface/completion_queue.cc +17 -16
  267. data/src/core/lib/surface/completion_queue_factory.cc +7 -7
  268. data/src/core/lib/surface/connection_context.h +45 -2
  269. data/src/core/lib/surface/filter_stack_call.cc +12 -23
  270. data/src/core/lib/surface/filter_stack_call.h +3 -4
  271. data/src/core/lib/surface/legacy_channel.cc +7 -7
  272. data/src/core/lib/surface/validate_metadata.h +2 -2
  273. data/src/core/lib/surface/version.cc +2 -2
  274. data/src/core/lib/transport/bdp_estimator.cc +2 -2
  275. data/src/core/lib/transport/bdp_estimator.h +3 -3
  276. data/src/core/lib/transport/promise_endpoint.cc +3 -3
  277. data/src/core/lib/transport/promise_endpoint.h +8 -8
  278. data/src/core/lib/transport/timeout_encoding.cc +4 -4
  279. data/src/core/load_balancing/child_policy_handler.cc +4 -4
  280. data/src/core/load_balancing/endpoint_list.cc +2 -2
  281. data/src/core/load_balancing/grpclb/grpclb.cc +24 -24
  282. data/src/core/load_balancing/health_check_client.cc +4 -4
  283. data/src/core/load_balancing/health_check_client_internal.h +2 -2
  284. data/src/core/load_balancing/lb_policy_registry.cc +2 -2
  285. data/src/core/load_balancing/oob_backend_metric.cc +4 -4
  286. data/src/core/load_balancing/oob_backend_metric_internal.h +2 -2
  287. data/src/core/load_balancing/outlier_detection/outlier_detection.cc +2 -2
  288. data/src/core/load_balancing/pick_first/pick_first.cc +14 -14
  289. data/src/core/load_balancing/priority/priority.cc +23 -24
  290. data/src/core/load_balancing/ring_hash/ring_hash.cc +3 -3
  291. data/src/core/load_balancing/rls/rls.cc +13 -13
  292. data/src/core/load_balancing/round_robin/round_robin.cc +9 -9
  293. data/src/core/load_balancing/weighted_round_robin/static_stride_scheduler.cc +3 -3
  294. data/src/core/load_balancing/weighted_round_robin/weighted_round_robin.cc +33 -26
  295. data/src/core/load_balancing/weighted_target/weighted_target.cc +5 -5
  296. data/src/core/load_balancing/xds/cds.cc +76 -32
  297. data/src/core/load_balancing/xds/xds_cluster_impl.cc +3 -3
  298. data/src/core/load_balancing/xds/xds_override_host.cc +4 -4
  299. data/src/core/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc +2 -2
  300. data/src/core/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +33 -33
  301. data/src/core/resolver/dns/c_ares/grpc_ares_wrapper.cc +10 -10
  302. data/src/core/resolver/dns/dns_resolver_plugin.cc +6 -3
  303. data/src/core/resolver/dns/event_engine/event_engine_client_channel_resolver.cc +2 -2
  304. data/src/core/resolver/endpoint_addresses.cc +3 -3
  305. data/src/core/resolver/endpoint_addresses.h +3 -0
  306. data/src/core/resolver/fake/fake_resolver.cc +2 -2
  307. data/src/core/resolver/google_c2p/google_c2p_resolver.cc +41 -54
  308. data/src/core/resolver/polling_resolver.cc +3 -3
  309. data/src/core/resolver/resolver_registry.cc +5 -4
  310. data/src/core/resolver/xds/xds_dependency_manager.cc +5 -5
  311. data/src/core/resolver/xds/xds_resolver.cc +9 -9
  312. data/src/core/server/server.cc +38 -38
  313. data/src/core/server/server_call_tracer_filter.h +4 -4
  314. data/src/core/server/server_config_selector_filter.cc +2 -2
  315. data/src/core/server/xds_server_config_fetcher.cc +9 -8
  316. data/src/core/service_config/service_config_impl.h +2 -2
  317. data/src/core/telemetry/call_tracer.cc +39 -49
  318. data/src/core/telemetry/call_tracer.h +199 -22
  319. data/src/core/telemetry/histogram.h +205 -0
  320. data/src/core/telemetry/instrument.cc +719 -0
  321. data/src/core/telemetry/instrument.h +932 -0
  322. data/src/core/telemetry/metrics.cc +13 -5
  323. data/src/core/telemetry/metrics.h +3 -1
  324. data/src/core/telemetry/stats_data.cc +0 -19
  325. data/src/core/telemetry/stats_data.h +0 -19
  326. data/src/core/transport/auth_context.cc +2 -2
  327. data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +78 -45
  328. data/src/core/tsi/alts/handshaker/alts_handshaker_client.h +1 -0
  329. data/src/core/tsi/alts/handshaker/alts_shared_resource.cc +3 -3
  330. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +39 -31
  331. data/src/core/tsi/alts/handshaker/alts_tsi_utils.cc +3 -3
  332. data/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.cc +3 -3
  333. data/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.cc +7 -7
  334. data/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc +3 -3
  335. data/src/core/tsi/fake_transport_security.cc +4 -4
  336. data/src/core/tsi/ssl/key_logging/ssl_key_logging.cc +4 -4
  337. data/src/core/tsi/ssl/session_cache/ssl_session_cache.cc +9 -9
  338. data/src/core/tsi/ssl/session_cache/ssl_session_openssl.cc +3 -3
  339. data/src/core/tsi/ssl_transport_security.cc +26 -25
  340. data/src/core/tsi/ssl_transport_security_utils.cc +9 -9
  341. data/src/core/util/chunked_vector.h +4 -4
  342. data/src/core/util/event_log.cc +2 -2
  343. data/src/core/util/gcp_metadata_query.cc +2 -2
  344. data/src/core/util/grpc_check.cc +22 -0
  345. data/src/core/util/grpc_check.h +103 -0
  346. data/src/core/util/http_client/httpcli.cc +3 -3
  347. data/src/core/util/http_client/parser.cc +4 -4
  348. data/src/core/util/latent_see.h +7 -4
  349. data/src/core/util/lru_cache.h +4 -4
  350. data/src/core/util/memory_usage.h +16 -0
  351. data/src/core/util/posix/directory_reader.cc +3 -2
  352. data/src/core/util/posix/sync.cc +24 -24
  353. data/src/core/util/postmortem_emit.cc +52 -0
  354. data/src/core/util/postmortem_emit.h +30 -0
  355. data/src/core/util/ref_counted_ptr.h +5 -0
  356. data/src/core/util/trie_lookup.h +170 -0
  357. data/src/core/util/unique_ptr_with_bitset.h +5 -5
  358. data/src/core/xds/grpc/xds_bootstrap_grpc.h +6 -1
  359. data/src/core/xds/grpc/xds_certificate_provider.cc +3 -3
  360. data/src/core/xds/grpc/xds_client_grpc.cc +34 -15
  361. data/src/core/xds/grpc/xds_client_grpc.h +4 -1
  362. data/src/core/xds/grpc/xds_cluster_parser.cc +2 -2
  363. data/src/core/xds/grpc/xds_cluster_specifier_plugin.cc +2 -2
  364. data/src/core/xds/grpc/xds_endpoint_parser.cc +2 -2
  365. data/src/core/xds/grpc/xds_http_filter_registry.cc +4 -3
  366. data/src/core/xds/grpc/xds_listener_parser.cc +3 -3
  367. data/src/core/xds/grpc/xds_matcher.cc +277 -0
  368. data/src/core/xds/grpc/xds_matcher.h +432 -0
  369. data/src/core/xds/grpc/xds_matcher_action.cc +47 -0
  370. data/src/core/xds/grpc/xds_matcher_action.h +48 -0
  371. data/src/core/xds/grpc/xds_matcher_context.cc +29 -0
  372. data/src/core/xds/grpc/xds_matcher_context.h +46 -0
  373. data/src/core/xds/grpc/xds_matcher_input.cc +79 -0
  374. data/src/core/xds/grpc/xds_matcher_input.h +105 -0
  375. data/src/core/xds/grpc/xds_matcher_parse.cc +356 -0
  376. data/src/core/xds/grpc/xds_matcher_parse.h +39 -0
  377. data/src/core/xds/grpc/xds_metadata.cc +4 -3
  378. data/src/core/xds/grpc/xds_route_config_parser.cc +6 -6
  379. data/src/core/xds/grpc/xds_routing.cc +3 -3
  380. data/src/core/xds/grpc/xds_transport_grpc.cc +10 -10
  381. data/src/core/xds/xds_client/lrs_client.cc +6 -6
  382. data/src/core/xds/xds_client/xds_client.cc +9 -9
  383. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +2 -2
  384. data/src/ruby/lib/grpc/version.rb +1 -1
  385. data/third_party/abseil-cpp/absl/container/internal/node_slot_policy.h +95 -0
  386. data/third_party/abseil-cpp/absl/container/node_hash_map.h +687 -0
  387. metadata +37 -2
@@ -21,10 +21,11 @@
21
21
 
22
22
  #include <queue>
23
23
 
24
- #include "absl/log/check.h"
25
24
  #include "absl/log/log.h"
26
25
  #include "src/core/ext/transport/chttp2/transport/header_assembler.h"
27
26
  #include "src/core/ext/transport/chttp2/transport/message_assembler.h"
27
+ #include "src/core/ext/transport/chttp2/transport/transport_common.h"
28
+ #include "src/core/util/grpc_check.h"
28
29
 
29
30
  namespace grpc_core {
30
31
  namespace http2 {
@@ -36,11 +37,6 @@ namespace http2 {
36
37
  template <typename T>
37
38
  class SimpleQueue {
38
39
  public:
39
- struct EnqueueResult {
40
- absl::Status status;
41
- bool became_non_empty;
42
- };
43
-
44
40
  explicit SimpleQueue(const uint32_t max_tokens) : max_tokens_(max_tokens) {}
45
41
  SimpleQueue(SimpleQueue&& rhs) = delete;
46
42
  SimpleQueue& operator=(SimpleQueue&& rhs) = delete;
@@ -54,10 +50,14 @@ class SimpleQueue {
54
50
  // with tokens = 0. Enqueues with tokens = 0 are primarily for sending
55
51
  // metadata as flow control does not apply to them. This function is NOT
56
52
  // thread safe.
57
- auto Enqueue(T& data, const uint32_t tokens) {
53
+ Poll<absl::StatusOr<bool>> Enqueue(T& data, const uint32_t tokens) {
58
54
  return PollEnqueue(data, tokens);
59
55
  }
60
56
 
57
+ absl::StatusOr<bool> ImmediateEnqueue(T data, const uint32_t tokens) {
58
+ return ImmediateEnqueueInternal(std::move(data), tokens);
59
+ }
60
+
61
61
  // Sync function to dequeue the next entry. Returns nullopt if the queue is
62
62
  // empty or if the front of the queue has more tokens than
63
63
  // allowed_dequeue_tokens. When allow_oversized_dequeue parameter is set to
@@ -77,10 +77,12 @@ class SimpleQueue {
77
77
  }
78
78
 
79
79
  // Returns true if the queue is empty. This function is NOT thread safe.
80
- bool TestOnlyIsEmpty() const { return IsEmpty(); }
80
+ bool IsEmpty() const { return queue_.empty(); }
81
+ // Clears the queue. This function is NOT thread safe.
82
+ void Clear() { std::queue<Entry>().swap(queue_); }
81
83
 
82
84
  private:
83
- Poll<EnqueueResult> PollEnqueue(T& data, const uint32_t tokens) {
85
+ Poll<absl::StatusOr<bool>> PollEnqueue(T& data, const uint32_t tokens) {
84
86
  GRPC_STREAM_DATA_QUEUE_DEBUG << "Enqueueing data. Data tokens: " << tokens;
85
87
  const uint32_t max_tokens_consumed_threshold =
86
88
  max_tokens_ >= tokens ? max_tokens_ - tokens : 0;
@@ -91,8 +93,7 @@ class SimpleQueue {
91
93
  GRPC_STREAM_DATA_QUEUE_DEBUG
92
94
  << "Enqueue successful. Data tokens: " << tokens
93
95
  << " Current tokens consumed: " << tokens_consumed_;
94
- return EnqueueResult{absl::OkStatus(),
95
- /*became_non_empty=*/queue_.size() == 1};
96
+ return /*became_non_empty*/ (queue_.size() == 1);
96
97
  }
97
98
 
98
99
  GRPC_STREAM_DATA_QUEUE_DEBUG
@@ -103,6 +104,16 @@ class SimpleQueue {
103
104
  return Pending{};
104
105
  }
105
106
 
107
+ inline absl::StatusOr<bool> ImmediateEnqueueInternal(T data,
108
+ const uint32_t tokens) {
109
+ tokens_consumed_ += tokens;
110
+ queue_.emplace(Entry{std::move(data), tokens});
111
+ GRPC_STREAM_DATA_QUEUE_DEBUG
112
+ << "Immediate enqueue successful. Data tokens: " << tokens
113
+ << " Current tokens consumed: " << tokens_consumed_;
114
+ return /*became_non_empty*/ (queue_.size() == 1);
115
+ }
116
+
106
117
  std::optional<T> DequeueInternal(const uint32_t allowed_dequeue_tokens,
107
118
  const bool allow_oversized_dequeue) {
108
119
  if (queue_.empty() || (queue_.front().tokens > allowed_dequeue_tokens &&
@@ -133,8 +144,6 @@ class SimpleQueue {
133
144
  return std::move(entry.data);
134
145
  }
135
146
 
136
- bool IsEmpty() const { return queue_.empty(); }
137
-
138
147
  struct Entry {
139
148
  T data;
140
149
  uint32_t tokens;
@@ -148,10 +157,10 @@ class SimpleQueue {
148
157
  // exception to this rule: if the sender tries to enqueue an item when the
149
158
  // queue has 0 tokens, the enqueue will always go through regardless of the
150
159
  // number of tokens.
151
- uint32_t max_tokens_;
160
+ const uint64_t max_tokens_;
152
161
  // The number of tokens that have been enqueued in the queue but not yet
153
162
  // dequeued.
154
- uint32_t tokens_consumed_ = 0;
163
+ uint64_t tokens_consumed_ = 0;
155
164
  Waker waker_;
156
165
  };
157
166
 
@@ -162,14 +171,17 @@ template <typename MetadataHandle>
162
171
  class StreamDataQueue : public RefCounted<StreamDataQueue<MetadataHandle>> {
163
172
  public:
164
173
  explicit StreamDataQueue(const bool is_client, const uint32_t stream_id,
165
- const uint32_t queue_size)
174
+ const uint32_t queue_size,
175
+ bool allow_true_binary_metadata)
166
176
  : stream_id_(stream_id),
167
177
  is_client_(is_client),
168
178
  queue_(queue_size),
169
179
  initial_metadata_disassembler_(stream_id,
170
- /*is_trailing_metadata=*/false),
180
+ /*is_trailing_metadata=*/false,
181
+ allow_true_binary_metadata),
171
182
  trailing_metadata_disassembler_(stream_id,
172
- /*is_trailing_metadata=*/true) {};
183
+ /*is_trailing_metadata=*/true,
184
+ allow_true_binary_metadata) {};
173
185
  ~StreamDataQueue() = default;
174
186
 
175
187
  StreamDataQueue(StreamDataQueue&& rhs) = delete;
@@ -194,66 +206,67 @@ class StreamDataQueue : public RefCounted<StreamDataQueue<MetadataHandle>> {
194
206
  // end_stream set. If the stream needs to be half closed, the client should
195
207
  // enqueue a half close message.
196
208
 
209
+ struct EnqueueResult {
210
+ bool became_writable;
211
+ WritableStreamPriority priority;
212
+ };
213
+
197
214
  // Enqueue Initial Metadata.
198
215
  // 1. MUST be called at most once.
199
216
  // 2. This MUST be called before any messages are enqueued.
200
217
  // 3. MUST not be called after trailing metadata is enqueued.
201
218
  // 4. This function is thread safe.
202
- auto EnqueueInitialMetadata(MetadataHandle metadata) {
203
- DCHECK(!is_initial_metadata_queued_);
204
- DCHECK(!is_trailing_metadata_or_half_close_queued_);
205
- DCHECK(metadata != nullptr);
206
- DCHECK(!is_reset_stream_queued_);
219
+ absl::StatusOr<EnqueueResult> EnqueueInitialMetadata(
220
+ MetadataHandle&& metadata) {
221
+ MutexLock lock(&mu_);
222
+ GRPC_DCHECK(!is_initial_metadata_queued_);
223
+ GRPC_DCHECK(!is_trailing_metadata_or_half_close_queued_);
224
+ GRPC_DCHECK(metadata != nullptr);
225
+ GRPC_DCHECK(reset_stream_state_ == RstStreamState::kNotQueued);
207
226
 
208
227
  is_initial_metadata_queued_ = true;
209
- return [self = this->Ref(),
210
- entry = QueueEntry{InitialMetadataType{
211
- std::move(metadata)}}]() mutable -> Poll<absl::StatusOr<bool>> {
212
- MutexLock lock(&self->mu_);
213
- auto result = self->queue_.Enqueue(entry, /*tokens=*/0);
214
- if (result.ready()) {
215
- GRPC_STREAM_DATA_QUEUE_DEBUG
216
- << "Enqueued initial metadata for stream " << self->stream_id_
217
- << " with status: " << result.value().status;
218
- if (result.value().status.ok()) {
219
- DCHECK(result.value().became_non_empty);
220
- return self->UpdateWritableStateLocked(
221
- result.value().became_non_empty);
222
- }
223
- return result.value().status;
224
- }
225
- return Pending{};
226
- };
228
+ absl::StatusOr<bool> result = queue_.ImmediateEnqueue(
229
+ QueueEntry{InitialMetadataType{std::move(metadata)}}, /*tokens=*/0);
230
+ if (GPR_UNLIKELY(!result.ok())) {
231
+ GRPC_STREAM_DATA_QUEUE_DEBUG
232
+ << "Immediate enqueueing initial metadata for stream " << stream_id_
233
+ << " failed with status: " << result.status();
234
+ return result.status();
235
+ }
236
+ return UpdateWritableStateLocked(
237
+ /*became_non_empty*/ result.value(), WritableStreamPriority::kDefault);
227
238
  }
228
239
 
229
240
  // Enqueue Trailing Metadata.
230
241
  // 1. MUST be called at most once.
231
242
  // 2. MUST be called only for a server.
232
243
  // 3. This function is thread safe.
233
- auto EnqueueTrailingMetadata(MetadataHandle metadata) {
234
- DCHECK(metadata != nullptr);
235
- DCHECK(!is_reset_stream_queued_);
236
- DCHECK(!is_client_);
237
- DCHECK(!is_trailing_metadata_or_half_close_queued_);
244
+ absl::StatusOr<EnqueueResult> EnqueueTrailingMetadata(
245
+ MetadataHandle&& metadata) {
246
+ MutexLock lock(&mu_);
247
+ GRPC_DCHECK(metadata != nullptr);
248
+ GRPC_DCHECK(!is_client_);
249
+ GRPC_DCHECK(!is_trailing_metadata_or_half_close_queued_);
250
+
251
+ if (GPR_UNLIKELY(IsEnqueueClosed())) {
252
+ GRPC_STREAM_DATA_QUEUE_DEBUG << "Enqueue closed for stream "
253
+ << stream_id_;
254
+ return EnqueueResult{/*became_writable=*/false,
255
+ WritableStreamPriority::kStreamClosed};
256
+ }
238
257
 
239
258
  is_trailing_metadata_or_half_close_queued_ = true;
240
- return [self = this->Ref(),
241
- entry = QueueEntry{TrailingMetadataType{
242
- std::move(metadata)}}]() mutable -> Poll<absl::StatusOr<bool>> {
243
- MutexLock lock(&self->mu_);
244
- auto result = self->queue_.Enqueue(entry, /*tokens=*/0);
245
- if (result.ready()) {
246
- GRPC_STREAM_DATA_QUEUE_DEBUG
247
- << "Enqueued trailing metadata for stream " << self->stream_id_
248
- << " with status: " << result.value().status;
249
- if (result.value().status.ok()) {
250
- return self->UpdateWritableStateLocked(
251
- result.value().became_non_empty);
252
- }
253
- return result.value().status;
254
- }
255
- return Pending{};
256
- };
259
+ absl::StatusOr<bool> result = queue_.ImmediateEnqueue(
260
+ QueueEntry{TrailingMetadataType{std::move(metadata)}}, /*tokens=*/0);
261
+ if (GPR_UNLIKELY(!result.ok())) {
262
+ GRPC_STREAM_DATA_QUEUE_DEBUG
263
+ << "Immediate enqueueing trailing metadata for stream " << stream_id_
264
+ << " failed with status: " << result.status();
265
+ return result.status();
266
+ }
267
+ return UpdateWritableStateLocked(
268
+ /*became_non_empty*/ result.value(),
269
+ WritableStreamPriority::kStreamClosed);
257
270
  }
258
271
 
259
272
  // Returns a promise that resolves when the message is enqueued. There may be
@@ -261,30 +274,37 @@ class StreamDataQueue : public RefCounted<StreamDataQueue<MetadataHandle>> {
261
274
  // 1. MUST be called after initial metadata is enqueued.
262
275
  // 2. MUST not be called after trailing metadata is enqueued.
263
276
  // 3. This function is thread safe.
264
- auto EnqueueMessage(MessageHandle message) {
265
- DCHECK(is_initial_metadata_queued_);
266
- DCHECK(message != nullptr);
267
- DCHECK(!is_reset_stream_queued_);
268
- DCHECK_LE(message->payload()->Length(),
269
- std::numeric_limits<uint32_t>::max() - kGrpcHeaderSizeInBytes);
270
- DCHECK(!is_trailing_metadata_or_half_close_queued_);
277
+ auto EnqueueMessage(MessageHandle&& message) {
278
+ GRPC_DCHECK(is_initial_metadata_queued_);
279
+ GRPC_DCHECK(message != nullptr);
280
+ GRPC_DCHECK_LE(
281
+ message->payload()->Length(),
282
+ std::numeric_limits<uint32_t>::max() - kGrpcHeaderSizeInBytes);
283
+ GRPC_DCHECK(!is_trailing_metadata_or_half_close_queued_);
271
284
 
272
285
  const uint32_t tokens =
273
286
  message->payload()->Length() + kGrpcHeaderSizeInBytes;
274
287
  return [self = this->Ref(), entry = QueueEntry{std::move(message)},
275
- tokens]() mutable -> Poll<absl::StatusOr<bool>> {
288
+ tokens]() mutable -> Poll<absl::StatusOr<EnqueueResult>> {
276
289
  MutexLock lock(&self->mu_);
277
- auto result = self->queue_.Enqueue(entry, tokens);
290
+ if (GPR_UNLIKELY(self->IsEnqueueClosed())) {
291
+ GRPC_STREAM_DATA_QUEUE_DEBUG << "Enqueue closed for stream "
292
+ << self->stream_id_;
293
+ return EnqueueResult{/*became_writable=*/false,
294
+ WritableStreamPriority::kStreamClosed};
295
+ }
296
+ Poll<absl::StatusOr<bool>> result = self->queue_.Enqueue(entry, tokens);
278
297
  if (result.ready()) {
279
298
  GRPC_STREAM_DATA_QUEUE_DEBUG
280
299
  << "Enqueued message for stream " << self->stream_id_
281
- << " with status: " << result.value().status;
300
+ << " with status: " << result.value().status();
282
301
  // TODO(akshitpatel) : [PH2][P2] : Add check for flow control tokens.
283
- if (result.value().status.ok()) {
302
+ if (GPR_LIKELY(result.value().ok())) {
284
303
  return self->UpdateWritableStateLocked(
285
- result.value().became_non_empty);
304
+ /*became_non_empty*/ result.value().value(),
305
+ WritableStreamPriority::kDefault);
286
306
  }
287
- return result.value().status;
307
+ return result.value().status();
288
308
  }
289
309
  return Pending{};
290
310
  };
@@ -294,66 +314,97 @@ class StreamDataQueue : public RefCounted<StreamDataQueue<MetadataHandle>> {
294
314
  // 1. MUST be called at most once.
295
315
  // 2. MUST be called only for a client.
296
316
  // 3. This function is thread safe.
297
- auto EnqueueHalfClosed() {
298
- DCHECK(is_initial_metadata_queued_);
299
- DCHECK(is_client_);
300
- DCHECK(!is_reset_stream_queued_);
301
- DCHECK(!is_trailing_metadata_or_half_close_queued_);
317
+ absl::StatusOr<EnqueueResult> EnqueueHalfClosed() {
318
+ MutexLock lock(&mu_);
319
+ GRPC_DCHECK(is_initial_metadata_queued_);
320
+ GRPC_DCHECK(is_client_);
321
+
322
+ if (GPR_UNLIKELY(IsEnqueueClosed() ||
323
+ is_trailing_metadata_or_half_close_queued_)) {
324
+ GRPC_STREAM_DATA_QUEUE_DEBUG
325
+ << "Enqueue closed or trailing metadata/half close queued for stream "
326
+ << stream_id_ << " is_trailing_metadata_or_half_close_queued_ = "
327
+ << is_trailing_metadata_or_half_close_queued_;
328
+ return EnqueueResult{/*became_writable=*/false,
329
+ WritableStreamPriority::kStreamClosed};
330
+ }
302
331
 
303
332
  is_trailing_metadata_or_half_close_queued_ = true;
304
- return [self = this->Ref(), entry = QueueEntry{HalfClosed{}}]() mutable
305
- -> Poll<absl::StatusOr<bool>> {
306
- MutexLock lock(&self->mu_);
307
- auto result = self->queue_.Enqueue(entry, /*tokens=*/0);
308
- if (result.ready()) {
309
- GRPC_STREAM_DATA_QUEUE_DEBUG
310
- << "Marking stream " << self->stream_id_ << " as half closed"
311
- << " with status: " << result.value().status;
312
- if (result.value().status.ok()) {
313
- return self->UpdateWritableStateLocked(
314
- result.value().became_non_empty);
315
- }
316
- return result.value().status;
317
- }
318
- return Pending{};
319
- };
333
+ absl::StatusOr<bool> result =
334
+ queue_.ImmediateEnqueue(QueueEntry{HalfClosed{}}, /*tokens=*/0);
335
+ if (GPR_UNLIKELY(!result.ok())) {
336
+ GRPC_STREAM_DATA_QUEUE_DEBUG
337
+ << "Immediate enqueueing half closed for stream " << stream_id_
338
+ << " failed with status: " << result.status();
339
+ return result.status();
340
+ }
341
+ return UpdateWritableStateLocked(
342
+ /*became_non_empty*/ result.value(),
343
+ WritableStreamPriority::kStreamClosed);
320
344
  }
321
345
 
322
346
  // Enqueue Reset Stream.
323
347
  // 1. MUST be called at most once.
324
348
  // 3. This function is thread safe.
325
- auto EnqueueResetStream(uint32_t error_code) {
326
- DCHECK(is_initial_metadata_queued_);
327
- DCHECK(!is_reset_stream_queued_);
328
-
329
- is_reset_stream_queued_ = true;
330
- return [self = this->Ref(),
331
- entry = QueueEntry{ResetStream{
332
- error_code}}]() mutable -> Poll<absl::StatusOr<bool>> {
333
- MutexLock lock(&self->mu_);
334
- auto result = self->queue_.Enqueue(entry, /*tokens=*/0);
335
- if (result.ready()) {
336
- GRPC_STREAM_DATA_QUEUE_DEBUG
337
- << "Enqueueing reset stream for stream " << self->stream_id_
338
- << " with status: " << result.value().status;
339
- if (result.value().status.ok()) {
340
- return self->UpdateWritableStateLocked(
341
- result.value().became_non_empty);
342
- }
343
- return result.value().status;
344
- }
345
- return Pending{};
346
- };
349
+ absl::StatusOr<EnqueueResult> EnqueueResetStream(const uint32_t error_code) {
350
+ MutexLock lock(&mu_);
351
+ GRPC_DCHECK(is_initial_metadata_queued_);
352
+
353
+ // This can happen when the transport tries to close the stream and the
354
+ // stream is cancelled from the call stack.
355
+ if (GPR_UNLIKELY(IsEnqueueClosed())) {
356
+ GRPC_STREAM_DATA_QUEUE_DEBUG << "Enqueue closed for stream "
357
+ << stream_id_;
358
+ return EnqueueResult{/*became_writable=*/false,
359
+ WritableStreamPriority::kStreamClosed};
360
+ }
361
+
362
+ GRPC_STREAM_DATA_QUEUE_DEBUG
363
+ << "Immediate enqueueing reset stream for stream " << stream_id_
364
+ << " with error code: " << error_code;
365
+ reset_stream_state_ = RstStreamState::kQueued;
366
+ reset_stream_error_code_ = error_code;
367
+
368
+ // became_non_empty is set to true if the queue is empty because we are not
369
+ // enqueueing reset stream to the queue. In this case, if the queue is
370
+ // empty, enqueuing reset stream to StreamDataQueue will make the stream
371
+ // writable.
372
+ return UpdateWritableStateLocked(
373
+ /*became_non_empty*/ queue_.IsEmpty(),
374
+ WritableStreamPriority::kStreamClosed);
347
375
  }
348
376
 
349
377
  //////////////////////////////////////////////////////////////////////////////
350
378
  // Dequeue Helpers
351
379
 
352
- // TODO(akshitpatel) : [PH2][P2] : Decide on whether it is needed to return
353
- // the number of tokens consumed by one call of this function.
380
+ static constexpr uint8_t kResetStreamDequeued = 0x1;
381
+ static constexpr uint8_t kHalfCloseDequeued = 0x2;
382
+ static constexpr uint8_t kInitialMetadataDequeued = 0x4;
383
+
354
384
  struct DequeueResult {
355
385
  std::vector<Http2Frame> frames;
356
386
  bool is_writable;
387
+ WritableStreamPriority priority;
388
+ // Maybe not be extremely accurate but should be good enough for our
389
+ // purposes.
390
+ size_t total_bytes_consumed = 0u;
391
+ // Bitmask of the dequeue flags.
392
+ uint8_t flags = 0u;
393
+
394
+ // Returns true if the reset stream was dequeued.
395
+ bool ResetStreamDequeued() const {
396
+ return (flags & kResetStreamDequeued) != 0u;
397
+ }
398
+
399
+ // Returns true if the half close was dequeued.
400
+ bool HalfCloseDequeued() const {
401
+ return (flags & kHalfCloseDequeued) != 0u;
402
+ }
403
+
404
+ // Returns true if the initial metadata was dequeued.
405
+ bool InitialMetadataDequeued() const {
406
+ return (flags & kInitialMetadataDequeued) != 0u;
407
+ }
357
408
  };
358
409
 
359
410
  // TODO(akshitpatel) : [PH2][P4] : Measure the performance of this function
@@ -375,16 +426,27 @@ class StreamDataQueue : public RefCounted<StreamDataQueue<MetadataHandle>> {
375
426
  // the partial first message (sum of payload of all returned frames <=
376
427
  // max_fc_tokens).
377
428
  // This function is thread safe.
378
- absl::StatusOr<DequeueResult> DequeueFrames(const uint32_t max_fc_tokens,
379
- const uint32_t max_frame_length,
380
- HPackCompressor& encoder) {
429
+ DequeueResult DequeueFrames(const uint32_t max_fc_tokens,
430
+ const uint32_t max_frame_length,
431
+ HPackCompressor& encoder,
432
+ const bool can_send_reset_stream) {
381
433
  MutexLock lock(&mu_);
382
- GRPC_STREAM_DATA_QUEUE_DEBUG << "Dequeueing frames for stream "
383
- << stream_id_
384
- << " Max fc tokens: " << max_fc_tokens
385
- << " Max frame length: " << max_frame_length
386
- << " Message disassembler buffered length: "
387
- << message_disassembler_.GetBufferedLength();
434
+ GRPC_STREAM_DATA_QUEUE_DEBUG
435
+ << "Dequeueing frames for stream " << stream_id_
436
+ << " Max fc tokens: " << max_fc_tokens
437
+ << " Max frame length: " << max_frame_length
438
+ << " Message disassembler buffered length: "
439
+ << message_disassembler_.GetBufferedLength()
440
+ << " Can send reset stream: " << can_send_reset_stream
441
+ << " Reset stream state: " << static_cast<uint8_t>(reset_stream_state_);
442
+
443
+ // If a reset stream is queued, we do not want to send any more frames. Any
444
+ // metadata enqueued has not reached HPACK encoder, so it is safe to drop
445
+ // all frames.
446
+ if (std::optional<DequeueResult> result =
447
+ HandleResetStreamLocked(can_send_reset_stream)) {
448
+ return std::move(*result);
449
+ }
388
450
 
389
451
  HandleDequeue handle_dequeue(max_fc_tokens, max_frame_length, encoder,
390
452
  *this);
@@ -408,13 +470,15 @@ class StreamDataQueue : public RefCounted<StreamDataQueue<MetadataHandle>> {
408
470
  GRPC_STREAM_DATA_QUEUE_DEBUG << "Stream id: " << stream_id_
409
471
  << " writable state changed to "
410
472
  << is_writable_;
411
- return DequeueResult{handle_dequeue.GetFrames(), is_writable_};
473
+ return DequeueResult{handle_dequeue.GetFrames(), is_writable_, priority_,
474
+ handle_dequeue.GetTotalBytesConsumed(),
475
+ handle_dequeue.GetDequeueFlags()};
412
476
  }
413
477
 
414
478
  // Returns true if the queue is empty. This function is thread safe.
415
479
  bool TestOnlyIsEmpty() {
416
480
  MutexLock lock(&mu_);
417
- return queue_.TestOnlyIsEmpty();
481
+ return queue_.IsEmpty();
418
482
  }
419
483
 
420
484
  private:
@@ -425,19 +489,15 @@ class StreamDataQueue : public RefCounted<StreamDataQueue<MetadataHandle>> {
425
489
  MetadataHandle metadata;
426
490
  };
427
491
  struct HalfClosed {};
428
- struct ResetStream {
429
- uint32_t error_code;
430
- };
431
492
  using QueueEntry = std::variant<InitialMetadataType, TrailingMetadataType,
432
- MessageHandle, HalfClosed, ResetStream>;
493
+ MessageHandle, HalfClosed>;
433
494
 
434
495
  class HandleDequeue {
435
496
  public:
436
- HandleDequeue(uint32_t max_tokens, uint32_t max_frame_length,
497
+ HandleDequeue(const uint32_t max_tokens, const uint32_t max_frame_length,
437
498
  HPackCompressor& encoder, StreamDataQueue& queue)
438
499
  : queue_(queue),
439
500
  max_frame_length_(max_frame_length),
440
- max_fc_tokens_(max_tokens),
441
501
  fc_tokens_available_(max_tokens),
442
502
  encoder_(encoder) {}
443
503
 
@@ -445,6 +505,7 @@ class StreamDataQueue : public RefCounted<StreamDataQueue<MetadataHandle>> {
445
505
  GRPC_STREAM_DATA_QUEUE_DEBUG << "Preparing initial metadata for sending";
446
506
  queue_.initial_metadata_disassembler_.PrepareForSending(
447
507
  std::move(initial_metadata.metadata), encoder_);
508
+ dequeue_flags_ |= kInitialMetadataDequeued;
448
509
  MaybeAppendInitialMetadataFrames();
449
510
  }
450
511
 
@@ -462,13 +523,7 @@ class StreamDataQueue : public RefCounted<StreamDataQueue<MetadataHandle>> {
462
523
 
463
524
  void operator()(GRPC_UNUSED HalfClosed half_closed) {
464
525
  GRPC_STREAM_DATA_QUEUE_DEBUG << "Preparing end of stream for sending";
465
- is_half_closed_ = true;
466
- }
467
-
468
- void operator()(ResetStream reset_stream) {
469
- GRPC_STREAM_DATA_QUEUE_DEBUG << "Preparing reset stream for sending";
470
- is_reset_stream_ = true;
471
- error_code_ = reset_stream.error_code;
526
+ dequeue_flags_ |= kHalfCloseDequeued;
472
527
  }
473
528
 
474
529
  std::vector<Http2Frame> GetFrames() {
@@ -483,56 +538,57 @@ class StreamDataQueue : public RefCounted<StreamDataQueue<MetadataHandle>> {
483
538
  MaybeAppendMessageFrames();
484
539
  MaybeAppendEndOfStreamFrame();
485
540
  MaybeAppendTrailingMetadataFrames();
486
- MaybeAppendResetStreamFrame();
487
541
  return std::move(frames_);
488
542
  }
489
543
 
544
+ size_t GetTotalBytesConsumed() const { return total_bytes_consumed_; }
545
+ uint8_t GetDequeueFlags() const { return dequeue_flags_; }
546
+
490
547
  private:
491
548
  inline void MaybeAppendInitialMetadataFrames() {
492
549
  while (queue_.initial_metadata_disassembler_.HasMoreData()) {
493
- DCHECK(!is_half_closed_);
494
- DCHECK(!is_reset_stream_);
550
+ GRPC_DCHECK(!(dequeue_flags_ & kHalfCloseDequeued));
551
+ GRPC_DCHECK(!(dequeue_flags_ & kResetStreamDequeued));
495
552
  // TODO(akshitpatel) : [PH2][P2] : I do not think we need this.
496
553
  // HasMoreData() should be enough.
497
554
  bool is_end_headers = false;
498
- frames_.emplace_back(queue_.initial_metadata_disassembler_.GetNextFrame(
555
+ AppendFrame(queue_.initial_metadata_disassembler_.GetNextFrame(
499
556
  max_frame_length_, is_end_headers));
500
557
  }
501
558
  }
502
559
 
503
560
  inline void MaybeAppendTrailingMetadataFrames() {
504
561
  while (queue_.trailing_metadata_disassembler_.HasMoreData()) {
505
- DCHECK(!is_half_closed_);
506
- DCHECK_EQ(queue_.message_disassembler_.GetBufferedLength(), 0u);
507
- DCHECK_EQ(queue_.initial_metadata_disassembler_.GetBufferedLength(),
508
- 0u);
562
+ GRPC_DCHECK(!(dequeue_flags_ & kHalfCloseDequeued));
563
+ GRPC_DCHECK_EQ(queue_.message_disassembler_.GetBufferedLength(), 0u);
564
+ GRPC_DCHECK_EQ(
565
+ queue_.initial_metadata_disassembler_.GetBufferedLength(), 0u);
509
566
  // TODO(akshitpatel) : [PH2][P2] : I do not think we need this.
510
567
  // HasMoreData() should be enough.
511
568
  bool is_end_headers = false;
512
- frames_.emplace_back(
513
- queue_.trailing_metadata_disassembler_.GetNextFrame(
514
- max_frame_length_, is_end_headers));
569
+ AppendFrame(queue_.trailing_metadata_disassembler_.GetNextFrame(
570
+ max_frame_length_, is_end_headers));
515
571
  }
516
572
  }
517
573
 
518
574
  inline void MaybeAppendEndOfStreamFrame() {
519
- if (is_half_closed_) {
520
- DCHECK_EQ(queue_.message_disassembler_.GetBufferedLength(), 0u);
521
- DCHECK_EQ(queue_.initial_metadata_disassembler_.GetBufferedLength(),
522
- 0u);
523
- DCHECK_EQ(queue_.trailing_metadata_disassembler_.GetBufferedLength(),
524
- 0u);
525
- frames_.emplace_back(Http2DataFrame{/*stream_id=*/queue_.stream_id_,
526
- /*end_stream=*/true,
527
- /*payload=*/SliceBuffer()});
575
+ if (dequeue_flags_ & kHalfCloseDequeued) {
576
+ GRPC_DCHECK_EQ(queue_.message_disassembler_.GetBufferedLength(), 0u);
577
+ GRPC_DCHECK_EQ(
578
+ queue_.initial_metadata_disassembler_.GetBufferedLength(), 0u);
579
+ GRPC_DCHECK_EQ(
580
+ queue_.trailing_metadata_disassembler_.GetBufferedLength(), 0u);
581
+ AppendFrame(Http2DataFrame{/*stream_id=*/queue_.stream_id_,
582
+ /*end_stream=*/true,
583
+ /*payload=*/SliceBuffer()});
528
584
  }
529
585
  }
530
586
 
531
587
  inline void MaybeAppendMessageFrames() {
532
588
  while (queue_.message_disassembler_.GetBufferedLength() > 0 &&
533
589
  fc_tokens_available_ > 0) {
534
- DCHECK_EQ(queue_.initial_metadata_disassembler_.GetBufferedLength(),
535
- 0u);
590
+ GRPC_DCHECK_EQ(
591
+ queue_.initial_metadata_disassembler_.GetBufferedLength(), 0u);
536
592
  Http2DataFrame frame = queue_.message_disassembler_.GenerateNextFrame(
537
593
  queue_.stream_id_,
538
594
  std::min(fc_tokens_available_, max_frame_length_));
@@ -540,60 +596,145 @@ class StreamDataQueue : public RefCounted<StreamDataQueue<MetadataHandle>> {
540
596
  GRPC_STREAM_DATA_QUEUE_DEBUG
541
597
  << "Appending message frame with length " << frame.payload.Length()
542
598
  << "Available tokens: " << fc_tokens_available_;
543
- frames_.emplace_back(std::move(frame));
599
+ AppendFrame(std::move(frame));
544
600
  }
545
601
  }
546
602
 
547
603
  inline void MaybeAppendResetStreamFrame() {
548
- if (is_reset_stream_) {
604
+ if (dequeue_flags_ & kResetStreamDequeued) {
549
605
  // TODO(akshitpatel) : [PH2][P2] : Consider if we can send reset stream
550
606
  // frame without flushing all the messages enqueued until now.
551
- DCHECK_EQ(queue_.message_disassembler_.GetBufferedLength(), 0u);
552
- DCHECK_EQ(queue_.initial_metadata_disassembler_.GetBufferedLength(),
553
- 0u);
554
- DCHECK_EQ(queue_.trailing_metadata_disassembler_.GetBufferedLength(),
555
- 0u);
556
- frames_.emplace_back(
557
- Http2RstStreamFrame{queue_.stream_id_, error_code_});
607
+ GRPC_DCHECK_EQ(queue_.message_disassembler_.GetBufferedLength(), 0u);
608
+ GRPC_DCHECK_EQ(
609
+ queue_.initial_metadata_disassembler_.GetBufferedLength(), 0u);
610
+ GRPC_DCHECK_EQ(
611
+ queue_.trailing_metadata_disassembler_.GetBufferedLength(), 0u);
612
+ AppendFrame(Http2RstStreamFrame{queue_.stream_id_, error_code_});
558
613
  }
559
614
  }
560
615
 
616
+ inline void AppendFrame(Http2Frame&& frame) {
617
+ total_bytes_consumed_ += GetFrameMemoryUsage(frame);
618
+ frames_.emplace_back(std::move(frame));
619
+ }
620
+
561
621
  StreamDataQueue& queue_;
562
622
  const uint32_t max_frame_length_;
563
- const uint32_t max_fc_tokens_;
564
623
  uint32_t fc_tokens_available_;
565
- bool is_half_closed_ = false;
566
- bool is_reset_stream_ = false;
567
624
  uint32_t error_code_ = static_cast<uint32_t>(Http2ErrorCode::kNoError);
568
625
  std::vector<Http2Frame> frames_;
569
626
  HPackCompressor& encoder_;
627
+ size_t total_bytes_consumed_ = 0u;
628
+ uint8_t dequeue_flags_ = 0u;
570
629
  };
571
630
 
572
- // Returns true if the queue is now writable. It is expected that the caller
573
- // will hold the lock on the queue when calling this function.
574
- bool UpdateWritableStateLocked(const bool became_non_empty)
631
+ // Updates the stream priority. Also sets the writable state to true if the
632
+ // stream has become writable. Returns if the stream became writable and
633
+ // updated priority. It is expected that the caller will hold the lock on the
634
+ // queue when calling this function.
635
+ EnqueueResult UpdateWritableStateLocked(const bool became_non_empty,
636
+ const WritableStreamPriority priority)
575
637
  ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_) {
638
+ priority_ = priority;
576
639
  if (!is_writable_ && became_non_empty) {
577
- GRPC_STREAM_DATA_QUEUE_DEBUG << "Stream id: " << stream_id_
578
- << " writeable state changed to true";
579
640
  is_writable_ = true;
580
- return true;
641
+ GRPC_STREAM_DATA_QUEUE_DEBUG
642
+ << "UpdateWritableStateLocked for stream id: " << stream_id_
643
+ << " became writable with priority: "
644
+ << GetWritableStreamPriorityString(priority_);
645
+ return EnqueueResult{/*became_writable=*/true, priority_};
646
+ }
647
+
648
+ GRPC_STREAM_DATA_QUEUE_DEBUG
649
+ << "UpdateWritableStateLocked for stream id: " << stream_id_
650
+ << " with priority: " << GetWritableStreamPriorityString(priority_)
651
+ << " is_writable: " << is_writable_;
652
+ return EnqueueResult{/*became_writable=*/false, priority_};
653
+ }
654
+
655
+ // Handles the case where a reset stream is queued.
656
+ // If a reset stream is queued or has been dequeued, this function returns a
657
+ // DequeueResult. Otherwise, it returns std::nullopt.
658
+ // This function must be called with mu_ held.
659
+ std::optional<DequeueResult> HandleResetStreamLocked(
660
+ const bool can_send_reset_stream) ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_) {
661
+ switch (reset_stream_state_) {
662
+ case RstStreamState::kDequeued:
663
+ GRPC_STREAM_DATA_QUEUE_DEBUG
664
+ << "Reset stream is already dequeued for stream " << stream_id_
665
+ << ". Returning empty frames.";
666
+ GRPC_DCHECK(queue_.IsEmpty());
667
+ is_writable_ = false;
668
+ return DequeueResult{std::vector<Http2Frame>(), is_writable_, priority_,
669
+ /*total_bytes_consumed=*/0u, /*flags=*/0u};
670
+ case RstStreamState::kQueued: {
671
+ GRPC_STREAM_DATA_QUEUE_DEBUG
672
+ << "Reset stream is queued. Skipping all frames (if any) for "
673
+ "dequeuing "
674
+ << stream_id_;
675
+ is_writable_ = false;
676
+ std::vector<Http2Frame> frames;
677
+ uint8_t flags = 0u;
678
+ if (can_send_reset_stream) {
679
+ frames.emplace_back(
680
+ Http2RstStreamFrame{stream_id_, reset_stream_error_code_});
681
+ flags = kResetStreamDequeued;
682
+ }
683
+ queue_.Clear();
684
+ reset_stream_state_ = RstStreamState::kDequeued;
685
+ return DequeueResult{std::move(frames), is_writable_, priority_,
686
+ /*total_bytes_consumed=*/0u, flags};
687
+ }
688
+ case RstStreamState::kNotQueued:
689
+ return std::nullopt;
690
+ default:
691
+ GRPC_CHECK(false) << "Invalid reset stream state: "
692
+ << static_cast<uint8_t>(reset_stream_state_);
693
+ }
694
+ }
695
+
696
+ bool IsEnqueueClosed() const ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_) {
697
+ switch (reset_stream_state_) {
698
+ case RstStreamState::kNotQueued:
699
+ return false;
700
+ case RstStreamState::kQueued:
701
+ case RstStreamState::kDequeued:
702
+ // This can happen when the transport tries to close the stream and the
703
+ // stream is cancelled from the call stack.
704
+ GRPC_STREAM_DATA_QUEUE_DEBUG
705
+ << "Reset stream already queued for stream " << stream_id_;
706
+ return true;
707
+ default:
708
+ GRPC_CHECK(false) << "Invalid reset stream state: "
709
+ << static_cast<uint8_t>(reset_stream_state_);
581
710
  }
582
- return false;
711
+
712
+ GPR_UNREACHABLE_CODE("Invalid reset stream state");
583
713
  }
584
714
 
585
715
  const uint32_t stream_id_;
586
716
  const bool is_client_;
587
717
 
718
+ enum class RstStreamState : uint8_t {
719
+ kNotQueued = 0,
720
+ kQueued,
721
+ kDequeued,
722
+ };
723
+
588
724
  // Accessed only during enqueue.
589
725
  bool is_initial_metadata_queued_ = false;
590
726
  bool is_trailing_metadata_or_half_close_queued_ = false;
591
- bool is_reset_stream_queued_ = false;
592
727
 
593
728
  // Access both during enqueue and dequeue.
594
729
  Mutex mu_;
595
730
  bool is_writable_ ABSL_GUARDED_BY(mu_) = false;
731
+ RstStreamState reset_stream_state_ ABSL_GUARDED_BY(mu_) =
732
+ RstStreamState::kNotQueued;
596
733
  SimpleQueue<QueueEntry> queue_;
734
+ WritableStreamPriority priority_ ABSL_GUARDED_BY(mu_) =
735
+ WritableStreamPriority::kDefault;
736
+ uint32_t reset_stream_error_code_ ABSL_GUARDED_BY(mu_) =
737
+ static_cast<uint32_t>(Http2ErrorCode::kNoError);
597
738
 
598
739
  // Accessed only during dequeue.
599
740
  HeaderDisassembler initial_metadata_disassembler_;