grpc 1.73.0 → 1.75.0

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 (786) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +116 -53
  3. data/include/grpc/create_channel_from_endpoint.h +54 -0
  4. data/include/grpc/credentials.h +18 -6
  5. data/include/grpc/event_engine/event_engine.h +74 -17
  6. data/include/grpc/grpc_posix.h +20 -1
  7. data/include/grpc/impl/channel_arg_names.h +2 -4
  8. data/include/grpc/module.modulemap +1 -0
  9. data/include/grpc/support/json.h +24 -0
  10. data/src/core/call/client_call.cc +4 -4
  11. data/src/core/call/filter_fusion.h +1230 -0
  12. data/src/core/call/interception_chain.h +7 -11
  13. data/src/core/call/metadata.cc +22 -0
  14. data/src/core/call/metadata.h +24 -2
  15. data/src/core/channelz/channel_trace.cc +213 -115
  16. data/src/core/channelz/channel_trace.h +380 -86
  17. data/src/core/channelz/channelz.cc +274 -192
  18. data/src/core/channelz/channelz.h +224 -72
  19. data/src/core/channelz/channelz_registry.cc +2 -163
  20. data/src/core/channelz/channelz_registry.h +37 -6
  21. data/src/core/channelz/property_list.cc +353 -0
  22. data/src/core/channelz/property_list.h +204 -0
  23. data/src/core/channelz/v2tov1/convert.cc +683 -0
  24. data/src/core/channelz/v2tov1/convert.h +58 -0
  25. data/src/core/channelz/v2tov1/legacy_api.cc +425 -0
  26. data/src/core/channelz/v2tov1/legacy_api.h +32 -0
  27. data/src/core/channelz/v2tov1/property_list.cc +118 -0
  28. data/src/core/channelz/v2tov1/property_list.h +52 -0
  29. data/src/core/channelz/ztrace_collector.h +3 -2
  30. data/src/core/client_channel/backup_poller.cc +17 -2
  31. data/src/core/client_channel/client_channel.cc +17 -28
  32. data/src/core/client_channel/client_channel_filter.cc +24 -33
  33. data/src/core/client_channel/client_channel_filter.h +2 -2
  34. data/src/core/client_channel/client_channel_internal.h +2 -1
  35. data/src/core/client_channel/config_selector.h +8 -2
  36. data/src/core/client_channel/dynamic_filters.cc +5 -6
  37. data/src/core/client_channel/dynamic_filters.h +1 -1
  38. data/src/core/client_channel/global_subchannel_pool.cc +4 -1
  39. data/src/core/client_channel/load_balanced_call_destination.cc +6 -5
  40. data/src/core/client_channel/retry_filter.cc +21 -27
  41. data/src/core/client_channel/retry_filter.h +10 -7
  42. data/src/core/client_channel/retry_filter_legacy_call_data.cc +5 -5
  43. data/src/core/client_channel/retry_filter_legacy_call_data.h +1 -1
  44. data/src/core/client_channel/retry_interceptor.cc +30 -44
  45. data/src/core/client_channel/retry_interceptor.h +18 -17
  46. data/src/core/client_channel/retry_throttle.cc +46 -61
  47. data/src/core/client_channel/retry_throttle.h +17 -39
  48. data/src/core/client_channel/subchannel.cc +57 -25
  49. data/src/core/client_channel/subchannel.h +10 -0
  50. data/src/core/config/config_vars.cc +2 -0
  51. data/src/core/config/core_configuration.cc +4 -1
  52. data/src/core/config/core_configuration.h +23 -0
  53. data/src/core/credentials/call/call_creds_registry.h +125 -0
  54. data/src/core/credentials/call/call_creds_registry_init.cc +91 -0
  55. data/src/core/credentials/call/gcp_service_account_identity/gcp_service_account_identity_credentials.cc +6 -48
  56. data/src/core/credentials/call/jwt_token_file/jwt_token_file_call_credentials.cc +86 -0
  57. data/src/core/credentials/call/jwt_token_file/jwt_token_file_call_credentials.h +74 -0
  58. data/src/core/credentials/call/jwt_util.cc +70 -0
  59. data/src/core/credentials/call/jwt_util.h +32 -0
  60. data/src/core/credentials/transport/alts/alts_credentials.cc +5 -0
  61. data/src/core/credentials/transport/alts/check_gcp_environment_windows.cc +2 -0
  62. data/src/core/credentials/transport/channel_creds_registry_init.cc +4 -2
  63. data/src/core/credentials/transport/google_default/google_default_credentials.cc +72 -4
  64. data/src/core/credentials/transport/ssl/ssl_credentials.cc +1 -2
  65. data/src/core/credentials/transport/ssl/ssl_security_connector.cc +8 -3
  66. data/src/core/credentials/transport/tls/grpc_tls_certificate_distributor.cc +29 -24
  67. data/src/core/credentials/transport/tls/grpc_tls_certificate_distributor.h +19 -8
  68. data/src/core/credentials/transport/tls/grpc_tls_certificate_provider.cc +96 -54
  69. data/src/core/credentials/transport/tls/grpc_tls_certificate_provider.h +15 -2
  70. data/src/core/credentials/transport/tls/load_system_roots_supported.cc +1 -0
  71. data/src/core/credentials/transport/tls/spiffe_utils.cc +371 -0
  72. data/src/core/credentials/transport/tls/spiffe_utils.h +171 -0
  73. data/src/core/credentials/transport/tls/ssl_utils.cc +11 -10
  74. data/src/core/credentials/transport/tls/ssl_utils.h +4 -2
  75. data/src/core/credentials/transport/tls/tls_credentials.cc +2 -0
  76. data/src/core/credentials/transport/tls/tls_security_connector.cc +11 -26
  77. data/src/core/credentials/transport/tls/tls_security_connector.h +12 -12
  78. data/src/core/credentials/transport/xds/xds_credentials.cc +0 -3
  79. data/src/core/ext/filters/backend_metrics/backend_metric_filter.cc +1 -2
  80. data/src/core/ext/filters/gcp_authentication/gcp_authentication_filter.cc +8 -8
  81. data/src/core/ext/filters/gcp_authentication/gcp_authentication_filter.h +16 -16
  82. data/src/core/ext/filters/http/client/http_client_filter.cc +3 -6
  83. data/src/core/ext/filters/http/client_authority_filter.cc +3 -6
  84. data/src/core/ext/filters/http/message_compress/compression_filter.cc +8 -8
  85. data/src/core/ext/filters/http/message_compress/compression_filter.h +25 -22
  86. data/src/core/ext/filters/http/server/http_server_filter.cc +3 -6
  87. data/src/core/ext/filters/http/server/http_server_filter.h +12 -11
  88. data/src/core/ext/filters/message_size/message_size_filter.cc +4 -4
  89. data/src/core/ext/filters/rbac/rbac_filter.cc +1 -1
  90. data/src/core/ext/filters/stateful_session/stateful_session_filter.cc +3 -5
  91. data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +120 -35
  92. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +6 -5
  93. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +165 -117
  94. data/src/core/ext/transport/chttp2/transport/chttp2_transport.h +0 -3
  95. data/src/core/ext/transport/chttp2/transport/decode_huff.cc +1239 -3514
  96. data/src/core/ext/transport/chttp2/transport/decode_huff.h +1008 -1486
  97. data/src/core/ext/transport/chttp2/transport/flow_control.cc +1 -0
  98. data/src/core/ext/transport/chttp2/transport/flow_control.h +23 -17
  99. data/src/core/ext/transport/chttp2/transport/frame.cc +99 -6
  100. data/src/core/ext/transport/chttp2/transport/frame.h +40 -2
  101. data/src/core/ext/transport/chttp2/transport/frame_data.cc +1 -1
  102. data/src/core/ext/transport/chttp2/transport/frame_settings.cc +7 -8
  103. data/src/core/ext/transport/chttp2/transport/frame_window_update.cc +4 -5
  104. data/src/core/ext/transport/chttp2/transport/header_assembler.h +290 -0
  105. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +1 -1
  106. data/src/core/ext/transport/chttp2/transport/hpack_parser.h +4 -1
  107. data/src/core/ext/transport/chttp2/transport/hpack_parser_table.cc +11 -5
  108. data/src/core/ext/transport/chttp2/transport/hpack_parser_table.h +12 -1
  109. data/src/core/ext/transport/chttp2/transport/http2_client_transport.cc +1233 -0
  110. data/src/core/ext/transport/chttp2/transport/http2_client_transport.h +712 -0
  111. data/src/core/ext/transport/chttp2/transport/http2_settings.cc +11 -38
  112. data/src/core/ext/transport/chttp2/transport/http2_settings.h +65 -51
  113. data/src/core/ext/transport/chttp2/transport/http2_settings_manager.cc +61 -0
  114. data/src/core/ext/transport/chttp2/transport/http2_settings_manager.h +142 -0
  115. data/{third_party/abseil-cpp/absl/strings/cord_buffer.cc → src/core/ext/transport/chttp2/transport/http2_stats_collector.cc} +14 -14
  116. data/src/core/ext/transport/chttp2/transport/http2_stats_collector.h +33 -0
  117. data/src/core/ext/transport/chttp2/transport/http2_status.h +6 -1
  118. data/src/core/ext/transport/chttp2/transport/http2_transport.cc +121 -0
  119. data/src/core/ext/transport/chttp2/transport/http2_transport.h +76 -0
  120. data/src/core/ext/transport/chttp2/transport/http2_ztrace_collector.h +0 -29
  121. data/src/core/ext/transport/chttp2/transport/internal.h +18 -8
  122. data/src/core/ext/transport/chttp2/transport/keepalive.cc +105 -0
  123. data/src/core/ext/transport/chttp2/transport/keepalive.h +138 -0
  124. data/src/core/ext/transport/chttp2/transport/message_assembler.h +185 -0
  125. data/src/core/ext/transport/chttp2/transport/parsing.cc +4 -5
  126. data/src/core/ext/transport/chttp2/transport/ping_callbacks.h +19 -0
  127. data/src/core/ext/transport/chttp2/transport/ping_promise.cc +152 -0
  128. data/src/core/ext/transport/chttp2/transport/ping_promise.h +197 -0
  129. data/src/core/ext/transport/chttp2/transport/ping_rate_policy.cc +5 -9
  130. data/src/core/ext/transport/chttp2/transport/ping_rate_policy.h +11 -0
  131. data/src/core/ext/transport/chttp2/transport/stream_data_queue.h +607 -0
  132. data/src/core/ext/transport/chttp2/transport/stream_lists.cc +39 -1
  133. data/src/core/ext/transport/chttp2/transport/transport_common.cc +19 -0
  134. data/src/core/ext/transport/chttp2/transport/transport_common.h +27 -0
  135. data/src/core/ext/transport/chttp2/transport/writable_streams.h +254 -0
  136. data/src/core/ext/transport/chttp2/transport/writing.cc +41 -13
  137. data/src/core/ext/upb-gen/src/proto/grpc/channelz/channelz.upb.h +4959 -0
  138. data/src/core/ext/upb-gen/src/proto/grpc/channelz/channelz.upb_minitable.c +1111 -0
  139. data/src/core/ext/upb-gen/src/proto/grpc/channelz/channelz.upb_minitable.h +108 -0
  140. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/channelz.upb.h +571 -0
  141. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/channelz.upb_minitable.c +120 -0
  142. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/channelz.upb_minitable.h +36 -0
  143. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/promise.upb.h +1272 -0
  144. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/promise.upb_minitable.c +312 -0
  145. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/promise.upb_minitable.h +50 -0
  146. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb.h +1072 -0
  147. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb_minitable.c +230 -0
  148. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb_minitable.h +44 -0
  149. data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/channelz.upbdefs.c +716 -0
  150. data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/channelz.upbdefs.h +227 -0
  151. data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/promise.upbdefs.c +175 -0
  152. data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/promise.upbdefs.h +82 -0
  153. data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/property_list.upbdefs.c +133 -0
  154. data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/property_list.upbdefs.h +67 -0
  155. data/src/core/filter/auth/auth_filters.h +2 -27
  156. data/src/core/filter/auth/client_auth_filter.cc +0 -118
  157. data/src/core/filter/filter_args.h +9 -23
  158. data/src/core/filter/fused_filters.cc +154 -0
  159. data/src/core/handshaker/handshaker.cc +23 -14
  160. data/src/core/handshaker/handshaker.h +3 -0
  161. data/src/core/handshaker/http_connect/http_connect_handshaker.cc +3 -1
  162. data/src/core/handshaker/security/legacy_secure_endpoint.cc +7 -6
  163. data/src/core/handshaker/security/pipelined_secure_endpoint.cc +965 -0
  164. data/src/core/handshaker/security/secure_endpoint.cc +98 -38
  165. data/src/core/handshaker/security/secure_endpoint.h +8 -0
  166. data/src/core/handshaker/security/security_handshaker.cc +4 -1
  167. data/src/core/handshaker/tcp_connect/tcp_connect_handshaker.cc +7 -1
  168. data/src/core/lib/channel/channel_args.cc +15 -0
  169. data/src/core/lib/channel/channel_args.h +3 -0
  170. data/src/core/lib/channel/channel_stack.cc +22 -23
  171. data/src/core/lib/channel/channel_stack.h +9 -7
  172. data/src/core/lib/channel/channel_stack_builder_impl.cc +1 -1
  173. data/src/core/lib/channel/channel_stack_builder_impl.h +2 -7
  174. data/src/core/lib/channel/promise_based_filter.cc +15 -25
  175. data/src/core/lib/channel/promise_based_filter.h +11 -10
  176. data/src/core/lib/debug/trace_impl.h +0 -1
  177. data/src/core/lib/event_engine/ares_resolver.cc +165 -46
  178. data/src/core/lib/event_engine/ares_resolver.h +51 -3
  179. data/src/core/lib/event_engine/cf_engine/cf_engine.cc +12 -6
  180. data/src/core/lib/event_engine/cf_engine/cf_engine.h +2 -4
  181. data/src/core/lib/event_engine/cf_engine/cfsocket_listener.cc +263 -0
  182. data/src/core/lib/event_engine/cf_engine/cfsocket_listener.h +107 -0
  183. data/src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc +31 -3
  184. data/src/core/lib/event_engine/cf_engine/cfstream_endpoint.h +14 -6
  185. data/src/core/lib/event_engine/endpoint_channel_arg_wrapper.cc +40 -0
  186. data/src/core/lib/event_engine/endpoint_channel_arg_wrapper.h +60 -0
  187. data/src/core/lib/event_engine/event_engine.cc +7 -0
  188. data/src/core/lib/event_engine/extensions/channelz.h +10 -6
  189. data/src/core/lib/event_engine/grpc_polled_fd.h +5 -0
  190. data/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc +139 -169
  191. data/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.h +17 -19
  192. data/src/core/lib/event_engine/posix_engine/ev_poll_posix.cc +90 -131
  193. data/src/core/lib/event_engine/posix_engine/ev_poll_posix.h +13 -13
  194. data/src/core/lib/event_engine/posix_engine/event_poller.h +18 -23
  195. data/src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc +11 -23
  196. data/src/core/lib/event_engine/posix_engine/event_poller_posix_default.h +3 -2
  197. data/src/core/lib/event_engine/posix_engine/file_descriptor_collection.cc +124 -0
  198. data/src/core/lib/event_engine/posix_engine/file_descriptor_collection.h +243 -0
  199. data/src/core/lib/event_engine/posix_engine/grpc_polled_fd_posix.h +30 -19
  200. data/src/core/lib/event_engine/posix_engine/internal_errqueue.cc +6 -2
  201. data/src/core/lib/event_engine/posix_engine/internal_errqueue.h +6 -1
  202. data/src/core/lib/event_engine/posix_engine/lockfree_event.cc +4 -4
  203. data/src/core/lib/event_engine/posix_engine/lockfree_event.h +3 -4
  204. data/src/core/lib/event_engine/posix_engine/posix_endpoint.cc +147 -94
  205. data/src/core/lib/event_engine/posix_engine/posix_endpoint.h +9 -19
  206. data/src/core/lib/event_engine/posix_engine/posix_engine.cc +435 -229
  207. data/src/core/lib/event_engine/posix_engine/posix_engine.h +78 -50
  208. data/src/core/lib/event_engine/posix_engine/posix_engine_listener.cc +46 -38
  209. data/src/core/lib/event_engine/posix_engine/posix_engine_listener.h +6 -4
  210. data/src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.cc +32 -142
  211. data/src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.h +6 -5
  212. data/src/core/lib/event_engine/posix_engine/posix_interface.h +211 -0
  213. data/src/core/lib/event_engine/posix_engine/posix_interface_posix.cc +1083 -0
  214. data/src/core/lib/event_engine/posix_engine/posix_interface_windows.cc +281 -0
  215. data/src/core/lib/event_engine/posix_engine/posix_write_event_sink.cc +154 -0
  216. data/src/core/lib/event_engine/posix_engine/posix_write_event_sink.h +174 -0
  217. data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.cc +3 -719
  218. data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.h +11 -171
  219. data/src/core/lib/event_engine/posix_engine/timer_manager.cc +33 -22
  220. data/src/core/lib/event_engine/posix_engine/timer_manager.h +13 -11
  221. data/src/core/lib/event_engine/posix_engine/traced_buffer_list.cc +117 -151
  222. data/src/core/lib/event_engine/posix_engine/traced_buffer_list.h +26 -94
  223. data/src/core/lib/event_engine/posix_engine/wakeup_fd_eventfd.cc +26 -25
  224. data/src/core/lib/event_engine/posix_engine/wakeup_fd_eventfd.h +6 -2
  225. data/src/core/lib/event_engine/posix_engine/wakeup_fd_pipe.cc +36 -62
  226. data/src/core/lib/event_engine/posix_engine/wakeup_fd_pipe.h +6 -2
  227. data/src/core/lib/event_engine/posix_engine/wakeup_fd_posix.h +7 -6
  228. data/src/core/lib/event_engine/posix_engine/wakeup_fd_posix_default.cc +12 -6
  229. data/src/core/lib/event_engine/posix_engine/wakeup_fd_posix_default.h +3 -1
  230. data/src/core/lib/event_engine/shim.cc +9 -0
  231. data/src/core/lib/event_engine/shim.h +3 -0
  232. data/src/core/lib/event_engine/thread_pool/thread_pool.h +7 -3
  233. data/src/core/lib/event_engine/thread_pool/thread_pool_factory.cc +0 -17
  234. data/src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.cc +4 -2
  235. data/src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.h +3 -2
  236. data/src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc +6 -1
  237. data/src/core/lib/event_engine/windows/grpc_polled_fd_windows.h +4 -0
  238. data/src/core/lib/event_engine/windows/windows_endpoint.h +2 -6
  239. data/src/core/lib/event_engine/windows/windows_engine.cc +0 -1
  240. data/src/core/lib/event_engine/windows/windows_engine.h +1 -3
  241. data/src/core/lib/event_engine/windows/windows_listener.cc +14 -2
  242. data/src/core/lib/experiments/experiments.cc +165 -99
  243. data/src/core/lib/experiments/experiments.h +65 -52
  244. data/src/core/lib/iomgr/combiner.cc +1 -1
  245. data/src/core/lib/iomgr/endpoint.cc +4 -3
  246. data/src/core/lib/iomgr/endpoint.h +7 -4
  247. data/src/core/lib/iomgr/endpoint_cfstream.cc +3 -2
  248. data/src/core/lib/iomgr/ev_epoll1_linux.cc +7 -2
  249. data/src/core/lib/iomgr/ev_poll_posix.cc +7 -2
  250. data/src/core/lib/iomgr/event_engine_shims/endpoint.cc +4 -6
  251. data/src/core/lib/iomgr/exec_ctx.h +3 -9
  252. data/src/core/lib/iomgr/socket_mutator.cc +1 -1
  253. data/src/core/lib/iomgr/socket_utils_posix.cc +1 -1
  254. data/src/core/lib/iomgr/socket_utils_posix.h +1 -1
  255. data/src/core/lib/iomgr/tcp_client_posix.cc +1 -1
  256. data/src/core/lib/iomgr/tcp_posix.cc +15 -9
  257. data/src/core/lib/iomgr/tcp_windows.cc +3 -2
  258. data/src/core/lib/promise/activity.h +3 -2
  259. data/src/core/lib/promise/arena_promise.h +23 -7
  260. data/src/core/lib/promise/detail/promise_factory.h +10 -0
  261. data/src/core/lib/promise/detail/promise_like.h +118 -11
  262. data/src/core/lib/promise/detail/promise_variant.h +50 -0
  263. data/src/core/lib/promise/detail/seq_state.h +687 -548
  264. data/src/core/lib/promise/if.h +20 -0
  265. data/src/core/lib/promise/inter_activity_latch.h +147 -0
  266. data/src/core/lib/promise/inter_activity_mutex.h +547 -0
  267. data/src/core/lib/promise/loop.h +65 -3
  268. data/src/core/lib/promise/map.h +24 -0
  269. data/src/core/lib/promise/match_promise.h +103 -0
  270. data/src/core/lib/promise/mpsc.cc +425 -0
  271. data/src/core/lib/promise/mpsc.h +490 -0
  272. data/src/core/lib/promise/party.cc +55 -6
  273. data/src/core/lib/promise/party.h +68 -3
  274. data/src/core/lib/promise/poll.h +10 -0
  275. data/src/core/lib/promise/race.h +31 -0
  276. data/src/core/lib/promise/seq.h +4 -1
  277. data/src/core/lib/promise/status_flag.h +7 -0
  278. data/src/core/lib/promise/try_seq.h +4 -1
  279. data/src/core/lib/promise/wait_set.cc +28 -0
  280. data/src/core/lib/promise/wait_set.h +86 -0
  281. data/src/core/lib/resource_quota/arena.h +19 -0
  282. data/src/core/lib/resource_quota/memory_quota.cc +90 -3
  283. data/src/core/lib/resource_quota/memory_quota.h +20 -9
  284. data/src/core/lib/resource_quota/periodic_update.cc +14 -0
  285. data/src/core/lib/resource_quota/periodic_update.h +8 -0
  286. data/src/core/lib/resource_quota/resource_quota.cc +15 -4
  287. data/src/core/lib/resource_quota/resource_quota.h +3 -0
  288. data/src/core/lib/security/authorization/grpc_server_authz_filter.cc +1 -2
  289. data/src/core/lib/slice/slice.h +5 -0
  290. data/src/core/lib/surface/call.cc +5 -5
  291. data/src/core/lib/surface/call.h +6 -5
  292. data/src/core/lib/surface/channel_create.cc +88 -13
  293. data/src/core/lib/surface/channel_create.h +4 -0
  294. data/src/core/lib/surface/channel_init.cc +164 -47
  295. data/src/core/lib/surface/channel_init.h +64 -1
  296. data/src/core/lib/surface/completion_queue.cc +2 -4
  297. data/src/core/lib/surface/filter_stack_call.cc +19 -10
  298. data/src/core/lib/surface/init.cc +6 -15
  299. data/src/core/lib/surface/legacy_channel.cc +3 -5
  300. data/src/core/lib/surface/legacy_channel.h +3 -1
  301. data/src/core/lib/surface/version.cc +2 -2
  302. data/src/core/lib/transport/promise_endpoint.cc +110 -0
  303. data/src/core/lib/transport/promise_endpoint.h +307 -0
  304. data/src/core/load_balancing/child_policy_handler.cc +2 -4
  305. data/src/core/load_balancing/delegating_helper.h +2 -3
  306. data/src/core/load_balancing/endpoint_list.cc +29 -2
  307. data/src/core/load_balancing/grpclb/client_load_reporting_filter.cc +3 -3
  308. data/src/core/load_balancing/grpclb/client_load_reporting_filter.h +1 -1
  309. data/src/core/load_balancing/health_check_client.cc +1 -5
  310. data/src/core/load_balancing/lb_policy.h +1 -3
  311. data/src/core/load_balancing/oob_backend_metric.cc +1 -5
  312. data/src/core/load_balancing/pick_first/pick_first.cc +15 -5
  313. data/src/core/load_balancing/xds/cds.cc +10 -1
  314. data/src/core/load_balancing/xds/xds_cluster_impl.cc +5 -3
  315. data/src/core/net/socket_mutator.cc +19 -0
  316. data/src/core/net/socket_mutator.h +25 -0
  317. data/src/core/plugin_registry/grpc_plugin_registry.cc +6 -0
  318. data/src/core/plugin_registry/grpc_plugin_registry_extra.cc +2 -0
  319. data/src/core/resolver/dns/c_ares/grpc_ares_ev_driver.h +6 -1
  320. data/src/core/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +2 -1
  321. data/src/core/resolver/dns/c_ares/grpc_ares_wrapper.cc +8 -5
  322. data/src/core/resolver/dns/c_ares/grpc_ares_wrapper.h +2 -1
  323. data/src/core/resolver/xds/xds_config.cc +6 -3
  324. data/src/core/resolver/xds/xds_config.h +9 -4
  325. data/src/core/resolver/xds/xds_dependency_manager.cc +22 -7
  326. data/src/core/resolver/xds/xds_dependency_manager.h +2 -1
  327. data/src/core/resolver/xds/xds_resolver.cc +31 -11
  328. data/src/core/server/server.cc +84 -13
  329. data/src/core/server/server.h +21 -2
  330. data/src/core/server/server_call_tracer_filter.cc +0 -66
  331. data/src/core/server/server_call_tracer_filter.h +64 -0
  332. data/src/core/server/server_config_selector_filter.cc +1 -1
  333. data/src/core/server/xds_server_config_fetcher.cc +63 -25
  334. data/src/core/service_config/service_config.h +1 -1
  335. data/src/core/service_config/service_config_channel_arg_filter.cc +3 -60
  336. data/src/core/service_config/service_config_channel_arg_filter.h +82 -0
  337. data/src/core/service_config/service_config_impl.h +1 -1
  338. data/src/core/telemetry/call_tracer.cc +20 -14
  339. data/src/core/telemetry/call_tracer.h +22 -17
  340. data/src/core/telemetry/context_list_entry.cc +38 -0
  341. data/src/core/telemetry/context_list_entry.h +42 -12
  342. data/src/core/telemetry/metrics.h +8 -8
  343. data/src/core/telemetry/stats_data.cc +369 -343
  344. data/src/core/telemetry/stats_data.h +341 -244
  345. data/src/core/telemetry/tcp_tracer.h +1 -1
  346. data/src/core/transport/auth_context.cc +20 -0
  347. data/src/core/transport/auth_context.h +4 -0
  348. data/src/core/transport/auth_context_comparator_registry.h +69 -0
  349. data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +2 -3
  350. data/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc +11 -3
  351. data/src/core/tsi/fake_transport_security.cc +17 -0
  352. data/src/core/tsi/ssl_transport_security.cc +205 -32
  353. data/src/core/tsi/ssl_transport_security.h +19 -10
  354. data/src/core/tsi/ssl_transport_security_utils.cc +21 -0
  355. data/src/core/tsi/ssl_transport_security_utils.h +4 -0
  356. data/src/core/tsi/transport_security_grpc.cc +8 -0
  357. data/src/core/tsi/transport_security_grpc.h +15 -0
  358. data/src/core/util/backoff.cc +1 -5
  359. data/src/core/util/backoff.h +1 -0
  360. data/src/core/util/down_cast.h +1 -1
  361. data/src/core/util/function_signature.h +15 -1
  362. data/src/core/util/http_client/httpcli.cc +12 -5
  363. data/src/core/util/http_client/httpcli.h +4 -1
  364. data/src/core/util/http_client/httpcli_security_connector.cc +3 -1
  365. data/src/core/util/latent_see.cc +178 -146
  366. data/src/core/util/latent_see.h +249 -189
  367. data/src/core/util/log.cc +4 -0
  368. data/src/core/util/memory_usage.h +268 -0
  369. data/src/core/util/per_cpu.cc +2 -0
  370. data/src/core/util/per_cpu.h +7 -0
  371. data/src/core/util/shared_bit_gen.h +20 -0
  372. data/src/core/util/single_set_ptr.h +7 -4
  373. data/src/core/util/upb_utils.h +42 -0
  374. data/src/core/util/uri.cc +3 -2
  375. data/src/core/util/useful.h +144 -2
  376. data/src/core/util/wait_for_single_owner.cc +31 -0
  377. data/src/core/util/wait_for_single_owner.h +24 -0
  378. data/src/core/util/windows/directory_reader.cc +1 -0
  379. data/src/core/util/windows/thd.cc +1 -3
  380. data/src/core/util/work_serializer.cc +1 -1
  381. data/src/core/xds/grpc/file_watcher_certificate_provider_factory.cc +32 -5
  382. data/src/core/xds/grpc/file_watcher_certificate_provider_factory.h +5 -0
  383. data/src/core/xds/grpc/xds_bootstrap_grpc.cc +2 -0
  384. data/src/core/xds/grpc/xds_bootstrap_grpc.h +5 -0
  385. data/src/core/xds/grpc/xds_certificate_provider.cc +5 -6
  386. data/src/core/xds/grpc/xds_client_grpc.cc +6 -2
  387. data/src/core/xds/grpc/xds_common_types_parser.cc +138 -50
  388. data/src/core/xds/grpc/xds_common_types_parser.h +12 -0
  389. data/src/core/xds/grpc/xds_http_filter.h +7 -0
  390. data/src/core/xds/grpc/xds_http_gcp_authn_filter.cc +22 -0
  391. data/src/core/xds/grpc/xds_http_gcp_authn_filter.h +3 -0
  392. data/src/core/xds/grpc/xds_route_config_parser.cc +15 -38
  393. data/src/core/xds/grpc/xds_server_grpc.cc +63 -13
  394. data/src/core/xds/grpc/xds_server_grpc.h +10 -2
  395. data/src/core/xds/grpc/xds_server_grpc_interface.h +4 -0
  396. data/src/core/xds/grpc/xds_transport_grpc.cc +18 -0
  397. data/src/core/xds/xds_client/xds_bootstrap.h +2 -0
  398. data/src/core/xds/xds_client/xds_client.cc +26 -5
  399. data/src/ruby/ext/grpc/extconf.rb +2 -0
  400. data/src/ruby/ext/grpc/rb_call.c +1 -8
  401. data/src/ruby/ext/grpc/rb_channel.c +70 -557
  402. data/src/ruby/ext/grpc/rb_channel.h +0 -3
  403. data/src/ruby/ext/grpc/rb_completion_queue.c +26 -14
  404. data/src/ruby/ext/grpc/rb_completion_queue.h +1 -7
  405. data/src/ruby/ext/grpc/rb_grpc.c +9 -5
  406. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +2 -2
  407. data/src/ruby/ext/grpc/rb_loader.c +0 -4
  408. data/src/ruby/ext/grpc/rb_server.c +31 -50
  409. data/src/ruby/lib/grpc/generic/client_stub.rb +4 -4
  410. data/src/ruby/lib/grpc/version.rb +1 -1
  411. data/src/ruby/spec/core_spec.rb +22 -0
  412. data/src/ruby/spec/generic/active_call_spec.rb +1 -1
  413. data/third_party/abseil-cpp/absl/algorithm/container.h +2 -19
  414. data/third_party/abseil-cpp/absl/base/attributes.h +76 -7
  415. data/third_party/abseil-cpp/absl/base/call_once.h +11 -12
  416. data/third_party/abseil-cpp/absl/base/config.h +20 -129
  417. data/third_party/abseil-cpp/absl/base/{internal/fast_type_id.h → fast_type_id.h} +11 -16
  418. data/third_party/abseil-cpp/absl/base/internal/cycleclock.cc +0 -5
  419. data/third_party/abseil-cpp/absl/base/internal/cycleclock_config.h +7 -7
  420. data/third_party/abseil-cpp/absl/base/internal/endian.h +34 -38
  421. data/third_party/abseil-cpp/absl/base/internal/iterator_traits.h +71 -0
  422. data/third_party/abseil-cpp/absl/base/internal/low_level_alloc.cc +6 -5
  423. data/third_party/abseil-cpp/absl/base/internal/{nullability_impl.h → nullability_deprecated.h} +45 -8
  424. data/third_party/abseil-cpp/absl/base/internal/spinlock.cc +0 -9
  425. data/third_party/abseil-cpp/absl/base/internal/spinlock.h +3 -13
  426. data/third_party/abseil-cpp/absl/base/internal/unaligned_access.h +6 -6
  427. data/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.h +8 -3
  428. data/third_party/abseil-cpp/absl/base/no_destructor.h +11 -32
  429. data/third_party/abseil-cpp/absl/base/nullability.h +84 -72
  430. data/third_party/abseil-cpp/absl/base/options.h +3 -80
  431. data/third_party/abseil-cpp/absl/base/policy_checks.h +7 -7
  432. data/third_party/abseil-cpp/absl/cleanup/cleanup.h +1 -3
  433. data/third_party/abseil-cpp/absl/cleanup/internal/cleanup.h +3 -4
  434. data/third_party/abseil-cpp/absl/container/btree_map.h +4 -2
  435. data/third_party/abseil-cpp/absl/container/btree_set.h +4 -2
  436. data/third_party/abseil-cpp/absl/container/fixed_array.h +7 -14
  437. data/third_party/abseil-cpp/absl/container/flat_hash_map.h +5 -0
  438. data/third_party/abseil-cpp/absl/container/flat_hash_set.h +6 -1
  439. data/third_party/abseil-cpp/absl/container/inlined_vector.h +8 -5
  440. data/third_party/abseil-cpp/absl/container/internal/btree.h +132 -29
  441. data/third_party/abseil-cpp/absl/container/internal/btree_container.h +175 -71
  442. data/third_party/abseil-cpp/absl/container/internal/common.h +43 -0
  443. data/third_party/abseil-cpp/absl/container/internal/common_policy_traits.h +1 -2
  444. data/third_party/abseil-cpp/absl/container/internal/container_memory.h +9 -10
  445. data/third_party/abseil-cpp/absl/container/internal/hash_function_defaults.h +1 -8
  446. data/third_party/abseil-cpp/absl/container/internal/hash_policy_traits.h +0 -4
  447. data/third_party/abseil-cpp/absl/container/internal/hashtable_control_bytes.h +527 -0
  448. data/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.cc +20 -4
  449. data/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.h +31 -12
  450. data/third_party/abseil-cpp/absl/container/internal/inlined_vector.h +2 -7
  451. data/third_party/abseil-cpp/absl/container/internal/layout.h +26 -42
  452. data/third_party/abseil-cpp/absl/container/internal/raw_hash_map.h +199 -68
  453. data/third_party/abseil-cpp/absl/container/internal/raw_hash_set.cc +1354 -183
  454. data/third_party/abseil-cpp/absl/container/internal/raw_hash_set.h +881 -1424
  455. data/third_party/abseil-cpp/absl/container/internal/raw_hash_set_resize_impl.h +80 -0
  456. data/third_party/abseil-cpp/absl/crc/crc32c.cc +0 -4
  457. data/third_party/abseil-cpp/absl/crc/crc32c.h +7 -5
  458. data/third_party/abseil-cpp/absl/crc/internal/crc32_x86_arm_combined_simd.h +0 -22
  459. data/third_party/abseil-cpp/absl/crc/internal/crc_x86_arm_combined.cc +45 -74
  460. data/third_party/abseil-cpp/absl/debugging/internal/addresses.h +57 -0
  461. data/third_party/abseil-cpp/absl/debugging/internal/decode_rust_punycode.cc +1 -1
  462. data/third_party/abseil-cpp/absl/debugging/internal/decode_rust_punycode.h +5 -5
  463. data/third_party/abseil-cpp/absl/debugging/internal/demangle.cc +8 -35
  464. data/third_party/abseil-cpp/absl/debugging/internal/demangle_rust.cc +16 -16
  465. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_aarch64-inl.inc +40 -37
  466. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_arm-inl.inc +16 -7
  467. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_emscripten-inl.inc +14 -5
  468. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_generic-inl.inc +10 -4
  469. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_powerpc-inl.inc +27 -16
  470. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_riscv-inl.inc +13 -4
  471. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_unimplemented-inl.inc +4 -3
  472. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_win32-inl.inc +15 -28
  473. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_x86-inl.inc +19 -9
  474. data/third_party/abseil-cpp/absl/debugging/stacktrace.cc +144 -27
  475. data/third_party/abseil-cpp/absl/debugging/stacktrace.h +73 -5
  476. data/third_party/abseil-cpp/absl/debugging/symbolize_elf.inc +19 -9
  477. data/third_party/abseil-cpp/absl/debugging/symbolize_emscripten.inc +3 -2
  478. data/third_party/abseil-cpp/absl/debugging/symbolize_win32.inc +25 -6
  479. data/third_party/abseil-cpp/absl/flags/commandlineflag.h +2 -2
  480. data/third_party/abseil-cpp/absl/flags/flag.h +4 -3
  481. data/third_party/abseil-cpp/absl/flags/internal/commandlineflag.h +2 -2
  482. data/third_party/abseil-cpp/absl/flags/internal/flag.cc +2 -1
  483. data/third_party/abseil-cpp/absl/flags/internal/flag.h +7 -6
  484. data/third_party/abseil-cpp/absl/flags/internal/registry.h +4 -3
  485. data/third_party/abseil-cpp/absl/flags/reflection.cc +2 -3
  486. data/third_party/abseil-cpp/absl/functional/any_invocable.h +8 -10
  487. data/third_party/abseil-cpp/absl/functional/function_ref.h +2 -9
  488. data/third_party/abseil-cpp/absl/functional/internal/any_invocable.h +110 -226
  489. data/third_party/abseil-cpp/absl/functional/internal/front_binder.h +10 -12
  490. data/third_party/abseil-cpp/absl/functional/internal/function_ref.h +2 -5
  491. data/third_party/abseil-cpp/absl/hash/hash.h +18 -0
  492. data/third_party/abseil-cpp/absl/hash/internal/hash.cc +1 -5
  493. data/third_party/abseil-cpp/absl/hash/internal/hash.h +86 -61
  494. data/third_party/abseil-cpp/absl/hash/internal/low_level_hash.cc +25 -68
  495. data/third_party/abseil-cpp/absl/hash/internal/low_level_hash.h +2 -6
  496. data/third_party/abseil-cpp/absl/hash/internal/weakly_mixed_integer.h +38 -0
  497. data/third_party/abseil-cpp/absl/log/check.h +2 -1
  498. data/third_party/abseil-cpp/absl/log/globals.h +4 -5
  499. data/third_party/abseil-cpp/absl/log/internal/append_truncated.h +28 -0
  500. data/third_party/abseil-cpp/absl/log/internal/check_op.cc +22 -22
  501. data/third_party/abseil-cpp/absl/log/internal/check_op.h +65 -62
  502. data/third_party/abseil-cpp/absl/log/internal/conditions.cc +5 -3
  503. data/third_party/abseil-cpp/absl/log/internal/conditions.h +7 -2
  504. data/third_party/abseil-cpp/absl/log/internal/log_message.cc +85 -43
  505. data/third_party/abseil-cpp/absl/log/internal/log_message.h +84 -59
  506. data/third_party/abseil-cpp/absl/log/internal/nullstream.h +1 -0
  507. data/third_party/abseil-cpp/absl/log/internal/proto.cc +3 -2
  508. data/third_party/abseil-cpp/absl/log/internal/proto.h +3 -3
  509. data/third_party/abseil-cpp/absl/log/internal/strip.h +4 -12
  510. data/third_party/abseil-cpp/absl/log/internal/vlog_config.h +8 -6
  511. data/third_party/abseil-cpp/absl/log/internal/voidify.h +10 -4
  512. data/third_party/abseil-cpp/absl/log/log.h +48 -35
  513. data/third_party/abseil-cpp/absl/log/log_sink_registry.h +2 -2
  514. data/third_party/abseil-cpp/absl/meta/type_traits.h +46 -175
  515. data/third_party/abseil-cpp/absl/numeric/bits.h +68 -2
  516. data/third_party/abseil-cpp/absl/numeric/int128.cc +0 -52
  517. data/third_party/abseil-cpp/absl/numeric/internal/bits.h +7 -3
  518. data/third_party/abseil-cpp/absl/profiling/internal/exponential_biased.cc +1 -1
  519. data/third_party/abseil-cpp/absl/random/bit_gen_ref.h +10 -11
  520. data/third_party/abseil-cpp/absl/random/distributions.h +6 -8
  521. data/third_party/abseil-cpp/absl/random/gaussian_distribution.h +1 -1
  522. data/third_party/abseil-cpp/absl/random/internal/distribution_caller.h +5 -6
  523. data/third_party/abseil-cpp/absl/random/internal/{pool_urbg.cc → entropy_pool.cc} +22 -90
  524. data/third_party/abseil-cpp/absl/random/internal/entropy_pool.h +35 -0
  525. data/third_party/abseil-cpp/absl/random/internal/nonsecure_base.h +5 -6
  526. data/third_party/abseil-cpp/absl/random/internal/randen_detect.cc +1 -1
  527. data/third_party/abseil-cpp/absl/random/internal/seed_material.cc +20 -12
  528. data/third_party/abseil-cpp/absl/random/internal/seed_material.h +5 -5
  529. data/third_party/abseil-cpp/absl/random/random.h +88 -53
  530. data/third_party/abseil-cpp/absl/random/seed_sequences.cc +6 -2
  531. data/third_party/abseil-cpp/absl/status/internal/status_internal.cc +3 -4
  532. data/third_party/abseil-cpp/absl/status/internal/status_internal.h +3 -4
  533. data/third_party/abseil-cpp/absl/status/internal/statusor_internal.h +4 -3
  534. data/third_party/abseil-cpp/absl/status/status.cc +4 -8
  535. data/third_party/abseil-cpp/absl/status/status.h +8 -8
  536. data/third_party/abseil-cpp/absl/status/status_payload_printer.h +2 -2
  537. data/third_party/abseil-cpp/absl/status/statusor.cc +2 -2
  538. data/third_party/abseil-cpp/absl/status/statusor.h +6 -6
  539. data/third_party/abseil-cpp/absl/strings/ascii.cc +9 -9
  540. data/third_party/abseil-cpp/absl/strings/ascii.h +18 -18
  541. data/third_party/abseil-cpp/absl/strings/charconv.cc +21 -22
  542. data/third_party/abseil-cpp/absl/strings/charconv.h +5 -5
  543. data/third_party/abseil-cpp/absl/strings/cord.cc +54 -58
  544. data/third_party/abseil-cpp/absl/strings/cord.h +94 -83
  545. data/third_party/abseil-cpp/absl/strings/cord_analysis.cc +11 -11
  546. data/third_party/abseil-cpp/absl/strings/cord_analysis.h +3 -3
  547. data/third_party/abseil-cpp/absl/strings/escaping.cc +130 -149
  548. data/third_party/abseil-cpp/absl/strings/escaping.h +9 -10
  549. data/third_party/abseil-cpp/absl/strings/internal/charconv_bigint.cc +1 -1
  550. data/third_party/abseil-cpp/absl/strings/internal/cord_internal.h +6 -8
  551. data/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree.cc +0 -4
  552. data/third_party/abseil-cpp/absl/strings/internal/cordz_info.cc +0 -4
  553. data/third_party/abseil-cpp/absl/strings/internal/str_format/arg.cc +7 -63
  554. data/third_party/abseil-cpp/absl/strings/internal/str_format/arg.h +1 -11
  555. data/third_party/abseil-cpp/absl/strings/internal/str_format/extension.cc +0 -22
  556. data/third_party/abseil-cpp/absl/strings/internal/str_format/output.cc +5 -3
  557. data/third_party/abseil-cpp/absl/strings/internal/str_format/parser.h +4 -2
  558. data/third_party/abseil-cpp/absl/strings/internal/str_join_internal.h +3 -3
  559. data/third_party/abseil-cpp/absl/strings/internal/string_constant.h +0 -5
  560. data/third_party/abseil-cpp/absl/strings/internal/utf8.cc +96 -1
  561. data/third_party/abseil-cpp/absl/strings/internal/utf8.h +15 -1
  562. data/third_party/abseil-cpp/absl/strings/numbers.cc +53 -32
  563. data/third_party/abseil-cpp/absl/strings/numbers.h +87 -58
  564. data/third_party/abseil-cpp/absl/strings/str_cat.cc +6 -7
  565. data/third_party/abseil-cpp/absl/strings/str_cat.h +32 -32
  566. data/third_party/abseil-cpp/absl/strings/str_format.h +18 -18
  567. data/third_party/abseil-cpp/absl/strings/str_replace.cc +3 -3
  568. data/third_party/abseil-cpp/absl/strings/str_replace.h +6 -6
  569. data/third_party/abseil-cpp/absl/strings/string_view.cc +4 -9
  570. data/third_party/abseil-cpp/absl/strings/string_view.h +27 -32
  571. data/third_party/abseil-cpp/absl/strings/strip.h +4 -4
  572. data/third_party/abseil-cpp/absl/strings/substitute.cc +5 -4
  573. data/third_party/abseil-cpp/absl/strings/substitute.h +66 -64
  574. data/third_party/abseil-cpp/absl/synchronization/internal/futex_waiter.cc +0 -4
  575. data/third_party/abseil-cpp/absl/synchronization/internal/kernel_timeout.cc +0 -5
  576. data/third_party/abseil-cpp/absl/synchronization/internal/pthread_waiter.cc +0 -4
  577. data/third_party/abseil-cpp/absl/synchronization/internal/sem_waiter.cc +0 -4
  578. data/third_party/abseil-cpp/absl/synchronization/internal/stdcpp_waiter.cc +0 -4
  579. data/third_party/abseil-cpp/absl/synchronization/internal/waiter_base.cc +0 -4
  580. data/third_party/abseil-cpp/absl/synchronization/internal/win32_waiter.cc +0 -4
  581. data/third_party/abseil-cpp/absl/synchronization/mutex.cc +1 -1
  582. data/third_party/abseil-cpp/absl/synchronization/mutex.h +97 -69
  583. data/third_party/abseil-cpp/absl/synchronization/notification.h +1 -1
  584. data/third_party/abseil-cpp/absl/time/civil_time.cc +1 -0
  585. data/third_party/abseil-cpp/absl/time/duration.cc +12 -7
  586. data/third_party/abseil-cpp/absl/time/internal/cctz/include/cctz/time_zone.h +1 -1
  587. data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup.cc +90 -111
  588. data/third_party/abseil-cpp/absl/time/time.h +20 -15
  589. data/third_party/abseil-cpp/absl/types/optional.h +7 -747
  590. data/third_party/abseil-cpp/absl/types/span.h +13 -11
  591. data/third_party/abseil-cpp/absl/types/variant.h +5 -784
  592. data/third_party/abseil-cpp/absl/utility/utility.h +10 -185
  593. data/third_party/cares/cares/include/ares.h +925 -460
  594. data/third_party/cares/cares/include/ares_dns.h +86 -71
  595. data/third_party/cares/cares/include/ares_dns_record.h +1118 -0
  596. data/third_party/cares/cares/include/ares_nameser.h +215 -189
  597. data/third_party/cares/cares/include/ares_version.h +37 -14
  598. data/third_party/cares/cares/src/lib/ares_addrinfo2hostent.c +305 -0
  599. data/third_party/cares/cares/src/lib/ares_addrinfo_localhost.c +245 -0
  600. data/third_party/cares/cares/src/lib/ares_android.c +216 -164
  601. data/third_party/cares/cares/src/lib/ares_android.h +25 -14
  602. data/third_party/cares/cares/src/lib/ares_cancel.c +68 -44
  603. data/third_party/cares/cares/src/lib/ares_close_sockets.c +137 -0
  604. data/third_party/cares/cares/src/lib/ares_conn.c +511 -0
  605. data/third_party/cares/cares/src/lib/ares_conn.h +196 -0
  606. data/third_party/cares/cares/src/lib/ares_cookie.c +461 -0
  607. data/third_party/cares/cares/src/lib/ares_data.c +93 -181
  608. data/third_party/cares/cares/src/lib/ares_data.h +50 -39
  609. data/third_party/cares/cares/src/lib/ares_destroy.c +127 -89
  610. data/third_party/cares/cares/src/lib/ares_free_hostent.c +35 -24
  611. data/third_party/cares/cares/src/lib/ares_free_string.c +24 -16
  612. data/third_party/cares/cares/src/lib/ares_freeaddrinfo.c +45 -38
  613. data/third_party/cares/cares/src/lib/ares_getaddrinfo.c +549 -663
  614. data/third_party/cares/cares/src/lib/ares_getenv.c +25 -15
  615. data/third_party/cares/cares/src/lib/ares_getenv.h +26 -18
  616. data/third_party/cares/cares/src/lib/ares_gethostbyaddr.c +163 -221
  617. data/third_party/cares/cares/src/lib/ares_gethostbyname.c +222 -223
  618. data/third_party/cares/cares/src/lib/ares_getnameinfo.c +328 -338
  619. data/third_party/cares/cares/src/lib/ares_hosts_file.c +952 -0
  620. data/third_party/cares/cares/src/lib/ares_inet_net_pton.h +25 -19
  621. data/third_party/cares/cares/src/lib/ares_init.c +425 -2091
  622. data/third_party/cares/cares/src/lib/ares_ipv6.h +63 -33
  623. data/third_party/cares/cares/src/lib/ares_library_init.c +110 -54
  624. data/third_party/cares/cares/src/lib/ares_metrics.c +261 -0
  625. data/third_party/cares/cares/src/lib/ares_options.c +418 -332
  626. data/third_party/cares/cares/src/lib/ares_parse_into_addrinfo.c +179 -0
  627. data/third_party/cares/cares/src/lib/ares_private.h +558 -356
  628. data/third_party/cares/cares/src/lib/ares_process.c +1224 -1369
  629. data/third_party/cares/cares/src/lib/ares_qcache.c +430 -0
  630. data/third_party/cares/cares/src/lib/ares_query.c +126 -121
  631. data/third_party/cares/cares/src/lib/ares_search.c +564 -262
  632. data/third_party/cares/cares/src/lib/ares_send.c +264 -93
  633. data/third_party/cares/cares/src/lib/ares_set_socket_functions.c +588 -0
  634. data/third_party/cares/cares/src/lib/ares_setup.h +115 -111
  635. data/third_party/cares/cares/src/lib/ares_socket.c +425 -0
  636. data/third_party/cares/cares/src/lib/ares_socket.h +163 -0
  637. data/third_party/cares/cares/src/lib/ares_sortaddrinfo.c +447 -0
  638. data/third_party/cares/cares/src/lib/ares_strerror.c +83 -48
  639. data/third_party/cares/cares/src/lib/ares_sysconfig.c +639 -0
  640. data/third_party/cares/cares/src/lib/ares_sysconfig_files.c +839 -0
  641. data/third_party/cares/cares/src/lib/ares_sysconfig_mac.c +373 -0
  642. data/third_party/cares/cares/src/lib/ares_sysconfig_win.c +621 -0
  643. data/third_party/cares/cares/src/lib/ares_timeout.c +136 -73
  644. data/third_party/cares/cares/src/lib/ares_update_servers.c +1362 -0
  645. data/third_party/cares/cares/src/lib/ares_version.c +29 -4
  646. data/third_party/cares/cares/src/lib/config-dos.h +88 -89
  647. data/third_party/cares/cares/src/lib/config-win32.h +122 -77
  648. data/third_party/cares/cares/src/lib/dsa/ares_array.c +394 -0
  649. data/third_party/cares/cares/src/lib/dsa/ares_htable.c +447 -0
  650. data/third_party/cares/cares/src/lib/dsa/ares_htable.h +174 -0
  651. data/third_party/cares/cares/src/lib/dsa/ares_htable_asvp.c +224 -0
  652. data/third_party/cares/cares/src/lib/dsa/ares_htable_dict.c +228 -0
  653. data/third_party/cares/cares/src/lib/dsa/ares_htable_strvp.c +210 -0
  654. data/third_party/cares/cares/src/lib/dsa/ares_htable_szvp.c +188 -0
  655. data/third_party/cares/cares/src/lib/dsa/ares_htable_vpstr.c +186 -0
  656. data/third_party/cares/cares/src/lib/dsa/ares_htable_vpvp.c +194 -0
  657. data/third_party/cares/cares/src/lib/dsa/ares_llist.c +382 -0
  658. data/third_party/cares/cares/src/lib/dsa/ares_slist.c +479 -0
  659. data/third_party/cares/cares/src/lib/dsa/ares_slist.h +207 -0
  660. data/third_party/cares/cares/src/lib/event/ares_event.h +191 -0
  661. data/third_party/cares/cares/src/lib/event/ares_event_configchg.c +743 -0
  662. data/third_party/cares/cares/src/lib/event/ares_event_epoll.c +192 -0
  663. data/third_party/cares/cares/src/lib/event/ares_event_kqueue.c +248 -0
  664. data/third_party/cares/cares/src/lib/event/ares_event_poll.c +140 -0
  665. data/third_party/cares/cares/src/lib/event/ares_event_select.c +159 -0
  666. data/third_party/cares/cares/src/lib/event/ares_event_thread.c +567 -0
  667. data/third_party/cares/cares/src/lib/event/ares_event_wake_pipe.c +166 -0
  668. data/third_party/cares/cares/src/lib/event/ares_event_win32.c +978 -0
  669. data/third_party/cares/cares/src/lib/event/ares_event_win32.h +161 -0
  670. data/third_party/cares/cares/src/lib/include/ares_array.h +276 -0
  671. data/third_party/cares/cares/src/lib/include/ares_buf.h +732 -0
  672. data/third_party/cares/cares/src/lib/include/ares_htable_asvp.h +130 -0
  673. data/third_party/cares/cares/src/lib/include/ares_htable_dict.h +123 -0
  674. data/third_party/cares/cares/src/lib/include/ares_htable_strvp.h +130 -0
  675. data/third_party/cares/cares/src/lib/include/ares_htable_szvp.h +118 -0
  676. data/third_party/cares/cares/src/lib/include/ares_htable_vpstr.h +111 -0
  677. data/third_party/cares/cares/src/lib/include/ares_htable_vpvp.h +128 -0
  678. data/third_party/cares/cares/src/lib/include/ares_llist.h +239 -0
  679. data/third_party/cares/cares/src/lib/include/ares_mem.h +38 -0
  680. data/third_party/cares/cares/src/lib/include/ares_str.h +244 -0
  681. data/third_party/cares/cares/src/lib/inet_net_pton.c +202 -157
  682. data/third_party/cares/cares/src/lib/inet_ntop.c +87 -69
  683. data/third_party/cares/cares/src/lib/legacy/ares_create_query.c +78 -0
  684. data/third_party/cares/cares/src/lib/legacy/ares_expand_name.c +99 -0
  685. data/third_party/cares/cares/src/lib/legacy/ares_expand_string.c +107 -0
  686. data/third_party/cares/cares/src/lib/legacy/ares_fds.c +80 -0
  687. data/third_party/cares/cares/src/lib/legacy/ares_getsock.c +85 -0
  688. data/third_party/cares/cares/src/lib/legacy/ares_parse_a_reply.c +107 -0
  689. data/third_party/cares/cares/src/lib/legacy/ares_parse_aaaa_reply.c +109 -0
  690. data/third_party/cares/cares/src/lib/legacy/ares_parse_caa_reply.c +137 -0
  691. data/third_party/cares/cares/src/lib/legacy/ares_parse_mx_reply.c +110 -0
  692. data/third_party/cares/cares/src/lib/legacy/ares_parse_naptr_reply.c +132 -0
  693. data/third_party/cares/cares/src/lib/legacy/ares_parse_ns_reply.c +154 -0
  694. data/third_party/cares/cares/src/lib/legacy/ares_parse_ptr_reply.c +213 -0
  695. data/third_party/cares/cares/src/lib/legacy/ares_parse_soa_reply.c +115 -0
  696. data/third_party/cares/cares/src/lib/legacy/ares_parse_srv_reply.c +114 -0
  697. data/third_party/cares/cares/src/lib/legacy/ares_parse_txt_reply.c +144 -0
  698. data/third_party/cares/cares/src/lib/legacy/ares_parse_uri_reply.c +113 -0
  699. data/third_party/cares/cares/src/lib/record/ares_dns_mapping.c +982 -0
  700. data/third_party/cares/cares/src/lib/record/ares_dns_multistring.c +307 -0
  701. data/third_party/cares/cares/src/lib/record/ares_dns_multistring.h +72 -0
  702. data/third_party/cares/cares/src/lib/record/ares_dns_name.c +673 -0
  703. data/third_party/cares/cares/src/lib/record/ares_dns_parse.c +1329 -0
  704. data/third_party/cares/cares/src/lib/record/ares_dns_private.h +273 -0
  705. data/third_party/cares/cares/src/lib/record/ares_dns_record.c +1661 -0
  706. data/third_party/cares/cares/src/lib/record/ares_dns_write.c +1229 -0
  707. data/third_party/cares/cares/src/lib/str/ares_buf.c +1498 -0
  708. data/third_party/cares/cares/src/lib/str/ares_str.c +508 -0
  709. data/third_party/cares/cares/src/lib/str/ares_strsplit.c +90 -0
  710. data/third_party/cares/cares/src/lib/str/ares_strsplit.h +51 -0
  711. data/third_party/cares/cares/src/lib/thirdparty/apple/dnsinfo.h +122 -0
  712. data/third_party/cares/cares/src/lib/util/ares_iface_ips.c +628 -0
  713. data/third_party/cares/cares/src/lib/util/ares_iface_ips.h +139 -0
  714. data/third_party/cares/cares/src/lib/util/ares_math.c +158 -0
  715. data/third_party/cares/cares/src/lib/util/ares_math.h +45 -0
  716. data/third_party/cares/cares/src/lib/util/ares_rand.c +389 -0
  717. data/third_party/cares/cares/src/lib/util/ares_rand.h +36 -0
  718. data/third_party/cares/cares/src/lib/util/ares_threads.c +614 -0
  719. data/third_party/cares/cares/src/lib/util/ares_threads.h +60 -0
  720. data/third_party/cares/cares/src/lib/util/ares_time.h +48 -0
  721. data/third_party/cares/cares/src/lib/util/ares_timeval.c +95 -0
  722. data/third_party/cares/cares/src/lib/util/ares_uri.c +1626 -0
  723. data/third_party/cares/cares/src/lib/util/ares_uri.h +252 -0
  724. data/third_party/cares/cares/src/lib/windows_port.c +16 -9
  725. metadata +192 -68
  726. data/src/core/lib/event_engine/forkable.cc +0 -105
  727. data/src/core/lib/event_engine/forkable.h +0 -67
  728. data/src/core/lib/iomgr/python_util.h +0 -46
  729. data/src/core/util/ring_buffer.h +0 -122
  730. data/third_party/abseil-cpp/absl/base/internal/inline_variable.h +0 -108
  731. data/third_party/abseil-cpp/absl/base/internal/invoke.h +0 -241
  732. data/third_party/abseil-cpp/absl/log/log_entry.cc +0 -41
  733. data/third_party/abseil-cpp/absl/random/internal/pool_urbg.h +0 -131
  734. data/third_party/abseil-cpp/absl/types/bad_optional_access.cc +0 -66
  735. data/third_party/abseil-cpp/absl/types/bad_optional_access.h +0 -78
  736. data/third_party/abseil-cpp/absl/types/bad_variant_access.cc +0 -82
  737. data/third_party/abseil-cpp/absl/types/bad_variant_access.h +0 -82
  738. data/third_party/abseil-cpp/absl/types/internal/optional.h +0 -352
  739. data/third_party/abseil-cpp/absl/types/internal/variant.h +0 -1622
  740. data/third_party/cares/cares/include/ares_rules.h +0 -125
  741. data/third_party/cares/cares/src/lib/ares__addrinfo2hostent.c +0 -266
  742. data/third_party/cares/cares/src/lib/ares__addrinfo_localhost.c +0 -240
  743. data/third_party/cares/cares/src/lib/ares__close_sockets.c +0 -61
  744. data/third_party/cares/cares/src/lib/ares__get_hostent.c +0 -260
  745. data/third_party/cares/cares/src/lib/ares__parse_into_addrinfo.c +0 -229
  746. data/third_party/cares/cares/src/lib/ares__read_line.c +0 -73
  747. data/third_party/cares/cares/src/lib/ares__readaddrinfo.c +0 -258
  748. data/third_party/cares/cares/src/lib/ares__sortaddrinfo.c +0 -507
  749. data/third_party/cares/cares/src/lib/ares__timeval.c +0 -111
  750. data/third_party/cares/cares/src/lib/ares_create_query.c +0 -197
  751. data/third_party/cares/cares/src/lib/ares_expand_name.c +0 -311
  752. data/third_party/cares/cares/src/lib/ares_expand_string.c +0 -67
  753. data/third_party/cares/cares/src/lib/ares_fds.c +0 -59
  754. data/third_party/cares/cares/src/lib/ares_getsock.c +0 -66
  755. data/third_party/cares/cares/src/lib/ares_iphlpapi.h +0 -221
  756. data/third_party/cares/cares/src/lib/ares_llist.c +0 -63
  757. data/third_party/cares/cares/src/lib/ares_llist.h +0 -39
  758. data/third_party/cares/cares/src/lib/ares_mkquery.c +0 -24
  759. data/third_party/cares/cares/src/lib/ares_nowarn.c +0 -260
  760. data/third_party/cares/cares/src/lib/ares_nowarn.h +0 -61
  761. data/third_party/cares/cares/src/lib/ares_parse_a_reply.c +0 -90
  762. data/third_party/cares/cares/src/lib/ares_parse_aaaa_reply.c +0 -92
  763. data/third_party/cares/cares/src/lib/ares_parse_caa_reply.c +0 -199
  764. data/third_party/cares/cares/src/lib/ares_parse_mx_reply.c +0 -164
  765. data/third_party/cares/cares/src/lib/ares_parse_naptr_reply.c +0 -183
  766. data/third_party/cares/cares/src/lib/ares_parse_ns_reply.c +0 -177
  767. data/third_party/cares/cares/src/lib/ares_parse_ptr_reply.c +0 -228
  768. data/third_party/cares/cares/src/lib/ares_parse_soa_reply.c +0 -179
  769. data/third_party/cares/cares/src/lib/ares_parse_srv_reply.c +0 -168
  770. data/third_party/cares/cares/src/lib/ares_parse_txt_reply.c +0 -214
  771. data/third_party/cares/cares/src/lib/ares_parse_uri_reply.c +0 -184
  772. data/third_party/cares/cares/src/lib/ares_platform.c +0 -11042
  773. data/third_party/cares/cares/src/lib/ares_platform.h +0 -43
  774. data/third_party/cares/cares/src/lib/ares_rand.c +0 -279
  775. data/third_party/cares/cares/src/lib/ares_strcasecmp.c +0 -66
  776. data/third_party/cares/cares/src/lib/ares_strcasecmp.h +0 -30
  777. data/third_party/cares/cares/src/lib/ares_strdup.c +0 -42
  778. data/third_party/cares/cares/src/lib/ares_strdup.h +0 -24
  779. data/third_party/cares/cares/src/lib/ares_strsplit.c +0 -94
  780. data/third_party/cares/cares/src/lib/ares_strsplit.h +0 -42
  781. data/third_party/cares/cares/src/lib/ares_writev.c +0 -79
  782. data/third_party/cares/cares/src/lib/ares_writev.h +0 -36
  783. data/third_party/cares/cares/src/lib/bitncmp.c +0 -59
  784. data/third_party/cares/cares/src/lib/bitncmp.h +0 -26
  785. data/third_party/cares/cares/src/lib/setup_once.h +0 -554
  786. data/third_party/cares/cares/src/tools/ares_getopt.h +0 -53
