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.
- checksums.yaml +4 -4
- data/Makefile +38 -17
- data/include/grpc/create_channel_from_endpoint.h +54 -0
- data/include/grpc/credentials.h +11 -5
- data/include/grpc/event_engine/event_engine.h +74 -17
- data/include/grpc/grpc_posix.h +20 -1
- data/include/grpc/impl/channel_arg_names.h +2 -4
- data/include/grpc/module.modulemap +1 -0
- data/include/grpc/support/json.h +24 -0
- data/src/core/call/interception_chain.h +7 -11
- data/src/core/channelz/channel_trace.cc +213 -115
- data/src/core/channelz/channel_trace.h +380 -86
- data/src/core/channelz/channelz.cc +270 -181
- data/src/core/channelz/channelz.h +168 -55
- data/src/core/channelz/channelz_registry.cc +2 -1
- data/src/core/channelz/channelz_registry.h +24 -0
- data/src/core/channelz/property_list.cc +357 -0
- data/src/core/channelz/property_list.h +202 -0
- data/src/core/channelz/ztrace_collector.h +3 -2
- data/src/core/client_channel/backup_poller.cc +17 -2
- data/src/core/client_channel/client_channel.cc +17 -28
- data/src/core/client_channel/client_channel_filter.cc +19 -29
- data/src/core/client_channel/config_selector.h +8 -2
- data/src/core/client_channel/dynamic_filters.cc +5 -6
- data/src/core/client_channel/dynamic_filters.h +1 -1
- data/src/core/client_channel/global_subchannel_pool.cc +4 -1
- data/src/core/client_channel/retry_filter.cc +21 -27
- data/src/core/client_channel/retry_filter.h +10 -7
- data/src/core/client_channel/retry_filter_legacy_call_data.cc +5 -5
- data/src/core/client_channel/retry_filter_legacy_call_data.h +1 -1
- data/src/core/client_channel/retry_interceptor.cc +30 -44
- data/src/core/client_channel/retry_interceptor.h +18 -17
- data/src/core/client_channel/retry_throttle.cc +46 -61
- data/src/core/client_channel/retry_throttle.h +17 -39
- data/src/core/client_channel/subchannel.cc +43 -19
- data/src/core/client_channel/subchannel.h +8 -0
- data/src/core/config/config_vars.cc +2 -0
- data/src/core/config/core_configuration.cc +1 -0
- data/src/core/config/core_configuration.h +11 -0
- data/src/core/credentials/call/call_creds_registry.h +125 -0
- data/src/core/credentials/call/call_creds_registry_init.cc +91 -0
- data/src/core/credentials/call/gcp_service_account_identity/gcp_service_account_identity_credentials.cc +6 -48
- data/src/core/credentials/call/jwt_token_file/jwt_token_file_call_credentials.cc +86 -0
- data/src/core/credentials/call/jwt_token_file/jwt_token_file_call_credentials.h +74 -0
- data/src/core/credentials/call/jwt_util.cc +70 -0
- data/src/core/credentials/call/jwt_util.h +32 -0
- data/src/core/credentials/transport/channel_creds_registry_init.cc +1 -1
- data/src/core/credentials/transport/google_default/google_default_credentials.cc +72 -4
- data/src/core/credentials/transport/ssl/ssl_credentials.cc +0 -1
- data/src/core/credentials/transport/tls/load_system_roots_supported.cc +1 -0
- data/src/core/credentials/transport/xds/xds_credentials.cc +0 -3
- data/src/core/ext/filters/gcp_authentication/gcp_authentication_filter.cc +8 -8
- data/src/core/ext/filters/gcp_authentication/gcp_authentication_filter.h +16 -16
- data/src/core/ext/filters/http/client_authority_filter.cc +2 -4
- data/src/core/ext/filters/http/message_compress/compression_filter.h +25 -22
- data/src/core/ext/filters/http/server/http_server_filter.h +12 -11
- data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +120 -35
- data/src/core/ext/transport/chttp2/server/chttp2_server.cc +6 -5
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +162 -115
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.h +0 -3
- data/src/core/ext/transport/chttp2/transport/decode_huff.cc +1239 -3514
- data/src/core/ext/transport/chttp2/transport/decode_huff.h +1008 -1486
- data/src/core/ext/transport/chttp2/transport/flow_control.h +22 -17
- data/src/core/ext/transport/chttp2/transport/frame.cc +10 -0
- data/src/core/ext/transport/chttp2/transport/frame.h +2 -2
- data/src/core/ext/transport/chttp2/transport/frame_data.cc +1 -1
- data/src/core/ext/transport/chttp2/transport/frame_settings.cc +7 -8
- data/src/core/ext/transport/chttp2/transport/frame_window_update.cc +4 -5
- data/src/core/ext/transport/chttp2/transport/header_assembler.h +299 -0
- data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +1 -1
- data/src/core/ext/transport/chttp2/transport/hpack_parser_table.cc +11 -5
- data/src/core/ext/transport/chttp2/transport/hpack_parser_table.h +12 -1
- data/src/core/ext/transport/chttp2/transport/http2_client_transport.cc +1017 -0
- data/src/core/ext/transport/chttp2/transport/http2_client_transport.h +593 -0
- data/src/core/ext/transport/chttp2/transport/http2_settings.h +19 -22
- data/{third_party/abseil-cpp/absl/strings/cord_buffer.cc → src/core/ext/transport/chttp2/transport/http2_stats_collector.cc} +14 -14
- data/src/core/ext/transport/chttp2/transport/http2_stats_collector.h +33 -0
- data/src/core/ext/transport/chttp2/transport/http2_status.h +6 -1
- data/src/core/ext/transport/chttp2/transport/http2_transport.cc +43 -0
- data/src/core/ext/transport/chttp2/transport/http2_transport.h +65 -0
- data/src/core/ext/transport/chttp2/transport/http2_ztrace_collector.h +0 -29
- data/src/core/ext/transport/chttp2/transport/internal.h +18 -8
- data/src/core/ext/transport/chttp2/transport/keepalive.cc +105 -0
- data/src/core/ext/transport/chttp2/transport/keepalive.h +138 -0
- data/src/core/ext/transport/chttp2/transport/message_assembler.h +185 -0
- data/src/core/ext/transport/chttp2/transport/parsing.cc +2 -4
- data/src/core/ext/transport/chttp2/transport/ping_callbacks.h +19 -0
- data/src/core/ext/transport/chttp2/transport/ping_promise.cc +151 -0
- data/src/core/ext/transport/chttp2/transport/ping_promise.h +180 -0
- data/src/core/ext/transport/chttp2/transport/ping_rate_policy.cc +5 -9
- data/src/core/ext/transport/chttp2/transport/ping_rate_policy.h +11 -0
- data/src/core/ext/transport/chttp2/transport/stream_lists.cc +39 -1
- data/src/core/ext/transport/chttp2/transport/transport_common.cc +19 -0
- data/src/core/ext/transport/chttp2/transport/transport_common.h +27 -0
- data/src/core/ext/transport/chttp2/transport/writing.cc +37 -11
- data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/channelz.upb.h +571 -0
- data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/channelz.upb_minitable.c +120 -0
- data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/channelz.upb_minitable.h +36 -0
- data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/promise.upb.h +1272 -0
- data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/promise.upb_minitable.c +312 -0
- data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/promise.upb_minitable.h +50 -0
- data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb.h +984 -0
- data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb_minitable.c +226 -0
- data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb_minitable.h +44 -0
- data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/promise.upbdefs.c +175 -0
- data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/promise.upbdefs.h +82 -0
- data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/property_list.upbdefs.c +135 -0
- data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/property_list.upbdefs.h +67 -0
- data/src/core/filter/auth/auth_filters.h +0 -25
- data/src/core/filter/auth/client_auth_filter.cc +0 -118
- data/src/core/filter/filter_args.h +9 -23
- data/src/core/handshaker/handshaker.cc +23 -14
- data/src/core/handshaker/handshaker.h +3 -0
- data/src/core/handshaker/http_connect/http_connect_handshaker.cc +3 -1
- data/src/core/handshaker/security/legacy_secure_endpoint.cc +6 -5
- data/src/core/handshaker/security/secure_endpoint.cc +70 -25
- data/src/core/handshaker/security/security_handshaker.cc +4 -1
- data/src/core/handshaker/tcp_connect/tcp_connect_handshaker.cc +7 -1
- data/src/core/lib/channel/channel_args.cc +15 -0
- data/src/core/lib/channel/channel_args.h +3 -0
- data/src/core/lib/channel/channel_stack.cc +22 -23
- data/src/core/lib/channel/channel_stack.h +9 -7
- data/src/core/lib/channel/channel_stack_builder_impl.cc +1 -1
- data/src/core/lib/channel/channel_stack_builder_impl.h +2 -7
- data/src/core/lib/channel/promise_based_filter.h +5 -5
- data/src/core/lib/debug/trace_impl.h +0 -1
- data/src/core/lib/event_engine/ares_resolver.cc +165 -46
- data/src/core/lib/event_engine/ares_resolver.h +48 -2
- data/src/core/lib/event_engine/cf_engine/cf_engine.cc +3 -1
- data/src/core/lib/event_engine/cf_engine/cf_engine.h +1 -4
- data/src/core/lib/event_engine/cf_engine/cfstream_endpoint.h +2 -6
- data/src/core/lib/event_engine/endpoint_channel_arg_wrapper.cc +40 -0
- data/src/core/lib/event_engine/endpoint_channel_arg_wrapper.h +60 -0
- data/src/core/lib/event_engine/event_engine.cc +7 -0
- data/src/core/lib/event_engine/extensions/channelz.h +10 -6
- data/src/core/lib/event_engine/grpc_polled_fd.h +5 -0
- data/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc +130 -162
- data/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.h +11 -15
- data/src/core/lib/event_engine/posix_engine/ev_poll_posix.cc +75 -117
- data/src/core/lib/event_engine/posix_engine/ev_poll_posix.h +7 -9
- data/src/core/lib/event_engine/posix_engine/event_poller.h +18 -15
- data/src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc +0 -18
- data/src/core/lib/event_engine/posix_engine/file_descriptor_collection.cc +124 -0
- data/src/core/lib/event_engine/posix_engine/file_descriptor_collection.h +243 -0
- data/src/core/lib/event_engine/posix_engine/grpc_polled_fd_posix.h +29 -19
- data/src/core/lib/event_engine/posix_engine/internal_errqueue.cc +6 -2
- data/src/core/lib/event_engine/posix_engine/internal_errqueue.h +6 -1
- data/src/core/lib/event_engine/posix_engine/posix_endpoint.cc +145 -92
- data/src/core/lib/event_engine/posix_engine/posix_endpoint.h +9 -19
- data/src/core/lib/event_engine/posix_engine/posix_engine.cc +333 -116
- data/src/core/lib/event_engine/posix_engine/posix_engine.h +61 -18
- data/src/core/lib/event_engine/posix_engine/posix_engine_listener.cc +45 -37
- data/src/core/lib/event_engine/posix_engine/posix_engine_listener.h +6 -4
- data/src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.cc +32 -142
- data/src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.h +6 -5
- data/src/core/lib/event_engine/posix_engine/posix_interface.h +211 -0
- data/src/core/lib/event_engine/posix_engine/posix_interface_posix.cc +1083 -0
- data/src/core/lib/event_engine/posix_engine/posix_interface_windows.cc +281 -0
- data/src/core/lib/event_engine/posix_engine/posix_write_event_sink.cc +154 -0
- data/src/core/lib/event_engine/posix_engine/posix_write_event_sink.h +174 -0
- data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.cc +3 -719
- data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.h +10 -170
- data/src/core/lib/event_engine/posix_engine/timer_manager.cc +33 -22
- data/src/core/lib/event_engine/posix_engine/timer_manager.h +13 -11
- data/src/core/lib/event_engine/posix_engine/traced_buffer_list.cc +117 -151
- data/src/core/lib/event_engine/posix_engine/traced_buffer_list.h +26 -94
- data/src/core/lib/event_engine/posix_engine/wakeup_fd_eventfd.cc +26 -25
- data/src/core/lib/event_engine/posix_engine/wakeup_fd_eventfd.h +6 -2
- data/src/core/lib/event_engine/posix_engine/wakeup_fd_pipe.cc +36 -62
- data/src/core/lib/event_engine/posix_engine/wakeup_fd_pipe.h +6 -2
- data/src/core/lib/event_engine/posix_engine/wakeup_fd_posix.h +7 -6
- data/src/core/lib/event_engine/posix_engine/wakeup_fd_posix_default.cc +12 -6
- data/src/core/lib/event_engine/posix_engine/wakeup_fd_posix_default.h +3 -1
- data/src/core/lib/event_engine/shim.cc +9 -0
- data/src/core/lib/event_engine/shim.h +3 -0
- data/src/core/lib/event_engine/thread_pool/thread_pool.h +7 -3
- data/src/core/lib/event_engine/thread_pool/thread_pool_factory.cc +0 -17
- data/src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.cc +4 -2
- data/src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.h +3 -2
- data/src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc +4 -0
- data/src/core/lib/event_engine/windows/grpc_polled_fd_windows.h +4 -0
- data/src/core/lib/event_engine/windows/windows_endpoint.h +2 -6
- data/src/core/lib/event_engine/windows/windows_engine.cc +0 -1
- data/src/core/lib/event_engine/windows/windows_engine.h +1 -3
- data/src/core/lib/event_engine/windows/windows_listener.cc +14 -2
- data/src/core/lib/experiments/experiments.cc +45 -93
- data/src/core/lib/experiments/experiments.h +21 -51
- data/src/core/lib/iomgr/endpoint.cc +4 -3
- data/src/core/lib/iomgr/endpoint.h +7 -4
- data/src/core/lib/iomgr/endpoint_cfstream.cc +3 -2
- data/src/core/lib/iomgr/ev_epoll1_linux.cc +7 -2
- data/src/core/lib/iomgr/ev_poll_posix.cc +7 -2
- data/src/core/lib/iomgr/event_engine_shims/endpoint.cc +4 -6
- data/src/core/lib/iomgr/tcp_posix.cc +12 -6
- data/src/core/lib/iomgr/tcp_windows.cc +3 -2
- data/src/core/lib/promise/activity.h +1 -0
- data/src/core/lib/promise/arena_promise.h +23 -7
- data/src/core/lib/promise/detail/promise_factory.h +10 -0
- data/src/core/lib/promise/detail/promise_like.h +118 -11
- data/src/core/lib/promise/detail/promise_variant.h +50 -0
- data/src/core/lib/promise/detail/seq_state.h +687 -548
- data/src/core/lib/promise/if.h +20 -0
- data/src/core/lib/promise/inter_activity_latch.h +147 -0
- data/src/core/lib/promise/inter_activity_mutex.h +547 -0
- data/src/core/lib/promise/loop.h +65 -3
- data/src/core/lib/promise/map.h +24 -0
- data/src/core/lib/promise/match_promise.h +103 -0
- data/src/core/lib/promise/mpsc.cc +425 -0
- data/src/core/lib/promise/mpsc.h +490 -0
- data/src/core/lib/promise/party.cc +50 -1
- data/src/core/lib/promise/party.h +66 -1
- data/src/core/lib/promise/race.h +31 -0
- data/src/core/lib/promise/seq.h +4 -1
- data/src/core/lib/promise/status_flag.h +7 -0
- data/src/core/lib/promise/try_seq.h +4 -1
- data/src/core/lib/promise/wait_set.cc +28 -0
- data/src/core/lib/promise/wait_set.h +86 -0
- data/src/core/lib/resource_quota/arena.h +19 -0
- data/src/core/lib/slice/slice.h +5 -0
- data/src/core/lib/surface/channel_create.cc +88 -13
- data/src/core/lib/surface/channel_create.h +4 -0
- data/src/core/lib/surface/channel_init.cc +164 -47
- data/src/core/lib/surface/channel_init.h +64 -1
- data/src/core/lib/surface/filter_stack_call.cc +18 -9
- data/src/core/lib/surface/init.cc +6 -15
- data/src/core/lib/surface/legacy_channel.cc +3 -5
- data/src/core/lib/surface/legacy_channel.h +3 -1
- data/src/core/lib/surface/version.cc +2 -2
- data/src/core/lib/transport/promise_endpoint.cc +110 -0
- data/src/core/lib/transport/promise_endpoint.h +307 -0
- data/src/core/load_balancing/child_policy_handler.cc +2 -4
- data/src/core/load_balancing/delegating_helper.h +2 -3
- data/src/core/load_balancing/health_check_client.cc +1 -5
- data/src/core/load_balancing/lb_policy.h +1 -3
- data/src/core/load_balancing/oob_backend_metric.cc +1 -5
- data/src/core/load_balancing/pick_first/pick_first.cc +3 -0
- data/src/core/load_balancing/xds/cds.cc +10 -1
- data/src/core/plugin_registry/grpc_plugin_registry_extra.cc +2 -0
- data/src/core/resolver/xds/xds_config.cc +6 -3
- data/src/core/resolver/xds/xds_config.h +9 -4
- data/src/core/resolver/xds/xds_dependency_manager.cc +21 -6
- data/src/core/resolver/xds/xds_dependency_manager.h +2 -1
- data/src/core/resolver/xds/xds_resolver.cc +31 -11
- data/src/core/server/server.cc +83 -12
- data/src/core/server/server.h +21 -2
- data/src/core/server/xds_server_config_fetcher.cc +63 -25
- data/src/core/service_config/service_config.h +1 -1
- data/src/core/service_config/service_config_impl.h +1 -1
- data/src/core/telemetry/context_list_entry.cc +38 -0
- data/src/core/telemetry/context_list_entry.h +42 -12
- data/src/core/telemetry/stats_data.cc +233 -207
- data/src/core/telemetry/stats_data.h +250 -153
- data/src/core/telemetry/tcp_tracer.h +1 -1
- data/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc +11 -3
- data/src/core/tsi/fake_transport_security.cc +17 -0
- data/src/core/tsi/ssl_transport_security.cc +2 -0
- data/src/core/tsi/transport_security_grpc.cc +8 -0
- data/src/core/tsi/transport_security_grpc.h +15 -0
- data/src/core/util/backoff.cc +1 -5
- data/src/core/util/backoff.h +1 -0
- data/src/core/util/down_cast.h +1 -1
- data/src/core/util/function_signature.h +15 -1
- data/src/core/util/http_client/httpcli.cc +12 -5
- data/src/core/util/http_client/httpcli.h +4 -1
- data/src/core/util/latent_see.h +8 -5
- data/src/core/util/log.cc +4 -0
- data/src/core/util/memory_usage.h +268 -0
- data/src/core/util/per_cpu.cc +2 -0
- data/src/core/util/per_cpu.h +7 -0
- data/src/core/util/shared_bit_gen.h +20 -0
- data/src/core/util/single_set_ptr.h +2 -2
- data/src/core/util/upb_utils.h +42 -0
- data/src/core/util/uri.cc +3 -2
- data/src/core/util/useful.h +53 -2
- data/src/core/util/wait_for_single_owner.cc +31 -0
- data/src/core/util/wait_for_single_owner.h +24 -0
- data/src/core/xds/grpc/xds_bootstrap_grpc.cc +2 -0
- data/src/core/xds/grpc/xds_bootstrap_grpc.h +5 -0
- data/src/core/xds/grpc/xds_client_grpc.cc +6 -2
- data/src/core/xds/grpc/xds_common_types_parser.cc +138 -50
- data/src/core/xds/grpc/xds_common_types_parser.h +12 -0
- data/src/core/xds/grpc/xds_http_filter.h +7 -0
- data/src/core/xds/grpc/xds_http_gcp_authn_filter.cc +22 -0
- data/src/core/xds/grpc/xds_http_gcp_authn_filter.h +3 -0
- data/src/core/xds/grpc/xds_route_config_parser.cc +15 -38
- data/src/core/xds/grpc/xds_server_grpc.cc +63 -13
- data/src/core/xds/grpc/xds_server_grpc.h +10 -2
- data/src/core/xds/grpc/xds_server_grpc_interface.h +4 -0
- data/src/core/xds/grpc/xds_transport_grpc.cc +18 -0
- data/src/core/xds/xds_client/xds_bootstrap.h +2 -0
- data/src/core/xds/xds_client/xds_client.cc +26 -5
- data/src/ruby/ext/grpc/extconf.rb +2 -0
- data/src/ruby/ext/grpc/rb_call.c +1 -8
- data/src/ruby/ext/grpc/rb_channel.c +72 -568
- data/src/ruby/ext/grpc/rb_channel.h +0 -3
- data/src/ruby/ext/grpc/rb_completion_queue.c +26 -14
- data/src/ruby/ext/grpc/rb_completion_queue.h +1 -7
- data/src/ruby/ext/grpc/rb_grpc.c +9 -5
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +1 -1
- data/src/ruby/ext/grpc/rb_loader.c +0 -4
- data/src/ruby/ext/grpc/rb_server.c +31 -50
- data/src/ruby/lib/grpc/generic/client_stub.rb +4 -4
- data/src/ruby/lib/grpc/version.rb +1 -1
- data/src/ruby/spec/core_spec.rb +22 -0
- data/src/ruby/spec/generic/active_call_spec.rb +1 -1
- data/third_party/abseil-cpp/absl/algorithm/container.h +2 -19
- data/third_party/abseil-cpp/absl/base/attributes.h +76 -7
- data/third_party/abseil-cpp/absl/base/call_once.h +11 -12
- data/third_party/abseil-cpp/absl/base/config.h +20 -129
- data/third_party/abseil-cpp/absl/base/{internal/fast_type_id.h → fast_type_id.h} +11 -16
- data/third_party/abseil-cpp/absl/base/internal/cycleclock.cc +0 -5
- data/third_party/abseil-cpp/absl/base/internal/cycleclock_config.h +7 -7
- data/third_party/abseil-cpp/absl/base/internal/endian.h +34 -38
- data/third_party/abseil-cpp/absl/base/internal/iterator_traits.h +71 -0
- data/third_party/abseil-cpp/absl/base/internal/low_level_alloc.cc +6 -5
- data/third_party/abseil-cpp/absl/base/internal/{nullability_impl.h → nullability_deprecated.h} +45 -8
- data/third_party/abseil-cpp/absl/base/internal/spinlock.cc +0 -9
- data/third_party/abseil-cpp/absl/base/internal/spinlock.h +3 -13
- data/third_party/abseil-cpp/absl/base/internal/unaligned_access.h +6 -6
- data/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.h +8 -3
- data/third_party/abseil-cpp/absl/base/no_destructor.h +11 -32
- data/third_party/abseil-cpp/absl/base/nullability.h +84 -72
- data/third_party/abseil-cpp/absl/base/options.h +3 -80
- data/third_party/abseil-cpp/absl/base/policy_checks.h +7 -7
- data/third_party/abseil-cpp/absl/cleanup/cleanup.h +1 -3
- data/third_party/abseil-cpp/absl/cleanup/internal/cleanup.h +3 -4
- data/third_party/abseil-cpp/absl/container/btree_map.h +4 -2
- data/third_party/abseil-cpp/absl/container/btree_set.h +4 -2
- data/third_party/abseil-cpp/absl/container/fixed_array.h +7 -14
- data/third_party/abseil-cpp/absl/container/flat_hash_map.h +5 -0
- data/third_party/abseil-cpp/absl/container/flat_hash_set.h +6 -1
- data/third_party/abseil-cpp/absl/container/inlined_vector.h +8 -5
- data/third_party/abseil-cpp/absl/container/internal/btree.h +132 -29
- data/third_party/abseil-cpp/absl/container/internal/btree_container.h +175 -71
- data/third_party/abseil-cpp/absl/container/internal/common.h +43 -0
- data/third_party/abseil-cpp/absl/container/internal/common_policy_traits.h +1 -2
- data/third_party/abseil-cpp/absl/container/internal/container_memory.h +9 -10
- data/third_party/abseil-cpp/absl/container/internal/hash_function_defaults.h +1 -8
- data/third_party/abseil-cpp/absl/container/internal/hash_policy_traits.h +0 -4
- data/third_party/abseil-cpp/absl/container/internal/hashtable_control_bytes.h +527 -0
- data/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.cc +20 -4
- data/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.h +31 -12
- data/third_party/abseil-cpp/absl/container/internal/inlined_vector.h +2 -7
- data/third_party/abseil-cpp/absl/container/internal/layout.h +26 -42
- data/third_party/abseil-cpp/absl/container/internal/raw_hash_map.h +199 -68
- data/third_party/abseil-cpp/absl/container/internal/raw_hash_set.cc +1354 -183
- data/third_party/abseil-cpp/absl/container/internal/raw_hash_set.h +881 -1424
- data/third_party/abseil-cpp/absl/container/internal/raw_hash_set_resize_impl.h +80 -0
- data/third_party/abseil-cpp/absl/crc/crc32c.cc +0 -4
- data/third_party/abseil-cpp/absl/crc/crc32c.h +7 -5
- data/third_party/abseil-cpp/absl/crc/internal/crc32_x86_arm_combined_simd.h +0 -22
- data/third_party/abseil-cpp/absl/crc/internal/crc_x86_arm_combined.cc +45 -74
- data/third_party/abseil-cpp/absl/debugging/internal/addresses.h +57 -0
- data/third_party/abseil-cpp/absl/debugging/internal/decode_rust_punycode.cc +1 -1
- data/third_party/abseil-cpp/absl/debugging/internal/decode_rust_punycode.h +5 -5
- data/third_party/abseil-cpp/absl/debugging/internal/demangle.cc +8 -35
- data/third_party/abseil-cpp/absl/debugging/internal/demangle_rust.cc +16 -16
- data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_aarch64-inl.inc +40 -37
- data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_arm-inl.inc +16 -7
- data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_emscripten-inl.inc +14 -5
- data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_generic-inl.inc +10 -4
- data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_powerpc-inl.inc +27 -16
- data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_riscv-inl.inc +13 -4
- data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_unimplemented-inl.inc +4 -3
- data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_win32-inl.inc +15 -28
- data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_x86-inl.inc +19 -9
- data/third_party/abseil-cpp/absl/debugging/stacktrace.cc +144 -27
- data/third_party/abseil-cpp/absl/debugging/stacktrace.h +73 -5
- data/third_party/abseil-cpp/absl/debugging/symbolize_elf.inc +19 -9
- data/third_party/abseil-cpp/absl/debugging/symbolize_emscripten.inc +3 -2
- data/third_party/abseil-cpp/absl/debugging/symbolize_win32.inc +25 -6
- data/third_party/abseil-cpp/absl/flags/commandlineflag.h +2 -2
- data/third_party/abseil-cpp/absl/flags/flag.h +4 -3
- data/third_party/abseil-cpp/absl/flags/internal/commandlineflag.h +2 -2
- data/third_party/abseil-cpp/absl/flags/internal/flag.cc +2 -1
- data/third_party/abseil-cpp/absl/flags/internal/flag.h +7 -6
- data/third_party/abseil-cpp/absl/flags/internal/registry.h +4 -3
- data/third_party/abseil-cpp/absl/flags/reflection.cc +2 -3
- data/third_party/abseil-cpp/absl/functional/any_invocable.h +8 -10
- data/third_party/abseil-cpp/absl/functional/function_ref.h +2 -9
- data/third_party/abseil-cpp/absl/functional/internal/any_invocable.h +110 -226
- data/third_party/abseil-cpp/absl/functional/internal/front_binder.h +10 -12
- data/third_party/abseil-cpp/absl/functional/internal/function_ref.h +2 -5
- data/third_party/abseil-cpp/absl/hash/hash.h +18 -0
- data/third_party/abseil-cpp/absl/hash/internal/hash.cc +1 -5
- data/third_party/abseil-cpp/absl/hash/internal/hash.h +86 -61
- data/third_party/abseil-cpp/absl/hash/internal/low_level_hash.cc +25 -68
- data/third_party/abseil-cpp/absl/hash/internal/low_level_hash.h +2 -6
- data/third_party/abseil-cpp/absl/hash/internal/weakly_mixed_integer.h +38 -0
- data/third_party/abseil-cpp/absl/log/check.h +2 -1
- data/third_party/abseil-cpp/absl/log/globals.h +4 -5
- data/third_party/abseil-cpp/absl/log/internal/append_truncated.h +28 -0
- data/third_party/abseil-cpp/absl/log/internal/check_op.cc +22 -22
- data/third_party/abseil-cpp/absl/log/internal/check_op.h +65 -62
- data/third_party/abseil-cpp/absl/log/internal/conditions.cc +5 -3
- data/third_party/abseil-cpp/absl/log/internal/conditions.h +7 -2
- data/third_party/abseil-cpp/absl/log/internal/log_message.cc +85 -43
- data/third_party/abseil-cpp/absl/log/internal/log_message.h +84 -59
- data/third_party/abseil-cpp/absl/log/internal/nullstream.h +1 -0
- data/third_party/abseil-cpp/absl/log/internal/proto.cc +3 -2
- data/third_party/abseil-cpp/absl/log/internal/proto.h +3 -3
- data/third_party/abseil-cpp/absl/log/internal/strip.h +4 -12
- data/third_party/abseil-cpp/absl/log/internal/vlog_config.h +8 -6
- data/third_party/abseil-cpp/absl/log/internal/voidify.h +10 -4
- data/third_party/abseil-cpp/absl/log/log.h +48 -35
- data/third_party/abseil-cpp/absl/log/log_sink_registry.h +2 -2
- data/third_party/abseil-cpp/absl/meta/type_traits.h +46 -175
- data/third_party/abseil-cpp/absl/numeric/bits.h +68 -2
- data/third_party/abseil-cpp/absl/numeric/int128.cc +0 -52
- data/third_party/abseil-cpp/absl/numeric/internal/bits.h +7 -3
- data/third_party/abseil-cpp/absl/profiling/internal/exponential_biased.cc +1 -1
- data/third_party/abseil-cpp/absl/random/bit_gen_ref.h +10 -11
- data/third_party/abseil-cpp/absl/random/distributions.h +6 -8
- data/third_party/abseil-cpp/absl/random/gaussian_distribution.h +1 -1
- data/third_party/abseil-cpp/absl/random/internal/distribution_caller.h +5 -6
- data/third_party/abseil-cpp/absl/random/internal/{pool_urbg.cc → entropy_pool.cc} +22 -90
- data/third_party/abseil-cpp/absl/random/internal/entropy_pool.h +35 -0
- data/third_party/abseil-cpp/absl/random/internal/nonsecure_base.h +5 -6
- data/third_party/abseil-cpp/absl/random/internal/randen_detect.cc +1 -1
- data/third_party/abseil-cpp/absl/random/internal/seed_material.cc +20 -12
- data/third_party/abseil-cpp/absl/random/internal/seed_material.h +5 -5
- data/third_party/abseil-cpp/absl/random/random.h +88 -53
- data/third_party/abseil-cpp/absl/random/seed_sequences.cc +6 -2
- data/third_party/abseil-cpp/absl/status/internal/status_internal.cc +3 -4
- data/third_party/abseil-cpp/absl/status/internal/status_internal.h +3 -4
- data/third_party/abseil-cpp/absl/status/internal/statusor_internal.h +4 -3
- data/third_party/abseil-cpp/absl/status/status.cc +4 -8
- data/third_party/abseil-cpp/absl/status/status.h +8 -8
- data/third_party/abseil-cpp/absl/status/status_payload_printer.h +2 -2
- data/third_party/abseil-cpp/absl/status/statusor.cc +2 -2
- data/third_party/abseil-cpp/absl/status/statusor.h +6 -6
- data/third_party/abseil-cpp/absl/strings/ascii.cc +9 -9
- data/third_party/abseil-cpp/absl/strings/ascii.h +18 -18
- data/third_party/abseil-cpp/absl/strings/charconv.cc +21 -22
- data/third_party/abseil-cpp/absl/strings/charconv.h +5 -5
- data/third_party/abseil-cpp/absl/strings/cord.cc +54 -58
- data/third_party/abseil-cpp/absl/strings/cord.h +94 -83
- data/third_party/abseil-cpp/absl/strings/cord_analysis.cc +11 -11
- data/third_party/abseil-cpp/absl/strings/cord_analysis.h +3 -3
- data/third_party/abseil-cpp/absl/strings/escaping.cc +130 -149
- data/third_party/abseil-cpp/absl/strings/escaping.h +9 -10
- data/third_party/abseil-cpp/absl/strings/internal/charconv_bigint.cc +1 -1
- data/third_party/abseil-cpp/absl/strings/internal/cord_internal.h +6 -8
- data/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree.cc +0 -4
- data/third_party/abseil-cpp/absl/strings/internal/cordz_info.cc +0 -4
- data/third_party/abseil-cpp/absl/strings/internal/str_format/arg.cc +7 -63
- data/third_party/abseil-cpp/absl/strings/internal/str_format/arg.h +1 -11
- data/third_party/abseil-cpp/absl/strings/internal/str_format/extension.cc +0 -22
- data/third_party/abseil-cpp/absl/strings/internal/str_format/output.cc +5 -3
- data/third_party/abseil-cpp/absl/strings/internal/str_format/parser.h +4 -2
- data/third_party/abseil-cpp/absl/strings/internal/str_join_internal.h +3 -3
- data/third_party/abseil-cpp/absl/strings/internal/string_constant.h +0 -5
- data/third_party/abseil-cpp/absl/strings/internal/utf8.cc +96 -1
- data/third_party/abseil-cpp/absl/strings/internal/utf8.h +15 -1
- data/third_party/abseil-cpp/absl/strings/numbers.cc +53 -32
- data/third_party/abseil-cpp/absl/strings/numbers.h +87 -58
- data/third_party/abseil-cpp/absl/strings/str_cat.cc +6 -7
- data/third_party/abseil-cpp/absl/strings/str_cat.h +32 -32
- data/third_party/abseil-cpp/absl/strings/str_format.h +18 -18
- data/third_party/abseil-cpp/absl/strings/str_replace.cc +3 -3
- data/third_party/abseil-cpp/absl/strings/str_replace.h +6 -6
- data/third_party/abseil-cpp/absl/strings/string_view.cc +4 -9
- data/third_party/abseil-cpp/absl/strings/string_view.h +27 -32
- data/third_party/abseil-cpp/absl/strings/strip.h +4 -4
- data/third_party/abseil-cpp/absl/strings/substitute.cc +5 -4
- data/third_party/abseil-cpp/absl/strings/substitute.h +66 -64
- data/third_party/abseil-cpp/absl/synchronization/internal/futex_waiter.cc +0 -4
- data/third_party/abseil-cpp/absl/synchronization/internal/kernel_timeout.cc +0 -5
- data/third_party/abseil-cpp/absl/synchronization/internal/pthread_waiter.cc +0 -4
- data/third_party/abseil-cpp/absl/synchronization/internal/sem_waiter.cc +0 -4
- data/third_party/abseil-cpp/absl/synchronization/internal/stdcpp_waiter.cc +0 -4
- data/third_party/abseil-cpp/absl/synchronization/internal/waiter_base.cc +0 -4
- data/third_party/abseil-cpp/absl/synchronization/internal/win32_waiter.cc +0 -4
- data/third_party/abseil-cpp/absl/synchronization/mutex.cc +1 -1
- data/third_party/abseil-cpp/absl/synchronization/mutex.h +97 -69
- data/third_party/abseil-cpp/absl/synchronization/notification.h +1 -1
- data/third_party/abseil-cpp/absl/time/civil_time.cc +1 -0
- data/third_party/abseil-cpp/absl/time/duration.cc +12 -7
- data/third_party/abseil-cpp/absl/time/internal/cctz/include/cctz/time_zone.h +1 -1
- data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup.cc +90 -111
- data/third_party/abseil-cpp/absl/time/time.h +20 -15
- data/third_party/abseil-cpp/absl/types/optional.h +7 -747
- data/third_party/abseil-cpp/absl/types/span.h +13 -11
- data/third_party/abseil-cpp/absl/types/variant.h +5 -784
- data/third_party/abseil-cpp/absl/utility/utility.h +10 -185
- metadata +72 -20
- data/src/core/lib/event_engine/forkable.cc +0 -105
- data/src/core/lib/event_engine/forkable.h +0 -67
- data/src/core/lib/iomgr/python_util.h +0 -46
- data/third_party/abseil-cpp/absl/base/internal/inline_variable.h +0 -108
- data/third_party/abseil-cpp/absl/base/internal/invoke.h +0 -241
- data/third_party/abseil-cpp/absl/log/log_entry.cc +0 -41
- data/third_party/abseil-cpp/absl/random/internal/pool_urbg.h +0 -131
- data/third_party/abseil-cpp/absl/types/bad_optional_access.cc +0 -66
- data/third_party/abseil-cpp/absl/types/bad_optional_access.h +0 -78
- data/third_party/abseil-cpp/absl/types/bad_variant_access.cc +0 -82
- data/third_party/abseil-cpp/absl/types/bad_variant_access.h +0 -82
- data/third_party/abseil-cpp/absl/types/internal/optional.h +0 -352
- 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
|