grpc 1.73.0 → 1.74.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 (499) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +38 -17
  3. data/include/grpc/create_channel_from_endpoint.h +54 -0
  4. data/include/grpc/credentials.h +11 -5
  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/interception_chain.h +7 -11
  11. data/src/core/channelz/channel_trace.cc +213 -115
  12. data/src/core/channelz/channel_trace.h +380 -86
  13. data/src/core/channelz/channelz.cc +270 -181
  14. data/src/core/channelz/channelz.h +168 -55
  15. data/src/core/channelz/channelz_registry.cc +2 -1
  16. data/src/core/channelz/channelz_registry.h +24 -0
  17. data/src/core/channelz/property_list.cc +357 -0
  18. data/src/core/channelz/property_list.h +202 -0
  19. data/src/core/channelz/ztrace_collector.h +3 -2
  20. data/src/core/client_channel/backup_poller.cc +17 -2
  21. data/src/core/client_channel/client_channel.cc +17 -28
  22. data/src/core/client_channel/client_channel_filter.cc +19 -29
  23. data/src/core/client_channel/config_selector.h +8 -2
  24. data/src/core/client_channel/dynamic_filters.cc +5 -6
  25. data/src/core/client_channel/dynamic_filters.h +1 -1
  26. data/src/core/client_channel/global_subchannel_pool.cc +4 -1
  27. data/src/core/client_channel/retry_filter.cc +21 -27
  28. data/src/core/client_channel/retry_filter.h +10 -7
  29. data/src/core/client_channel/retry_filter_legacy_call_data.cc +5 -5
  30. data/src/core/client_channel/retry_filter_legacy_call_data.h +1 -1
  31. data/src/core/client_channel/retry_interceptor.cc +30 -44
  32. data/src/core/client_channel/retry_interceptor.h +18 -17
  33. data/src/core/client_channel/retry_throttle.cc +46 -61
  34. data/src/core/client_channel/retry_throttle.h +17 -39
  35. data/src/core/client_channel/subchannel.cc +43 -19
  36. data/src/core/client_channel/subchannel.h +8 -0
  37. data/src/core/config/config_vars.cc +2 -0
  38. data/src/core/config/core_configuration.cc +1 -0
  39. data/src/core/config/core_configuration.h +11 -0
  40. data/src/core/credentials/call/call_creds_registry.h +125 -0
  41. data/src/core/credentials/call/call_creds_registry_init.cc +91 -0
  42. data/src/core/credentials/call/gcp_service_account_identity/gcp_service_account_identity_credentials.cc +6 -48
  43. data/src/core/credentials/call/jwt_token_file/jwt_token_file_call_credentials.cc +86 -0
  44. data/src/core/credentials/call/jwt_token_file/jwt_token_file_call_credentials.h +74 -0
  45. data/src/core/credentials/call/jwt_util.cc +70 -0
  46. data/src/core/credentials/call/jwt_util.h +32 -0
  47. data/src/core/credentials/transport/channel_creds_registry_init.cc +1 -1
  48. data/src/core/credentials/transport/google_default/google_default_credentials.cc +72 -4
  49. data/src/core/credentials/transport/ssl/ssl_credentials.cc +0 -1
  50. data/src/core/credentials/transport/tls/load_system_roots_supported.cc +1 -0
  51. data/src/core/credentials/transport/xds/xds_credentials.cc +0 -3
  52. data/src/core/ext/filters/gcp_authentication/gcp_authentication_filter.cc +8 -8
  53. data/src/core/ext/filters/gcp_authentication/gcp_authentication_filter.h +16 -16
  54. data/src/core/ext/filters/http/client_authority_filter.cc +2 -4
  55. data/src/core/ext/filters/http/message_compress/compression_filter.h +25 -22
  56. data/src/core/ext/filters/http/server/http_server_filter.h +12 -11
  57. data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +120 -35
  58. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +6 -5
  59. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +162 -115
  60. data/src/core/ext/transport/chttp2/transport/chttp2_transport.h +0 -3
  61. data/src/core/ext/transport/chttp2/transport/decode_huff.cc +1239 -3514
  62. data/src/core/ext/transport/chttp2/transport/decode_huff.h +1008 -1486
  63. data/src/core/ext/transport/chttp2/transport/flow_control.h +22 -17
  64. data/src/core/ext/transport/chttp2/transport/frame.cc +10 -0
  65. data/src/core/ext/transport/chttp2/transport/frame.h +2 -2
  66. data/src/core/ext/transport/chttp2/transport/frame_data.cc +1 -1
  67. data/src/core/ext/transport/chttp2/transport/frame_settings.cc +7 -8
  68. data/src/core/ext/transport/chttp2/transport/frame_window_update.cc +4 -5
  69. data/src/core/ext/transport/chttp2/transport/header_assembler.h +299 -0
  70. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +1 -1
  71. data/src/core/ext/transport/chttp2/transport/hpack_parser_table.cc +11 -5
  72. data/src/core/ext/transport/chttp2/transport/hpack_parser_table.h +12 -1
  73. data/src/core/ext/transport/chttp2/transport/http2_client_transport.cc +1017 -0
  74. data/src/core/ext/transport/chttp2/transport/http2_client_transport.h +593 -0
  75. data/src/core/ext/transport/chttp2/transport/http2_settings.h +19 -22
  76. data/{third_party/abseil-cpp/absl/strings/cord_buffer.cc → src/core/ext/transport/chttp2/transport/http2_stats_collector.cc} +14 -14
  77. data/src/core/ext/transport/chttp2/transport/http2_stats_collector.h +33 -0
  78. data/src/core/ext/transport/chttp2/transport/http2_status.h +6 -1
  79. data/src/core/ext/transport/chttp2/transport/http2_transport.cc +43 -0
  80. data/src/core/ext/transport/chttp2/transport/http2_transport.h +65 -0
  81. data/src/core/ext/transport/chttp2/transport/http2_ztrace_collector.h +0 -29
  82. data/src/core/ext/transport/chttp2/transport/internal.h +18 -8
  83. data/src/core/ext/transport/chttp2/transport/keepalive.cc +105 -0
  84. data/src/core/ext/transport/chttp2/transport/keepalive.h +138 -0
  85. data/src/core/ext/transport/chttp2/transport/message_assembler.h +185 -0
  86. data/src/core/ext/transport/chttp2/transport/parsing.cc +2 -4
  87. data/src/core/ext/transport/chttp2/transport/ping_callbacks.h +19 -0
  88. data/src/core/ext/transport/chttp2/transport/ping_promise.cc +151 -0
  89. data/src/core/ext/transport/chttp2/transport/ping_promise.h +180 -0
  90. data/src/core/ext/transport/chttp2/transport/ping_rate_policy.cc +5 -9
  91. data/src/core/ext/transport/chttp2/transport/ping_rate_policy.h +11 -0
  92. data/src/core/ext/transport/chttp2/transport/stream_lists.cc +39 -1
  93. data/src/core/ext/transport/chttp2/transport/transport_common.cc +19 -0
  94. data/src/core/ext/transport/chttp2/transport/transport_common.h +27 -0
  95. data/src/core/ext/transport/chttp2/transport/writing.cc +37 -11
  96. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/channelz.upb.h +571 -0
  97. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/channelz.upb_minitable.c +120 -0
  98. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/channelz.upb_minitable.h +36 -0
  99. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/promise.upb.h +1272 -0
  100. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/promise.upb_minitable.c +312 -0
  101. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/promise.upb_minitable.h +50 -0
  102. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb.h +984 -0
  103. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb_minitable.c +226 -0
  104. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb_minitable.h +44 -0
  105. data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/promise.upbdefs.c +175 -0
  106. data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/promise.upbdefs.h +82 -0
  107. data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/property_list.upbdefs.c +135 -0
  108. data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/property_list.upbdefs.h +67 -0
  109. data/src/core/filter/auth/auth_filters.h +0 -25
  110. data/src/core/filter/auth/client_auth_filter.cc +0 -118
  111. data/src/core/filter/filter_args.h +9 -23
  112. data/src/core/handshaker/handshaker.cc +23 -14
  113. data/src/core/handshaker/handshaker.h +3 -0
  114. data/src/core/handshaker/http_connect/http_connect_handshaker.cc +3 -1
  115. data/src/core/handshaker/security/legacy_secure_endpoint.cc +6 -5
  116. data/src/core/handshaker/security/secure_endpoint.cc +70 -25
  117. data/src/core/handshaker/security/security_handshaker.cc +4 -1
  118. data/src/core/handshaker/tcp_connect/tcp_connect_handshaker.cc +7 -1
  119. data/src/core/lib/channel/channel_args.cc +15 -0
  120. data/src/core/lib/channel/channel_args.h +3 -0
  121. data/src/core/lib/channel/channel_stack.cc +22 -23
  122. data/src/core/lib/channel/channel_stack.h +9 -7
  123. data/src/core/lib/channel/channel_stack_builder_impl.cc +1 -1
  124. data/src/core/lib/channel/channel_stack_builder_impl.h +2 -7
  125. data/src/core/lib/channel/promise_based_filter.h +5 -5
  126. data/src/core/lib/debug/trace_impl.h +0 -1
  127. data/src/core/lib/event_engine/ares_resolver.cc +165 -46
  128. data/src/core/lib/event_engine/ares_resolver.h +48 -2
  129. data/src/core/lib/event_engine/cf_engine/cf_engine.cc +3 -1
  130. data/src/core/lib/event_engine/cf_engine/cf_engine.h +1 -4
  131. data/src/core/lib/event_engine/cf_engine/cfstream_endpoint.h +2 -6
  132. data/src/core/lib/event_engine/endpoint_channel_arg_wrapper.cc +40 -0
  133. data/src/core/lib/event_engine/endpoint_channel_arg_wrapper.h +60 -0
  134. data/src/core/lib/event_engine/event_engine.cc +7 -0
  135. data/src/core/lib/event_engine/extensions/channelz.h +10 -6
  136. data/src/core/lib/event_engine/grpc_polled_fd.h +5 -0
  137. data/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc +130 -162
  138. data/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.h +11 -15
  139. data/src/core/lib/event_engine/posix_engine/ev_poll_posix.cc +75 -117
  140. data/src/core/lib/event_engine/posix_engine/ev_poll_posix.h +7 -9
  141. data/src/core/lib/event_engine/posix_engine/event_poller.h +18 -15
  142. data/src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc +0 -18
  143. data/src/core/lib/event_engine/posix_engine/file_descriptor_collection.cc +124 -0
  144. data/src/core/lib/event_engine/posix_engine/file_descriptor_collection.h +243 -0
  145. data/src/core/lib/event_engine/posix_engine/grpc_polled_fd_posix.h +29 -19
  146. data/src/core/lib/event_engine/posix_engine/internal_errqueue.cc +6 -2
  147. data/src/core/lib/event_engine/posix_engine/internal_errqueue.h +6 -1
  148. data/src/core/lib/event_engine/posix_engine/posix_endpoint.cc +145 -92
  149. data/src/core/lib/event_engine/posix_engine/posix_endpoint.h +9 -19
  150. data/src/core/lib/event_engine/posix_engine/posix_engine.cc +333 -116
  151. data/src/core/lib/event_engine/posix_engine/posix_engine.h +61 -18
  152. data/src/core/lib/event_engine/posix_engine/posix_engine_listener.cc +45 -37
  153. data/src/core/lib/event_engine/posix_engine/posix_engine_listener.h +6 -4
  154. data/src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.cc +32 -142
  155. data/src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.h +6 -5
  156. data/src/core/lib/event_engine/posix_engine/posix_interface.h +211 -0
  157. data/src/core/lib/event_engine/posix_engine/posix_interface_posix.cc +1083 -0
  158. data/src/core/lib/event_engine/posix_engine/posix_interface_windows.cc +281 -0
  159. data/src/core/lib/event_engine/posix_engine/posix_write_event_sink.cc +154 -0
  160. data/src/core/lib/event_engine/posix_engine/posix_write_event_sink.h +174 -0
  161. data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.cc +3 -719
  162. data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.h +10 -170
  163. data/src/core/lib/event_engine/posix_engine/timer_manager.cc +33 -22
  164. data/src/core/lib/event_engine/posix_engine/timer_manager.h +13 -11
  165. data/src/core/lib/event_engine/posix_engine/traced_buffer_list.cc +117 -151
  166. data/src/core/lib/event_engine/posix_engine/traced_buffer_list.h +26 -94
  167. data/src/core/lib/event_engine/posix_engine/wakeup_fd_eventfd.cc +26 -25
  168. data/src/core/lib/event_engine/posix_engine/wakeup_fd_eventfd.h +6 -2
  169. data/src/core/lib/event_engine/posix_engine/wakeup_fd_pipe.cc +36 -62
  170. data/src/core/lib/event_engine/posix_engine/wakeup_fd_pipe.h +6 -2
  171. data/src/core/lib/event_engine/posix_engine/wakeup_fd_posix.h +7 -6
  172. data/src/core/lib/event_engine/posix_engine/wakeup_fd_posix_default.cc +12 -6
  173. data/src/core/lib/event_engine/posix_engine/wakeup_fd_posix_default.h +3 -1
  174. data/src/core/lib/event_engine/shim.cc +9 -0
  175. data/src/core/lib/event_engine/shim.h +3 -0
  176. data/src/core/lib/event_engine/thread_pool/thread_pool.h +7 -3
  177. data/src/core/lib/event_engine/thread_pool/thread_pool_factory.cc +0 -17
  178. data/src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.cc +4 -2
  179. data/src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.h +3 -2
  180. data/src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc +4 -0
  181. data/src/core/lib/event_engine/windows/grpc_polled_fd_windows.h +4 -0
  182. data/src/core/lib/event_engine/windows/windows_endpoint.h +2 -6
  183. data/src/core/lib/event_engine/windows/windows_engine.cc +0 -1
  184. data/src/core/lib/event_engine/windows/windows_engine.h +1 -3
  185. data/src/core/lib/event_engine/windows/windows_listener.cc +14 -2
  186. data/src/core/lib/experiments/experiments.cc +45 -93
  187. data/src/core/lib/experiments/experiments.h +21 -51
  188. data/src/core/lib/iomgr/endpoint.cc +4 -3
  189. data/src/core/lib/iomgr/endpoint.h +7 -4
  190. data/src/core/lib/iomgr/endpoint_cfstream.cc +3 -2
  191. data/src/core/lib/iomgr/ev_epoll1_linux.cc +7 -2
  192. data/src/core/lib/iomgr/ev_poll_posix.cc +7 -2
  193. data/src/core/lib/iomgr/event_engine_shims/endpoint.cc +4 -6
  194. data/src/core/lib/iomgr/tcp_posix.cc +12 -6
  195. data/src/core/lib/iomgr/tcp_windows.cc +3 -2
  196. data/src/core/lib/promise/activity.h +1 -0
  197. data/src/core/lib/promise/arena_promise.h +23 -7
  198. data/src/core/lib/promise/detail/promise_factory.h +10 -0
  199. data/src/core/lib/promise/detail/promise_like.h +118 -11
  200. data/src/core/lib/promise/detail/promise_variant.h +50 -0
  201. data/src/core/lib/promise/detail/seq_state.h +687 -548
  202. data/src/core/lib/promise/if.h +20 -0
  203. data/src/core/lib/promise/inter_activity_latch.h +147 -0
  204. data/src/core/lib/promise/inter_activity_mutex.h +547 -0
  205. data/src/core/lib/promise/loop.h +65 -3
  206. data/src/core/lib/promise/map.h +24 -0
  207. data/src/core/lib/promise/match_promise.h +103 -0
  208. data/src/core/lib/promise/mpsc.cc +425 -0
  209. data/src/core/lib/promise/mpsc.h +490 -0
  210. data/src/core/lib/promise/party.cc +50 -1
  211. data/src/core/lib/promise/party.h +66 -1
  212. data/src/core/lib/promise/race.h +31 -0
  213. data/src/core/lib/promise/seq.h +4 -1
  214. data/src/core/lib/promise/status_flag.h +7 -0
  215. data/src/core/lib/promise/try_seq.h +4 -1
  216. data/src/core/lib/promise/wait_set.cc +28 -0
  217. data/src/core/lib/promise/wait_set.h +86 -0
  218. data/src/core/lib/resource_quota/arena.h +19 -0
  219. data/src/core/lib/slice/slice.h +5 -0
  220. data/src/core/lib/surface/channel_create.cc +88 -13
  221. data/src/core/lib/surface/channel_create.h +4 -0
  222. data/src/core/lib/surface/channel_init.cc +164 -47
  223. data/src/core/lib/surface/channel_init.h +64 -1
  224. data/src/core/lib/surface/filter_stack_call.cc +18 -9
  225. data/src/core/lib/surface/init.cc +6 -15
  226. data/src/core/lib/surface/legacy_channel.cc +3 -5
  227. data/src/core/lib/surface/legacy_channel.h +3 -1
  228. data/src/core/lib/surface/version.cc +2 -2
  229. data/src/core/lib/transport/promise_endpoint.cc +110 -0
  230. data/src/core/lib/transport/promise_endpoint.h +307 -0
  231. data/src/core/load_balancing/child_policy_handler.cc +2 -4
  232. data/src/core/load_balancing/delegating_helper.h +2 -3
  233. data/src/core/load_balancing/health_check_client.cc +1 -5
  234. data/src/core/load_balancing/lb_policy.h +1 -3
  235. data/src/core/load_balancing/oob_backend_metric.cc +1 -5
  236. data/src/core/load_balancing/pick_first/pick_first.cc +3 -0
  237. data/src/core/load_balancing/xds/cds.cc +10 -1
  238. data/src/core/plugin_registry/grpc_plugin_registry_extra.cc +2 -0
  239. data/src/core/resolver/xds/xds_config.cc +6 -3
  240. data/src/core/resolver/xds/xds_config.h +9 -4
  241. data/src/core/resolver/xds/xds_dependency_manager.cc +21 -6
  242. data/src/core/resolver/xds/xds_dependency_manager.h +2 -1
  243. data/src/core/resolver/xds/xds_resolver.cc +31 -11
  244. data/src/core/server/server.cc +83 -12
  245. data/src/core/server/server.h +21 -2
  246. data/src/core/server/xds_server_config_fetcher.cc +63 -25
  247. data/src/core/service_config/service_config.h +1 -1
  248. data/src/core/service_config/service_config_impl.h +1 -1
  249. data/src/core/telemetry/context_list_entry.cc +38 -0
  250. data/src/core/telemetry/context_list_entry.h +42 -12
  251. data/src/core/telemetry/stats_data.cc +233 -207
  252. data/src/core/telemetry/stats_data.h +250 -153
  253. data/src/core/telemetry/tcp_tracer.h +1 -1
  254. data/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc +11 -3
  255. data/src/core/tsi/fake_transport_security.cc +17 -0
  256. data/src/core/tsi/ssl_transport_security.cc +2 -0
  257. data/src/core/tsi/transport_security_grpc.cc +8 -0
  258. data/src/core/tsi/transport_security_grpc.h +15 -0
  259. data/src/core/util/backoff.cc +1 -5
  260. data/src/core/util/backoff.h +1 -0
  261. data/src/core/util/down_cast.h +1 -1
  262. data/src/core/util/function_signature.h +15 -1
  263. data/src/core/util/http_client/httpcli.cc +12 -5
  264. data/src/core/util/http_client/httpcli.h +4 -1
  265. data/src/core/util/latent_see.h +8 -5
  266. data/src/core/util/log.cc +4 -0
  267. data/src/core/util/memory_usage.h +268 -0
  268. data/src/core/util/per_cpu.cc +2 -0
  269. data/src/core/util/per_cpu.h +7 -0
  270. data/src/core/util/shared_bit_gen.h +20 -0
  271. data/src/core/util/single_set_ptr.h +2 -2
  272. data/src/core/util/upb_utils.h +42 -0
  273. data/src/core/util/uri.cc +3 -2
  274. data/src/core/util/useful.h +53 -2
  275. data/src/core/util/wait_for_single_owner.cc +31 -0
  276. data/src/core/util/wait_for_single_owner.h +24 -0
  277. data/src/core/xds/grpc/xds_bootstrap_grpc.cc +2 -0
  278. data/src/core/xds/grpc/xds_bootstrap_grpc.h +5 -0
  279. data/src/core/xds/grpc/xds_client_grpc.cc +6 -2
  280. data/src/core/xds/grpc/xds_common_types_parser.cc +138 -50
  281. data/src/core/xds/grpc/xds_common_types_parser.h +12 -0
  282. data/src/core/xds/grpc/xds_http_filter.h +7 -0
  283. data/src/core/xds/grpc/xds_http_gcp_authn_filter.cc +22 -0
  284. data/src/core/xds/grpc/xds_http_gcp_authn_filter.h +3 -0
  285. data/src/core/xds/grpc/xds_route_config_parser.cc +15 -38
  286. data/src/core/xds/grpc/xds_server_grpc.cc +63 -13
  287. data/src/core/xds/grpc/xds_server_grpc.h +10 -2
  288. data/src/core/xds/grpc/xds_server_grpc_interface.h +4 -0
  289. data/src/core/xds/grpc/xds_transport_grpc.cc +18 -0
  290. data/src/core/xds/xds_client/xds_bootstrap.h +2 -0
  291. data/src/core/xds/xds_client/xds_client.cc +26 -5
  292. data/src/ruby/ext/grpc/extconf.rb +2 -0
  293. data/src/ruby/ext/grpc/rb_call.c +1 -8
  294. data/src/ruby/ext/grpc/rb_channel.c +72 -568
  295. data/src/ruby/ext/grpc/rb_channel.h +0 -3
  296. data/src/ruby/ext/grpc/rb_completion_queue.c +26 -14
  297. data/src/ruby/ext/grpc/rb_completion_queue.h +1 -7
  298. data/src/ruby/ext/grpc/rb_grpc.c +9 -5
  299. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +1 -1
  300. data/src/ruby/ext/grpc/rb_loader.c +0 -4
  301. data/src/ruby/ext/grpc/rb_server.c +31 -50
  302. data/src/ruby/lib/grpc/generic/client_stub.rb +4 -4
  303. data/src/ruby/lib/grpc/version.rb +1 -1
  304. data/src/ruby/spec/core_spec.rb +22 -0
  305. data/src/ruby/spec/generic/active_call_spec.rb +1 -1
  306. data/third_party/abseil-cpp/absl/algorithm/container.h +2 -19
  307. data/third_party/abseil-cpp/absl/base/attributes.h +76 -7
  308. data/third_party/abseil-cpp/absl/base/call_once.h +11 -12
  309. data/third_party/abseil-cpp/absl/base/config.h +20 -129
  310. data/third_party/abseil-cpp/absl/base/{internal/fast_type_id.h → fast_type_id.h} +11 -16
  311. data/third_party/abseil-cpp/absl/base/internal/cycleclock.cc +0 -5
  312. data/third_party/abseil-cpp/absl/base/internal/cycleclock_config.h +7 -7
  313. data/third_party/abseil-cpp/absl/base/internal/endian.h +34 -38
  314. data/third_party/abseil-cpp/absl/base/internal/iterator_traits.h +71 -0
  315. data/third_party/abseil-cpp/absl/base/internal/low_level_alloc.cc +6 -5
  316. data/third_party/abseil-cpp/absl/base/internal/{nullability_impl.h → nullability_deprecated.h} +45 -8
  317. data/third_party/abseil-cpp/absl/base/internal/spinlock.cc +0 -9
  318. data/third_party/abseil-cpp/absl/base/internal/spinlock.h +3 -13
  319. data/third_party/abseil-cpp/absl/base/internal/unaligned_access.h +6 -6
  320. data/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.h +8 -3
  321. data/third_party/abseil-cpp/absl/base/no_destructor.h +11 -32
  322. data/third_party/abseil-cpp/absl/base/nullability.h +84 -72
  323. data/third_party/abseil-cpp/absl/base/options.h +3 -80
  324. data/third_party/abseil-cpp/absl/base/policy_checks.h +7 -7
  325. data/third_party/abseil-cpp/absl/cleanup/cleanup.h +1 -3
  326. data/third_party/abseil-cpp/absl/cleanup/internal/cleanup.h +3 -4
  327. data/third_party/abseil-cpp/absl/container/btree_map.h +4 -2
  328. data/third_party/abseil-cpp/absl/container/btree_set.h +4 -2
  329. data/third_party/abseil-cpp/absl/container/fixed_array.h +7 -14
  330. data/third_party/abseil-cpp/absl/container/flat_hash_map.h +5 -0
  331. data/third_party/abseil-cpp/absl/container/flat_hash_set.h +6 -1
  332. data/third_party/abseil-cpp/absl/container/inlined_vector.h +8 -5
  333. data/third_party/abseil-cpp/absl/container/internal/btree.h +132 -29
  334. data/third_party/abseil-cpp/absl/container/internal/btree_container.h +175 -71
  335. data/third_party/abseil-cpp/absl/container/internal/common.h +43 -0
  336. data/third_party/abseil-cpp/absl/container/internal/common_policy_traits.h +1 -2
  337. data/third_party/abseil-cpp/absl/container/internal/container_memory.h +9 -10
  338. data/third_party/abseil-cpp/absl/container/internal/hash_function_defaults.h +1 -8
  339. data/third_party/abseil-cpp/absl/container/internal/hash_policy_traits.h +0 -4
  340. data/third_party/abseil-cpp/absl/container/internal/hashtable_control_bytes.h +527 -0
  341. data/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.cc +20 -4
  342. data/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.h +31 -12
  343. data/third_party/abseil-cpp/absl/container/internal/inlined_vector.h +2 -7
  344. data/third_party/abseil-cpp/absl/container/internal/layout.h +26 -42
  345. data/third_party/abseil-cpp/absl/container/internal/raw_hash_map.h +199 -68
  346. data/third_party/abseil-cpp/absl/container/internal/raw_hash_set.cc +1354 -183
  347. data/third_party/abseil-cpp/absl/container/internal/raw_hash_set.h +881 -1424
  348. data/third_party/abseil-cpp/absl/container/internal/raw_hash_set_resize_impl.h +80 -0
  349. data/third_party/abseil-cpp/absl/crc/crc32c.cc +0 -4
  350. data/third_party/abseil-cpp/absl/crc/crc32c.h +7 -5
  351. data/third_party/abseil-cpp/absl/crc/internal/crc32_x86_arm_combined_simd.h +0 -22
  352. data/third_party/abseil-cpp/absl/crc/internal/crc_x86_arm_combined.cc +45 -74
  353. data/third_party/abseil-cpp/absl/debugging/internal/addresses.h +57 -0
  354. data/third_party/abseil-cpp/absl/debugging/internal/decode_rust_punycode.cc +1 -1
  355. data/third_party/abseil-cpp/absl/debugging/internal/decode_rust_punycode.h +5 -5
  356. data/third_party/abseil-cpp/absl/debugging/internal/demangle.cc +8 -35
  357. data/third_party/abseil-cpp/absl/debugging/internal/demangle_rust.cc +16 -16
  358. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_aarch64-inl.inc +40 -37
  359. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_arm-inl.inc +16 -7
  360. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_emscripten-inl.inc +14 -5
  361. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_generic-inl.inc +10 -4
  362. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_powerpc-inl.inc +27 -16
  363. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_riscv-inl.inc +13 -4
  364. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_unimplemented-inl.inc +4 -3
  365. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_win32-inl.inc +15 -28
  366. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_x86-inl.inc +19 -9
  367. data/third_party/abseil-cpp/absl/debugging/stacktrace.cc +144 -27
  368. data/third_party/abseil-cpp/absl/debugging/stacktrace.h +73 -5
  369. data/third_party/abseil-cpp/absl/debugging/symbolize_elf.inc +19 -9
  370. data/third_party/abseil-cpp/absl/debugging/symbolize_emscripten.inc +3 -2
  371. data/third_party/abseil-cpp/absl/debugging/symbolize_win32.inc +25 -6
  372. data/third_party/abseil-cpp/absl/flags/commandlineflag.h +2 -2
  373. data/third_party/abseil-cpp/absl/flags/flag.h +4 -3
  374. data/third_party/abseil-cpp/absl/flags/internal/commandlineflag.h +2 -2
  375. data/third_party/abseil-cpp/absl/flags/internal/flag.cc +2 -1
  376. data/third_party/abseil-cpp/absl/flags/internal/flag.h +7 -6
  377. data/third_party/abseil-cpp/absl/flags/internal/registry.h +4 -3
  378. data/third_party/abseil-cpp/absl/flags/reflection.cc +2 -3
  379. data/third_party/abseil-cpp/absl/functional/any_invocable.h +8 -10
  380. data/third_party/abseil-cpp/absl/functional/function_ref.h +2 -9
  381. data/third_party/abseil-cpp/absl/functional/internal/any_invocable.h +110 -226
  382. data/third_party/abseil-cpp/absl/functional/internal/front_binder.h +10 -12
  383. data/third_party/abseil-cpp/absl/functional/internal/function_ref.h +2 -5
  384. data/third_party/abseil-cpp/absl/hash/hash.h +18 -0
  385. data/third_party/abseil-cpp/absl/hash/internal/hash.cc +1 -5
  386. data/third_party/abseil-cpp/absl/hash/internal/hash.h +86 -61
  387. data/third_party/abseil-cpp/absl/hash/internal/low_level_hash.cc +25 -68
  388. data/third_party/abseil-cpp/absl/hash/internal/low_level_hash.h +2 -6
  389. data/third_party/abseil-cpp/absl/hash/internal/weakly_mixed_integer.h +38 -0
  390. data/third_party/abseil-cpp/absl/log/check.h +2 -1
  391. data/third_party/abseil-cpp/absl/log/globals.h +4 -5
  392. data/third_party/abseil-cpp/absl/log/internal/append_truncated.h +28 -0
  393. data/third_party/abseil-cpp/absl/log/internal/check_op.cc +22 -22
  394. data/third_party/abseil-cpp/absl/log/internal/check_op.h +65 -62
  395. data/third_party/abseil-cpp/absl/log/internal/conditions.cc +5 -3
  396. data/third_party/abseil-cpp/absl/log/internal/conditions.h +7 -2
  397. data/third_party/abseil-cpp/absl/log/internal/log_message.cc +85 -43
  398. data/third_party/abseil-cpp/absl/log/internal/log_message.h +84 -59
  399. data/third_party/abseil-cpp/absl/log/internal/nullstream.h +1 -0
  400. data/third_party/abseil-cpp/absl/log/internal/proto.cc +3 -2
  401. data/third_party/abseil-cpp/absl/log/internal/proto.h +3 -3
  402. data/third_party/abseil-cpp/absl/log/internal/strip.h +4 -12
  403. data/third_party/abseil-cpp/absl/log/internal/vlog_config.h +8 -6
  404. data/third_party/abseil-cpp/absl/log/internal/voidify.h +10 -4
  405. data/third_party/abseil-cpp/absl/log/log.h +48 -35
  406. data/third_party/abseil-cpp/absl/log/log_sink_registry.h +2 -2
  407. data/third_party/abseil-cpp/absl/meta/type_traits.h +46 -175
  408. data/third_party/abseil-cpp/absl/numeric/bits.h +68 -2
  409. data/third_party/abseil-cpp/absl/numeric/int128.cc +0 -52
  410. data/third_party/abseil-cpp/absl/numeric/internal/bits.h +7 -3
  411. data/third_party/abseil-cpp/absl/profiling/internal/exponential_biased.cc +1 -1
  412. data/third_party/abseil-cpp/absl/random/bit_gen_ref.h +10 -11
  413. data/third_party/abseil-cpp/absl/random/distributions.h +6 -8
  414. data/third_party/abseil-cpp/absl/random/gaussian_distribution.h +1 -1
  415. data/third_party/abseil-cpp/absl/random/internal/distribution_caller.h +5 -6
  416. data/third_party/abseil-cpp/absl/random/internal/{pool_urbg.cc → entropy_pool.cc} +22 -90
  417. data/third_party/abseil-cpp/absl/random/internal/entropy_pool.h +35 -0
  418. data/third_party/abseil-cpp/absl/random/internal/nonsecure_base.h +5 -6
  419. data/third_party/abseil-cpp/absl/random/internal/randen_detect.cc +1 -1
  420. data/third_party/abseil-cpp/absl/random/internal/seed_material.cc +20 -12
  421. data/third_party/abseil-cpp/absl/random/internal/seed_material.h +5 -5
  422. data/third_party/abseil-cpp/absl/random/random.h +88 -53
  423. data/third_party/abseil-cpp/absl/random/seed_sequences.cc +6 -2
  424. data/third_party/abseil-cpp/absl/status/internal/status_internal.cc +3 -4
  425. data/third_party/abseil-cpp/absl/status/internal/status_internal.h +3 -4
  426. data/third_party/abseil-cpp/absl/status/internal/statusor_internal.h +4 -3
  427. data/third_party/abseil-cpp/absl/status/status.cc +4 -8
  428. data/third_party/abseil-cpp/absl/status/status.h +8 -8
  429. data/third_party/abseil-cpp/absl/status/status_payload_printer.h +2 -2
  430. data/third_party/abseil-cpp/absl/status/statusor.cc +2 -2
  431. data/third_party/abseil-cpp/absl/status/statusor.h +6 -6
  432. data/third_party/abseil-cpp/absl/strings/ascii.cc +9 -9
  433. data/third_party/abseil-cpp/absl/strings/ascii.h +18 -18
  434. data/third_party/abseil-cpp/absl/strings/charconv.cc +21 -22
  435. data/third_party/abseil-cpp/absl/strings/charconv.h +5 -5
  436. data/third_party/abseil-cpp/absl/strings/cord.cc +54 -58
  437. data/third_party/abseil-cpp/absl/strings/cord.h +94 -83
  438. data/third_party/abseil-cpp/absl/strings/cord_analysis.cc +11 -11
  439. data/third_party/abseil-cpp/absl/strings/cord_analysis.h +3 -3
  440. data/third_party/abseil-cpp/absl/strings/escaping.cc +130 -149
  441. data/third_party/abseil-cpp/absl/strings/escaping.h +9 -10
  442. data/third_party/abseil-cpp/absl/strings/internal/charconv_bigint.cc +1 -1
  443. data/third_party/abseil-cpp/absl/strings/internal/cord_internal.h +6 -8
  444. data/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree.cc +0 -4
  445. data/third_party/abseil-cpp/absl/strings/internal/cordz_info.cc +0 -4
  446. data/third_party/abseil-cpp/absl/strings/internal/str_format/arg.cc +7 -63
  447. data/third_party/abseil-cpp/absl/strings/internal/str_format/arg.h +1 -11
  448. data/third_party/abseil-cpp/absl/strings/internal/str_format/extension.cc +0 -22
  449. data/third_party/abseil-cpp/absl/strings/internal/str_format/output.cc +5 -3
  450. data/third_party/abseil-cpp/absl/strings/internal/str_format/parser.h +4 -2
  451. data/third_party/abseil-cpp/absl/strings/internal/str_join_internal.h +3 -3
  452. data/third_party/abseil-cpp/absl/strings/internal/string_constant.h +0 -5
  453. data/third_party/abseil-cpp/absl/strings/internal/utf8.cc +96 -1
  454. data/third_party/abseil-cpp/absl/strings/internal/utf8.h +15 -1
  455. data/third_party/abseil-cpp/absl/strings/numbers.cc +53 -32
  456. data/third_party/abseil-cpp/absl/strings/numbers.h +87 -58
  457. data/third_party/abseil-cpp/absl/strings/str_cat.cc +6 -7
  458. data/third_party/abseil-cpp/absl/strings/str_cat.h +32 -32
  459. data/third_party/abseil-cpp/absl/strings/str_format.h +18 -18
  460. data/third_party/abseil-cpp/absl/strings/str_replace.cc +3 -3
  461. data/third_party/abseil-cpp/absl/strings/str_replace.h +6 -6
  462. data/third_party/abseil-cpp/absl/strings/string_view.cc +4 -9
  463. data/third_party/abseil-cpp/absl/strings/string_view.h +27 -32
  464. data/third_party/abseil-cpp/absl/strings/strip.h +4 -4
  465. data/third_party/abseil-cpp/absl/strings/substitute.cc +5 -4
  466. data/third_party/abseil-cpp/absl/strings/substitute.h +66 -64
  467. data/third_party/abseil-cpp/absl/synchronization/internal/futex_waiter.cc +0 -4
  468. data/third_party/abseil-cpp/absl/synchronization/internal/kernel_timeout.cc +0 -5
  469. data/third_party/abseil-cpp/absl/synchronization/internal/pthread_waiter.cc +0 -4
  470. data/third_party/abseil-cpp/absl/synchronization/internal/sem_waiter.cc +0 -4
  471. data/third_party/abseil-cpp/absl/synchronization/internal/stdcpp_waiter.cc +0 -4
  472. data/third_party/abseil-cpp/absl/synchronization/internal/waiter_base.cc +0 -4
  473. data/third_party/abseil-cpp/absl/synchronization/internal/win32_waiter.cc +0 -4
  474. data/third_party/abseil-cpp/absl/synchronization/mutex.cc +1 -1
  475. data/third_party/abseil-cpp/absl/synchronization/mutex.h +97 -69
  476. data/third_party/abseil-cpp/absl/synchronization/notification.h +1 -1
  477. data/third_party/abseil-cpp/absl/time/civil_time.cc +1 -0
  478. data/third_party/abseil-cpp/absl/time/duration.cc +12 -7
  479. data/third_party/abseil-cpp/absl/time/internal/cctz/include/cctz/time_zone.h +1 -1
  480. data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup.cc +90 -111
  481. data/third_party/abseil-cpp/absl/time/time.h +20 -15
  482. data/third_party/abseil-cpp/absl/types/optional.h +7 -747
  483. data/third_party/abseil-cpp/absl/types/span.h +13 -11
  484. data/third_party/abseil-cpp/absl/types/variant.h +5 -784
  485. data/third_party/abseil-cpp/absl/utility/utility.h +10 -185
  486. metadata +72 -20
  487. data/src/core/lib/event_engine/forkable.cc +0 -105
  488. data/src/core/lib/event_engine/forkable.h +0 -67
  489. data/src/core/lib/iomgr/python_util.h +0 -46
  490. data/third_party/abseil-cpp/absl/base/internal/inline_variable.h +0 -108
  491. data/third_party/abseil-cpp/absl/base/internal/invoke.h +0 -241
  492. data/third_party/abseil-cpp/absl/log/log_entry.cc +0 -41
  493. data/third_party/abseil-cpp/absl/random/internal/pool_urbg.h +0 -131
  494. data/third_party/abseil-cpp/absl/types/bad_optional_access.cc +0 -66
  495. data/third_party/abseil-cpp/absl/types/bad_optional_access.h +0 -78
  496. data/third_party/abseil-cpp/absl/types/bad_variant_access.cc +0 -82
  497. data/third_party/abseil-cpp/absl/types/bad_variant_access.h +0 -82
  498. data/third_party/abseil-cpp/absl/types/internal/optional.h +0 -352
  499. data/third_party/abseil-cpp/absl/types/internal/variant.h +0 -1622