@@ -0,0 +1,1233 @@
1
+ //
2
+ //
3
+ // Copyright 2024 gRPC authors.
4
+ //
5
+ // Licensed under the Apache License, Version 2.0 (the "License");
6
+ // you may not use this file except in compliance with the License.
7
+ // You may obtain a copy of the License at
8
+ //
9
+ // http://www.apache.org/licenses/LICENSE-2.0
10
+ //
11
+ // Unless required by applicable law or agreed to in writing, software
12
+ // distributed under the License is distributed on an "AS IS" BASIS,
13
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ // See the License for the specific language governing permissions and
15
+ // limitations under the License.
16
+ //
17
+ //
18
+
19
+ #include "src/core/ext/transport/chttp2/transport/http2_client_transport.h"
20
+
21
+ #include <grpc/event_engine/event_engine.h>
22
+ #include <grpc/support/port_platform.h>
23
+
24
+ #include <cstdint>
25
+ #include <memory>
26
+ #include <optional>
27
+ #include <utility>
28
+
29
+ #include "absl/log/check.h"
30
+ #include "absl/log/log.h"
31
+ #include "absl/status/status.h"
32
+ #include "src/core/call/call_spine.h"
33
+ #include "src/core/call/message.h"
34
+ #include "src/core/call/metadata_batch.h"
35
+ #include "src/core/ext/transport/chttp2/transport/frame.h"
36
+ #include "src/core/ext/transport/chttp2/transport/header_assembler.h"
37
+ #include "src/core/ext/transport/chttp2/transport/http2_settings.h"
38
+ #include "src/core/ext/transport/chttp2/transport/http2_settings_manager.h"
39
+ #include "src/core/ext/transport/chttp2/transport/http2_status.h"
40
+ #include "src/core/ext/transport/chttp2/transport/internal_channel_arg_names.h"
41
+ #include "src/core/ext/transport/chttp2/transport/message_assembler.h"
42
+ #include "src/core/ext/transport/chttp2/transport/transport_common.h"
43
+ #include "src/core/lib/channel/channel_args.h"
44
+ #include "src/core/lib/debug/trace.h"
45
+ #include "src/core/lib/promise/for_each.h"
46
+ #include "src/core/lib/promise/loop.h"
47
+ #include "src/core/lib/promise/map.h"
48
+ #include "src/core/lib/promise/match_promise.h"
49
+ #include "src/core/lib/promise/party.h"
50
+ #include "src/core/lib/promise/poll.h"
51
+ #include "src/core/lib/promise/promise.h"
52
+ #include "src/core/lib/promise/try_seq.h"
53
+ #include "src/core/lib/resource_quota/arena.h"
54
+ #include "src/core/lib/slice/slice.h"
55
+ #include "src/core/lib/slice/slice_buffer.h"
56
+ #include "src/core/lib/transport/promise_endpoint.h"
57
+ #include "src/core/lib/transport/transport.h"
58
+ #include "src/core/util/ref_counted_ptr.h"
59
+ #include "src/core/util/sync.h"
60
+
61
+ namespace grpc_core {
62
+ namespace http2 {
63
+
64
+ using grpc_event_engine::experimental::EventEngine;
65
+
66
+ // Experimental : This is just the initial skeleton of class
67
+ // and it is functions. The code will be written iteratively.
68
+ // Do not use or edit any of these functions unless you are
69
+ // familiar with the PH2 project (Moving chttp2 to promises.)
70
+ // TODO(tjagtap) : [PH2][P3] : Delete this comment when http2
71
+ // rollout begins
72
+
73
+ void Http2ClientTransport::PerformOp(grpc_transport_op* op) {
74
+ // Notes : Refer : src/core/ext/transport/chaotic_good/client_transport.cc
75
+ // Functions : StartConnectivityWatch, StopConnectivityWatch, PerformOp
76
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport PerformOp Begin";
77
+ bool did_stuff = false;
78
+ if (op->start_connectivity_watch != nullptr) {
79
+ StartConnectivityWatch(op->start_connectivity_watch_state,
80
+ std::move(op->start_connectivity_watch));
81
+ did_stuff = true;
82
+ }
83
+ if (op->stop_connectivity_watch != nullptr) {
84
+ StopConnectivityWatch(op->stop_connectivity_watch);
85
+ did_stuff = true;
86
+ }
87
+ CHECK(!op->set_accept_stream) << "Set_accept_stream not supported on clients";
88
+ DCHECK(did_stuff) << "Unimplemented transport perform op ";
89
+
90
+ ExecCtx::Run(DEBUG_LOCATION, op->on_consumed, absl::OkStatus());
91
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport PerformOp End";
92
+ // TODO(tjagtap) : [PH2][P2] :
93
+ // Refer src/core/ext/transport/chttp2/transport/chttp2_transport.cc
94
+ // perform_transport_op_locked
95
+ // Maybe more operations needed to be implemented.
96
+ // TODO(tjagtap) : [PH2][P2] : Consider either not using a transport level
97
+ // lock, or making this run on the Transport party - whatever is better.
98
+ }
99
+
100
+ void Http2ClientTransport::StartConnectivityWatch(
101
+ grpc_connectivity_state state,
102
+ OrphanablePtr<ConnectivityStateWatcherInterface> watcher) {
103
+ MutexLock lock(&transport_mutex_);
104
+ state_tracker_.AddWatcher(state, std::move(watcher));
105
+ }
106
+
107
+ void Http2ClientTransport::StopConnectivityWatch(
108
+ ConnectivityStateWatcherInterface* watcher) {
109
+ MutexLock lock(&transport_mutex_);
110
+ state_tracker_.RemoveWatcher(watcher);
111
+ }
112
+
113
+ void Http2ClientTransport::Orphan() {
114
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport Orphan Begin";
115
+ // Accessing general_party here is not advisable. It may so happen that
116
+ // the party is already freed/may free up any time. The only guarantee here
117
+ // is that the transport is still valid.
118
+ MaybeSpawnCloseTransport(Http2Status::AbslConnectionError(
119
+ absl::StatusCode::kUnavailable, "Orphaned"));
120
+ Unref();
121
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport Orphan End";
122
+ }
123
+
124
+ void Http2ClientTransport::AbortWithError() {
125
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport AbortWithError Begin";
126
+ // TODO(tjagtap) : [PH2][P2] : Implement this function.
127
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport AbortWithError End";
128
+ }
129
+
130
+ ///////////////////////////////////////////////////////////////////////////////
131
+ // Processing each type of frame
132
+
133
+ Http2Status Http2ClientTransport::ProcessHttp2DataFrame(Http2DataFrame frame) {
134
+ // https://www.rfc-editor.org/rfc/rfc9113.html#name-data
135
+ GRPC_HTTP2_CLIENT_DLOG << "Http2Transport ProcessHttp2DataFrame { stream_id="
136
+ << frame.stream_id
137
+ << ", end_stream=" << frame.end_stream
138
+ << ", payload=" << frame.payload.JoinIntoString()
139
+ << "}";
140
+
141
+ // TODO(akshitpatel) : [PH2][P3] : Investigate if we should do this even if
142
+ // the function returns a non-ok status?
143
+ ping_manager_.ReceivedDataFrame();
144
+
145
+ // Lookup stream
146
+ GRPC_HTTP2_CLIENT_DLOG << "Http2Transport ProcessHttp2DataFrame LookupStream";
147
+ RefCountedPtr<Stream> stream = LookupStream(frame.stream_id);
148
+ if (stream == nullptr) {
149
+ // TODO(tjagtap) : [PH2][P2] : Implement the correct behaviour later.
150
+ // RFC9113 : If a DATA frame is received whose stream is not in the "open"
151
+ // or "half-closed (local)" state, the recipient MUST respond with a stream
152
+ // error (Section 5.4.2) of type STREAM_CLOSED.
153
+ GRPC_HTTP2_CLIENT_DLOG
154
+ << "Http2Transport ProcessHttp2DataFrame { stream_id="
155
+ << frame.stream_id << "} Lookup Failed";
156
+ return Http2Status::Ok();
157
+ }
158
+
159
+ if (stream->GetStreamState() == HttpStreamState::kHalfClosedRemote) {
160
+ return Http2Status::Http2StreamError(
161
+ Http2ErrorCode::kStreamClosed,
162
+ std::string(RFC9113::kHalfClosedRemoteState));
163
+ }
164
+
165
+ // Add frame to assembler
166
+ GRPC_HTTP2_CLIENT_DLOG
167
+ << "Http2Transport ProcessHttp2DataFrame AppendNewDataFrame";
168
+ GrpcMessageAssembler& assembler = stream->assembler;
169
+ Http2Status status =
170
+ assembler.AppendNewDataFrame(frame.payload, frame.end_stream);
171
+ if (!status.IsOk()) {
172
+ GRPC_HTTP2_CLIENT_DLOG
173
+ << "Http2Transport ProcessHttp2DataFrame AppendNewDataFrame Failed";
174
+ return status;
175
+ }
176
+
177
+ // Pass the messages up the stack if it is ready.
178
+ while (true) {
179
+ GRPC_HTTP2_CLIENT_DLOG
180
+ << "Http2Transport ProcessHttp2DataFrame ExtractMessage";
181
+ ValueOrHttp2Status<MessageHandle> result = assembler.ExtractMessage();
182
+ if (!result.IsOk()) {
183
+ GRPC_HTTP2_CLIENT_DLOG
184
+ << "Http2Transport ProcessHttp2DataFrame ExtractMessage Failed";
185
+ return ValueOrHttp2Status<MessageHandle>::TakeStatus(std::move(result));
186
+ }
187
+ MessageHandle message = TakeValue(std::move(result));
188
+ if (message != nullptr) {
189
+ GRPC_HTTP2_CLIENT_DLOG
190
+ << "Http2Transport ProcessHttp2DataFrame SpawnPushMessage "
191
+ << message->DebugString();
192
+ stream->call.SpawnPushMessage(std::move(message));
193
+ continue;
194
+ }
195
+ GRPC_HTTP2_CLIENT_DLOG
196
+ << "Http2Transport ProcessHttp2DataFrame While Break";
197
+ break;
198
+ }
199
+
200
+ // TODO(tjagtap) : [PH2][P2] : List of Tests:
201
+ // 1. Data frame with unknown stream ID
202
+ // 2. Data frame with only half a message and then end stream
203
+ // 3. One data frame with a full message
204
+ // 4. Three data frames with one full message
205
+ // 5. One data frame with three full messages. All messages should be pushed.
206
+ // Will need to mock the call_handler object and test this along with the
207
+ // Header reading code. Because we need a stream in place for the lookup to
208
+ // work.
209
+ return Http2Status::Ok();
210
+ }
211
+
212
+ Http2Status Http2ClientTransport::ProcessHttp2HeaderFrame(
213
+ Http2HeaderFrame frame) {
214
+ // https://www.rfc-editor.org/rfc/rfc9113.html#name-headers
215
+ GRPC_HTTP2_CLIENT_DLOG
216
+ << "Http2Transport ProcessHttp2HeaderFrame Promise { stream_id="
217
+ << frame.stream_id << ", end_headers=" << frame.end_headers
218
+ << ", end_stream=" << frame.end_stream
219
+ << ", payload=" << frame.payload.JoinIntoString() << " }";
220
+ ping_manager_.ReceivedDataFrame();
221
+
222
+ RefCountedPtr<Http2ClientTransport::Stream> stream =
223
+ LookupStream(frame.stream_id);
224
+ if (stream == nullptr) {
225
+ // TODO(tjagtap) : [PH2][P3] : Implement this.
226
+ // RFC9113 : The identifier of a newly established stream MUST be
227
+ // numerically greater than all streams that the initiating endpoint has
228
+ // opened or reserved. This governs streams that are opened using a HEADERS
229
+ // frame and streams that are reserved using PUSH_PROMISE. An endpoint that
230
+ // receives an unexpected stream identifier MUST respond with a connection
231
+ // error (Section 5.4.1) of type PROTOCOL_ERROR.
232
+ GRPC_HTTP2_CLIENT_DLOG
233
+ << "Http2Transport ProcessHttp2HeaderFrame Promise { stream_id="
234
+ << frame.stream_id << "} Lookup Failed";
235
+ return Http2Status::Ok();
236
+ }
237
+ if (stream->GetStreamState() == HttpStreamState::kHalfClosedRemote) {
238
+ return Http2Status::Http2StreamError(
239
+ Http2ErrorCode::kStreamClosed,
240
+ std::string(RFC9113::kHalfClosedRemoteState));
241
+ }
242
+
243
+ incoming_header_in_progress_ = !frame.end_headers;
244
+ incoming_header_stream_id_ = frame.stream_id;
245
+ incoming_header_end_stream_ = frame.end_stream;
246
+ if ((incoming_header_end_stream_ && stream->did_push_trailing_metadata) ||
247
+ (!incoming_header_end_stream_ && stream->did_push_initial_metadata)) {
248
+ return Http2Status::Http2StreamError(
249
+ Http2ErrorCode::kInternalError,
250
+ "gRPC Error : A gRPC server can send upto 1 initial metadata followed "
251
+ "by upto 1 trailing metadata");
252
+ }
253
+
254
+ HeaderAssembler& assembler = stream->header_assembler;
255
+ Http2Status append_result = assembler.AppendHeaderFrame(std::move(frame));
256
+ if (append_result.IsOk()) {
257
+ return ProcessMetadata(stream->stream_id, assembler, stream->call,
258
+ stream->did_push_initial_metadata,
259
+ stream->did_push_trailing_metadata);
260
+ }
261
+ return append_result;
262
+ }
263
+
264
+ Http2Status Http2ClientTransport::ProcessMetadata(
265
+ uint32_t stream_id, HeaderAssembler& assembler, CallHandler& call,
266
+ bool& did_push_initial_metadata, bool& did_push_trailing_metadata) {
267
+ GRPC_HTTP2_CLIENT_DLOG << "Http2Transport ProcessMetadata";
268
+ if (assembler.IsReady()) {
269
+ ValueOrHttp2Status<Arena::PoolPtr<grpc_metadata_batch>> read_result =
270
+ assembler.ReadMetadata(parser_, !incoming_header_end_stream_,
271
+ /*is_client=*/true,
272
+ /*max_header_list_size_soft_limit=*/
273
+ max_header_list_size_soft_limit_,
274
+ /*max_header_list_size_hard_limit=*/
275
+ settings_.acked().max_header_list_size());
276
+ if (read_result.IsOk()) {
277
+ Arena::PoolPtr<grpc_metadata_batch> metadata =
278
+ TakeValue(std::move(read_result));
279
+ if (incoming_header_end_stream_) {
280
+ // TODO(tjagtap) : [PH2][P1] : Is this the right way to differentiate
281
+ // between initial and trailing metadata?
282
+ GRPC_HTTP2_CLIENT_DLOG
283
+ << "Http2Transport ProcessMetadata SpawnPushServerTrailingMetadata";
284
+ did_push_trailing_metadata = true;
285
+ call.SpawnPushServerTrailingMetadata(std::move(metadata));
286
+ CloseStream(stream_id, absl::OkStatus(),
287
+ CloseStreamArgs{
288
+ /*close_reads=*/true,
289
+ /*close_writes=*/true,
290
+ /*send_rst_stream=*/false,
291
+ /*should_not_push_trailers=*/true,
292
+ });
293
+
294
+ } else {
295
+ GRPC_HTTP2_CLIENT_DLOG
296
+ << "Http2Transport ProcessMetadata SpawnPushServerInitialMetadata";
297
+ did_push_initial_metadata = true;
298
+ call.SpawnPushServerInitialMetadata(std::move(metadata));
299
+ }
300
+ return Http2Status::Ok();
301
+ }
302
+ GRPC_HTTP2_CLIENT_DLOG << "Http2Transport ProcessMetadata Failed";
303
+ return ValueOrHttp2Status<Arena::PoolPtr<grpc_metadata_batch>>::TakeStatus(
304
+ std::move(read_result));
305
+ }
306
+ return Http2Status::Ok();
307
+ }
308
+
309
+ Http2Status Http2ClientTransport::ProcessHttp2RstStreamFrame(
310
+ Http2RstStreamFrame frame) {
311
+ // https://www.rfc-editor.org/rfc/rfc9113.html#name-rst_stream
312
+ GRPC_HTTP2_CLIENT_DLOG
313
+ << "Http2Transport ProcessHttp2RstStreamFrame { stream_id="
314
+ << frame.stream_id << ", error_code=" << frame.error_code << " }";
315
+ Http2ErrorCode error_code =
316
+ Http2ErrorCodeFromRstFrameErrorCode(frame.error_code);
317
+ CloseStream(frame.stream_id,
318
+ absl::Status((ErrorCodeToAbslStatusCode(error_code)),
319
+ "Reset stream frame received."),
320
+ CloseStreamArgs{
321
+ /*close_reads=*/true,
322
+ /*close_writes=*/true,
323
+ /*send_rst_stream=*/false,
324
+ /*push_trailing_metadata=*/true,
325
+ });
326
+ // In case of stream error, we do not want the Read Loop to be broken. Hence
327
+ // returning an ok status.
328
+ return Http2Status::Ok();
329
+ }
330
+
331
+ Http2Status Http2ClientTransport::ProcessHttp2SettingsFrame(
332
+ Http2SettingsFrame frame) {
333
+ // https://www.rfc-editor.org/rfc/rfc9113.html#name-settings
334
+
335
+ GRPC_HTTP2_CLIENT_DLOG << "Http2Transport ProcessHttp2SettingsFrame { ack="
336
+ << frame.ack
337
+ << ", settings length=" << frame.settings.size()
338
+ << "}";
339
+
340
+ // The connector code needs us to run this
341
+ if (on_receive_settings_ != nullptr) {
342
+ ExecCtx::Run(DEBUG_LOCATION, on_receive_settings_, absl::OkStatus());
343
+ on_receive_settings_ = nullptr;
344
+ }
345
+
346
+ if (!frame.ack) {
347
+ // Check if the received settings have legal values
348
+ Http2Status status = ValidateSettingsValues(frame.settings);
349
+ if (!status.IsOk()) {
350
+ return status;
351
+ }
352
+ // TODO(tjagtap) : [PH2][P1]
353
+ // Apply the new settings
354
+ // Quickly send the ACK to the peer once the settings are applied
355
+ } else {
356
+ // TODO(tjagtap) : [PH2][P1]
357
+ // Stop the setting timeout promise
358
+ // Update the ACKed setting data structure
359
+ }
360
+
361
+ return Http2Status::Ok();
362
+ }
363
+
364
+ auto Http2ClientTransport::ProcessHttp2PingFrame(Http2PingFrame frame) {
365
+ // https://www.rfc-editor.org/rfc/rfc9113.html#name-ping
366
+ GRPC_HTTP2_CLIENT_DLOG << "Http2Transport ProcessHttp2PingFrame { ack="
367
+ << frame.ack << ", opaque=" << frame.opaque << " }";
368
+ return AssertResultType<Http2Status>(If(
369
+ frame.ack,
370
+ [self = RefAsSubclass<Http2ClientTransport>(), opaque = frame.opaque]() {
371
+ // Received a ping ack.
372
+ return self->AckPing(opaque);
373
+ },
374
+ [self = RefAsSubclass<Http2ClientTransport>(), opaque = frame.opaque]() {
375
+ // TODO(akshitpatel) : [PH2][P2] : Have a counter to track number of
376
+ // pending induced frames (Ping/Settings Ack). This is to ensure that
377
+ // if write is taking a long time, we can stop reads and prioritize
378
+ // writes.
379
+ // RFC9113: PING responses SHOULD be given higher priority than any
380
+ // other frame.
381
+ self->pending_ping_acks_.push_back(opaque);
382
+ // TODO(akshitpatel) : [PH2][P2] : This is done assuming that the other
383
+ // ProcessFrame promises may return stream or connection failures. If
384
+ // this does not turn out to be true, consider returning absl::Status
385
+ // here.
386
+ return Map(self->TriggerWriteCycle(), [](absl::Status status) {
387
+ return (status.ok())
388
+ ? Http2Status::Ok()
389
+ : Http2Status::AbslConnectionError(
390
+ status.code(), std::string(status.message()));
391
+ });
392
+ }));
393
+ }
394
+
395
+ Http2Status Http2ClientTransport::ProcessHttp2GoawayFrame(
396
+ Http2GoawayFrame frame) {
397
+ // https://www.rfc-editor.org/rfc/rfc9113.html#name-goaway
398
+ GRPC_HTTP2_CLIENT_DLOG << "Http2Transport ProcessHttp2GoawayFrame Factory";
399
+ // TODO(tjagtap) : [PH2][P2] : Implement this.
400
+ GRPC_HTTP2_CLIENT_DLOG << "Http2Transport ProcessHttp2GoawayFrame Promise { "
401
+ "last_stream_id="
402
+ << frame.last_stream_id
403
+ << ", error_code=" << frame.error_code
404
+ << ", debug_data=" << frame.debug_data.as_string_view()
405
+ << "}";
406
+ return Http2Status::Ok();
407
+ }
408
+
409
+ Http2Status Http2ClientTransport::ProcessHttp2WindowUpdateFrame(
410
+ Http2WindowUpdateFrame frame) {
411
+ // https://www.rfc-editor.org/rfc/rfc9113.html#name-window_update
412
+ GRPC_HTTP2_CLIENT_DLOG
413
+ << "Http2Transport ProcessHttp2WindowUpdateFrame Factory";
414
+ // TODO(tjagtap) : [PH2][P2] : Implement this.
415
+ GRPC_HTTP2_CLIENT_DLOG
416
+ << "Http2Transport ProcessHttp2WindowUpdateFrame Promise { "
417
+ " stream_id="
418
+ << frame.stream_id << ", increment=" << frame.increment << "}";
419
+ return Http2Status::Ok();
420
+ }
421
+
422
+ Http2Status Http2ClientTransport::ProcessHttp2ContinuationFrame(
423
+ Http2ContinuationFrame frame) {
424
+ // https://www.rfc-editor.org/rfc/rfc9113.html#name-continuation
425
+ GRPC_HTTP2_CLIENT_DLOG
426
+ << "Http2Transport ProcessHttp2ContinuationFrame Promise { "
427
+ "stream_id="
428
+ << frame.stream_id << ", end_headers=" << frame.end_headers
429
+ << ", payload=" << frame.payload.JoinIntoString() << " }";
430
+ incoming_header_in_progress_ = !frame.end_headers;
431
+ RefCountedPtr<Stream> stream = LookupStream(frame.stream_id);
432
+ if (stream == nullptr) {
433
+ // TODO(tjagtap) : [PH2][P3] : Implement this.
434
+ // RFC9113 : The identifier of a newly established stream MUST be
435
+ // numerically greater than all streams that the initiating endpoint has
436
+ // opened or reserved. This governs streams that are opened using a HEADERS
437
+ // frame and streams that are reserved using PUSH_PROMISE. An endpoint that
438
+ // receives an unexpected stream identifier MUST respond with a connection
439
+ // error (Section 5.4.1) of type PROTOCOL_ERROR.
440
+ return Http2Status::Ok();
441
+ }
442
+ if (stream->GetStreamState() == HttpStreamState::kHalfClosedRemote) {
443
+ return Http2Status::Http2StreamError(
444
+ Http2ErrorCode::kStreamClosed,
445
+ std::string(RFC9113::kHalfClosedRemoteState));
446
+ }
447
+
448
+ HeaderAssembler& assember = stream->header_assembler;
449
+ Http2Status result = assember.AppendContinuationFrame(std::move(frame));
450
+ if (result.IsOk()) {
451
+ return ProcessMetadata(stream->stream_id, assember, stream->call,
452
+ stream->did_push_initial_metadata,
453
+ stream->did_push_trailing_metadata);
454
+ }
455
+ return result;
456
+ }
457
+
458
+ Http2Status Http2ClientTransport::ProcessHttp2SecurityFrame(
459
+ Http2SecurityFrame frame) {
460
+ GRPC_HTTP2_CLIENT_DLOG << "Http2Transport ProcessHttp2SecurityFrame "
461
+ "ProcessHttp2SecurityFrame { payload="
462
+ << frame.payload.JoinIntoString() << " }";
463
+ if ((settings_.acked().allow_security_frame() ||
464
+ settings_.local().allow_security_frame()) &&
465
+ settings_.peer().allow_security_frame()) {
466
+ // TODO(tjagtap) : [PH2][P4] : Evaluate when to accept the frame and when to
467
+ // reject it. Compare it with the requirement and with CHTTP2.
468
+ // TODO(tjagtap) : [PH2][P3] : Add handling of Security frame
469
+ // Just the frame.payload needs to be passed to the endpoint_ object.
470
+ // Refer usage of TransportFramingEndpointExtension.
471
+ }
472
+ // Ignore the Security frame if it is not expected.
473
+ return Http2Status::Ok();
474
+ }
475
+
476
+ auto Http2ClientTransport::ProcessOneFrame(Http2Frame frame) {
477
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport ProcessOneFrame Factory";
478
+ return AssertResultType<Http2Status>(MatchPromise(
479
+ std::move(frame),
480
+ [self = RefAsSubclass<Http2ClientTransport>()](Http2DataFrame frame) {
481
+ return self->ProcessHttp2DataFrame(std::move(frame));
482
+ },
483
+ [self = RefAsSubclass<Http2ClientTransport>()](Http2HeaderFrame frame) {
484
+ return self->ProcessHttp2HeaderFrame(std::move(frame));
485
+ },
486
+ [self =
487
+ RefAsSubclass<Http2ClientTransport>()](Http2RstStreamFrame frame) {
488
+ return self->ProcessHttp2RstStreamFrame(frame);
489
+ },
490
+ [self = RefAsSubclass<Http2ClientTransport>()](Http2SettingsFrame frame) {
491
+ return self->ProcessHttp2SettingsFrame(std::move(frame));
492
+ },
493
+ [self = RefAsSubclass<Http2ClientTransport>()](Http2PingFrame frame) {
494
+ return self->ProcessHttp2PingFrame(frame);
495
+ },
496
+ [self = RefAsSubclass<Http2ClientTransport>()](Http2GoawayFrame frame) {
497
+ return self->ProcessHttp2GoawayFrame(std::move(frame));
498
+ },
499
+ [self = RefAsSubclass<Http2ClientTransport>()](
500
+ Http2WindowUpdateFrame frame) {
501
+ return self->ProcessHttp2WindowUpdateFrame(frame);
502
+ },
503
+ [self = RefAsSubclass<Http2ClientTransport>()](
504
+ Http2ContinuationFrame frame) {
505
+ return self->ProcessHttp2ContinuationFrame(std::move(frame));
506
+ },
507
+ [self = RefAsSubclass<Http2ClientTransport>()](Http2SecurityFrame frame) {
508
+ return self->ProcessHttp2SecurityFrame(std::move(frame));
509
+ },
510
+ [](GRPC_UNUSED Http2UnknownFrame frame) {
511
+ // As per HTTP2 RFC, implementations MUST ignore and discard frames of
512
+ // unknown types.
513
+ return Http2Status::Ok();
514
+ },
515
+ [](GRPC_UNUSED Http2EmptyFrame frame) {
516
+ LOG(DFATAL)
517
+ << "ParseFramePayload should never return a Http2EmptyFrame";
518
+ return Http2Status::Ok();
519
+ }));
520
+ }
521
+
522
+ ///////////////////////////////////////////////////////////////////////////////
523
+ // Read Related Promises and Promise Factories
524
+
525
+ auto Http2ClientTransport::ReadAndProcessOneFrame() {
526
+ GRPC_HTTP2_CLIENT_DLOG
527
+ << "Http2ClientTransport ReadAndProcessOneFrame Factory";
528
+ return AssertResultType<absl::Status>(TrySeq(
529
+ // Fetch the first kFrameHeaderSize bytes of the Frame, these contain
530
+ // the frame header.
531
+ EndpointReadSlice(kFrameHeaderSize),
532
+ // Parse the frame header.
533
+ [](Slice header_bytes) -> Http2FrameHeader {
534
+ GRPC_HTTP2_CLIENT_DLOG
535
+ << "Http2ClientTransport ReadAndProcessOneFrame Parse "
536
+ << header_bytes.as_string_view();
537
+ return Http2FrameHeader::Parse(header_bytes.begin());
538
+ },
539
+ // Validate the incoming frame as per the current state of the transport
540
+ [self = RefAsSubclass<Http2ClientTransport>()](Http2FrameHeader header) {
541
+ Http2Status status = ValidateFrameHeader(
542
+ /*max_frame_size_setting*/ self->settings_.acked().max_frame_size(),
543
+ /*incoming_header_in_progress*/ self->incoming_header_in_progress_,
544
+ /*incoming_header_stream_id*/ self->incoming_header_stream_id_,
545
+ /*current_frame_header*/ header);
546
+
547
+ if (!status.IsOk()) {
548
+ return self->HandleError(std::move(status));
549
+ }
550
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport ReadAndProcessOneFrame "
551
+ "Validated Frame Header:"
552
+ << header.ToString();
553
+ self->current_frame_header_ = header;
554
+ return absl::OkStatus();
555
+ },
556
+ // Read the payload of the frame.
557
+ [self = RefAsSubclass<Http2ClientTransport>()]() {
558
+ GRPC_HTTP2_CLIENT_DLOG
559
+ << "Http2ClientTransport ReadAndProcessOneFrame Read Frame ";
560
+ return AssertResultType<absl::StatusOr<SliceBuffer>>(
561
+ self->EndpointRead(self->current_frame_header_.length));
562
+ },
563
+ // Parse the payload of the frame based on frame type.
564
+ [self = RefAsSubclass<Http2ClientTransport>()](
565
+ SliceBuffer payload) -> absl::StatusOr<Http2Frame> {
566
+ GRPC_HTTP2_CLIENT_DLOG
567
+ << "Http2ClientTransport ReadAndProcessOneFrame ParseFramePayload "
568
+ << payload.JoinIntoString();
569
+ ValueOrHttp2Status<Http2Frame> frame =
570
+ ParseFramePayload(self->current_frame_header_, std::move(payload));
571
+ if (!frame.IsOk()) {
572
+ return self->HandleError(
573
+ ValueOrHttp2Status<Http2Frame>::TakeStatus(std::move(frame)));
574
+ }
575
+ return TakeValue(std::move(frame));
576
+ },
577
+ [self = RefAsSubclass<Http2ClientTransport>()](
578
+ GRPC_UNUSED Http2Frame frame) {
579
+ GRPC_HTTP2_CLIENT_DLOG
580
+ << "Http2ClientTransport ReadAndProcessOneFrame ProcessOneFrame";
581
+ return AssertResultType<absl::Status>(
582
+ Map(self->ProcessOneFrame(std::move(frame)),
583
+ [self](Http2Status status) {
584
+ if (!status.IsOk()) {
585
+ return self->HandleError(std::move(status));
586
+ }
587
+ return absl::OkStatus();
588
+ }));
589
+ }));
590
+ }
591
+
592
+ auto Http2ClientTransport::ReadLoop() {
593
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport ReadLoop Factory";
594
+ return AssertResultType<absl::Status>(
595
+ Loop([self = RefAsSubclass<Http2ClientTransport>()]() {
596
+ return TrySeq(self->ReadAndProcessOneFrame(),
597
+ []() -> LoopCtl<absl::Status> {
598
+ GRPC_HTTP2_CLIENT_DLOG
599
+ << "Http2ClientTransport ReadLoop Continue";
600
+ return Continue();
601
+ });
602
+ }));
603
+ }
604
+
605
+ auto Http2ClientTransport::OnReadLoopEnded() {
606
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport OnReadLoopEnded Factory";
607
+ return
608
+ [self = RefAsSubclass<Http2ClientTransport>()](absl::Status status) {
609
+ GRPC_HTTP2_CLIENT_DLOG
610
+ << "Http2ClientTransport OnReadLoopEnded Promise Status=" << status;
611
+ GRPC_UNUSED absl::Status error =
612
+ self->HandleError(Http2Status::AbslConnectionError(
613
+ status.code(), std::string(status.message())));
614
+ };
615
+ }
616
+
617
+ ///////////////////////////////////////////////////////////////////////////////
618
+ // Write Related Promises and Promise Factories
619
+
620
+ auto Http2ClientTransport::WriteFromQueue() {
621
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport WriteFromQueue Factory";
622
+ return TrySeq(
623
+ outgoing_frames_.NextBatch(128),
624
+ [self = RefAsSubclass<Http2ClientTransport>()](
625
+ std::vector<Http2Frame> frames) {
626
+ SliceBuffer output_buf;
627
+ if (self->is_first_write_) {
628
+ GRPC_HTTP2_CLIENT_DLOG
629
+ << "Http2ClientTransport Write GRPC_CHTTP2_CLIENT_CONNECT_STRING";
630
+ output_buf.Append(Slice(grpc_slice_from_copied_string(
631
+ GRPC_CHTTP2_CLIENT_CONNECT_STRING)));
632
+ self->is_first_write_ = false;
633
+ }
634
+ Serialize(absl::Span<Http2Frame>(frames), output_buf);
635
+ uint64_t buffer_length = output_buf.Length();
636
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport WriteFromQueue Promise";
637
+ return If(
638
+ buffer_length > 0,
639
+ [self, output_buffer = std::move(output_buf)]() mutable {
640
+ self->bytes_sent_in_last_write_ = true;
641
+ return self->endpoint_.Write(std::move(output_buffer),
642
+ PromiseEndpoint::WriteArgs{});
643
+ },
644
+ [] { return absl::OkStatus(); });
645
+ });
646
+ }
647
+
648
+ auto Http2ClientTransport::WriteLoop() {
649
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport WriteLoop Factory";
650
+ return AssertResultType<absl::Status>(
651
+ Loop([self = RefAsSubclass<Http2ClientTransport>()]() {
652
+ // TODO(akshitpatel) : [PH2][P1] : Once a common SliceBuffer is used, we
653
+ // can move bytes_sent_in_last_write_ to be a local variable.
654
+ self->bytes_sent_in_last_write_ = false;
655
+ return TrySeq(
656
+ // TODO(akshitpatel) : [PH2][P1] : WriteFromQueue may write settings
657
+ // acks as well. This will break the call to ResetPingClock as it
658
+ // only needs to be called on writing Data/Header/WindowUpdate
659
+ // frames. Possible fixes: Either WriteFromQueue iterates over all
660
+ // the frames and figures out the types of frames needed (this may
661
+ // anyways be needed to check that we do not send frames for closed
662
+ // streams) or we have flags to indicate the types of frame that are
663
+ // enqueued.
664
+ self->WriteFromQueue(), [self] { return self->MaybeSendPing(); },
665
+ [self] { return self->MaybeSendPingAcks(); },
666
+ [self]() -> LoopCtl<absl::Status> {
667
+ // If any Header/Data/WindowUpdate frame was sent in the last
668
+ // write, reset the ping clock.
669
+ if (self->bytes_sent_in_last_write_) {
670
+ self->ping_manager_.ResetPingClock(/*is_client=*/true);
671
+ }
672
+ GRPC_HTTP2_CLIENT_DLOG
673
+ << "Http2ClientTransport WriteLoop Continue";
674
+ return Continue();
675
+ });
676
+ }));
677
+ }
678
+
679
+ auto Http2ClientTransport::OnWriteLoopEnded() {
680
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport OnWriteLoopEnded Factory";
681
+ return
682
+ [self = RefAsSubclass<Http2ClientTransport>()](absl::Status status) {
683
+ GRPC_HTTP2_CLIENT_DLOG
684
+ << "Http2ClientTransport OnWriteLoopEnded Promise Status="
685
+ << status;
686
+ GRPC_UNUSED absl::Status error =
687
+ self->HandleError(Http2Status::AbslConnectionError(
688
+ status.code(), std::string(status.message())));
689
+ };
690
+ }
691
+
692
+ auto Http2ClientTransport::StreamMultiplexerLoop() {
693
+ GRPC_HTTP2_CLIENT_DLOG
694
+ << "Http2ClientTransport StreamMultiplexerLoop Factory";
695
+ // This loop iterates over all the writable streams and drains them. If
696
+ // there are no writable streams, StreamMultiplexerLoop blocks until there
697
+ // is a writable stream.
698
+ return Loop([self = RefAsSubclass<Http2ClientTransport>()]() mutable {
699
+ // Overview:
700
+ // 1. Get the next writable stream.
701
+ // 2. Dequeue frames from the stream queue based on available transport
702
+ // tokens.
703
+ // 3. If the stream is still writable, enqueue the stream back to the
704
+ // writable stream list.
705
+ // 4. Enqueue the dequeued frames to the MPSC queue.
706
+ return TrySeq(
707
+ self->writable_stream_list_.Next(/*transport_tokens_available*/ true),
708
+ [self](const uint32_t stream_id) mutable
709
+ -> absl::StatusOr<std::vector<Http2Frame>> {
710
+ RefCountedPtr<Stream> stream = self->LookupStream(stream_id);
711
+ if (GPR_UNLIKELY(stream == nullptr)) {
712
+ // Stream was closed before we could dequeue.
713
+ // TODO(akshitpatel) : [PH2][P2] : Race condition. Determine should
714
+ // we have a DCHECK here based on how ResetStream/Aborts are
715
+ // handled.
716
+ return std::vector<Http2Frame>();
717
+ }
718
+
719
+ // TODO(akshitpatel) : [PH2][P3] : Plug transport_tokens when
720
+ // transport flow control is implemented.
721
+ absl::StatusOr<StreamDataQueue<ClientMetadataHandle>::DequeueResult>
722
+ result = stream->DequeueFrames(
723
+ /*transport_tokens*/ std::numeric_limits<uint32_t>::max(),
724
+ self->settings_.peer().max_frame_size(), self->encoder_);
725
+ if (result.ok() && result->is_writable) {
726
+ // Stream is still writable. Enqueue it back to the writable stream
727
+ // list.
728
+ // TODO(akshitpatel) : [PH2][P3] : Plug transport_tokens when
729
+ // transport flow control is implemented.
730
+ absl::Status status = self->writable_stream_list_.Enqueue(
731
+ stream_id, WritableStreams::StreamPriority::kDefault);
732
+
733
+ if (GPR_UNLIKELY(!status.ok())) {
734
+ LOG(ERROR) << "Failed to enqueue stream " << stream_id
735
+ << " with status: " << status;
736
+ // Close transport if we fail to enqueue stream.
737
+ return absl::InternalError("Failed to enqueue stream");
738
+ }
739
+ } else if (GPR_UNLIKELY(!result.ok())) {
740
+ // Close the corresponding stream if we fail to dequeue frames from
741
+ // the stream queue.
742
+ LOG(ERROR) << "Failed to dequeue frames for stream " << stream_id
743
+ << " with status: " << result.status();
744
+ absl::Status status =
745
+ self->HandleError(Http2Status::AbslStreamError(
746
+ absl::StatusCode::kInternal, "Failed to dequeue frames"));
747
+ return std::vector<Http2Frame>();
748
+ }
749
+ GRPC_HTTP2_CLIENT_DLOG
750
+ << "Http2ClientTransport StreamMultiplexerLoop. Dequeued "
751
+ << result->frames.size()
752
+ << " frames for "
753
+ "stream: "
754
+ << stream_id;
755
+ return std::move(result->frames);
756
+ },
757
+ [self](std::vector<Http2Frame> frames) {
758
+ // Enqueue the frames to the MPSC queue.
759
+ return Loop([self, frames = std::move(frames), idx = 0u]() mutable {
760
+ return If(
761
+ idx < frames.size(),
762
+ [self, &frames, &idx]() {
763
+ return Map(
764
+ // Enqueue to the MPSC queue could return pending. This
765
+ // induces backpressure for the sender. Only after writing
766
+ // to the MPSC queue we will loop back to read more
767
+ // streams.
768
+ self->EnqueueOutgoingFrame(std::move(frames[idx++])),
769
+ [](absl::Status status) -> LoopCtl<absl::Status> {
770
+ if (GPR_UNLIKELY(!status.ok())) {
771
+ return status;
772
+ }
773
+ return Continue{};
774
+ });
775
+ },
776
+ []() -> LoopCtl<absl::Status> { return absl::OkStatus(); });
777
+ });
778
+ },
779
+ []() -> LoopCtl<absl::Status> { return Continue{}; });
780
+ });
781
+ }
782
+
783
+ auto Http2ClientTransport::OnStreamMultiplexerLoopEnded() {
784
+ GRPC_HTTP2_CLIENT_DLOG
785
+ << "Http2ClientTransport OnStreamMultiplexerLoopEnded Factory";
786
+ return [self = RefAsSubclass<Http2ClientTransport>()](absl::Status status) {
787
+ GRPC_HTTP2_CLIENT_DLOG
788
+ << "Http2ClientTransport OnStreamMultiplexerLoopEnded Promise Status="
789
+ << status;
790
+ GRPC_UNUSED absl::Status error =
791
+ self->HandleError(Http2Status::AbslConnectionError(
792
+ status.code(), std::string(status.message())));
793
+ };
794
+ }
795
+
796
+ ///////////////////////////////////////////////////////////////////////////////
797
+ // Constructor Destructor
798
+
799
+ Http2ClientTransport::Http2ClientTransport(
800
+ PromiseEndpoint endpoint, GRPC_UNUSED const ChannelArgs& channel_args,
801
+ std::shared_ptr<EventEngine> event_engine,
802
+ grpc_closure* on_receive_settings)
803
+ : endpoint_(std::move(endpoint)),
804
+ outgoing_frames_(kMpscSize),
805
+ stream_id_mutex_(/*Initial Stream Id*/ 1),
806
+ bytes_sent_in_last_write_(false),
807
+ incoming_header_in_progress_(false),
808
+ incoming_header_end_stream_(false),
809
+ is_first_write_(true),
810
+ incoming_header_stream_id_(0),
811
+ on_receive_settings_(on_receive_settings),
812
+ max_header_list_size_soft_limit_(
813
+ GetSoftLimitFromChannelArgs(channel_args)),
814
+ keepalive_time_(std::max(
815
+ Duration::Seconds(10),
816
+ channel_args.GetDurationFromIntMillis(GRPC_ARG_KEEPALIVE_TIME_MS)
817
+ .value_or(Duration::Infinity()))),
818
+ // Keepalive timeout is only passed to the keepalive manager if it is less
819
+ // than the ping timeout. As keepalives use pings for health checks, if
820
+ // keepalive timeout is greater than ping timeout, we would always hit the
821
+ // ping timeout first.
822
+ keepalive_timeout_(std::max(
823
+ Duration::Zero(),
824
+ channel_args.GetDurationFromIntMillis(GRPC_ARG_KEEPALIVE_TIMEOUT_MS)
825
+ .value_or(keepalive_time_ == Duration::Infinity()
826
+ ? Duration::Infinity()
827
+ : (Duration::Seconds(20))))),
828
+ ping_timeout_(std::max(
829
+ Duration::Zero(),
830
+ channel_args.GetDurationFromIntMillis(GRPC_ARG_PING_TIMEOUT_MS)
831
+ .value_or(keepalive_time_ == Duration::Infinity()
832
+ ? Duration::Infinity()
833
+ : Duration::Minutes(1)))),
834
+ ping_manager_(channel_args, PingSystemInterfaceImpl::Make(this),
835
+ event_engine),
836
+ keepalive_manager_(
837
+ KeepAliveInterfaceImpl::Make(this),
838
+ ((keepalive_timeout_ < ping_timeout_) ? keepalive_timeout_
839
+ : Duration::Infinity()),
840
+ keepalive_time_),
841
+ keepalive_permit_without_calls_(false) {
842
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport Constructor Begin";
843
+
844
+ InitLocalSettings(settings_.mutable_local(), /*is_client=*/true);
845
+ ReadSettingsFromChannelArgs(channel_args, settings_.mutable_local(),
846
+ /*is_client=*/true);
847
+
848
+ // Initialize the general party and write party.
849
+ auto general_party_arena = SimpleArenaAllocator(0)->MakeArena();
850
+ general_party_arena->SetContext<EventEngine>(event_engine.get());
851
+ general_party_ = Party::Make(std::move(general_party_arena));
852
+
853
+ general_party_->Spawn("ReadLoop", ReadLoop(), OnReadLoopEnded());
854
+ // TODO(tjagtap) : [PH2][P2] Fix when needed.
855
+ general_party_->Spawn("WriteLoop", WriteLoop(), OnWriteLoopEnded());
856
+ general_party_->Spawn("StreamMultiplexerLoop", StreamMultiplexerLoop(),
857
+ OnStreamMultiplexerLoopEnded());
858
+
859
+ // The keepalive loop is only spawned if the keepalive time is not infinity.
860
+ keepalive_manager_.Spawn(general_party_.get());
861
+
862
+ // TODO(tjagtap) : [PH2][P2] Delete this hack once flow control is done.
863
+ // We are increasing the flow control window so that we can avoid sending
864
+ // WINDOW_UPDATE frames while flow control is under development. Once it is
865
+ // ready we should remove these lines.
866
+ // <DeleteAfterFlowControl>
867
+ Http2ErrorCode code = settings_.mutable_local().Apply(
868
+ Http2Settings::kInitialWindowSizeWireId,
869
+ (Http2Settings::max_initial_window_size() - 1));
870
+ DCHECK(code == Http2ErrorCode::kNoError);
871
+ // </DeleteAfterFlowControl>
872
+
873
+ const int max_hpack_table_size =
874
+ channel_args.GetInt(GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_ENCODER).value_or(-1);
875
+ if (max_hpack_table_size >= 0) {
876
+ encoder_.SetMaxUsableSize(max_hpack_table_size);
877
+ }
878
+
879
+ settings_timeout_ =
880
+ channel_args.GetDurationFromIntMillis(GRPC_ARG_SETTINGS_TIMEOUT)
881
+ .value_or(std::max(keepalive_timeout_ * 2, Duration::Minutes(1)));
882
+
883
+ std::optional<Http2SettingsFrame> settings_frame =
884
+ settings_.MaybeSendUpdate();
885
+ if (settings_frame.has_value()) {
886
+ GRPC_HTTP2_CLIENT_DLOG
887
+ << "Http2ClientTransport Constructor Spawn SendFirstSettingsFrame";
888
+ general_party_->Spawn(
889
+ "SendFirstSettingsFrame",
890
+ [self = RefAsSubclass<Http2ClientTransport>(),
891
+ frame = std::move(*settings_frame)]() mutable {
892
+ return self->EnqueueOutgoingFrame(std::move(frame));
893
+ },
894
+ [](GRPC_UNUSED absl::Status status) {});
895
+ }
896
+ if (settings_.local().allow_security_frame()) {
897
+ // TODO(tjagtap) : [PH2][P3] : Setup the plumbing to pass the security frame
898
+ // to the endpoing via TransportFramingEndpointExtension.
899
+ // Also decide if this plumbing is done here, or when the peer sends
900
+ // allow_security_frame too.
901
+ }
902
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport Constructor End";
903
+ }
904
+
905
+ // This function MUST be idempotent.
906
+ void Http2ClientTransport::CloseStream(uint32_t stream_id, absl::Status status,
907
+ CloseStreamArgs args,
908
+ DebugLocation whence) {
909
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::CloseStream for stream id: "
910
+ << stream_id << " status=" << status
911
+ << " location=" << whence.file() << ":"
912
+ << whence.line();
913
+
914
+ // TODO(akshitpatel) : [PH2][P3] : Measure the impact of holding mutex
915
+ // throughout this function.
916
+ MutexLock lock(&transport_mutex_);
917
+ auto pair = stream_list_.find(stream_id);
918
+ if (pair == stream_list_.end()) {
919
+ GRPC_HTTP2_CLIENT_DLOG
920
+ << "Http2ClientTransport::CloseStream for stream id: " << stream_id
921
+ << " stream not found";
922
+ return;
923
+ }
924
+ auto& stream = pair->second;
925
+
926
+ if (args.close_reads) {
927
+ stream->MarkHalfClosedRemote();
928
+ }
929
+ if (args.close_writes) {
930
+ stream->MarkHalfClosedLocal();
931
+ }
932
+
933
+ if (stream->IsClosed()) {
934
+ GRPC_HTTP2_CLIENT_DLOG
935
+ << "Http2ClientTransport::CloseStream for stream id: " << stream_id
936
+ << " closing stream.";
937
+ if (args.send_rst_stream) {
938
+ // TODO(akshitpatel) : [PH2][P2] : Send RST_STREAM frame.
939
+ }
940
+
941
+ if (args.push_trailing_metadata) {
942
+ stream->call.SpawnPushServerTrailingMetadata(
943
+ ServerMetadataFromStatus(status));
944
+ }
945
+ stream_list_.erase(stream_id);
946
+ }
947
+ }
948
+
949
+ void Http2ClientTransport::CloseTransport() {
950
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::CloseTransport";
951
+
952
+ // This is the only place where the general_party_ is
953
+ // reset.
954
+ general_party_.reset();
955
+ }
956
+
957
+ void Http2ClientTransport::MaybeSpawnCloseTransport(Http2Status http2_status,
958
+ DebugLocation whence) {
959
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::MaybeSpawnCloseTransport "
960
+ "status="
961
+ << http2_status << " location=" << whence.file() << ":"
962
+ << whence.line();
963
+
964
+ // Free up the stream_list at this point. This would still allow the frames
965
+ // in the MPSC to be drained and block any additional frames from being
966
+ // enqueued. Additionally this also prevents additional frames with non-zero
967
+ // stream_ids from being processed by the read loop.
968
+ ReleasableMutexLock lock(&transport_mutex_);
969
+ if (is_transport_closed_) {
970
+ lock.Release();
971
+ return;
972
+ }
973
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::MaybeSpawnCloseTransport "
974
+ "Initiating transport close";
975
+ is_transport_closed_ = true;
976
+ absl::flat_hash_map<uint32_t, RefCountedPtr<Stream>> stream_list =
977
+ std::move(stream_list_);
978
+ stream_list_.clear();
979
+ state_tracker_.SetState(GRPC_CHANNEL_SHUTDOWN,
980
+ http2_status.GetAbslConnectionError(),
981
+ "transport closed");
982
+ lock.Release();
983
+
984
+ general_party_->Spawn(
985
+ "CloseTransport",
986
+ [self = RefAsSubclass<Http2ClientTransport>(),
987
+ stream_list = std::move(stream_list),
988
+ http2_status = std::move(http2_status)]() mutable {
989
+ GRPC_HTTP2_CLIENT_DLOG
990
+ << "Http2ClientTransport::CloseTransport Cleaning up call stacks";
991
+ // Clean up the call stacks for all active streams.
992
+ for (const auto& pair : stream_list) {
993
+ // There is no merit in transitioning the stream to
994
+ // closed state here as the subsequent lookups would
995
+ // fail. Also, as this is running on the transport
996
+ // party, there would not be concurrent access to the stream.
997
+ auto& stream = pair.second;
998
+ stream->call.SpawnPushServerTrailingMetadata(
999
+ ServerMetadataFromStatus(http2_status.GetAbslConnectionError()));
1000
+ }
1001
+
1002
+ // RFC9113 : A GOAWAY frame might not immediately precede closing of
1003
+ // the connection; a receiver of a GOAWAY that has no more use for the
1004
+ // connection SHOULD still send a GOAWAY frame before terminating the
1005
+ // connection.
1006
+ // TODO(akshitpatel) : [PH2][P2] : There would a timer for sending
1007
+ // goaway here. Once goaway is sent or timer is expired, close the
1008
+ // transport.
1009
+ return Map(Immediate(absl::OkStatus()),
1010
+ [self](GRPC_UNUSED absl::Status) mutable {
1011
+ self->CloseTransport();
1012
+ return Empty{};
1013
+ });
1014
+ },
1015
+ [](Empty) {});
1016
+ }
1017
+
1018
+ Http2ClientTransport::~Http2ClientTransport() {
1019
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport Destructor Begin";
1020
+ DCHECK(stream_list_.empty());
1021
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport Destructor End";
1022
+ }
1023
+
1024
+ ///////////////////////////////////////////////////////////////////////////////
1025
+ // Stream Related Operations
1026
+
1027
+ RefCountedPtr<Http2ClientTransport::Stream> Http2ClientTransport::LookupStream(
1028
+ uint32_t stream_id) {
1029
+ MutexLock lock(&transport_mutex_);
1030
+ auto it = stream_list_.find(stream_id);
1031
+ if (it == stream_list_.end()) {
1032
+ GRPC_HTTP2_CLIENT_DLOG
1033
+ << "Http2ClientTransport::LookupStream Stream not found stream_id="
1034
+ << stream_id;
1035
+ return nullptr;
1036
+ }
1037
+ return it->second;
1038
+ }
1039
+
1040
+ bool Http2ClientTransport::MakeStream(CallHandler call_handler,
1041
+ const uint32_t stream_id) {
1042
+ // https://datatracker.ietf.org/doc/html/rfc9113#name-stream-identifiers
1043
+ // TODO(tjagtap) : [PH2][P2] Validate implementation.
1044
+
1045
+ // TODO(akshitpatel) : [PH2][P1] : Probably do not need this lock. This
1046
+ // function is always called under the stream_id_mutex_. The issue is the
1047
+ // OnDone needs to be synchronous and hence InterActivityMutex might not be
1048
+ // an option to protect the stream_list_.
1049
+ MutexLock lock(&transport_mutex_);
1050
+ const bool on_done_added =
1051
+ call_handler.OnDone([self = RefAsSubclass<Http2ClientTransport>(),
1052
+ stream_id](bool cancelled) {
1053
+ GRPC_HTTP2_CLIENT_DLOG << "PH2: Client call " << self.get()
1054
+ << " id=" << stream_id
1055
+ << " done: cancelled=" << cancelled;
1056
+ if (cancelled) {
1057
+ // TODO(akshitpatel) : [PH2][P2] : There are two ways to handle
1058
+ // cancellation.
1059
+ // 1. Call CloseStream from the on_done callback as done here. This
1060
+ // will be invoked when PullServerTrailingMetadata resolves.
1061
+ // 2. Call CloseStream from the OutboundLoop. When the call is
1062
+ // cancelled, for_each() should return with an error. The
1063
+ // WasCancelled() function can be used to determinie if the call
1064
+ // was cancelled.
1065
+ // At this point, both the above mentioned approaches seem to be more
1066
+ // or less the same as both are running on the call party.
1067
+ self->CloseStream(stream_id, absl::CancelledError(),
1068
+ CloseStreamArgs{
1069
+ /*close_reads=*/true,
1070
+ /*close_writes=*/true,
1071
+ /*send_rst_stream=*/true,
1072
+ /*push_trailing_metadata=*/false,
1073
+ });
1074
+ }
1075
+ });
1076
+ if (!on_done_added) return false;
1077
+ stream_list_.emplace(
1078
+ stream_id, MakeRefCounted<Stream>(std::move(call_handler), stream_id));
1079
+ return true;
1080
+ }
1081
+
1082
+ ///////////////////////////////////////////////////////////////////////////////
1083
+ // Call Spine related operations
1084
+
1085
+ auto Http2ClientTransport::CallOutboundLoop(
1086
+ CallHandler call_handler, const uint32_t stream_id,
1087
+ InterActivityMutex<uint32_t>::Lock lock /* Locked stream_id_mutex */,
1088
+ ClientMetadataHandle metadata) {
1089
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport CallOutboundLoop";
1090
+
1091
+ auto send_message = [self = RefAsSubclass<Http2ClientTransport>(),
1092
+ stream_id](MessageHandle&& message) mutable {
1093
+ RefCountedPtr<Stream> stream = self->LookupStream(stream_id);
1094
+ return If(
1095
+ stream != nullptr,
1096
+ [self, stream, message = std::move(message), stream_id]() mutable {
1097
+ return TrySeq(stream->EnqueueMessage(std::move(message)),
1098
+ [self, stream_id](bool became_writable) {
1099
+ GRPC_HTTP2_CLIENT_DLOG
1100
+ << "Http2ClientTransport CallOutboundLoop "
1101
+ "Enqueued Message";
1102
+ return self->MaybeAddStreamToWritableStreamList(
1103
+ stream_id, became_writable);
1104
+ });
1105
+ },
1106
+ []() {
1107
+ // This will trigger Call stack cleanup.
1108
+ return absl::InternalError("Stream not found while sending message");
1109
+ });
1110
+ };
1111
+
1112
+ auto send_initial_metadata = [self = RefAsSubclass<Http2ClientTransport>(),
1113
+ stream_id,
1114
+ metadata = std::move(metadata)]() mutable {
1115
+ RefCountedPtr<Stream> stream = self->LookupStream(stream_id);
1116
+ return If(
1117
+ stream != nullptr,
1118
+ [self, stream, metadata = std::move(metadata), stream_id]() mutable {
1119
+ return TrySeq(
1120
+ stream->EnqueueInitialMetadata(std::move(metadata)),
1121
+ [self, stream_id](bool became_writable) {
1122
+ GRPC_HTTP2_CLIENT_DLOG
1123
+ << "Http2ClientTransport CallOutboundLoop "
1124
+ "Enqueued Initial Metadata";
1125
+ return self->MaybeAddStreamToWritableStreamList(
1126
+ stream_id, became_writable);
1127
+ },
1128
+ [stream] {
1129
+ // TODO(akshitpatel) : [PH2][P2] : Think how to handle stream
1130
+ // states.
1131
+ stream->SentInitialMetadata();
1132
+ return absl::OkStatus();
1133
+ });
1134
+ },
1135
+ []() {
1136
+ // This will trigger Call stack cleanup.
1137
+ return absl::InternalError(
1138
+ "Stream not found while sending initial metadata");
1139
+ });
1140
+ };
1141
+
1142
+ auto send_half_closed = [self = RefAsSubclass<Http2ClientTransport>(),
1143
+ stream_id]() mutable {
1144
+ RefCountedPtr<Stream> stream = self->LookupStream(stream_id);
1145
+ return If(
1146
+ stream != nullptr,
1147
+ [self, stream, stream_id]() mutable {
1148
+ return TrySeq(stream->EnqueueHalfClosed(),
1149
+ [self, stream_id](bool became_writable) {
1150
+ GRPC_HTTP2_CLIENT_DLOG
1151
+ << "Http2ClientTransport CallOutboundLoop "
1152
+ "Enqueued Half Closed";
1153
+ return self->MaybeAddStreamToWritableStreamList(
1154
+ stream_id, became_writable);
1155
+ });
1156
+ },
1157
+ []() {
1158
+ // This will trigger Call stack cleanup.
1159
+ return absl::InternalError(
1160
+ "Stream not found while sending half closed");
1161
+ });
1162
+ };
1163
+ return GRPC_LATENT_SEE_PROMISE(
1164
+ "Ph2CallOutboundLoop",
1165
+ TrySeq(
1166
+ send_initial_metadata(),
1167
+ [call_handler, send_message, lock = std::move(lock)]() {
1168
+ // The lock will be released once the promise is constructed from
1169
+ // this factory. ForEach will be polled after the lock is
1170
+ // released.
1171
+ return ForEach(MessagesFrom(call_handler), send_message);
1172
+ },
1173
+ [self = RefAsSubclass<Http2ClientTransport>(),
1174
+ send_half_closed = std::move(send_half_closed)]() mutable {
1175
+ return send_half_closed();
1176
+ },
1177
+ [call_handler]() mutable {
1178
+ return Map(call_handler.WasCancelled(), [](bool cancelled) {
1179
+ GRPC_HTTP2_CLIENT_DLOG
1180
+ << "Http2ClientTransport PH2CallOutboundLoop End with "
1181
+ "cancelled="
1182
+ << cancelled;
1183
+ return (cancelled) ? absl::CancelledError() : absl::OkStatus();
1184
+ });
1185
+ }));
1186
+ }
1187
+
1188
+ void Http2ClientTransport::StartCall(CallHandler call_handler) {
1189
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport StartCall Begin";
1190
+ call_handler.SpawnGuarded(
1191
+ "OutboundLoop",
1192
+ TrySeq(
1193
+ call_handler.PullClientInitialMetadata(),
1194
+ [self = RefAsSubclass<Http2ClientTransport>()](
1195
+ ClientMetadataHandle metadata) {
1196
+ // Lock the stream_id_mutex_
1197
+ return Staple(self->stream_id_mutex_.Acquire(),
1198
+ std::move(metadata));
1199
+ },
1200
+ [self = RefAsSubclass<Http2ClientTransport>(),
1201
+ call_handler](auto args /* Locked stream_id_mutex */) mutable {
1202
+ // For a gRPC Client, we only need to check the
1203
+ // MAX_CONCURRENT_STREAMS setting compliance at the time of
1204
+ // sending (that is write path). A gRPC Client will never
1205
+ // receive a stream initiated by a server, so we dont have to
1206
+ // check MAX_CONCURRENT_STREAMS compliance on the Read-Path.
1207
+ //
1208
+ // TODO(tjagtap) : [PH2][P1] Check for MAX_CONCURRENT_STREAMS
1209
+ // sent by peer before making a stream. Decide behaviour if we are
1210
+ // crossing this threshold.
1211
+ //
1212
+ // TODO(tjagtap) : [PH2][P1] : For a server we will have to do
1213
+ // this for incoming streams only. If a server receives more streams
1214
+ // from a client than is allowed by the clients settings, whether or
1215
+ // not we should fail is debatable.
1216
+ const uint32_t stream_id = self->NextStreamId(std::get<0>(args));
1217
+ return If(
1218
+ self->MakeStream(call_handler, stream_id),
1219
+ [self, call_handler, stream_id,
1220
+ args = std::move(args)]() mutable {
1221
+ return Map(
1222
+ self->CallOutboundLoop(call_handler, stream_id,
1223
+ std::move(std::get<0>(args)),
1224
+ std::move(std::get<1>(args))),
1225
+ [](absl::Status status) { return status; });
1226
+ },
1227
+ []() { return absl::InternalError("Failed to make stream"); });
1228
+ }));
1229
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport StartCall End";
1230
+ }
1231
+
1232
+ } // namespace http2
1233
+ } // namespace grpc_core