@@ -0,0 +1,1017 @@
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_status.h"
39
+ #include "src/core/ext/transport/chttp2/transport/internal_channel_arg_names.h"
40
+ #include "src/core/ext/transport/chttp2/transport/message_assembler.h"
41
+ #include "src/core/ext/transport/chttp2/transport/transport_common.h"
42
+ #include "src/core/lib/channel/channel_args.h"
43
+ #include "src/core/lib/debug/trace.h"
44
+ #include "src/core/lib/promise/for_each.h"
45
+ #include "src/core/lib/promise/loop.h"
46
+ #include "src/core/lib/promise/map.h"
47
+ #include "src/core/lib/promise/match_promise.h"
48
+ #include "src/core/lib/promise/party.h"
49
+ #include "src/core/lib/promise/poll.h"
50
+ #include "src/core/lib/promise/promise.h"
51
+ #include "src/core/lib/promise/try_seq.h"
52
+ #include "src/core/lib/resource_quota/arena.h"
53
+ #include "src/core/lib/slice/slice.h"
54
+ #include "src/core/lib/slice/slice_buffer.h"
55
+ #include "src/core/lib/transport/promise_endpoint.h"
56
+ #include "src/core/lib/transport/transport.h"
57
+ #include "src/core/util/ref_counted_ptr.h"
58
+ #include "src/core/util/sync.h"
59
+
60
+ namespace grpc_core {
61
+ namespace http2 {
62
+
63
+ using grpc_event_engine::experimental::EventEngine;
64
+
65
+ // Experimental : This is just the initial skeleton of class
66
+ // and it is functions. The code will be written iteratively.
67
+ // Do not use or edit any of these functions unless you are
68
+ // familiar with the PH2 project (Moving chttp2 to promises.)
69
+ // TODO(tjagtap) : [PH2][P3] : Delete this comment when http2
70
+ // rollout begins
71
+
72
+ void Http2ClientTransport::PerformOp(grpc_transport_op* op) {
73
+ // Notes : Refer : src/core/ext/transport/chaotic_good/client_transport.cc
74
+ // Functions : StartConnectivityWatch, StopConnectivityWatch, PerformOp
75
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport PerformOp Begin";
76
+ bool did_stuff = false;
77
+ if (op->start_connectivity_watch != nullptr) {
78
+ StartConnectivityWatch(op->start_connectivity_watch_state,
79
+ std::move(op->start_connectivity_watch));
80
+ did_stuff = true;
81
+ }
82
+ if (op->stop_connectivity_watch != nullptr) {
83
+ StopConnectivityWatch(op->stop_connectivity_watch);
84
+ did_stuff = true;
85
+ }
86
+ CHECK(!op->set_accept_stream) << "Set_accept_stream not supported on clients";
87
+ DCHECK(did_stuff) << "Unimplemented transport perform op ";
88
+
89
+ ExecCtx::Run(DEBUG_LOCATION, op->on_consumed, absl::OkStatus());
90
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport PerformOp End";
91
+ // TODO(tjagtap) : [PH2][P2] :
92
+ // Refer src/core/ext/transport/chttp2/transport/chttp2_transport.cc
93
+ // perform_transport_op_locked
94
+ // Maybe more operations needed to be implemented.
95
+ // TODO(tjagtap) : [PH2][P2] : Consider either not using a transport level
96
+ // lock, or making this run on the Transport party - whatever is better.
97
+ }
98
+
99
+ void Http2ClientTransport::StartConnectivityWatch(
100
+ grpc_connectivity_state state,
101
+ OrphanablePtr<ConnectivityStateWatcherInterface> watcher) {
102
+ MutexLock lock(&transport_mutex_);
103
+ state_tracker_.AddWatcher(state, std::move(watcher));
104
+ }
105
+
106
+ void Http2ClientTransport::StopConnectivityWatch(
107
+ ConnectivityStateWatcherInterface* watcher) {
108
+ MutexLock lock(&transport_mutex_);
109
+ state_tracker_.RemoveWatcher(watcher);
110
+ }
111
+
112
+ void Http2ClientTransport::Orphan() {
113
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport Orphan Begin";
114
+ // Accessing general_party here is not advisable. It may so happen that
115
+ // the party is already freed/may free up any time. The only guarantee here
116
+ // is that the transport is still valid.
117
+ MaybeSpawnCloseTransport(Http2Status::AbslConnectionError(
118
+ absl::StatusCode::kUnavailable, "Orphaned"));
119
+ Unref();
120
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport Orphan End";
121
+ }
122
+
123
+ void Http2ClientTransport::AbortWithError() {
124
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport AbortWithError Begin";
125
+ // TODO(tjagtap) : [PH2][P2] : Implement this function.
126
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport AbortWithError End";
127
+ }
128
+
129
+ ///////////////////////////////////////////////////////////////////////////////
130
+ // Processing each type of frame
131
+
132
+ Http2Status Http2ClientTransport::ProcessHttp2DataFrame(Http2DataFrame frame) {
133
+ // https://www.rfc-editor.org/rfc/rfc9113.html#name-data
134
+ GRPC_HTTP2_CLIENT_DLOG << "Http2Transport ProcessHttp2DataFrame { stream_id="
135
+ << frame.stream_id
136
+ << ", end_stream=" << frame.end_stream
137
+ << ", payload=" << frame.payload.JoinIntoString()
138
+ << "}";
139
+
140
+ // TODO(akshitpatel) : [PH2][P3] : Investigate if we should do this even if
141
+ // the function returns a non-ok status?
142
+ ping_manager_.ReceivedDataFrame();
143
+
144
+ // Lookup stream
145
+ GRPC_HTTP2_CLIENT_DLOG << "Http2Transport ProcessHttp2DataFrame LookupStream";
146
+ RefCountedPtr<Stream> stream = LookupStream(frame.stream_id);
147
+ if (stream == nullptr) {
148
+ // TODO(tjagtap) : [PH2][P2] : Implement the correct behaviour later.
149
+ // RFC9113 : If a DATA frame is received whose stream is not in the "open"
150
+ // or "half-closed (local)" state, the recipient MUST respond with a stream
151
+ // error (Section 5.4.2) of type STREAM_CLOSED.
152
+ GRPC_HTTP2_CLIENT_DLOG
153
+ << "Http2Transport ProcessHttp2DataFrame { stream_id="
154
+ << frame.stream_id << "} Lookup Failed";
155
+ return Http2Status::Ok();
156
+ }
157
+
158
+ // Add frame to assembler
159
+ GRPC_HTTP2_CLIENT_DLOG
160
+ << "Http2Transport ProcessHttp2DataFrame AppendNewDataFrame";
161
+ GrpcMessageAssembler& assembler = stream->assembler;
162
+ Http2Status status =
163
+ assembler.AppendNewDataFrame(frame.payload, frame.end_stream);
164
+ if (!status.IsOk()) {
165
+ GRPC_HTTP2_CLIENT_DLOG
166
+ << "Http2Transport ProcessHttp2DataFrame AppendNewDataFrame Failed";
167
+ return status;
168
+ }
169
+
170
+ // Pass the messages up the stack if it is ready.
171
+ while (true) {
172
+ GRPC_HTTP2_CLIENT_DLOG
173
+ << "Http2Transport ProcessHttp2DataFrame ExtractMessage";
174
+ ValueOrHttp2Status<MessageHandle> result = assembler.ExtractMessage();
175
+ if (!result.IsOk()) {
176
+ GRPC_HTTP2_CLIENT_DLOG
177
+ << "Http2Transport ProcessHttp2DataFrame ExtractMessage Failed";
178
+ return ValueOrHttp2Status<MessageHandle>::TakeStatus(std::move(result));
179
+ }
180
+ MessageHandle message = TakeValue(std::move(result));
181
+ if (message != nullptr) {
182
+ GRPC_HTTP2_CLIENT_DLOG
183
+ << "Http2Transport ProcessHttp2DataFrame SpawnPushMessage "
184
+ << message->DebugString();
185
+ stream->call.SpawnPushMessage(std::move(message));
186
+ continue;
187
+ }
188
+ GRPC_HTTP2_CLIENT_DLOG
189
+ << "Http2Transport ProcessHttp2DataFrame While Break";
190
+ break;
191
+ }
192
+
193
+ // TODO(tjagtap) : [PH2][P2] : List of Tests:
194
+ // 1. Data frame with unknown stream ID
195
+ // 2. Data frame with only half a message and then end stream
196
+ // 3. One data frame with a full message
197
+ // 4. Three data frames with one full message
198
+ // 5. One data frame with three full messages. All messages should be pushed.
199
+ // Will need to mock the call_handler object and test this along with the
200
+ // Header reading code. Because we need a stream in place for the lookup to
201
+ // work.
202
+ return Http2Status::Ok();
203
+ }
204
+
205
+ Http2Status Http2ClientTransport::ProcessHttp2HeaderFrame(
206
+ Http2HeaderFrame frame) {
207
+ // https://www.rfc-editor.org/rfc/rfc9113.html#name-headers
208
+ GRPC_HTTP2_CLIENT_DLOG
209
+ << "Http2Transport ProcessHttp2HeaderFrame Promise { stream_id="
210
+ << frame.stream_id << ", end_headers=" << frame.end_headers
211
+ << ", end_stream=" << frame.end_stream
212
+ << ", payload=" << frame.payload.JoinIntoString() << " }";
213
+ ping_manager_.ReceivedDataFrame();
214
+
215
+ RefCountedPtr<Http2ClientTransport::Stream> stream =
216
+ LookupStream(frame.stream_id);
217
+ if (stream == nullptr) {
218
+ // TODO(tjagtap) : [PH2][P3] : Implement this.
219
+ // RFC9113 : The identifier of a newly established stream MUST be
220
+ // numerically greater than all streams that the initiating endpoint has
221
+ // opened or reserved. This governs streams that are opened using a HEADERS
222
+ // frame and streams that are reserved using PUSH_PROMISE. An endpoint that
223
+ // receives an unexpected stream identifier MUST respond with a connection
224
+ // error (Section 5.4.1) of type PROTOCOL_ERROR.
225
+ GRPC_HTTP2_CLIENT_DLOG
226
+ << "Http2Transport ProcessHttp2HeaderFrame Promise { stream_id="
227
+ << frame.stream_id << "} Lookup Failed";
228
+ return Http2Status::Ok();
229
+ }
230
+
231
+ incoming_header_in_progress_ = !frame.end_headers;
232
+ incoming_header_stream_id_ = frame.stream_id;
233
+ incoming_header_end_stream_ = frame.end_stream;
234
+ if ((incoming_header_end_stream_ && stream->did_push_trailing_metadata) ||
235
+ (!incoming_header_end_stream_ && stream->did_push_initial_metadata)) {
236
+ return Http2Status::Http2StreamError(
237
+ Http2ErrorCode::kInternalError,
238
+ "gRPC Error : A gRPC server can send upto 1 initial metadata followed "
239
+ "by upto 1 trailing metadata");
240
+ }
241
+
242
+ HeaderAssembler& assembler = stream->header_assembler;
243
+ Http2Status append_result = assembler.AppendHeaderFrame(std::move(frame));
244
+ if (append_result.IsOk()) {
245
+ return ProcessMetadata(stream->stream_id, assembler, stream->call,
246
+ stream->did_push_initial_metadata,
247
+ stream->did_push_trailing_metadata);
248
+ }
249
+ return append_result;
250
+ }
251
+
252
+ Http2Status Http2ClientTransport::ProcessMetadata(
253
+ uint32_t stream_id, HeaderAssembler& assembler, CallHandler& call,
254
+ bool& did_push_initial_metadata, bool& did_push_trailing_metadata) {
255
+ GRPC_HTTP2_CLIENT_DLOG << "Http2Transport ProcessMetadata";
256
+ if (assembler.IsReady()) {
257
+ ValueOrHttp2Status<Arena::PoolPtr<grpc_metadata_batch>> read_result =
258
+ assembler.ReadMetadata(parser_, !incoming_header_end_stream_,
259
+ /*is_client=*/true);
260
+ if (read_result.IsOk()) {
261
+ Arena::PoolPtr<grpc_metadata_batch> metadata =
262
+ TakeValue(std::move(read_result));
263
+ if (incoming_header_end_stream_) {
264
+ // TODO(tjagtap) : [PH2][P1] : Is this the right way to differentiate
265
+ // between initial and trailing metadata?
266
+ GRPC_HTTP2_CLIENT_DLOG
267
+ << "Http2Transport ProcessMetadata SpawnPushServerTrailingMetadata";
268
+ did_push_trailing_metadata = true;
269
+ call.SpawnPushServerTrailingMetadata(std::move(metadata));
270
+ CloseStream(stream_id, absl::OkStatus(),
271
+ CloseStreamArgs{
272
+ /*close_reads=*/true,
273
+ /*close_writes=*/true,
274
+ /*send_rst_stream=*/false,
275
+ /*should_not_push_trailers=*/true,
276
+ });
277
+
278
+ } else {
279
+ GRPC_HTTP2_CLIENT_DLOG
280
+ << "Http2Transport ProcessMetadata SpawnPushServerInitialMetadata";
281
+ did_push_initial_metadata = true;
282
+ call.SpawnPushServerInitialMetadata(std::move(metadata));
283
+ }
284
+ return Http2Status::Ok();
285
+ }
286
+ GRPC_HTTP2_CLIENT_DLOG << "Http2Transport ProcessMetadata Failed";
287
+ return ValueOrHttp2Status<Arena::PoolPtr<grpc_metadata_batch>>::TakeStatus(
288
+ std::move(read_result));
289
+ }
290
+ return Http2Status::Ok();
291
+ }
292
+
293
+ Http2Status Http2ClientTransport::ProcessHttp2RstStreamFrame(
294
+ Http2RstStreamFrame frame) {
295
+ // https://www.rfc-editor.org/rfc/rfc9113.html#name-rst_stream
296
+ GRPC_HTTP2_CLIENT_DLOG
297
+ << "Http2Transport ProcessHttp2RstStreamFrame { stream_id="
298
+ << frame.stream_id << ", error_code=" << frame.error_code << " }";
299
+ Http2ErrorCode error_code =
300
+ Http2ErrorCodeFromRstFrameErrorCode(frame.error_code);
301
+ CloseStream(frame.stream_id,
302
+ absl::Status((ErrorCodeToAbslStatusCode(error_code)),
303
+ "Reset stream frame received."),
304
+ CloseStreamArgs{
305
+ /*close_reads=*/true,
306
+ /*close_writes=*/true,
307
+ /*send_rst_stream=*/false,
308
+ /*push_trailing_metadata=*/true,
309
+ });
310
+ // In case of stream error, we do not want the Read Loop to be broken. Hence
311
+ // returning an ok status.
312
+ return Http2Status::Ok();
313
+ }
314
+
315
+ Http2Status Http2ClientTransport::ProcessHttp2SettingsFrame(
316
+ Http2SettingsFrame frame) {
317
+ // https://www.rfc-editor.org/rfc/rfc9113.html#name-settings
318
+ GRPC_HTTP2_CLIENT_DLOG << "Http2Transport ProcessHttp2SettingsFrame Factory";
319
+ // TODO(tjagtap) : [PH2][P2] : Implement this.
320
+ // Load into this.settings_
321
+ // Take necessary actions as per settings that have changed.
322
+ GRPC_HTTP2_CLIENT_DLOG
323
+ << "Http2Transport ProcessHttp2SettingsFrame Promise { ack=" << frame.ack
324
+ << ", settings length=" << frame.settings.size() << "}";
325
+ if (on_receive_settings_ != nullptr) {
326
+ ExecCtx::Run(DEBUG_LOCATION, on_receive_settings_, absl::OkStatus());
327
+ on_receive_settings_ = nullptr;
328
+ }
329
+ return Http2Status::Ok();
330
+ }
331
+
332
+ auto Http2ClientTransport::ProcessHttp2PingFrame(Http2PingFrame frame) {
333
+ // https://www.rfc-editor.org/rfc/rfc9113.html#name-ping
334
+ GRPC_HTTP2_CLIENT_DLOG << "Http2Transport ProcessHttp2PingFrame { ack="
335
+ << frame.ack << ", opaque=" << frame.opaque << " }";
336
+ return AssertResultType<Http2Status>(If(
337
+ frame.ack,
338
+ [self = RefAsSubclass<Http2ClientTransport>(), opaque = frame.opaque]() {
339
+ // Received a ping ack.
340
+ if (!self->ping_manager_.AckPing(opaque)) {
341
+ GRPC_HTTP2_CLIENT_DLOG
342
+ << "Unknown ping response received for ping id=" << opaque;
343
+ }
344
+ return Immediate(Http2Status::Ok());
345
+ },
346
+ [self = RefAsSubclass<Http2ClientTransport>(), opaque = frame.opaque]() {
347
+ // TODO(akshitpatel) : [PH2][P2] : Have a counter to track number of
348
+ // pending induced frames (Ping/Settings Ack). This is to ensure that
349
+ // if write is taking a long time, we can stop reads and prioritize
350
+ // writes.
351
+ // RFC9113: PING responses SHOULD be given higher priority than any
352
+ // other frame.
353
+ self->pending_ping_acks_.push_back(opaque);
354
+ // TODO(akshitpatel) : [PH2][P2] : This is done assuming that the other
355
+ // ProcessFrame promises may return stream or connection failures. If
356
+ // this does not turn out to be true, consider returning absl::Status
357
+ // here.
358
+ return Map(self->TriggerWriteCycle(), [](absl::Status status) {
359
+ return (status.ok())
360
+ ? Http2Status::Ok()
361
+ : Http2Status::AbslConnectionError(
362
+ status.code(), std::string(status.message()));
363
+ });
364
+ }));
365
+ }
366
+
367
+ Http2Status Http2ClientTransport::ProcessHttp2GoawayFrame(
368
+ Http2GoawayFrame frame) {
369
+ // https://www.rfc-editor.org/rfc/rfc9113.html#name-goaway
370
+ GRPC_HTTP2_CLIENT_DLOG << "Http2Transport ProcessHttp2GoawayFrame Factory";
371
+ // TODO(tjagtap) : [PH2][P2] : Implement this.
372
+ GRPC_HTTP2_CLIENT_DLOG << "Http2Transport ProcessHttp2GoawayFrame Promise { "
373
+ "last_stream_id="
374
+ << frame.last_stream_id
375
+ << ", error_code=" << frame.error_code
376
+ << ", debug_data=" << frame.debug_data.as_string_view()
377
+ << "}";
378
+ return Http2Status::Ok();
379
+ }
380
+
381
+ Http2Status Http2ClientTransport::ProcessHttp2WindowUpdateFrame(
382
+ Http2WindowUpdateFrame frame) {
383
+ // https://www.rfc-editor.org/rfc/rfc9113.html#name-window_update
384
+ GRPC_HTTP2_CLIENT_DLOG
385
+ << "Http2Transport ProcessHttp2WindowUpdateFrame Factory";
386
+ // TODO(tjagtap) : [PH2][P2] : Implement this.
387
+ GRPC_HTTP2_CLIENT_DLOG
388
+ << "Http2Transport ProcessHttp2WindowUpdateFrame Promise { "
389
+ " stream_id="
390
+ << frame.stream_id << ", increment=" << frame.increment << "}";
391
+ return Http2Status::Ok();
392
+ }
393
+
394
+ Http2Status Http2ClientTransport::ProcessHttp2ContinuationFrame(
395
+ Http2ContinuationFrame frame) {
396
+ // https://www.rfc-editor.org/rfc/rfc9113.html#name-continuation
397
+ GRPC_HTTP2_CLIENT_DLOG
398
+ << "Http2Transport ProcessHttp2ContinuationFrame Promise { "
399
+ "stream_id="
400
+ << frame.stream_id << ", end_headers=" << frame.end_headers
401
+ << ", payload=" << frame.payload.JoinIntoString() << " }";
402
+ incoming_header_in_progress_ = !frame.end_headers;
403
+ RefCountedPtr<Stream> stream = LookupStream(frame.stream_id);
404
+ if (stream == nullptr) {
405
+ // TODO(tjagtap) : [PH2][P3] : Implement this.
406
+ // RFC9113 : The identifier of a newly established stream MUST be
407
+ // numerically greater than all streams that the initiating endpoint has
408
+ // opened or reserved. This governs streams that are opened using a HEADERS
409
+ // frame and streams that are reserved using PUSH_PROMISE. An endpoint that
410
+ // receives an unexpected stream identifier MUST respond with a connection
411
+ // error (Section 5.4.1) of type PROTOCOL_ERROR.
412
+ return Http2Status::Ok();
413
+ }
414
+
415
+ HeaderAssembler& assember = stream->header_assembler;
416
+ Http2Status result = assember.AppendContinuationFrame(std::move(frame));
417
+ if (result.IsOk()) {
418
+ return ProcessMetadata(stream->stream_id, assember, stream->call,
419
+ stream->did_push_initial_metadata,
420
+ stream->did_push_trailing_metadata);
421
+ }
422
+ return result;
423
+ }
424
+
425
+ Http2Status Http2ClientTransport::ProcessHttp2SecurityFrame(
426
+ Http2SecurityFrame frame) {
427
+ GRPC_HTTP2_CLIENT_DLOG << "Http2Transport ProcessHttp2SecurityFrame Factory";
428
+ // TODO(tjagtap) : [PH2][P2] : Implement this.
429
+ GRPC_HTTP2_CLIENT_DLOG
430
+ << "Http2Transport ProcessHttp2SecurityFrame Promise { payload="
431
+ << frame.payload.JoinIntoString() << " }";
432
+ return Http2Status::Ok();
433
+ }
434
+
435
+ auto Http2ClientTransport::ProcessOneFrame(Http2Frame frame) {
436
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport ProcessOneFrame Factory";
437
+ return AssertResultType<Http2Status>(MatchPromise(
438
+ std::move(frame),
439
+ [self = RefAsSubclass<Http2ClientTransport>()](Http2DataFrame frame) {
440
+ return self->ProcessHttp2DataFrame(std::move(frame));
441
+ },
442
+ [self = RefAsSubclass<Http2ClientTransport>()](Http2HeaderFrame frame) {
443
+ return self->ProcessHttp2HeaderFrame(std::move(frame));
444
+ },
445
+ [self =
446
+ RefAsSubclass<Http2ClientTransport>()](Http2RstStreamFrame frame) {
447
+ return self->ProcessHttp2RstStreamFrame(frame);
448
+ },
449
+ [self = RefAsSubclass<Http2ClientTransport>()](Http2SettingsFrame frame) {
450
+ return self->ProcessHttp2SettingsFrame(std::move(frame));
451
+ },
452
+ [self = RefAsSubclass<Http2ClientTransport>()](Http2PingFrame frame) {
453
+ return self->ProcessHttp2PingFrame(frame);
454
+ },
455
+ [self = RefAsSubclass<Http2ClientTransport>()](Http2GoawayFrame frame) {
456
+ return self->ProcessHttp2GoawayFrame(std::move(frame));
457
+ },
458
+ [self = RefAsSubclass<Http2ClientTransport>()](
459
+ Http2WindowUpdateFrame frame) {
460
+ return self->ProcessHttp2WindowUpdateFrame(frame);
461
+ },
462
+ [self = RefAsSubclass<Http2ClientTransport>()](
463
+ Http2ContinuationFrame frame) {
464
+ return self->ProcessHttp2ContinuationFrame(std::move(frame));
465
+ },
466
+ [self = RefAsSubclass<Http2ClientTransport>()](Http2SecurityFrame frame) {
467
+ return self->ProcessHttp2SecurityFrame(std::move(frame));
468
+ },
469
+ [](GRPC_UNUSED Http2UnknownFrame frame) {
470
+ // As per HTTP2 RFC, implementations MUST ignore and discard frames of
471
+ // unknown types.
472
+ return Http2Status::Ok();
473
+ },
474
+ [](GRPC_UNUSED Http2EmptyFrame frame) {
475
+ LOG(DFATAL)
476
+ << "ParseFramePayload should never return a Http2EmptyFrame";
477
+ return Http2Status::Ok();
478
+ }));
479
+ }
480
+
481
+ ///////////////////////////////////////////////////////////////////////////////
482
+ // Read Related Promises and Promise Factories
483
+
484
+ auto Http2ClientTransport::ReadAndProcessOneFrame() {
485
+ GRPC_HTTP2_CLIENT_DLOG
486
+ << "Http2ClientTransport ReadAndProcessOneFrame Factory";
487
+ return AssertResultType<absl::Status>(TrySeq(
488
+ // Fetch the first kFrameHeaderSize bytes of the Frame, these contain
489
+ // the frame header.
490
+ EndpointReadSlice(kFrameHeaderSize),
491
+ // Parse the frame header.
492
+ [](Slice header_bytes) -> Http2FrameHeader {
493
+ GRPC_HTTP2_CLIENT_DLOG
494
+ << "Http2ClientTransport ReadAndProcessOneFrame Parse "
495
+ << header_bytes.as_string_view();
496
+ return Http2FrameHeader::Parse(header_bytes.begin());
497
+ },
498
+ // Validate the incoming frame as per the current state of the transport
499
+ [self = RefAsSubclass<Http2ClientTransport>()](Http2FrameHeader header) {
500
+ if (self->incoming_header_in_progress_ &&
501
+ (self->current_frame_header_.type != 9 /*Continuation*/ ||
502
+ self->current_frame_header_.stream_id !=
503
+ self->incoming_header_stream_id_)) {
504
+ LOG(ERROR) << "Closing Connection " << header.ToString() << " "
505
+ << kAssemblerContiguousSequenceError;
506
+ return self->HandleError(Http2Status::Http2ConnectionError(
507
+ Http2ErrorCode::kProtocolError,
508
+ std::string(kAssemblerContiguousSequenceError)));
509
+ }
510
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport ReadAndProcessOneFrame "
511
+ "Validated Frame Header:"
512
+ << header.ToString();
513
+ self->current_frame_header_ = header;
514
+ return absl::OkStatus();
515
+ },
516
+ // Read the payload of the frame.
517
+ [self = RefAsSubclass<Http2ClientTransport>()]() {
518
+ GRPC_HTTP2_CLIENT_DLOG
519
+ << "Http2ClientTransport ReadAndProcessOneFrame Read Frame ";
520
+ return AssertResultType<absl::StatusOr<SliceBuffer>>(
521
+ self->EndpointRead(self->current_frame_header_.length));
522
+ },
523
+ // Parse the payload of the frame based on frame type.
524
+ [self = RefAsSubclass<Http2ClientTransport>()](
525
+ SliceBuffer payload) -> absl::StatusOr<Http2Frame> {
526
+ GRPC_HTTP2_CLIENT_DLOG
527
+ << "Http2ClientTransport ReadAndProcessOneFrame ParseFramePayload "
528
+ << payload.JoinIntoString();
529
+ ValueOrHttp2Status<Http2Frame> frame =
530
+ ParseFramePayload(self->current_frame_header_, std::move(payload));
531
+ if (!frame.IsOk()) {
532
+ return self->HandleError(
533
+ ValueOrHttp2Status<Http2Frame>::TakeStatus(std::move(frame)));
534
+ }
535
+ return TakeValue(std::move(frame));
536
+ },
537
+ [self = RefAsSubclass<Http2ClientTransport>()](
538
+ GRPC_UNUSED Http2Frame frame) {
539
+ GRPC_HTTP2_CLIENT_DLOG
540
+ << "Http2ClientTransport ReadAndProcessOneFrame ProcessOneFrame";
541
+ return AssertResultType<absl::Status>(
542
+ Map(self->ProcessOneFrame(std::move(frame)),
543
+ [self](Http2Status status) {
544
+ if (!status.IsOk()) {
545
+ return self->HandleError(std::move(status));
546
+ }
547
+ return absl::OkStatus();
548
+ }));
549
+ }));
550
+ }
551
+
552
+ auto Http2ClientTransport::ReadLoop() {
553
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport ReadLoop Factory";
554
+ return AssertResultType<absl::Status>(
555
+ Loop([self = RefAsSubclass<Http2ClientTransport>()]() {
556
+ return TrySeq(self->ReadAndProcessOneFrame(),
557
+ []() -> LoopCtl<absl::Status> {
558
+ GRPC_HTTP2_CLIENT_DLOG
559
+ << "Http2ClientTransport ReadLoop Continue";
560
+ return Continue();
561
+ });
562
+ }));
563
+ }
564
+
565
+ auto Http2ClientTransport::OnReadLoopEnded() {
566
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport OnReadLoopEnded Factory";
567
+ return
568
+ [self = RefAsSubclass<Http2ClientTransport>()](absl::Status status) {
569
+ GRPC_HTTP2_CLIENT_DLOG
570
+ << "Http2ClientTransport OnReadLoopEnded Promise Status=" << status;
571
+ GRPC_UNUSED absl::Status error =
572
+ self->HandleError(Http2Status::AbslConnectionError(
573
+ status.code(), std::string(status.message())));
574
+ };
575
+ }
576
+
577
+ ///////////////////////////////////////////////////////////////////////////////
578
+ // Write Related Promises and Promise Factories
579
+
580
+ auto Http2ClientTransport::WriteFromQueue() {
581
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport WriteFromQueue Factory";
582
+ return TrySeq(
583
+ outgoing_frames_.NextBatch(128),
584
+ [self = RefAsSubclass<Http2ClientTransport>()](
585
+ std::vector<Http2Frame> frames) {
586
+ SliceBuffer output_buf;
587
+ if (self->is_first_write_) {
588
+ GRPC_HTTP2_CLIENT_DLOG
589
+ << "Http2ClientTransport Write GRPC_CHTTP2_CLIENT_CONNECT_STRING";
590
+ output_buf.Append(Slice(grpc_slice_from_copied_string(
591
+ GRPC_CHTTP2_CLIENT_CONNECT_STRING)));
592
+ self->is_first_write_ = false;
593
+ }
594
+ Serialize(absl::Span<Http2Frame>(frames), output_buf);
595
+ uint64_t buffer_length = output_buf.Length();
596
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport WriteFromQueue Promise";
597
+ return If(
598
+ buffer_length > 0,
599
+ [self, output_buffer = std::move(output_buf)]() mutable {
600
+ self->bytes_sent_in_last_write_ = true;
601
+ return self->endpoint_.Write(std::move(output_buffer),
602
+ PromiseEndpoint::WriteArgs{});
603
+ },
604
+ [] { return absl::OkStatus(); });
605
+ });
606
+ }
607
+
608
+ auto Http2ClientTransport::WriteLoop() {
609
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport WriteLoop Factory";
610
+ return AssertResultType<absl::Status>(
611
+ Loop([self = RefAsSubclass<Http2ClientTransport>()]() {
612
+ // TODO(akshitpatel) : [PH2][P1] : Once a common SliceBuffer is used, we
613
+ // can move bytes_sent_in_last_write_ to be a local variable.
614
+ self->bytes_sent_in_last_write_ = false;
615
+ return TrySeq(
616
+ // TODO(akshitpatel) : [PH2][P1] : WriteFromQueue may write settings
617
+ // acks as well. This will break the call to ResetPingClock as it
618
+ // only needs to be called on writing Data/Header/WindowUpdate
619
+ // frames. Possible fixes: Either WriteFromQueue iterates over all
620
+ // the frames and figures out the types of frames needed (this may
621
+ // anyways be needed to check that we do not send frames for closed
622
+ // streams) or we have flags to indicate the types of frame that are
623
+ // enqueued.
624
+ self->WriteFromQueue(), [self] { return self->MaybeSendPing(); },
625
+ [self] { return self->MaybeSendPingAcks(); },
626
+ [self]() -> LoopCtl<absl::Status> {
627
+ // If any Header/Data/WindowUpdate frame was sent in the last
628
+ // write, reset the ping clock.
629
+ if (self->bytes_sent_in_last_write_) {
630
+ self->ping_manager_.ResetPingClock(/*is_client=*/true);
631
+ }
632
+ GRPC_HTTP2_CLIENT_DLOG
633
+ << "Http2ClientTransport WriteLoop Continue";
634
+ return Continue();
635
+ });
636
+ }));
637
+ }
638
+
639
+ auto Http2ClientTransport::OnWriteLoopEnded() {
640
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport OnWriteLoopEnded Factory";
641
+ return
642
+ [self = RefAsSubclass<Http2ClientTransport>()](absl::Status status) {
643
+ GRPC_HTTP2_CLIENT_DLOG
644
+ << "Http2ClientTransport OnWriteLoopEnded Promise Status="
645
+ << status;
646
+ GRPC_UNUSED absl::Status error =
647
+ self->HandleError(Http2Status::AbslConnectionError(
648
+ status.code(), std::string(status.message())));
649
+ };
650
+ }
651
+
652
+ ///////////////////////////////////////////////////////////////////////////////
653
+ // Constructor Destructor
654
+
655
+ Http2ClientTransport::Http2ClientTransport(
656
+ PromiseEndpoint endpoint, GRPC_UNUSED const ChannelArgs& channel_args,
657
+ std::shared_ptr<EventEngine> event_engine,
658
+ grpc_closure* on_receive_settings)
659
+ : endpoint_(std::move(endpoint)),
660
+ outgoing_frames_(kMpscSize),
661
+ stream_id_mutex_(/*Initial Stream Id*/ 1),
662
+ bytes_sent_in_last_write_(false),
663
+ incoming_header_in_progress_(false),
664
+ incoming_header_end_stream_(false),
665
+ is_first_write_(true),
666
+ incoming_header_stream_id_(0),
667
+ on_receive_settings_(on_receive_settings),
668
+ keepalive_time_(std::max(
669
+ Duration::Seconds(10),
670
+ channel_args.GetDurationFromIntMillis(GRPC_ARG_KEEPALIVE_TIME_MS)
671
+ .value_or(Duration::Infinity()))),
672
+ // Keepalive timeout is only passed to the keepalive manager if it is less
673
+ // than the ping timeout. As keepalives use pings for health checks, if
674
+ // keepalive timeout is greater than ping timeout, we would always hit the
675
+ // ping timeout first.
676
+ keepalive_timeout_(std::max(
677
+ Duration::Zero(),
678
+ channel_args.GetDurationFromIntMillis(GRPC_ARG_KEEPALIVE_TIMEOUT_MS)
679
+ .value_or(keepalive_time_ == Duration::Infinity()
680
+ ? Duration::Infinity()
681
+ : (Duration::Seconds(20))))),
682
+ ping_timeout_(std::max(
683
+ Duration::Zero(),
684
+ channel_args.GetDurationFromIntMillis(GRPC_ARG_PING_TIMEOUT_MS)
685
+ .value_or(keepalive_time_ == Duration::Infinity()
686
+ ? Duration::Infinity()
687
+ : Duration::Minutes(1)))),
688
+ ping_manager_(channel_args, PingSystemInterfaceImpl::Make(this),
689
+ event_engine),
690
+ keepalive_manager_(
691
+ KeepAliveInterfaceImpl::Make(this),
692
+ ((keepalive_timeout_ < ping_timeout_) ? keepalive_timeout_
693
+ : Duration::Infinity()),
694
+ keepalive_time_),
695
+ keepalive_permit_without_calls_(false) {
696
+ // TODO(tjagtap) : [PH2][P2] : Save and apply channel_args.
697
+ // TODO(tjagtap) : [PH2][P2] : Initialize settings_ to appropriate values.
698
+
699
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport Constructor Begin";
700
+
701
+ // Initialize the general party and write party.
702
+ auto general_party_arena = SimpleArenaAllocator(0)->MakeArena();
703
+ general_party_arena->SetContext<EventEngine>(event_engine.get());
704
+ general_party_ = Party::Make(std::move(general_party_arena));
705
+
706
+ general_party_->Spawn("ReadLoop", ReadLoop(), OnReadLoopEnded());
707
+ // TODO(tjagtap) : [PH2][P2] Fix when needed.
708
+ general_party_->Spawn("WriteLoop", WriteLoop(), OnWriteLoopEnded());
709
+
710
+ // The keepalive loop is only spawned if the keepalive time is not infinity.
711
+ keepalive_manager_.Spawn(general_party_.get());
712
+
713
+ // TODO(tjagtap) : [PH2][P2] Fix Settings workflow.
714
+ Http2ErrorCode code = settings_.mutable_local().Apply(
715
+ Http2Settings::kInitialWindowSizeWireId,
716
+ (Http2Settings::max_initial_window_size() - 1));
717
+ DCHECK(code == Http2ErrorCode::kNoError);
718
+ std::optional<Http2SettingsFrame> settings_frame =
719
+ settings_.MaybeSendUpdate();
720
+ if (settings_frame.has_value()) {
721
+ general_party_->Spawn(
722
+ "SendFirstSettingsFrame",
723
+ [self = RefAsSubclass<Http2ClientTransport>(),
724
+ frame = std::move(*settings_frame)]() mutable {
725
+ return self->EnqueueOutgoingFrame(std::move(frame));
726
+ },
727
+ [](GRPC_UNUSED absl::Status status) {});
728
+ }
729
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport Constructor End";
730
+ }
731
+
732
+ // This function MUST be idempotent.
733
+ void Http2ClientTransport::CloseStream(uint32_t stream_id, absl::Status status,
734
+ CloseStreamArgs args,
735
+ DebugLocation whence) {
736
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::CloseStream for stream id: "
737
+ << stream_id << " status=" << status
738
+ << " location=" << whence.file() << ":"
739
+ << whence.line();
740
+
741
+ // TODO(akshitpatel) : [PH2][P3] : Measure the impact of holding mutex
742
+ // throughout this function.
743
+ MutexLock lock(&transport_mutex_);
744
+ auto pair = stream_list_.find(stream_id);
745
+ if (pair == stream_list_.end()) {
746
+ GRPC_HTTP2_CLIENT_DLOG
747
+ << "Http2ClientTransport::CloseStream for stream id: " << stream_id
748
+ << " stream not found";
749
+ return;
750
+ }
751
+ auto& stream = pair->second;
752
+
753
+ if (args.close_reads) {
754
+ stream->MarkHalfClosedRemote();
755
+ }
756
+ if (args.close_writes) {
757
+ stream->MarkHalfClosedLocal();
758
+ }
759
+
760
+ if (stream->IsClosed()) {
761
+ GRPC_HTTP2_CLIENT_DLOG
762
+ << "Http2ClientTransport::CloseStream for stream id: " << stream_id
763
+ << " closing stream.";
764
+ if (args.send_rst_stream) {
765
+ // TODO(akshitpatel) : [PH2][P2] : Send RST_STREAM frame.
766
+ }
767
+
768
+ if (args.push_trailing_metadata) {
769
+ stream->call.SpawnPushServerTrailingMetadata(
770
+ ServerMetadataFromStatus(status));
771
+ }
772
+ stream_list_.erase(stream_id);
773
+ }
774
+ }
775
+
776
+ void Http2ClientTransport::CloseTransport() {
777
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::CloseTransport";
778
+
779
+ // This is the only place where the general_party_ is
780
+ // reset.
781
+ general_party_.reset();
782
+ }
783
+
784
+ void Http2ClientTransport::MaybeSpawnCloseTransport(Http2Status http2_status,
785
+ DebugLocation whence) {
786
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::MaybeSpawnCloseTransport "
787
+ "status="
788
+ << http2_status << " location=" << whence.file() << ":"
789
+ << whence.line();
790
+
791
+ // Free up the stream_list at this point. This would still allow the frames
792
+ // in the MPSC to be drained and block any additional frames from being
793
+ // enqueued. Additionally this also prevents additional frames with non-zero
794
+ // stream_ids from being processed by the read loop.
795
+ ReleasableMutexLock lock(&transport_mutex_);
796
+ if (is_transport_closed_) {
797
+ lock.Release();
798
+ return;
799
+ }
800
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::MaybeSpawnCloseTransport "
801
+ "Initiating transport close";
802
+ is_transport_closed_ = true;
803
+ absl::flat_hash_map<uint32_t, RefCountedPtr<Stream>> stream_list =
804
+ std::move(stream_list_);
805
+ stream_list_.clear();
806
+ state_tracker_.SetState(GRPC_CHANNEL_SHUTDOWN,
807
+ http2_status.GetAbslConnectionError(),
808
+ "transport closed");
809
+ lock.Release();
810
+
811
+ general_party_->Spawn(
812
+ "CloseTransport",
813
+ [self = RefAsSubclass<Http2ClientTransport>(),
814
+ stream_list = std::move(stream_list),
815
+ http2_status = std::move(http2_status)]() mutable {
816
+ GRPC_HTTP2_CLIENT_DLOG
817
+ << "Http2ClientTransport::CloseTransport Cleaning up call stacks";
818
+ // Clean up the call stacks for all active streams.
819
+ for (const auto& pair : stream_list) {
820
+ // There is no merit in transitioning the stream to
821
+ // closed state here as the subsequent lookups would
822
+ // fail. Also, as this is running on the transport
823
+ // party, there would not be concurrent access to the stream.
824
+ auto& stream = pair.second;
825
+ stream->call.SpawnPushServerTrailingMetadata(
826
+ ServerMetadataFromStatus(http2_status.GetAbslConnectionError()));
827
+ }
828
+
829
+ // RFC9113 : A GOAWAY frame might not immediately precede closing of
830
+ // the connection; a receiver of a GOAWAY that has no more use for the
831
+ // connection SHOULD still send a GOAWAY frame before terminating the
832
+ // connection.
833
+ // TODO(akshitpatel) : [PH2][P2] : There would a timer for sending
834
+ // goaway here. Once goaway is sent or timer is expired, close the
835
+ // transport.
836
+ return Map(Immediate(absl::OkStatus()),
837
+ [self](GRPC_UNUSED absl::Status) mutable {
838
+ self->CloseTransport();
839
+ return Empty{};
840
+ });
841
+ },
842
+ [](Empty) {});
843
+ }
844
+
845
+ Http2ClientTransport::~Http2ClientTransport() {
846
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport Destructor Begin";
847
+ DCHECK(stream_list_.empty());
848
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport Destructor End";
849
+ }
850
+
851
+ ///////////////////////////////////////////////////////////////////////////////
852
+ // Stream Related Operations
853
+
854
+ RefCountedPtr<Http2ClientTransport::Stream> Http2ClientTransport::LookupStream(
855
+ uint32_t stream_id) {
856
+ MutexLock lock(&transport_mutex_);
857
+ auto it = stream_list_.find(stream_id);
858
+ if (it == stream_list_.end()) {
859
+ GRPC_HTTP2_CLIENT_DLOG
860
+ << "Http2ClientTransport::LookupStream Stream not found stream_id="
861
+ << stream_id;
862
+ return nullptr;
863
+ }
864
+ return it->second;
865
+ }
866
+
867
+ bool Http2ClientTransport::MakeStream(CallHandler call_handler,
868
+ const uint32_t stream_id) {
869
+ // https://datatracker.ietf.org/doc/html/rfc9113#name-stream-identifiers
870
+ // TODO(tjagtap) : [PH2][P2] Validate implementation.
871
+
872
+ // TODO(akshitpatel) : [PH2][P1] : Probably do not need this lock. This
873
+ // function is always called under the stream_id_mutex_. The issue is the
874
+ // OnDone needs to be synchronous and hence InterActivityMutex might not be
875
+ // an option to protect the stream_list_.
876
+ MutexLock lock(&transport_mutex_);
877
+ const bool on_done_added =
878
+ call_handler.OnDone([self = RefAsSubclass<Http2ClientTransport>(),
879
+ stream_id](bool cancelled) {
880
+ GRPC_HTTP2_CLIENT_DLOG << "PH2: Client call " << self.get()
881
+ << " id=" << stream_id
882
+ << " done: cancelled=" << cancelled;
883
+ if (cancelled) {
884
+ // TODO(akshitpatel) : [PH2][P2] : There are two ways to handle
885
+ // cancellation.
886
+ // 1. Call CloseStream from the on_done callback as done here. This
887
+ // will be invoked when PullServerTrailingMetadata resolves.
888
+ // 2. Call CloseStream from the OutboundLoop. When the call is
889
+ // cancelled, for_each() should return with an error. The
890
+ // WasCancelled() function can be used to determinie if the call
891
+ // was cancelled.
892
+ // At this point, both the above mentioned approaches seem to be more
893
+ // or less the same as both are running on the call party.
894
+ self->CloseStream(stream_id, absl::CancelledError(),
895
+ CloseStreamArgs{
896
+ /*close_reads=*/true,
897
+ /*close_writes=*/true,
898
+ /*send_rst_stream=*/true,
899
+ /*push_trailing_metadata=*/false,
900
+ });
901
+ }
902
+ });
903
+ if (!on_done_added) return false;
904
+ stream_list_.emplace(
905
+ stream_id, MakeRefCounted<Stream>(std::move(call_handler), stream_id));
906
+ return true;
907
+ }
908
+
909
+ ///////////////////////////////////////////////////////////////////////////////
910
+ // Call Spine related operations
911
+
912
+ auto Http2ClientTransport::CallOutboundLoop(
913
+ CallHandler call_handler, const uint32_t stream_id,
914
+ InterActivityMutex<uint32_t>::Lock lock /* Locked stream_id_mutex */,
915
+ ClientMetadataHandle metadata) {
916
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport CallOutboundLoop";
917
+
918
+ // Convert a message to a Http2DataFrame and send the frame out.
919
+ auto send_message =
920
+ [self = RefAsSubclass<Http2ClientTransport>(),
921
+ stream_id](MessageHandle message) mutable {
922
+ // TODO(akshitpatel) : [PH2][P2] : Assuming one message per frame.
923
+ // This will eventually change as more logic is added.
924
+ SliceBuffer frame_payload;
925
+ size_t payload_size = message->payload()->Length();
926
+ AppendGrpcHeaderToSliceBuffer(frame_payload, message->flags(),
927
+ payload_size);
928
+ frame_payload.TakeAndAppend(*message->payload());
929
+ Http2DataFrame frame{stream_id, /*end_stream*/ false,
930
+ std::move(frame_payload)};
931
+ GRPC_HTTP2_CLIENT_DLOG
932
+ << "Http2ClientTransport CallOutboundLoop send_message";
933
+ return self->EnqueueOutgoingFrame(std::move(frame));
934
+ };
935
+
936
+ SliceBuffer buf;
937
+ encoder_.EncodeRawHeaders(*metadata.get(), buf);
938
+ Http2Frame frame = Http2HeaderFrame{stream_id, /*end_headers*/ true,
939
+ /*end_stream*/ false, std::move(buf)};
940
+ return GRPC_LATENT_SEE_PROMISE(
941
+ "Ph2CallOutboundLoop",
942
+ TrySeq(
943
+ Map(EnqueueOutgoingFrame(std::move(frame)),
944
+ [self = RefAsSubclass<Http2ClientTransport>(),
945
+ stream_id](absl::Status status) {
946
+ if (status.ok()) {
947
+ // TODO(akshitpatel) : [PH2][P3] : Investigate if stream
948
+ // lookup can be done once outside the promise and all the
949
+ // promises can hold a reference to the stream.
950
+ auto stream = self->LookupStream(stream_id);
951
+ if (GPR_UNLIKELY(stream == nullptr)) {
952
+ LOG(ERROR)
953
+ << "Stream not found while sending initial metadata";
954
+ return absl::InternalError(
955
+ "Stream not found while sending initial metadata");
956
+ }
957
+ stream->SentInitialMetadata();
958
+ }
959
+ return status;
960
+ }),
961
+ [call_handler, send_message, lock = std::move(lock)]() {
962
+ // The lock will be released once the promise is constructed from
963
+ // this factory. ForEach will be polled after the lock is
964
+ // released.
965
+ return ForEach(MessagesFrom(call_handler), send_message);
966
+ },
967
+ [self = RefAsSubclass<Http2ClientTransport>(), stream_id]() mutable {
968
+ // TODO(akshitpatel): [PH2][P2] : Figure out a way to send the end
969
+ // of stream frame in the same frame as the last message.
970
+ Http2DataFrame frame{stream_id, /*end_stream*/ true, SliceBuffer()};
971
+ return self->EnqueueOutgoingFrame(std::move(frame));
972
+ },
973
+ [call_handler]() mutable {
974
+ return Map(call_handler.WasCancelled(), [](bool cancelled) {
975
+ GRPC_HTTP2_CLIENT_DLOG
976
+ << "Http2ClientTransport PH2CallOutboundLoop End with "
977
+ "cancelled="
978
+ << cancelled;
979
+ return (cancelled) ? absl::CancelledError() : absl::OkStatus();
980
+ });
981
+ }));
982
+ }
983
+
984
+ void Http2ClientTransport::StartCall(CallHandler call_handler) {
985
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport StartCall Begin";
986
+ call_handler.SpawnGuarded(
987
+ "OutboundLoop",
988
+ TrySeq(
989
+ call_handler.PullClientInitialMetadata(),
990
+ [self = RefAsSubclass<Http2ClientTransport>()](
991
+ ClientMetadataHandle metadata) {
992
+ // Lock the stream_id_mutex_
993
+ return Staple(self->stream_id_mutex_.Acquire(),
994
+ std::move(metadata));
995
+ },
996
+ [self = RefAsSubclass<Http2ClientTransport>(),
997
+ call_handler](auto args /* Locked stream_id_mutex */) mutable {
998
+ // TODO (akshitpatel) : [PH2][P2] :
999
+ // Check for max concurrent streams.
1000
+ const uint32_t stream_id = self->NextStreamId(std::get<0>(args));
1001
+ return If(
1002
+ self->MakeStream(call_handler, stream_id),
1003
+ [self, call_handler, stream_id,
1004
+ args = std::move(args)]() mutable {
1005
+ return Map(
1006
+ self->CallOutboundLoop(call_handler, stream_id,
1007
+ std::move(std::get<0>(args)),
1008
+ std::move(std::get<1>(args))),
1009
+ [](absl::Status status) { return status; });
1010
+ },
1011
+ []() { return absl::InternalError("Failed to make stream"); });
1012
+ }));
1013
+ GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport StartCall End";
1014
+ }
1015
+
1016
+ } // namespace http2
1017
+ } // namespace grpc_core