grpc 1.75.0.pre1 → 1.76.0.pre1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Makefile +18 -5
- data/include/grpc/credentials.h +21 -5
- data/src/core/call/call_filters.cc +4 -4
- data/src/core/call/call_filters.h +36 -36
- data/src/core/call/call_spine.h +27 -27
- data/src/core/call/client_call.cc +6 -5
- data/src/core/call/filter_fusion.h +5 -5
- data/src/core/call/metadata_batch.h +3 -3
- data/src/core/call/security_context.cc +1 -1
- data/src/core/call/server_call.cc +4 -4
- data/src/core/call/server_call.h +1 -1
- data/src/core/channelz/channelz.cc +12 -18
- data/src/core/channelz/channelz.h +32 -16
- data/src/core/channelz/channelz_registry.h +11 -0
- data/src/core/channelz/property_list.cc +18 -0
- data/src/core/channelz/property_list.h +10 -1
- data/src/core/channelz/text_encode.cc +66 -0
- data/src/core/channelz/text_encode.h +29 -0
- data/src/core/channelz/v2tov1/convert.cc +11 -0
- data/src/core/channelz/v2tov1/legacy_api.cc +15 -8
- data/src/core/channelz/ztrace_collector.h +247 -86
- data/src/core/client_channel/backup_poller.cc +5 -6
- data/src/core/client_channel/client_channel.cc +20 -13
- data/src/core/client_channel/client_channel_filter.cc +53 -45
- data/src/core/client_channel/client_channel_filter.h +2 -2
- data/src/core/client_channel/client_channel_internal.h +3 -4
- data/src/core/client_channel/config_selector.h +3 -3
- data/src/core/client_channel/dynamic_filters.cc +3 -3
- data/src/core/client_channel/global_subchannel_pool.cc +0 -37
- data/src/core/client_channel/global_subchannel_pool.h +0 -27
- data/src/core/client_channel/load_balanced_call_destination.cc +7 -7
- data/src/core/client_channel/local_subchannel_pool.cc +4 -4
- data/src/core/client_channel/retry_filter.h +3 -3
- data/src/core/client_channel/retry_filter_legacy_call_data.cc +5 -5
- data/src/core/client_channel/subchannel.cc +8 -8
- data/src/core/client_channel/subchannel_stream_client.cc +4 -4
- data/src/core/config/config_vars.cc +30 -1
- data/src/core/config/config_vars.h +21 -0
- data/src/core/config/core_configuration.cc +5 -5
- data/src/core/config/core_configuration.h +7 -7
- data/src/core/config/load_config.cc +12 -0
- data/src/core/config/load_config.h +2 -0
- data/src/core/credentials/call/call_credentials.h +2 -2
- data/src/core/credentials/call/call_creds_util.cc +4 -3
- data/src/core/credentials/call/composite/composite_call_credentials.cc +4 -4
- data/src/core/credentials/call/external/aws_external_account_credentials.cc +3 -3
- data/src/core/credentials/call/external/external_account_credentials.cc +1 -1
- data/src/core/credentials/call/external/url_external_account_credentials.cc +1 -1
- data/src/core/credentials/call/iam/iam_credentials.cc +4 -4
- data/src/core/credentials/call/jwt/json_token.cc +3 -3
- data/src/core/credentials/call/jwt/jwt_credentials.cc +2 -2
- data/src/core/credentials/call/jwt/jwt_verifier.cc +14 -13
- data/src/core/credentials/call/oauth2/oauth2_credentials.cc +20 -12
- data/src/core/credentials/call/plugin/plugin_credentials.cc +2 -2
- data/src/core/credentials/transport/alts/alts_credentials.cc +4 -4
- data/src/core/credentials/transport/alts/alts_security_connector.cc +14 -12
- data/src/core/credentials/transport/alts/grpc_alts_credentials_client_options.cc +22 -2
- data/src/core/credentials/transport/alts/grpc_alts_credentials_options.cc +10 -1
- data/src/core/credentials/transport/alts/grpc_alts_credentials_options.h +31 -0
- data/src/core/credentials/transport/alts/grpc_alts_credentials_server_options.cc +8 -3
- data/src/core/credentials/transport/composite/composite_channel_credentials.cc +5 -5
- data/src/core/credentials/transport/fake/fake_security_connector.cc +2 -2
- data/src/core/credentials/transport/google_default/google_default_credentials.cc +78 -28
- data/src/core/credentials/transport/insecure/insecure_security_connector.cc +3 -3
- data/src/core/credentials/transport/local/local_security_connector.cc +8 -8
- data/src/core/credentials/transport/security_connector.cc +5 -5
- data/src/core/credentials/transport/ssl/ssl_credentials.cc +12 -12
- data/src/core/credentials/transport/ssl/ssl_credentials.h +2 -2
- data/src/core/credentials/transport/ssl/ssl_security_connector.cc +3 -3
- data/src/core/credentials/transport/tls/certificate_provider_registry.cc +2 -2
- data/src/core/credentials/transport/tls/grpc_tls_certificate_distributor.cc +24 -24
- data/src/core/credentials/transport/tls/grpc_tls_certificate_provider.cc +5 -5
- data/src/core/credentials/transport/tls/grpc_tls_certificate_provider.h +2 -2
- data/src/core/credentials/transport/tls/grpc_tls_certificate_verifier.cc +2 -2
- data/src/core/credentials/transport/tls/grpc_tls_certificate_verifier.h +2 -2
- data/src/core/credentials/transport/tls/grpc_tls_credentials_options.cc +17 -17
- data/src/core/credentials/transport/tls/ssl_utils.cc +14 -9
- data/src/core/credentials/transport/tls/tls_credentials.cc +2 -2
- data/src/core/credentials/transport/tls/tls_security_connector.cc +11 -11
- data/src/core/credentials/transport/transport_credentials.cc +2 -2
- data/src/core/credentials/transport/transport_credentials.h +2 -2
- data/src/core/credentials/transport/xds/xds_credentials.cc +5 -5
- data/src/core/ext/filters/channel_idle/legacy_channel_idle_filter.cc +2 -0
- data/src/core/ext/filters/gcp_authentication/gcp_authentication_filter.cc +1 -1
- data/src/core/ext/filters/http/message_compress/compression_filter.cc +8 -8
- data/src/core/ext/filters/http/message_compress/compression_filter.h +3 -3
- data/src/core/ext/filters/stateful_session/stateful_session_filter.cc +7 -7
- data/src/core/ext/transport/chttp2/alpn/alpn.cc +2 -2
- data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +10 -9
- data/src/core/ext/transport/chttp2/server/chttp2_server.cc +10 -7
- data/src/core/ext/transport/chttp2/transport/bin_decoder.cc +5 -5
- data/src/core/ext/transport/chttp2/transport/bin_encoder.cc +6 -6
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +96 -88
- data/src/core/ext/transport/chttp2/transport/flow_control.cc +3 -3
- data/src/core/ext/transport/chttp2/transport/flow_control.h +12 -7
- data/src/core/ext/transport/chttp2/transport/flow_control_manager.h +60 -0
- data/src/core/ext/transport/chttp2/transport/frame.cc +32 -10
- data/src/core/ext/transport/chttp2/transport/frame.h +16 -2
- data/src/core/ext/transport/chttp2/transport/frame_data.cc +2 -2
- data/src/core/ext/transport/chttp2/transport/frame_goaway.cc +4 -4
- data/src/core/ext/transport/chttp2/transport/frame_ping.cc +2 -2
- data/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +2 -2
- data/src/core/ext/transport/chttp2/transport/frame_window_update.cc +3 -3
- data/src/core/ext/transport/chttp2/transport/header_assembler.h +28 -12
- data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +2 -2
- data/src/core/ext/transport/chttp2/transport/hpack_encoder.h +4 -2
- data/src/core/ext/transport/chttp2/transport/hpack_encoder_table.cc +8 -8
- data/src/core/ext/transport/chttp2/transport/hpack_parse_result.cc +2 -2
- data/src/core/ext/transport/chttp2/transport/hpack_parse_result.h +2 -2
- data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +27 -27
- data/src/core/ext/transport/chttp2/transport/hpack_parser.h +2 -3
- data/src/core/ext/transport/chttp2/transport/hpack_parser_table.cc +4 -4
- data/src/core/ext/transport/chttp2/transport/http2_client_transport.cc +543 -366
- data/src/core/ext/transport/chttp2/transport/http2_client_transport.h +198 -277
- data/src/core/ext/transport/chttp2/transport/http2_settings_manager.cc +3 -0
- data/src/core/ext/transport/chttp2/transport/http2_settings_manager.h +11 -0
- data/src/core/ext/transport/chttp2/transport/http2_settings_promises.h +179 -0
- data/src/core/ext/transport/chttp2/transport/http2_transport.cc +51 -23
- data/src/core/ext/transport/chttp2/transport/http2_transport.h +13 -6
- data/src/core/ext/transport/chttp2/transport/http2_ztrace_collector.h +115 -71
- data/src/core/ext/transport/chttp2/transport/internal.h +6 -14
- data/src/core/ext/transport/chttp2/transport/message_assembler.h +7 -7
- data/src/core/ext/transport/chttp2/transport/parsing.cc +17 -15
- data/src/core/ext/transport/chttp2/transport/ping_callbacks.cc +2 -2
- data/src/core/ext/transport/chttp2/transport/ping_promise.cc +62 -26
- data/src/core/ext/transport/chttp2/transport/ping_promise.h +58 -22
- data/src/core/ext/transport/chttp2/transport/stream.h +207 -0
- data/src/core/ext/transport/chttp2/transport/stream_data_queue.h +328 -187
- data/src/core/ext/transport/chttp2/transport/stream_lists.cc +7 -7
- data/src/core/ext/transport/chttp2/transport/transport_common.cc +17 -1
- data/src/core/ext/transport/chttp2/transport/transport_common.h +52 -0
- data/src/core/ext/transport/chttp2/transport/varint.h +2 -2
- data/src/core/ext/transport/chttp2/transport/writable_streams.h +181 -79
- data/src/core/ext/transport/chttp2/transport/write_size_policy.cc +2 -2
- data/src/core/ext/transport/chttp2/transport/writing.cc +3 -3
- data/src/core/ext/transport/inproc/inproc_transport.cc +1 -1
- data/src/core/ext/transport/inproc/legacy_inproc_transport.cc +3 -3
- data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/service.upb.h +740 -0
- data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/service.upb_minitable.c +218 -0
- data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/service.upb_minitable.h +46 -0
- data/src/core/ext/upb-gen/src/proto/grpc/gcp/handshaker.upb.h +87 -55
- data/src/core/ext/upb-gen/src/proto/grpc/gcp/handshaker.upb_minitable.c +23 -21
- data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/channelz.upbdefs.c +80 -0
- data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/channelz.upbdefs.h +47 -0
- data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/service.upbdefs.c +129 -0
- data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/service.upbdefs.h +72 -0
- data/src/core/filter/auth/server_auth_filter.cc +2 -2
- data/src/core/handshaker/handshaker.cc +3 -3
- data/src/core/handshaker/http_connect/http_proxy_mapper.cc +2 -2
- data/src/core/handshaker/security/legacy_secure_endpoint.cc +2 -2
- data/src/core/handshaker/security/pipelined_secure_endpoint.cc +31 -8
- data/src/core/handshaker/security/secure_endpoint.cc +16 -6
- data/src/core/handshaker/security/security_handshaker.cc +3 -3
- data/src/core/handshaker/tcp_connect/tcp_connect_handshaker.cc +2 -2
- data/src/core/lib/channel/channel_stack.cc +8 -5
- data/src/core/lib/channel/channel_stack.h +3 -0
- data/src/core/lib/channel/channel_stack_builder_impl.cc +1 -0
- data/src/core/lib/channel/connected_channel.cc +2 -2
- data/src/core/lib/channel/promise_based_filter.cc +69 -64
- data/src/core/lib/channel/promise_based_filter.h +16 -15
- data/src/core/lib/compression/compression_internal.cc +2 -2
- data/src/core/lib/compression/message_compress.cc +7 -7
- data/src/core/lib/event_engine/ares_resolver.cc +22 -20
- data/src/core/lib/event_engine/cf_engine/cf_engine.cc +2 -2
- data/src/core/lib/event_engine/cf_engine/dns_service_resolver.cc +2 -2
- data/src/core/lib/event_engine/cf_engine/dns_service_resolver.h +2 -2
- data/src/core/lib/event_engine/extensions/channelz.h +2 -2
- data/src/core/lib/event_engine/extensions/supports_fd.h +5 -5
- data/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc +8 -8
- data/src/core/lib/event_engine/posix_engine/ev_poll_posix.cc +10 -10
- data/src/core/lib/event_engine/posix_engine/lockfree_event.cc +2 -2
- data/src/core/lib/event_engine/posix_engine/posix_endpoint.cc +23 -22
- data/src/core/lib/event_engine/posix_engine/posix_endpoint.h +11 -11
- data/src/core/lib/event_engine/posix_engine/posix_engine.cc +168 -170
- data/src/core/lib/event_engine/posix_engine/posix_engine.h +33 -54
- data/src/core/lib/event_engine/posix_engine/posix_engine_listener.cc +4 -3
- data/src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.cc +5 -5
- data/src/core/lib/event_engine/posix_engine/posix_interface.h +1 -1
- data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.cc +1 -1
- data/src/core/lib/event_engine/posix_engine/timer_manager.cc +3 -3
- data/src/core/lib/event_engine/resolved_address.cc +3 -3
- data/src/core/lib/event_engine/shim.cc +8 -11
- data/src/core/lib/event_engine/shim.h +2 -1
- data/src/core/lib/event_engine/slice.cc +2 -2
- data/src/core/lib/event_engine/tcp_socket_utils.cc +11 -11
- data/src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.cc +7 -7
- data/src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc +31 -31
- data/src/core/lib/event_engine/windows/iocp.cc +10 -10
- data/src/core/lib/event_engine/windows/win_socket.cc +6 -6
- data/src/core/lib/event_engine/windows/windows_endpoint.cc +11 -11
- data/src/core/lib/event_engine/windows/windows_engine.cc +16 -14
- data/src/core/lib/event_engine/windows/windows_listener.cc +7 -7
- data/src/core/lib/experiments/experiments.cc +105 -18
- data/src/core/lib/experiments/experiments.h +43 -11
- data/src/core/lib/iomgr/call_combiner.cc +3 -3
- data/src/core/lib/iomgr/endpoint_cfstream.cc +6 -6
- data/src/core/lib/iomgr/endpoint_pair_posix.cc +5 -5
- data/src/core/lib/iomgr/endpoint_pair_windows.cc +15 -14
- data/src/core/lib/iomgr/ev_epoll1_linux.cc +15 -15
- data/src/core/lib/iomgr/ev_poll_posix.cc +11 -11
- data/src/core/lib/iomgr/event_engine_shims/endpoint.cc +5 -4
- data/src/core/lib/iomgr/event_engine_shims/endpoint.h +1 -1
- data/src/core/lib/iomgr/iocp_windows.cc +8 -8
- data/src/core/lib/iomgr/iomgr_windows.cc +3 -3
- data/src/core/lib/iomgr/lockfree_event.cc +2 -2
- data/src/core/lib/iomgr/polling_entity.cc +3 -3
- data/src/core/lib/iomgr/socket_utils_common_posix.cc +2 -2
- data/src/core/lib/iomgr/socket_windows.cc +4 -4
- data/src/core/lib/iomgr/tcp_client_posix.cc +4 -4
- data/src/core/lib/iomgr/tcp_client_windows.cc +4 -4
- data/src/core/lib/iomgr/tcp_posix.cc +42 -42
- data/src/core/lib/iomgr/tcp_server.cc +5 -0
- data/src/core/lib/iomgr/tcp_server.h +7 -0
- data/src/core/lib/iomgr/tcp_server_posix.cc +47 -27
- data/src/core/lib/iomgr/tcp_server_utils_posix.h +3 -0
- data/src/core/lib/iomgr/tcp_server_utils_posix_common.cc +5 -5
- data/src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.cc +2 -2
- data/src/core/lib/iomgr/tcp_server_windows.cc +68 -29
- data/src/core/lib/iomgr/tcp_windows.cc +7 -7
- data/src/core/lib/iomgr/timer_generic.cc +2 -2
- data/src/core/lib/iomgr/timer_manager.cc +2 -2
- data/src/core/lib/iomgr/unix_sockets_posix.cc +2 -2
- data/src/core/lib/iomgr/unix_sockets_posix_noop.cc +2 -2
- data/src/core/lib/promise/activity.cc +2 -2
- data/src/core/lib/promise/activity.h +6 -6
- data/src/core/lib/promise/context.h +2 -2
- data/src/core/lib/promise/detail/join_state.h +9 -9
- data/src/core/lib/promise/detail/seq_state.h +13 -13
- data/src/core/lib/promise/detail/status.h +2 -2
- data/src/core/lib/promise/for_each.h +5 -5
- data/src/core/lib/promise/interceptor_list.h +2 -2
- data/src/core/lib/promise/latch.h +7 -7
- data/src/core/lib/promise/mpsc.cc +26 -26
- data/src/core/lib/promise/mpsc.h +2 -2
- data/src/core/lib/promise/observable.h +4 -4
- data/src/core/lib/promise/party.cc +32 -25
- data/src/core/lib/promise/party.h +16 -19
- data/src/core/lib/promise/pipe.h +15 -15
- data/src/core/lib/promise/poll.h +5 -4
- data/src/core/lib/promise/promise.h +0 -2
- data/src/core/lib/promise/sleep.cc +3 -1
- data/src/core/lib/promise/status_flag.h +7 -7
- data/src/core/lib/promise/try_join.h +2 -2
- data/src/core/lib/promise/try_seq.h +2 -2
- data/src/core/lib/resource_quota/arena.h +15 -2
- data/src/core/lib/resource_quota/connection_quota.cc +9 -7
- data/src/core/lib/resource_quota/memory_quota.cc +45 -24
- data/src/core/lib/resource_quota/memory_quota.h +48 -16
- data/src/core/lib/resource_quota/telemetry.h +54 -0
- data/src/core/lib/resource_quota/thread_quota.cc +2 -2
- data/src/core/lib/resource_tracker/resource_tracker.cc +33 -0
- data/src/core/lib/resource_tracker/resource_tracker.h +46 -0
- data/src/core/lib/security/authorization/audit_logging.cc +5 -5
- data/src/core/lib/security/authorization/grpc_authorization_engine.cc +2 -2
- data/src/core/lib/security/authorization/stdout_logger.cc +3 -3
- data/src/core/lib/surface/byte_buffer_reader.cc +2 -2
- data/src/core/lib/surface/call.cc +16 -14
- data/src/core/lib/surface/call.h +1 -1
- data/src/core/lib/surface/call_utils.cc +2 -2
- data/src/core/lib/surface/call_utils.h +2 -2
- data/src/core/lib/surface/channel.cc +4 -4
- data/src/core/lib/surface/channel_create.cc +10 -6
- data/src/core/lib/surface/channel_init.cc +80 -23
- data/src/core/lib/surface/channel_init.h +26 -11
- data/src/core/lib/surface/completion_queue.cc +17 -16
- data/src/core/lib/surface/completion_queue_factory.cc +7 -7
- data/src/core/lib/surface/connection_context.h +45 -2
- data/src/core/lib/surface/filter_stack_call.cc +12 -23
- data/src/core/lib/surface/filter_stack_call.h +3 -4
- data/src/core/lib/surface/legacy_channel.cc +7 -7
- data/src/core/lib/surface/validate_metadata.h +2 -2
- data/src/core/lib/surface/version.cc +2 -2
- data/src/core/lib/transport/bdp_estimator.cc +2 -2
- data/src/core/lib/transport/bdp_estimator.h +3 -3
- data/src/core/lib/transport/promise_endpoint.cc +3 -3
- data/src/core/lib/transport/promise_endpoint.h +8 -8
- data/src/core/lib/transport/timeout_encoding.cc +4 -4
- data/src/core/load_balancing/child_policy_handler.cc +4 -4
- data/src/core/load_balancing/endpoint_list.cc +2 -2
- data/src/core/load_balancing/grpclb/grpclb.cc +24 -24
- data/src/core/load_balancing/health_check_client.cc +4 -4
- data/src/core/load_balancing/health_check_client_internal.h +2 -2
- data/src/core/load_balancing/lb_policy_registry.cc +2 -2
- data/src/core/load_balancing/oob_backend_metric.cc +4 -4
- data/src/core/load_balancing/oob_backend_metric_internal.h +2 -2
- data/src/core/load_balancing/outlier_detection/outlier_detection.cc +2 -2
- data/src/core/load_balancing/pick_first/pick_first.cc +14 -14
- data/src/core/load_balancing/priority/priority.cc +23 -24
- data/src/core/load_balancing/ring_hash/ring_hash.cc +3 -3
- data/src/core/load_balancing/rls/rls.cc +13 -13
- data/src/core/load_balancing/round_robin/round_robin.cc +9 -9
- data/src/core/load_balancing/weighted_round_robin/static_stride_scheduler.cc +3 -3
- data/src/core/load_balancing/weighted_round_robin/weighted_round_robin.cc +33 -26
- data/src/core/load_balancing/weighted_target/weighted_target.cc +5 -5
- data/src/core/load_balancing/xds/cds.cc +76 -32
- data/src/core/load_balancing/xds/xds_cluster_impl.cc +3 -3
- data/src/core/load_balancing/xds/xds_override_host.cc +4 -4
- data/src/core/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc +2 -2
- data/src/core/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +33 -33
- data/src/core/resolver/dns/c_ares/grpc_ares_wrapper.cc +10 -10
- data/src/core/resolver/dns/dns_resolver_plugin.cc +6 -3
- data/src/core/resolver/dns/event_engine/event_engine_client_channel_resolver.cc +2 -2
- data/src/core/resolver/endpoint_addresses.cc +3 -3
- data/src/core/resolver/endpoint_addresses.h +3 -0
- data/src/core/resolver/fake/fake_resolver.cc +2 -2
- data/src/core/resolver/google_c2p/google_c2p_resolver.cc +41 -54
- data/src/core/resolver/polling_resolver.cc +3 -3
- data/src/core/resolver/resolver_registry.cc +5 -4
- data/src/core/resolver/xds/xds_dependency_manager.cc +5 -5
- data/src/core/resolver/xds/xds_resolver.cc +9 -9
- data/src/core/server/server.cc +38 -38
- data/src/core/server/server_call_tracer_filter.h +4 -4
- data/src/core/server/server_config_selector_filter.cc +2 -2
- data/src/core/server/xds_server_config_fetcher.cc +9 -8
- data/src/core/service_config/service_config_impl.h +2 -2
- data/src/core/telemetry/call_tracer.cc +39 -49
- data/src/core/telemetry/call_tracer.h +199 -22
- data/src/core/telemetry/histogram.h +205 -0
- data/src/core/telemetry/instrument.cc +719 -0
- data/src/core/telemetry/instrument.h +932 -0
- data/src/core/telemetry/metrics.cc +13 -5
- data/src/core/telemetry/metrics.h +3 -1
- data/src/core/telemetry/stats_data.cc +0 -19
- data/src/core/telemetry/stats_data.h +0 -19
- data/src/core/transport/auth_context.cc +2 -2
- data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +78 -45
- data/src/core/tsi/alts/handshaker/alts_handshaker_client.h +1 -0
- data/src/core/tsi/alts/handshaker/alts_shared_resource.cc +3 -3
- data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +39 -31
- data/src/core/tsi/alts/handshaker/alts_tsi_utils.cc +3 -3
- data/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.cc +3 -3
- data/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.cc +7 -7
- data/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc +3 -3
- data/src/core/tsi/fake_transport_security.cc +4 -4
- data/src/core/tsi/ssl/key_logging/ssl_key_logging.cc +4 -4
- data/src/core/tsi/ssl/session_cache/ssl_session_cache.cc +9 -9
- data/src/core/tsi/ssl/session_cache/ssl_session_openssl.cc +3 -3
- data/src/core/tsi/ssl_transport_security.cc +26 -25
- data/src/core/tsi/ssl_transport_security_utils.cc +9 -9
- data/src/core/util/chunked_vector.h +4 -4
- data/src/core/util/event_log.cc +2 -2
- data/src/core/util/gcp_metadata_query.cc +2 -2
- data/src/core/util/grpc_check.cc +22 -0
- data/src/core/util/grpc_check.h +103 -0
- data/src/core/util/http_client/httpcli.cc +3 -3
- data/src/core/util/http_client/parser.cc +4 -4
- data/src/core/util/latent_see.h +7 -4
- data/src/core/util/lru_cache.h +4 -4
- data/src/core/util/memory_usage.h +16 -0
- data/src/core/util/posix/directory_reader.cc +3 -2
- data/src/core/util/posix/sync.cc +24 -24
- data/src/core/util/postmortem_emit.cc +52 -0
- data/src/core/util/postmortem_emit.h +30 -0
- data/src/core/util/ref_counted_ptr.h +5 -0
- data/src/core/util/trie_lookup.h +170 -0
- data/src/core/util/unique_ptr_with_bitset.h +5 -5
- data/src/core/xds/grpc/xds_bootstrap_grpc.h +6 -1
- data/src/core/xds/grpc/xds_certificate_provider.cc +3 -3
- data/src/core/xds/grpc/xds_client_grpc.cc +34 -15
- data/src/core/xds/grpc/xds_client_grpc.h +4 -1
- data/src/core/xds/grpc/xds_cluster_parser.cc +2 -2
- data/src/core/xds/grpc/xds_cluster_specifier_plugin.cc +2 -2
- data/src/core/xds/grpc/xds_endpoint_parser.cc +2 -2
- data/src/core/xds/grpc/xds_http_filter_registry.cc +4 -3
- data/src/core/xds/grpc/xds_listener_parser.cc +3 -3
- data/src/core/xds/grpc/xds_matcher.cc +277 -0
- data/src/core/xds/grpc/xds_matcher.h +432 -0
- data/src/core/xds/grpc/xds_matcher_action.cc +47 -0
- data/src/core/xds/grpc/xds_matcher_action.h +48 -0
- data/src/core/xds/grpc/xds_matcher_context.cc +29 -0
- data/src/core/xds/grpc/xds_matcher_context.h +46 -0
- data/src/core/xds/grpc/xds_matcher_input.cc +79 -0
- data/src/core/xds/grpc/xds_matcher_input.h +105 -0
- data/src/core/xds/grpc/xds_matcher_parse.cc +356 -0
- data/src/core/xds/grpc/xds_matcher_parse.h +39 -0
- data/src/core/xds/grpc/xds_metadata.cc +4 -3
- data/src/core/xds/grpc/xds_route_config_parser.cc +6 -6
- data/src/core/xds/grpc/xds_routing.cc +3 -3
- data/src/core/xds/grpc/xds_transport_grpc.cc +10 -10
- data/src/core/xds/xds_client/lrs_client.cc +6 -6
- data/src/core/xds/xds_client/xds_client.cc +9 -9
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +2 -2
- data/src/ruby/lib/grpc/version.rb +1 -1
- data/third_party/abseil-cpp/absl/container/internal/node_slot_policy.h +95 -0
- data/third_party/abseil-cpp/absl/container/node_hash_map.h +687 -0
- metadata +37 -2
@@ -26,19 +26,23 @@
|
|
26
26
|
#include <optional>
|
27
27
|
#include <utility>
|
28
28
|
|
29
|
-
#include "absl/log/check.h"
|
30
29
|
#include "absl/log/log.h"
|
31
30
|
#include "absl/status/status.h"
|
31
|
+
#include "absl/strings/string_view.h"
|
32
32
|
#include "src/core/call/call_spine.h"
|
33
33
|
#include "src/core/call/message.h"
|
34
34
|
#include "src/core/call/metadata_batch.h"
|
35
|
+
#include "src/core/ext/transport/chttp2/transport/flow_control.h"
|
36
|
+
#include "src/core/ext/transport/chttp2/transport/flow_control_manager.h"
|
35
37
|
#include "src/core/ext/transport/chttp2/transport/frame.h"
|
36
38
|
#include "src/core/ext/transport/chttp2/transport/header_assembler.h"
|
37
39
|
#include "src/core/ext/transport/chttp2/transport/http2_settings.h"
|
38
40
|
#include "src/core/ext/transport/chttp2/transport/http2_settings_manager.h"
|
39
41
|
#include "src/core/ext/transport/chttp2/transport/http2_status.h"
|
42
|
+
#include "src/core/ext/transport/chttp2/transport/http2_ztrace_collector.h"
|
40
43
|
#include "src/core/ext/transport/chttp2/transport/internal_channel_arg_names.h"
|
41
44
|
#include "src/core/ext/transport/chttp2/transport/message_assembler.h"
|
45
|
+
#include "src/core/ext/transport/chttp2/transport/stream_data_queue.h"
|
42
46
|
#include "src/core/ext/transport/chttp2/transport/transport_common.h"
|
43
47
|
#include "src/core/lib/channel/channel_args.h"
|
44
48
|
#include "src/core/lib/debug/trace.h"
|
@@ -51,10 +55,12 @@
|
|
51
55
|
#include "src/core/lib/promise/promise.h"
|
52
56
|
#include "src/core/lib/promise/try_seq.h"
|
53
57
|
#include "src/core/lib/resource_quota/arena.h"
|
58
|
+
#include "src/core/lib/resource_quota/resource_quota.h"
|
54
59
|
#include "src/core/lib/slice/slice.h"
|
55
60
|
#include "src/core/lib/slice/slice_buffer.h"
|
56
61
|
#include "src/core/lib/transport/promise_endpoint.h"
|
57
62
|
#include "src/core/lib/transport/transport.h"
|
63
|
+
#include "src/core/util/grpc_check.h"
|
58
64
|
#include "src/core/util/ref_counted_ptr.h"
|
59
65
|
#include "src/core/util/sync.h"
|
60
66
|
|
@@ -62,6 +68,7 @@ namespace grpc_core {
|
|
62
68
|
namespace http2 {
|
63
69
|
|
64
70
|
using grpc_event_engine::experimental::EventEngine;
|
71
|
+
using EnqueueResult = StreamDataQueue<ClientMetadataHandle>::EnqueueResult;
|
65
72
|
|
66
73
|
// Experimental : This is just the initial skeleton of class
|
67
74
|
// and it is functions. The code will be written iteratively.
|
@@ -84,8 +91,9 @@ void Http2ClientTransport::PerformOp(grpc_transport_op* op) {
|
|
84
91
|
StopConnectivityWatch(op->stop_connectivity_watch);
|
85
92
|
did_stuff = true;
|
86
93
|
}
|
87
|
-
|
88
|
-
|
94
|
+
GRPC_CHECK(!op->set_accept_stream)
|
95
|
+
<< "Set_accept_stream not supported on clients";
|
96
|
+
GRPC_DCHECK(did_stuff) << "Unimplemented transport perform op ";
|
89
97
|
|
90
98
|
ExecCtx::Run(DEBUG_LOCATION, op->on_consumed, absl::OkStatus());
|
91
99
|
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport PerformOp End";
|
@@ -219,8 +227,7 @@ Http2Status Http2ClientTransport::ProcessHttp2HeaderFrame(
|
|
219
227
|
<< ", payload=" << frame.payload.JoinIntoString() << " }";
|
220
228
|
ping_manager_.ReceivedDataFrame();
|
221
229
|
|
222
|
-
RefCountedPtr<
|
223
|
-
LookupStream(frame.stream_id);
|
230
|
+
RefCountedPtr<Stream> stream = LookupStream(frame.stream_id);
|
224
231
|
if (stream == nullptr) {
|
225
232
|
// TODO(tjagtap) : [PH2][P3] : Implement this.
|
226
233
|
// RFC9113 : The identifier of a newly established stream MUST be
|
@@ -254,19 +261,20 @@ Http2Status Http2ClientTransport::ProcessHttp2HeaderFrame(
|
|
254
261
|
HeaderAssembler& assembler = stream->header_assembler;
|
255
262
|
Http2Status append_result = assembler.AppendHeaderFrame(std::move(frame));
|
256
263
|
if (append_result.IsOk()) {
|
257
|
-
return ProcessMetadata(stream
|
258
|
-
stream->did_push_initial_metadata,
|
259
|
-
stream->did_push_trailing_metadata);
|
264
|
+
return ProcessMetadata(stream);
|
260
265
|
}
|
261
266
|
return append_result;
|
262
267
|
}
|
263
268
|
|
264
269
|
Http2Status Http2ClientTransport::ProcessMetadata(
|
265
|
-
|
266
|
-
|
270
|
+
RefCountedPtr<Stream> stream) {
|
271
|
+
const uint32_t stream_id = stream->GetStreamId();
|
272
|
+
HeaderAssembler& assembler = stream->header_assembler;
|
273
|
+
CallHandler call = stream->call;
|
274
|
+
|
267
275
|
GRPC_HTTP2_CLIENT_DLOG << "Http2Transport ProcessMetadata";
|
268
276
|
if (assembler.IsReady()) {
|
269
|
-
ValueOrHttp2Status<
|
277
|
+
ValueOrHttp2Status<ServerMetadataHandle> read_result =
|
270
278
|
assembler.ReadMetadata(parser_, !incoming_header_end_stream_,
|
271
279
|
/*is_client=*/true,
|
272
280
|
/*max_header_list_size_soft_limit=*/
|
@@ -274,27 +282,21 @@ Http2Status Http2ClientTransport::ProcessMetadata(
|
|
274
282
|
/*max_header_list_size_hard_limit=*/
|
275
283
|
settings_.acked().max_header_list_size());
|
276
284
|
if (read_result.IsOk()) {
|
277
|
-
|
278
|
-
TakeValue(std::move(read_result));
|
285
|
+
ServerMetadataHandle metadata = TakeValue(std::move(read_result));
|
279
286
|
if (incoming_header_end_stream_) {
|
280
287
|
// TODO(tjagtap) : [PH2][P1] : Is this the right way to differentiate
|
281
288
|
// between initial and trailing metadata?
|
282
289
|
GRPC_HTTP2_CLIENT_DLOG
|
283
290
|
<< "Http2Transport ProcessMetadata SpawnPushServerTrailingMetadata";
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
/*close_writes=*/true,
|
290
|
-
/*send_rst_stream=*/false,
|
291
|
-
/*should_not_push_trailers=*/true,
|
292
|
-
});
|
293
|
-
|
291
|
+
stream->MarkHalfClosedRemote();
|
292
|
+
BeginCloseStream(
|
293
|
+
stream_id,
|
294
|
+
Http2ErrorCodeToRstFrameErrorCode(Http2ErrorCode::kNoError),
|
295
|
+
std::move(metadata));
|
294
296
|
} else {
|
295
297
|
GRPC_HTTP2_CLIENT_DLOG
|
296
298
|
<< "Http2Transport ProcessMetadata SpawnPushServerInitialMetadata";
|
297
|
-
did_push_initial_metadata = true;
|
299
|
+
stream->did_push_initial_metadata = true;
|
298
300
|
call.SpawnPushServerInitialMetadata(std::move(metadata));
|
299
301
|
}
|
300
302
|
return Http2Status::Ok();
|
@@ -313,16 +315,12 @@ Http2Status Http2ClientTransport::ProcessHttp2RstStreamFrame(
|
|
313
315
|
<< "Http2Transport ProcessHttp2RstStreamFrame { stream_id="
|
314
316
|
<< frame.stream_id << ", error_code=" << frame.error_code << " }";
|
315
317
|
Http2ErrorCode error_code =
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
/*close_writes=*/true,
|
323
|
-
/*send_rst_stream=*/false,
|
324
|
-
/*push_trailing_metadata=*/true,
|
325
|
-
});
|
318
|
+
RstFrameErrorCodeToHttp2ErrorCode(frame.error_code);
|
319
|
+
absl::Status status = absl::Status(ErrorCodeToAbslStatusCode(error_code),
|
320
|
+
"Reset stream frame received.");
|
321
|
+
BeginCloseStream(frame.stream_id, /*reset_stream_error_code=*/std::nullopt,
|
322
|
+
CancelledServerMetadataFromStatus(status));
|
323
|
+
|
326
324
|
// In case of stream error, we do not want the Read Loop to be broken. Hence
|
327
325
|
// returning an ok status.
|
328
326
|
return Http2Status::Ok();
|
@@ -343,6 +341,9 @@ Http2Status Http2ClientTransport::ProcessHttp2SettingsFrame(
|
|
343
341
|
on_receive_settings_ = nullptr;
|
344
342
|
}
|
345
343
|
|
344
|
+
// TODO(tjagtap) : [PH2][P2] Decide later if we want this only for AckLastSend
|
345
|
+
// or does any other operation also need this lock.
|
346
|
+
MutexLock lock(&transport_mutex_);
|
346
347
|
if (!frame.ack) {
|
347
348
|
// Check if the received settings have legal values
|
348
349
|
Http2Status status = ValidateSettingsValues(frame.settings);
|
@@ -353,9 +354,15 @@ Http2Status Http2ClientTransport::ProcessHttp2SettingsFrame(
|
|
353
354
|
// Apply the new settings
|
354
355
|
// Quickly send the ACK to the peer once the settings are applied
|
355
356
|
} else {
|
356
|
-
//
|
357
|
-
|
358
|
-
|
357
|
+
// Process the SETTINGS ACK Frame
|
358
|
+
if (settings_.AckLastSend()) {
|
359
|
+
transport_settings_.OnSettingsAckReceived();
|
360
|
+
} else {
|
361
|
+
// TODO(tjagtap) [PH2][P4] : The RFC does not say anything about what
|
362
|
+
// should happen if we receive an unsolicited SETTINGS ACK. Decide if we
|
363
|
+
// want to respond with any error or just proceed.
|
364
|
+
LOG(ERROR) << "Settings ack received without sending settings";
|
365
|
+
}
|
359
366
|
}
|
360
367
|
|
361
368
|
return Http2Status::Ok();
|
@@ -378,7 +385,7 @@ auto Http2ClientTransport::ProcessHttp2PingFrame(Http2PingFrame frame) {
|
|
378
385
|
// writes.
|
379
386
|
// RFC9113: PING responses SHOULD be given higher priority than any
|
380
387
|
// other frame.
|
381
|
-
self->
|
388
|
+
self->ping_manager_.AddPendingPingAck(opaque);
|
382
389
|
// TODO(akshitpatel) : [PH2][P2] : This is done assuming that the other
|
383
390
|
// ProcessFrame promises may return stream or connection failures. If
|
384
391
|
// this does not turn out to be true, consider returning absl::Status
|
@@ -416,6 +423,18 @@ Http2Status Http2ClientTransport::ProcessHttp2WindowUpdateFrame(
|
|
416
423
|
<< "Http2Transport ProcessHttp2WindowUpdateFrame Promise { "
|
417
424
|
" stream_id="
|
418
425
|
<< frame.stream_id << ", increment=" << frame.increment << "}";
|
426
|
+
if (frame.stream_id != 0) {
|
427
|
+
RefCountedPtr<Stream> stream = LookupStream(frame.stream_id);
|
428
|
+
if (stream != nullptr) {
|
429
|
+
chttp2::StreamFlowControl::OutgoingUpdateContext fc_update(
|
430
|
+
&stream->flow_control);
|
431
|
+
fc_update.RecvUpdate(frame.increment);
|
432
|
+
}
|
433
|
+
} else {
|
434
|
+
chttp2::TransportFlowControl::OutgoingUpdateContext fc_update(
|
435
|
+
&flow_control_);
|
436
|
+
fc_update.RecvUpdate(frame.increment);
|
437
|
+
}
|
419
438
|
return Http2Status::Ok();
|
420
439
|
}
|
421
440
|
|
@@ -448,9 +467,7 @@ Http2Status Http2ClientTransport::ProcessHttp2ContinuationFrame(
|
|
448
467
|
HeaderAssembler& assember = stream->header_assembler;
|
449
468
|
Http2Status result = assember.AppendContinuationFrame(std::move(frame));
|
450
469
|
if (result.IsOk()) {
|
451
|
-
return ProcessMetadata(stream
|
452
|
-
stream->did_push_initial_metadata,
|
453
|
-
stream->did_push_trailing_metadata);
|
470
|
+
return ProcessMetadata(stream);
|
454
471
|
}
|
455
472
|
return result;
|
456
473
|
}
|
@@ -544,8 +561,10 @@ auto Http2ClientTransport::ReadAndProcessOneFrame() {
|
|
544
561
|
/*incoming_header_stream_id*/ self->incoming_header_stream_id_,
|
545
562
|
/*current_frame_header*/ header);
|
546
563
|
|
547
|
-
if (!status.IsOk()) {
|
548
|
-
|
564
|
+
if (GPR_UNLIKELY(!status.IsOk())) {
|
565
|
+
GRPC_DCHECK(status.GetType() ==
|
566
|
+
Http2Status::Http2ErrorType::kConnectionError);
|
567
|
+
return self->HandleError(std::nullopt, std::move(status));
|
549
568
|
}
|
550
569
|
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport ReadAndProcessOneFrame "
|
551
570
|
"Validated Frame Header:"
|
@@ -570,6 +589,7 @@ auto Http2ClientTransport::ReadAndProcessOneFrame() {
|
|
570
589
|
ParseFramePayload(self->current_frame_header_, std::move(payload));
|
571
590
|
if (!frame.IsOk()) {
|
572
591
|
return self->HandleError(
|
592
|
+
self->current_frame_header_.stream_id,
|
573
593
|
ValueOrHttp2Status<Http2Frame>::TakeStatus(std::move(frame)));
|
574
594
|
}
|
575
595
|
return TakeValue(std::move(frame));
|
@@ -578,14 +598,15 @@ auto Http2ClientTransport::ReadAndProcessOneFrame() {
|
|
578
598
|
GRPC_UNUSED Http2Frame frame) {
|
579
599
|
GRPC_HTTP2_CLIENT_DLOG
|
580
600
|
<< "Http2ClientTransport ReadAndProcessOneFrame ProcessOneFrame";
|
581
|
-
return AssertResultType<absl::Status>(
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
601
|
+
return AssertResultType<absl::Status>(Map(
|
602
|
+
self->ProcessOneFrame(std::move(frame)),
|
603
|
+
[self](Http2Status status) {
|
604
|
+
if (!status.IsOk()) {
|
605
|
+
return self->HandleError(self->current_frame_header_.stream_id,
|
606
|
+
std::move(status));
|
607
|
+
}
|
608
|
+
return absl::OkStatus();
|
609
|
+
}));
|
589
610
|
}));
|
590
611
|
}
|
591
612
|
|
@@ -608,189 +629,281 @@ auto Http2ClientTransport::OnReadLoopEnded() {
|
|
608
629
|
[self = RefAsSubclass<Http2ClientTransport>()](absl::Status status) {
|
609
630
|
GRPC_HTTP2_CLIENT_DLOG
|
610
631
|
<< "Http2ClientTransport OnReadLoopEnded Promise Status=" << status;
|
611
|
-
GRPC_UNUSED absl::Status error =
|
612
|
-
|
613
|
-
|
632
|
+
GRPC_UNUSED absl::Status error = self->HandleError(
|
633
|
+
std::nullopt, Http2Status::AbslConnectionError(
|
634
|
+
status.code(), std::string(status.message())));
|
614
635
|
};
|
615
636
|
}
|
616
637
|
|
638
|
+
// Equivalent to grpc_chttp2_act_on_flowctl_action in chttp2_transport.cc
|
639
|
+
// TODO(tjagtap) : [PH2][P4] : grpc_chttp2_act_on_flowctl_action has a "reason"
|
640
|
+
// parameter which looks like it would be really helpful for debugging. Add that
|
641
|
+
void Http2ClientTransport::ActOnFlowControlAction(
|
642
|
+
const chttp2::FlowControlAction& action, const uint32_t stream_id) {
|
643
|
+
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::ActOnFlowControlAction";
|
644
|
+
if (action.send_stream_update() != kNoActionNeeded) {
|
645
|
+
GRPC_DCHECK_GT(stream_id, 0u);
|
646
|
+
RefCountedPtr<Stream> stream = LookupStream(stream_id);
|
647
|
+
if (GPR_LIKELY(stream != nullptr)) {
|
648
|
+
const HttpStreamState state = stream->GetStreamState();
|
649
|
+
if (state != HttpStreamState::kHalfClosedRemote &&
|
650
|
+
state != HttpStreamState::kClosed) {
|
651
|
+
// Stream is not remotely closed, so sending a WINDOW_UPDATE is
|
652
|
+
// potentially useful.
|
653
|
+
// TODO(tjagtap) : [PH2][P1] Plumb with flow control
|
654
|
+
}
|
655
|
+
} else {
|
656
|
+
GRPC_HTTP2_CLIENT_DLOG
|
657
|
+
<< "Http2ClientTransport ActOnFlowControlAction stream is null";
|
658
|
+
}
|
659
|
+
}
|
660
|
+
|
661
|
+
if (action.send_transport_update() != kNoActionNeeded) {
|
662
|
+
// TODO(tjagtap) : [PH2][P1] Plumb with flow control
|
663
|
+
}
|
664
|
+
|
665
|
+
// TODO(tjagtap) : [PH2][P1] Plumb
|
666
|
+
// enable_preferred_rx_crypto_frame_advertisement with settings
|
667
|
+
ActOnFlowControlActionSettings(
|
668
|
+
action, settings_.mutable_local(),
|
669
|
+
/*enable_preferred_rx_crypto_frame_advertisement=*/true);
|
670
|
+
|
671
|
+
if (action.AnyUpdateImmediately()) {
|
672
|
+
TriggerWriteCycle();
|
673
|
+
}
|
674
|
+
}
|
675
|
+
|
617
676
|
///////////////////////////////////////////////////////////////////////////////
|
618
677
|
// Write Related Promises and Promise Factories
|
619
678
|
|
620
|
-
auto Http2ClientTransport::
|
621
|
-
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
679
|
+
auto Http2ClientTransport::WriteControlFrames() {
|
680
|
+
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport WriteControlFrames Factory";
|
681
|
+
SliceBuffer output_buf;
|
682
|
+
if (is_first_write_) {
|
683
|
+
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport Write "
|
684
|
+
"GRPC_CHTTP2_CLIENT_CONNECT_STRING";
|
685
|
+
output_buf.Append(Slice(
|
686
|
+
grpc_slice_from_copied_string(GRPC_CHTTP2_CLIENT_CONNECT_STRING)));
|
687
|
+
is_first_write_ = false;
|
688
|
+
}
|
689
|
+
MaybeGetSettingsFrame(output_buf);
|
690
|
+
ping_manager_.MaybeGetSerializedPingFrames(output_buf,
|
691
|
+
NextAllowedPingInterval());
|
692
|
+
const uint64_t buffer_length = output_buf.Length();
|
693
|
+
return If(
|
694
|
+
buffer_length > 0,
|
695
|
+
[self = RefAsSubclass<Http2ClientTransport>(),
|
696
|
+
output_buf = std::move(output_buf), buffer_length]() mutable {
|
697
|
+
GRPC_HTTP2_CLIENT_DLOG
|
698
|
+
<< "Http2ClientTransport WriteControlFrames Writing buffer of size "
|
699
|
+
<< buffer_length << " to endpoint";
|
700
|
+
return self->endpoint_.Write(std::move(output_buf),
|
701
|
+
PromiseEndpoint::WriteArgs{});
|
702
|
+
},
|
703
|
+
[self = RefAsSubclass<Http2ClientTransport>(), buffer_length] {
|
704
|
+
self->ztrace_collector_->Append(
|
705
|
+
PromiseEndpointWriteTrace{buffer_length});
|
706
|
+
return absl::OkStatus();
|
645
707
|
});
|
646
708
|
}
|
647
709
|
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
// can move bytes_sent_in_last_write_ to be a local variable.
|
654
|
-
self->bytes_sent_in_last_write_ = false;
|
655
|
-
return TrySeq(
|
656
|
-
// TODO(akshitpatel) : [PH2][P1] : WriteFromQueue may write settings
|
657
|
-
// acks as well. This will break the call to ResetPingClock as it
|
658
|
-
// only needs to be called on writing Data/Header/WindowUpdate
|
659
|
-
// frames. Possible fixes: Either WriteFromQueue iterates over all
|
660
|
-
// the frames and figures out the types of frames needed (this may
|
661
|
-
// anyways be needed to check that we do not send frames for closed
|
662
|
-
// streams) or we have flags to indicate the types of frame that are
|
663
|
-
// enqueued.
|
664
|
-
self->WriteFromQueue(), [self] { return self->MaybeSendPing(); },
|
665
|
-
[self] { return self->MaybeSendPingAcks(); },
|
666
|
-
[self]() -> LoopCtl<absl::Status> {
|
667
|
-
// If any Header/Data/WindowUpdate frame was sent in the last
|
668
|
-
// write, reset the ping clock.
|
669
|
-
if (self->bytes_sent_in_last_write_) {
|
670
|
-
self->ping_manager_.ResetPingClock(/*is_client=*/true);
|
671
|
-
}
|
672
|
-
GRPC_HTTP2_CLIENT_DLOG
|
673
|
-
<< "Http2ClientTransport WriteLoop Continue";
|
674
|
-
return Continue();
|
675
|
-
});
|
676
|
-
}));
|
710
|
+
void Http2ClientTransport::NotifyControlFramesWriteDone() {
|
711
|
+
// Notify Control modules that we have sent the frames.
|
712
|
+
// All notifications are expected to be synchronous.
|
713
|
+
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport NotifyControlFramesWriteDone";
|
714
|
+
ping_manager_.NotifyPingSent(ping_timeout_);
|
677
715
|
}
|
678
716
|
|
679
|
-
auto Http2ClientTransport::
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
717
|
+
auto Http2ClientTransport::SerializeAndWrite(std::vector<Http2Frame>&& frames) {
|
718
|
+
SliceBuffer output_buf;
|
719
|
+
should_reset_ping_clock_ =
|
720
|
+
Serialize(absl::Span<Http2Frame>(frames), output_buf)
|
721
|
+
.should_reset_ping_clock;
|
722
|
+
size_t output_buf_length = output_buf.Length();
|
723
|
+
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport SerializeAndWrite Write "
|
724
|
+
"output_buf.length() = "
|
725
|
+
<< output_buf_length;
|
726
|
+
return AssertResultType<absl::Status>(If(
|
727
|
+
output_buf_length > 0,
|
728
|
+
[self = RefAsSubclass<Http2ClientTransport>(),
|
729
|
+
output_buf = std::move(output_buf)]() mutable {
|
730
|
+
return self->endpoint_.Write(std::move(output_buf),
|
731
|
+
PromiseEndpoint::WriteArgs{});
|
732
|
+
},
|
733
|
+
[]() { return absl::OkStatus(); }));
|
690
734
|
}
|
691
735
|
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
//
|
696
|
-
//
|
697
|
-
//
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
736
|
+
absl::StatusOr<std::vector<Http2Frame>>
|
737
|
+
Http2ClientTransport::DequeueStreamFrames(RefCountedPtr<Stream> stream) {
|
738
|
+
// write_bytes_remaining_ is passed as an upper bound on the max
|
739
|
+
// number of tokens that can be dequeued to prevent dequeuing huge
|
740
|
+
// data frames when write_bytes_remaining_ is very low. As the
|
741
|
+
// available transport tokens can only range from 0 to 2^31 - 1,
|
742
|
+
// we are clamping the write_bytes_remaining_ to that range.
|
743
|
+
// TODO(akshitpatel) : [PH2][P3] : Plug transport_tokens when
|
744
|
+
// transport flow control is implemented.
|
745
|
+
StreamDataQueue<ClientMetadataHandle>::DequeueResult result =
|
746
|
+
stream->DequeueFrames(
|
747
|
+
/*transport_tokens*/ std::min(
|
748
|
+
std::numeric_limits<uint32_t>::max(),
|
749
|
+
static_cast<uint32_t>(Clamp<size_t>(write_bytes_remaining_, 0,
|
750
|
+
RFC9113::kMaxSize31Bit - 1))),
|
751
|
+
settings_.peer().max_frame_size(), encoder_);
|
752
|
+
if (result.is_writable) {
|
753
|
+
// Stream is still writable. Enqueue it back to the writable
|
754
|
+
// stream list.
|
755
|
+
// TODO(akshitpatel) : [PH2][P3] : Plug transport_tokens when
|
756
|
+
// transport flow control is implemented.
|
757
|
+
absl::Status status =
|
758
|
+
writable_stream_list_.Enqueue(stream, result.priority);
|
759
|
+
if (GPR_UNLIKELY(!status.ok())) {
|
760
|
+
GRPC_HTTP2_CLIENT_DLOG
|
761
|
+
<< "Http2ClientTransport MultiplexerLoop Failed to "
|
762
|
+
"enqueue stream "
|
763
|
+
<< stream->GetStreamId() << " with status: " << status;
|
764
|
+
// Close transport if we fail to enqueue stream.
|
765
|
+
return HandleError(std::nullopt, Http2Status::AbslConnectionError(
|
766
|
+
absl::StatusCode::kUnavailable,
|
767
|
+
std::string(status.message())));
|
768
|
+
}
|
769
|
+
}
|
770
|
+
if (result.InitialMetadataDequeued()) {
|
771
|
+
stream->SentInitialMetadata();
|
772
|
+
}
|
773
|
+
if (result.HalfCloseDequeued()) {
|
774
|
+
CloseStream(stream, CloseStreamArgs{/*close_reads=*/false,
|
775
|
+
/*close_writes=*/true});
|
776
|
+
stream->MarkHalfClosedLocal();
|
777
|
+
}
|
778
|
+
if (result.ResetStreamDequeued()) {
|
779
|
+
CloseStream(stream, CloseStreamArgs{/*close_reads=*/true,
|
780
|
+
/*close_writes=*/true});
|
781
|
+
stream->MarkHalfClosedLocal();
|
782
|
+
}
|
718
783
|
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
784
|
+
// Update the write_bytes_remaining_ based on the bytes consumed
|
785
|
+
// in the current dequeue.
|
786
|
+
write_bytes_remaining_ =
|
787
|
+
(write_bytes_remaining_ >= result.total_bytes_consumed)
|
788
|
+
? (write_bytes_remaining_ - result.total_bytes_consumed)
|
789
|
+
: 0;
|
790
|
+
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport MultiplexerLoop "
|
791
|
+
"write_bytes_remaining_ after dequeue = "
|
792
|
+
<< write_bytes_remaining_ << " total_bytes_consumed = "
|
793
|
+
<< result.total_bytes_consumed
|
794
|
+
<< " stream_id = " << stream->GetStreamId()
|
795
|
+
<< " is_writable = " << result.is_writable
|
796
|
+
<< " stream_priority = "
|
797
|
+
<< static_cast<uint8_t>(result.priority)
|
798
|
+
<< " number of frames = " << result.frames.size();
|
799
|
+
return std::move(result.frames);
|
800
|
+
}
|
801
|
+
|
802
|
+
auto Http2ClientTransport::MultiplexerLoop() {
|
803
|
+
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport MultiplexerLoop Factory";
|
804
|
+
return AssertResultType<
|
805
|
+
absl::Status>(Loop([self = RefAsSubclass<Http2ClientTransport>()]() {
|
806
|
+
self->write_bytes_remaining_ = self->GetMaxWriteSize();
|
807
|
+
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport MultiplexerLoop "
|
808
|
+
<< " max_write_size_=" << self->GetMaxWriteSize();
|
809
|
+
return TrySeq(
|
810
|
+
self->writable_stream_list_.WaitForReady(
|
811
|
+
self->AreTransportFlowControlTokensAvailable()),
|
812
|
+
[self]() {
|
813
|
+
// TODO(akshitpatel) : [PH2][P2] : Return an `important` tag from
|
814
|
+
// WriteControlFrames() to indicate if we should do a separate write
|
815
|
+
// for the queued control frames or send the queued frames with the
|
816
|
+
// data frames(if any).
|
817
|
+
return Map(self->WriteControlFrames(), [self](absl::Status status) {
|
818
|
+
if (GPR_UNLIKELY(!status.ok())) {
|
819
|
+
GRPC_HTTP2_CLIENT_DLOG
|
820
|
+
<< "Http2ClientTransport MultiplexerLoop Failed to "
|
821
|
+
"write control frames with status: "
|
822
|
+
<< status;
|
823
|
+
return status;
|
824
|
+
}
|
825
|
+
self->NotifyControlFramesWriteDone();
|
826
|
+
return absl::OkStatus();
|
827
|
+
});
|
828
|
+
},
|
829
|
+
[self]() -> absl::StatusOr<std::vector<Http2Frame>> {
|
830
|
+
std::vector<Http2Frame> frames;
|
831
|
+
// Drain all the writable streams till we have written
|
832
|
+
// max_write_size_ bytes of data or there is no more data to send. In
|
833
|
+
// some cases, we may write more than max_write_size_ bytes(like
|
834
|
+
// writing metadata).
|
835
|
+
while (self->write_bytes_remaining_ > 0) {
|
728
836
|
// TODO(akshitpatel) : [PH2][P3] : Plug transport_tokens when
|
729
837
|
// transport flow control is implemented.
|
730
|
-
|
731
|
-
|
838
|
+
std::optional<RefCountedPtr<Stream>> optional_stream =
|
839
|
+
self->writable_stream_list_.ImmediateNext(
|
840
|
+
self->AreTransportFlowControlTokensAvailable());
|
841
|
+
if (!optional_stream.has_value()) {
|
842
|
+
GRPC_HTTP2_CLIENT_DLOG
|
843
|
+
<< "Http2ClientTransport MultiplexerLoop "
|
844
|
+
"No writable streams available, write_bytes_remaining_ = "
|
845
|
+
<< self->write_bytes_remaining_;
|
846
|
+
break;
|
847
|
+
}
|
848
|
+
RefCountedPtr<Stream> stream = std::move(optional_stream.value());
|
849
|
+
GRPC_HTTP2_CLIENT_DLOG
|
850
|
+
<< "Http2ClientTransport MultiplexerLoop "
|
851
|
+
"Next writable stream id = "
|
852
|
+
<< stream->GetStreamId()
|
853
|
+
<< " is_closed_for_writes = " << stream->IsClosedForWrites();
|
854
|
+
|
855
|
+
if (GPR_LIKELY(!stream->IsClosedForWrites())) {
|
856
|
+
auto stream_frames = self->DequeueStreamFrames(stream);
|
857
|
+
if (GPR_UNLIKELY(!stream_frames.ok())) {
|
858
|
+
GRPC_HTTP2_CLIENT_DLOG
|
859
|
+
<< "Http2ClientTransport MultiplexerLoop "
|
860
|
+
"Failed to dequeue stream frames with status: "
|
861
|
+
<< stream_frames.status();
|
862
|
+
return stream_frames.status();
|
863
|
+
}
|
732
864
|
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
865
|
+
frames.reserve(frames.size() + stream_frames.value().size());
|
866
|
+
frames.insert(
|
867
|
+
frames.end(),
|
868
|
+
std::make_move_iterator(stream_frames.value().begin()),
|
869
|
+
std::make_move_iterator(stream_frames.value().end()));
|
738
870
|
}
|
739
|
-
} else if (GPR_UNLIKELY(!result.ok())) {
|
740
|
-
// Close the corresponding stream if we fail to dequeue frames from
|
741
|
-
// the stream queue.
|
742
|
-
LOG(ERROR) << "Failed to dequeue frames for stream " << stream_id
|
743
|
-
<< " with status: " << result.status();
|
744
|
-
absl::Status status =
|
745
|
-
self->HandleError(Http2Status::AbslStreamError(
|
746
|
-
absl::StatusCode::kInternal, "Failed to dequeue frames"));
|
747
|
-
return std::vector<Http2Frame>();
|
748
871
|
}
|
872
|
+
|
749
873
|
GRPC_HTTP2_CLIENT_DLOG
|
750
|
-
<< "Http2ClientTransport
|
751
|
-
|
752
|
-
<<
|
753
|
-
|
754
|
-
|
755
|
-
return std::move(result->frames);
|
874
|
+
<< "Http2ClientTransport MultiplexerLoop "
|
875
|
+
"write_bytes_remaining_ after draining all writable streams = "
|
876
|
+
<< self->write_bytes_remaining_;
|
877
|
+
|
878
|
+
return std::move(frames);
|
756
879
|
},
|
757
880
|
[self](std::vector<Http2Frame> frames) {
|
758
|
-
|
759
|
-
return Loop([self, frames = std::move(frames), idx = 0u]() mutable {
|
760
|
-
return If(
|
761
|
-
idx < frames.size(),
|
762
|
-
[self, &frames, &idx]() {
|
763
|
-
return Map(
|
764
|
-
// Enqueue to the MPSC queue could return pending. This
|
765
|
-
// induces backpressure for the sender. Only after writing
|
766
|
-
// to the MPSC queue we will loop back to read more
|
767
|
-
// streams.
|
768
|
-
self->EnqueueOutgoingFrame(std::move(frames[idx++])),
|
769
|
-
[](absl::Status status) -> LoopCtl<absl::Status> {
|
770
|
-
if (GPR_UNLIKELY(!status.ok())) {
|
771
|
-
return status;
|
772
|
-
}
|
773
|
-
return Continue{};
|
774
|
-
});
|
775
|
-
},
|
776
|
-
[]() -> LoopCtl<absl::Status> { return absl::OkStatus(); });
|
777
|
-
});
|
881
|
+
return self->SerializeAndWrite(std::move(frames));
|
778
882
|
},
|
779
|
-
[]() -> LoopCtl<absl::Status> {
|
780
|
-
|
883
|
+
[self]() -> LoopCtl<absl::Status> {
|
884
|
+
if (self->should_reset_ping_clock_) {
|
885
|
+
GRPC_HTTP2_CLIENT_DLOG
|
886
|
+
<< "Http2ClientTransport MultiplexerLoop ResetPingClock";
|
887
|
+
self->ping_manager_.ResetPingClock(/*is_client=*/true);
|
888
|
+
self->should_reset_ping_clock_ = false;
|
889
|
+
}
|
890
|
+
return Continue();
|
891
|
+
});
|
892
|
+
}));
|
781
893
|
}
|
782
894
|
|
783
|
-
auto Http2ClientTransport::
|
895
|
+
auto Http2ClientTransport::OnMultiplexerLoopEnded() {
|
784
896
|
GRPC_HTTP2_CLIENT_DLOG
|
785
|
-
<< "Http2ClientTransport
|
786
|
-
return
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
self->HandleError(
|
792
|
-
|
793
|
-
|
897
|
+
<< "Http2ClientTransport OnMultiplexerLoopEnded Factory";
|
898
|
+
return
|
899
|
+
[self = RefAsSubclass<Http2ClientTransport>()](absl::Status status) {
|
900
|
+
GRPC_HTTP2_CLIENT_DLOG
|
901
|
+
<< "Http2ClientTransport OnMultiplexerLoopEnded Promise Status="
|
902
|
+
<< status;
|
903
|
+
GRPC_UNUSED absl::Status error = self->HandleError(
|
904
|
+
std::nullopt, Http2Status::AbslConnectionError(
|
905
|
+
status.code(), std::string(status.message())));
|
906
|
+
};
|
794
907
|
}
|
795
908
|
|
796
909
|
///////////////////////////////////////////////////////////////////////////////
|
@@ -800,10 +913,11 @@ Http2ClientTransport::Http2ClientTransport(
|
|
800
913
|
PromiseEndpoint endpoint, GRPC_UNUSED const ChannelArgs& channel_args,
|
801
914
|
std::shared_ptr<EventEngine> event_engine,
|
802
915
|
grpc_closure* on_receive_settings)
|
803
|
-
:
|
804
|
-
|
916
|
+
: channelz::DataSource(http2::CreateChannelzSocketNode(
|
917
|
+
endpoint.GetEventEngineEndpoint(), channel_args)),
|
918
|
+
endpoint_(std::move(endpoint)),
|
805
919
|
stream_id_mutex_(/*Initial Stream Id*/ 1),
|
806
|
-
|
920
|
+
should_reset_ping_clock_(false),
|
807
921
|
incoming_header_in_progress_(false),
|
808
922
|
incoming_header_end_stream_(false),
|
809
923
|
is_first_write_(true),
|
@@ -811,6 +925,7 @@ Http2ClientTransport::Http2ClientTransport(
|
|
811
925
|
on_receive_settings_(on_receive_settings),
|
812
926
|
max_header_list_size_soft_limit_(
|
813
927
|
GetSoftLimitFromChannelArgs(channel_args)),
|
928
|
+
max_write_size_(kMaxWriteSize),
|
814
929
|
keepalive_time_(std::max(
|
815
930
|
Duration::Seconds(10),
|
816
931
|
channel_args.GetDurationFromIntMillis(GRPC_ARG_KEEPALIVE_TIME_MS)
|
@@ -838,24 +953,38 @@ Http2ClientTransport::Http2ClientTransport(
|
|
838
953
|
((keepalive_timeout_ < ping_timeout_) ? keepalive_timeout_
|
839
954
|
: Duration::Infinity()),
|
840
955
|
keepalive_time_),
|
841
|
-
keepalive_permit_without_calls_(
|
956
|
+
keepalive_permit_without_calls_(
|
957
|
+
channel_args.GetBool(GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS)
|
958
|
+
.value_or(false)),
|
959
|
+
enable_preferred_rx_crypto_frame_advertisement_(
|
960
|
+
channel_args
|
961
|
+
.GetBool(GRPC_ARG_EXPERIMENTAL_HTTP2_PREFERRED_CRYPTO_FRAME_SIZE)
|
962
|
+
.value_or(false)),
|
963
|
+
memory_owner_(channel_args.GetObject<ResourceQuota>()
|
964
|
+
->memory_quota()
|
965
|
+
->CreateMemoryOwner()),
|
966
|
+
flow_control_(
|
967
|
+
"PH2_Client",
|
968
|
+
channel_args.GetBool(GRPC_ARG_HTTP2_BDP_PROBE).value_or(true),
|
969
|
+
&memory_owner_),
|
970
|
+
ztrace_collector_(std::make_shared<PromiseHttp2ZTraceCollector>()) {
|
842
971
|
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport Constructor Begin";
|
972
|
+
SourceConstructed();
|
843
973
|
|
844
974
|
InitLocalSettings(settings_.mutable_local(), /*is_client=*/true);
|
845
975
|
ReadSettingsFromChannelArgs(channel_args, settings_.mutable_local(),
|
846
|
-
/*is_client=*/true);
|
976
|
+
flow_control_, /*is_client=*/true);
|
847
977
|
|
848
978
|
// Initialize the general party and write party.
|
849
979
|
auto general_party_arena = SimpleArenaAllocator(0)->MakeArena();
|
850
980
|
general_party_arena->SetContext<EventEngine>(event_engine.get());
|
851
981
|
general_party_ = Party::Make(std::move(general_party_arena));
|
852
982
|
|
853
|
-
general_party_->Spawn("ReadLoop", ReadLoop(),
|
854
|
-
|
855
|
-
general_party_->Spawn("
|
856
|
-
|
857
|
-
|
858
|
-
|
983
|
+
general_party_->Spawn("ReadLoop", UntilTransportClosed(ReadLoop()),
|
984
|
+
OnReadLoopEnded());
|
985
|
+
general_party_->Spawn("MultiplexerLoop",
|
986
|
+
UntilTransportClosed(MultiplexerLoop()),
|
987
|
+
OnMultiplexerLoopEnded());
|
859
988
|
// The keepalive loop is only spawned if the keepalive time is not infinity.
|
860
989
|
keepalive_manager_.Spawn(general_party_.get());
|
861
990
|
|
@@ -867,7 +996,7 @@ Http2ClientTransport::Http2ClientTransport(
|
|
867
996
|
Http2ErrorCode code = settings_.mutable_local().Apply(
|
868
997
|
Http2Settings::kInitialWindowSizeWireId,
|
869
998
|
(Http2Settings::max_initial_window_size() - 1));
|
870
|
-
|
999
|
+
GRPC_DCHECK(code == Http2ErrorCode::kNoError);
|
871
1000
|
// </DeleteAfterFlowControl>
|
872
1001
|
|
873
1002
|
const int max_hpack_table_size =
|
@@ -876,79 +1005,127 @@ Http2ClientTransport::Http2ClientTransport(
|
|
876
1005
|
encoder_.SetMaxUsableSize(max_hpack_table_size);
|
877
1006
|
}
|
878
1007
|
|
879
|
-
|
880
|
-
channel_args.GetDurationFromIntMillis(GRPC_ARG_SETTINGS_TIMEOUT)
|
881
|
-
.value_or(std::max(keepalive_timeout_ * 2, Duration::Minutes(1)));
|
1008
|
+
transport_settings_.SetSettingsTimeout(channel_args, keepalive_timeout_);
|
882
1009
|
|
883
|
-
std::optional<Http2SettingsFrame> settings_frame =
|
884
|
-
settings_.MaybeSendUpdate();
|
885
|
-
if (settings_frame.has_value()) {
|
886
|
-
GRPC_HTTP2_CLIENT_DLOG
|
887
|
-
<< "Http2ClientTransport Constructor Spawn SendFirstSettingsFrame";
|
888
|
-
general_party_->Spawn(
|
889
|
-
"SendFirstSettingsFrame",
|
890
|
-
[self = RefAsSubclass<Http2ClientTransport>(),
|
891
|
-
frame = std::move(*settings_frame)]() mutable {
|
892
|
-
return self->EnqueueOutgoingFrame(std::move(frame));
|
893
|
-
},
|
894
|
-
[](GRPC_UNUSED absl::Status status) {});
|
895
|
-
}
|
896
1010
|
if (settings_.local().allow_security_frame()) {
|
897
1011
|
// TODO(tjagtap) : [PH2][P3] : Setup the plumbing to pass the security frame
|
898
1012
|
// to the endpoing via TransportFramingEndpointExtension.
|
899
1013
|
// Also decide if this plumbing is done here, or when the peer sends
|
900
1014
|
// allow_security_frame too.
|
901
1015
|
}
|
1016
|
+
|
1017
|
+
// Spawn a promise to flush the gRPC initial connection string and settings
|
1018
|
+
// frames.
|
1019
|
+
general_party_->Spawn("SpawnFlushInitialFrames", TriggerWriteCycle(),
|
1020
|
+
[](GRPC_UNUSED absl::Status status) {});
|
1021
|
+
|
902
1022
|
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport Constructor End";
|
903
1023
|
}
|
904
1024
|
|
905
|
-
// This function MUST be idempotent.
|
906
|
-
|
1025
|
+
// This function MUST be idempotent. This function MUST be called from the
|
1026
|
+
// transport party.
|
1027
|
+
void Http2ClientTransport::CloseStream(RefCountedPtr<Stream> stream,
|
907
1028
|
CloseStreamArgs args,
|
908
1029
|
DebugLocation whence) {
|
1030
|
+
// TODO(akshitpatel) : [PH2][P3] : Measure the impact of holding mutex
|
1031
|
+
// throughout this function.
|
1032
|
+
MutexLock lock(&transport_mutex_);
|
1033
|
+
GRPC_DCHECK(stream != nullptr) << "stream is null";
|
909
1034
|
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::CloseStream for stream id: "
|
910
|
-
<<
|
1035
|
+
<< stream->GetStreamId()
|
911
1036
|
<< " location=" << whence.file() << ":"
|
912
1037
|
<< whence.line();
|
913
1038
|
|
914
|
-
|
915
|
-
|
916
|
-
MutexLock lock(&transport_mutex_);
|
917
|
-
auto pair = stream_list_.find(stream_id);
|
918
|
-
if (pair == stream_list_.end()) {
|
919
|
-
GRPC_HTTP2_CLIENT_DLOG
|
920
|
-
<< "Http2ClientTransport::CloseStream for stream id: " << stream_id
|
921
|
-
<< " stream not found";
|
922
|
-
return;
|
1039
|
+
if (args.close_writes) {
|
1040
|
+
stream->SetWriteClosed();
|
923
1041
|
}
|
924
|
-
auto& stream = pair->second;
|
925
1042
|
|
926
1043
|
if (args.close_reads) {
|
927
|
-
|
928
|
-
|
929
|
-
|
930
|
-
stream->
|
1044
|
+
GRPC_HTTP2_CLIENT_DLOG
|
1045
|
+
<< "Http2ClientTransport::CloseStream for stream id: "
|
1046
|
+
<< stream->GetStreamId() << " closing stream for reads.";
|
1047
|
+
stream_list_.erase(stream->GetStreamId());
|
931
1048
|
}
|
1049
|
+
}
|
932
1050
|
|
933
|
-
|
934
|
-
|
935
|
-
|
936
|
-
|
937
|
-
|
938
|
-
|
1051
|
+
// Here is the flow for stream close:
|
1052
|
+
// 1. BeginCloseStream is invoked if the transport needs to close the stream.
|
1053
|
+
// 2. If reset stream does not need to be sent, the stream is closed for reads
|
1054
|
+
// and writes immediately. Also, the stream is removed from the
|
1055
|
+
// stream_list_.
|
1056
|
+
// 3. If reset stream needs to be sent and the stream is cancelled, the stream
|
1057
|
+
// is closed for reads immediately. This will result in stream being removed
|
1058
|
+
// from the stream_list_. Additionally, the reset stream frame is enqueued
|
1059
|
+
// and the stream is closed for writes once the frame is created.
|
1060
|
+
// 4. Trailing metadata is pushed to the call stack.
|
1061
|
+
// Extended:
|
1062
|
+
// 5. Eventually CallHandler.OnDone() is invoked.
|
1063
|
+
// 6. If the call was cancelled, we try to enqueue a reset stream frame. In most
|
1064
|
+
// of the cases, this would be a no-op. The only case where this would
|
1065
|
+
// enqueue the reset stream frame is an application initiated abort.
|
1066
|
+
// 7. If the call was not cancelled, we try to enqueue a half close frame. If
|
1067
|
+
// the stream was already closed from writes, this would be a no-op.
|
1068
|
+
void Http2ClientTransport::BeginCloseStream(
|
1069
|
+
const uint32_t stream_id, std::optional<uint32_t> reset_stream_error_code,
|
1070
|
+
ServerMetadataHandle&& metadata, DebugLocation whence) {
|
1071
|
+
GRPC_HTTP2_CLIENT_DLOG
|
1072
|
+
<< "Http2ClientTransport::BeginCloseStream for stream id: " << stream_id
|
1073
|
+
<< " error_code="
|
1074
|
+
<< (reset_stream_error_code.has_value()
|
1075
|
+
? absl::StrCat(*reset_stream_error_code)
|
1076
|
+
: "nullopt")
|
1077
|
+
<< " ServerMetadata=" << metadata->DebugString()
|
1078
|
+
<< " location=" << whence.file() << ":" << whence.line();
|
1079
|
+
|
1080
|
+
RefCountedPtr<Stream> stream = LookupStream(stream_id);
|
1081
|
+
if (stream != nullptr) {
|
1082
|
+
if (stream->did_push_trailing_metadata) {
|
1083
|
+
return;
|
939
1084
|
}
|
940
1085
|
|
941
|
-
|
942
|
-
|
943
|
-
|
1086
|
+
// If reset stream needs to be sent, CloseStream will be called from the
|
1087
|
+
// Multiplexer after the reset stream frame is created.
|
1088
|
+
if (!reset_stream_error_code) {
|
1089
|
+
// Callers taking this path:
|
1090
|
+
// 1. Reading a RST stream frame (will not send any frame out).
|
1091
|
+
|
1092
|
+
CloseStream(stream,
|
1093
|
+
CloseStreamArgs{/*close_reads*/ true, /*close_writes=*/true},
|
1094
|
+
whence);
|
1095
|
+
stream->MarkHalfClosedRemote();
|
1096
|
+
} else {
|
1097
|
+
// Callers taking this path:
|
1098
|
+
// 1. Reading Trailing Metadata (MAY send half close from OnDone).
|
1099
|
+
// 2. Processing Error in transport (will send reset stream from here).
|
1100
|
+
|
1101
|
+
if (metadata->get(GrpcCallWasCancelled())) {
|
1102
|
+
CloseStream(
|
1103
|
+
stream,
|
1104
|
+
CloseStreamArgs{/*close_reads*/ true, /*close_writes=*/false},
|
1105
|
+
whence);
|
1106
|
+
absl::StatusOr<EnqueueResult> enqueue_result =
|
1107
|
+
stream->EnqueueResetStream(reset_stream_error_code.value());
|
1108
|
+
GRPC_HTTP2_CLIENT_DLOG << "Enqueued ResetStream with error code="
|
1109
|
+
<< reset_stream_error_code.value()
|
1110
|
+
<< " status=" << enqueue_result.status();
|
1111
|
+
if (enqueue_result.ok()) {
|
1112
|
+
GRPC_UNUSED absl::Status status = MaybeAddStreamToWritableStreamList(
|
1113
|
+
stream, enqueue_result.value());
|
1114
|
+
}
|
1115
|
+
}
|
944
1116
|
}
|
945
|
-
|
1117
|
+
|
1118
|
+
stream->did_push_trailing_metadata = true;
|
1119
|
+
// This maybe called multiple times while closing a stream. This should be
|
1120
|
+
// fine as the the call spine ignores the subsequent calls.
|
1121
|
+
stream->call.SpawnPushServerTrailingMetadata(std::move(metadata));
|
946
1122
|
}
|
947
1123
|
}
|
948
1124
|
|
949
1125
|
void Http2ClientTransport::CloseTransport() {
|
950
1126
|
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport::CloseTransport";
|
951
1127
|
|
1128
|
+
transport_closed_latch_.Set();
|
952
1129
|
// This is the only place where the general_party_ is
|
953
1130
|
// reset.
|
954
1131
|
general_party_.reset();
|
@@ -995,8 +1172,11 @@ void Http2ClientTransport::MaybeSpawnCloseTransport(Http2Status http2_status,
|
|
995
1172
|
// fail. Also, as this is running on the transport
|
996
1173
|
// party, there would not be concurrent access to the stream.
|
997
1174
|
auto& stream = pair.second;
|
998
|
-
stream->
|
999
|
-
|
1175
|
+
self->BeginCloseStream(stream->stream_id,
|
1176
|
+
Http2ErrorCodeToRstFrameErrorCode(
|
1177
|
+
http2_status.GetConnectionErrorCode()),
|
1178
|
+
CancelledServerMetadataFromStatus(
|
1179
|
+
http2_status.GetAbslConnectionError()));
|
1000
1180
|
}
|
1001
1181
|
|
1002
1182
|
// RFC9113 : A GOAWAY frame might not immediately precede closing of
|
@@ -1017,15 +1197,30 @@ void Http2ClientTransport::MaybeSpawnCloseTransport(Http2Status http2_status,
|
|
1017
1197
|
|
1018
1198
|
Http2ClientTransport::~Http2ClientTransport() {
|
1019
1199
|
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport Destructor Begin";
|
1020
|
-
|
1200
|
+
GRPC_DCHECK(stream_list_.empty());
|
1201
|
+
memory_owner_.Reset();
|
1202
|
+
SourceDestructing();
|
1021
1203
|
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport Destructor End";
|
1022
1204
|
}
|
1023
1205
|
|
1206
|
+
void Http2ClientTransport::AddData(channelz::DataSink sink) {
|
1207
|
+
sink.AddData(
|
1208
|
+
"Http2ClientTransport",
|
1209
|
+
channelz::PropertyList()
|
1210
|
+
.Set("settings", settings_.ChannelzProperties())
|
1211
|
+
.Set("keepalive_time", keepalive_time_)
|
1212
|
+
.Set("keepalive_timeout", keepalive_timeout_)
|
1213
|
+
.Set("ping_timeout", ping_timeout_)
|
1214
|
+
.Set("keepalive_permit_without_calls",
|
1215
|
+
keepalive_permit_without_calls_)
|
1216
|
+
.Set("flow_control", flow_control_.stats().ChannelzProperties()));
|
1217
|
+
general_party_->ExportToChannelz("Http2ClientTransport Party", sink);
|
1218
|
+
}
|
1219
|
+
|
1024
1220
|
///////////////////////////////////////////////////////////////////////////////
|
1025
1221
|
// Stream Related Operations
|
1026
1222
|
|
1027
|
-
RefCountedPtr<
|
1028
|
-
uint32_t stream_id) {
|
1223
|
+
RefCountedPtr<Stream> Http2ClientTransport::LookupStream(uint32_t stream_id) {
|
1029
1224
|
MutexLock lock(&transport_mutex_);
|
1030
1225
|
auto it = stream_list_.find(stream_id);
|
1031
1226
|
if (it == stream_list_.end()) {
|
@@ -1037,8 +1232,45 @@ RefCountedPtr<Http2ClientTransport::Stream> Http2ClientTransport::LookupStream(
|
|
1037
1232
|
return it->second;
|
1038
1233
|
}
|
1039
1234
|
|
1040
|
-
bool Http2ClientTransport::
|
1041
|
-
|
1235
|
+
bool Http2ClientTransport::SetOnDone(CallHandler call_handler,
|
1236
|
+
RefCountedPtr<Stream> stream) {
|
1237
|
+
return call_handler.OnDone(
|
1238
|
+
[self = RefAsSubclass<Http2ClientTransport>(), stream,
|
1239
|
+
stream_id = stream->GetStreamId()](bool cancelled) {
|
1240
|
+
GRPC_HTTP2_CLIENT_DLOG << "PH2: Client call " << self.get()
|
1241
|
+
<< " id=" << stream_id
|
1242
|
+
<< " done: cancelled=" << cancelled;
|
1243
|
+
absl::StatusOr<EnqueueResult> enqueue_result;
|
1244
|
+
GRPC_HTTP2_CLIENT_DLOG
|
1245
|
+
<< "PH2: Client call " << self.get() << " id=" << stream_id
|
1246
|
+
<< " done: stream=" << stream.get() << " cancelled=" << cancelled;
|
1247
|
+
if (cancelled) {
|
1248
|
+
// In most of the cases, EnqueueResetStream would be a no-op as
|
1249
|
+
// BeginCloseStream would have already enqueued the reset stream.
|
1250
|
+
// Currently only Aborts from application will actually enqueue
|
1251
|
+
// the reset stream here.
|
1252
|
+
enqueue_result = stream->EnqueueResetStream(
|
1253
|
+
static_cast<uint32_t>(Http2ErrorCode::kCancel));
|
1254
|
+
GRPC_HTTP2_CLIENT_DLOG
|
1255
|
+
<< "Enqueued ResetStream with error code="
|
1256
|
+
<< static_cast<uint32_t>(Http2ErrorCode::kCancel)
|
1257
|
+
<< " status=" << enqueue_result.status();
|
1258
|
+
} else {
|
1259
|
+
enqueue_result = stream->EnqueueHalfClosed();
|
1260
|
+
GRPC_HTTP2_CLIENT_DLOG << "Enqueued HalfClosed with result="
|
1261
|
+
<< enqueue_result.status();
|
1262
|
+
}
|
1263
|
+
|
1264
|
+
if (enqueue_result.ok()) {
|
1265
|
+
GRPC_UNUSED absl::Status status =
|
1266
|
+
self->MaybeAddStreamToWritableStreamList(stream,
|
1267
|
+
enqueue_result.value());
|
1268
|
+
}
|
1269
|
+
});
|
1270
|
+
}
|
1271
|
+
|
1272
|
+
std::optional<RefCountedPtr<Stream>> Http2ClientTransport::MakeStream(
|
1273
|
+
CallHandler call_handler, const uint32_t stream_id) {
|
1042
1274
|
// https://datatracker.ietf.org/doc/html/rfc9113#name-stream-identifiers
|
1043
1275
|
// TODO(tjagtap) : [PH2][P2] Validate implementation.
|
1044
1276
|
|
@@ -1047,118 +1279,62 @@ bool Http2ClientTransport::MakeStream(CallHandler call_handler,
|
|
1047
1279
|
// OnDone needs to be synchronous and hence InterActivityMutex might not be
|
1048
1280
|
// an option to protect the stream_list_.
|
1049
1281
|
MutexLock lock(&transport_mutex_);
|
1050
|
-
|
1051
|
-
call_handler
|
1052
|
-
|
1053
|
-
|
1054
|
-
|
1055
|
-
|
1056
|
-
|
1057
|
-
// TODO(akshitpatel) : [PH2][P2] : There are two ways to handle
|
1058
|
-
// cancellation.
|
1059
|
-
// 1. Call CloseStream from the on_done callback as done here. This
|
1060
|
-
// will be invoked when PullServerTrailingMetadata resolves.
|
1061
|
-
// 2. Call CloseStream from the OutboundLoop. When the call is
|
1062
|
-
// cancelled, for_each() should return with an error. The
|
1063
|
-
// WasCancelled() function can be used to determinie if the call
|
1064
|
-
// was cancelled.
|
1065
|
-
// At this point, both the above mentioned approaches seem to be more
|
1066
|
-
// or less the same as both are running on the call party.
|
1067
|
-
self->CloseStream(stream_id, absl::CancelledError(),
|
1068
|
-
CloseStreamArgs{
|
1069
|
-
/*close_reads=*/true,
|
1070
|
-
/*close_writes=*/true,
|
1071
|
-
/*send_rst_stream=*/true,
|
1072
|
-
/*push_trailing_metadata=*/false,
|
1073
|
-
});
|
1074
|
-
}
|
1075
|
-
});
|
1076
|
-
if (!on_done_added) return false;
|
1077
|
-
stream_list_.emplace(
|
1078
|
-
stream_id, MakeRefCounted<Stream>(std::move(call_handler), stream_id));
|
1079
|
-
return true;
|
1282
|
+
RefCountedPtr<Stream> stream = MakeRefCounted<Stream>(
|
1283
|
+
call_handler, stream_id, settings_.peer().allow_true_binary_metadata(),
|
1284
|
+
settings_.acked().allow_true_binary_metadata(), flow_control_);
|
1285
|
+
const bool on_done_added = SetOnDone(call_handler, stream);
|
1286
|
+
if (!on_done_added) return std::nullopt;
|
1287
|
+
stream_list_.emplace(stream_id, stream);
|
1288
|
+
return stream;
|
1080
1289
|
}
|
1081
1290
|
|
1082
1291
|
///////////////////////////////////////////////////////////////////////////////
|
1083
1292
|
// Call Spine related operations
|
1084
1293
|
|
1085
1294
|
auto Http2ClientTransport::CallOutboundLoop(
|
1086
|
-
CallHandler call_handler,
|
1295
|
+
CallHandler call_handler, RefCountedPtr<Stream> stream,
|
1087
1296
|
InterActivityMutex<uint32_t>::Lock lock /* Locked stream_id_mutex */,
|
1088
1297
|
ClientMetadataHandle metadata) {
|
1089
1298
|
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport CallOutboundLoop";
|
1299
|
+
GRPC_DCHECK(stream != nullptr);
|
1090
1300
|
|
1091
1301
|
auto send_message = [self = RefAsSubclass<Http2ClientTransport>(),
|
1092
|
-
|
1093
|
-
|
1094
|
-
|
1095
|
-
|
1096
|
-
|
1097
|
-
|
1098
|
-
|
1099
|
-
|
1100
|
-
|
1101
|
-
"Enqueued Message";
|
1102
|
-
return self->MaybeAddStreamToWritableStreamList(
|
1103
|
-
stream_id, became_writable);
|
1104
|
-
});
|
1105
|
-
},
|
1106
|
-
[]() {
|
1107
|
-
// This will trigger Call stack cleanup.
|
1108
|
-
return absl::InternalError("Stream not found while sending message");
|
1109
|
-
});
|
1302
|
+
stream](MessageHandle&& message) mutable {
|
1303
|
+
return TrySeq(stream->EnqueueMessage(std::move(message)),
|
1304
|
+
[self, stream](const EnqueueResult result) mutable {
|
1305
|
+
GRPC_HTTP2_CLIENT_DLOG
|
1306
|
+
<< "Http2ClientTransport CallOutboundLoop "
|
1307
|
+
"Enqueued Message";
|
1308
|
+
return self->MaybeAddStreamToWritableStreamList(
|
1309
|
+
std::move(stream), result);
|
1310
|
+
});
|
1110
1311
|
};
|
1111
1312
|
|
1112
1313
|
auto send_initial_metadata = [self = RefAsSubclass<Http2ClientTransport>(),
|
1113
|
-
|
1314
|
+
stream,
|
1114
1315
|
metadata = std::move(metadata)]() mutable {
|
1115
|
-
|
1116
|
-
|
1117
|
-
|
1118
|
-
[self, stream, metadata = std::move(metadata), stream_id]() mutable {
|
1119
|
-
return TrySeq(
|
1120
|
-
stream->EnqueueInitialMetadata(std::move(metadata)),
|
1121
|
-
[self, stream_id](bool became_writable) {
|
1122
|
-
GRPC_HTTP2_CLIENT_DLOG
|
1123
|
-
<< "Http2ClientTransport CallOutboundLoop "
|
1124
|
-
"Enqueued Initial Metadata";
|
1125
|
-
return self->MaybeAddStreamToWritableStreamList(
|
1126
|
-
stream_id, became_writable);
|
1127
|
-
},
|
1128
|
-
[stream] {
|
1129
|
-
// TODO(akshitpatel) : [PH2][P2] : Think how to handle stream
|
1130
|
-
// states.
|
1131
|
-
stream->SentInitialMetadata();
|
1132
|
-
return absl::OkStatus();
|
1133
|
-
});
|
1316
|
+
return TrySeq(
|
1317
|
+
[stream, metadata = std::move(metadata)]() mutable {
|
1318
|
+
return stream->EnqueueInitialMetadata(std::move(metadata));
|
1134
1319
|
},
|
1135
|
-
[]() {
|
1136
|
-
|
1137
|
-
|
1138
|
-
|
1320
|
+
[self, stream](const EnqueueResult result) mutable {
|
1321
|
+
GRPC_HTTP2_CLIENT_DLOG << "Http2ClientTransport CallOutboundLoop "
|
1322
|
+
"Enqueued Initial Metadata";
|
1323
|
+
return self->MaybeAddStreamToWritableStreamList(std::move(stream),
|
1324
|
+
result);
|
1139
1325
|
});
|
1140
1326
|
};
|
1141
1327
|
|
1142
1328
|
auto send_half_closed = [self = RefAsSubclass<Http2ClientTransport>(),
|
1143
|
-
|
1144
|
-
|
1145
|
-
|
1146
|
-
|
1147
|
-
|
1148
|
-
|
1149
|
-
|
1150
|
-
|
1151
|
-
|
1152
|
-
"Enqueued Half Closed";
|
1153
|
-
return self->MaybeAddStreamToWritableStreamList(
|
1154
|
-
stream_id, became_writable);
|
1155
|
-
});
|
1156
|
-
},
|
1157
|
-
[]() {
|
1158
|
-
// This will trigger Call stack cleanup.
|
1159
|
-
return absl::InternalError(
|
1160
|
-
"Stream not found while sending half closed");
|
1161
|
-
});
|
1329
|
+
stream]() mutable {
|
1330
|
+
return TrySeq([stream]() { return stream->EnqueueHalfClosed(); },
|
1331
|
+
[self, stream](const EnqueueResult result) mutable {
|
1332
|
+
GRPC_HTTP2_CLIENT_DLOG
|
1333
|
+
<< "Http2ClientTransport CallOutboundLoop "
|
1334
|
+
"Enqueued Half Closed";
|
1335
|
+
return self->MaybeAddStreamToWritableStreamList(
|
1336
|
+
std::move(stream), result);
|
1337
|
+
});
|
1162
1338
|
};
|
1163
1339
|
return GRPC_LATENT_SEE_PROMISE(
|
1164
1340
|
"Ph2CallOutboundLoop",
|
@@ -1214,12 +1390,13 @@ void Http2ClientTransport::StartCall(CallHandler call_handler) {
|
|
1214
1390
|
// from a client than is allowed by the clients settings, whether or
|
1215
1391
|
// not we should fail is debatable.
|
1216
1392
|
const uint32_t stream_id = self->NextStreamId(std::get<0>(args));
|
1393
|
+
std::optional<RefCountedPtr<Stream>> stream =
|
1394
|
+
self->MakeStream(call_handler, stream_id);
|
1217
1395
|
return If(
|
1218
|
-
|
1219
|
-
[self, call_handler,
|
1220
|
-
args = std::move(args)]() mutable {
|
1396
|
+
stream.has_value(),
|
1397
|
+
[self, call_handler, stream, args = std::move(args)]() mutable {
|
1221
1398
|
return Map(
|
1222
|
-
self->CallOutboundLoop(call_handler,
|
1399
|
+
self->CallOutboundLoop(call_handler, stream.value(),
|
1223
1400
|
std::move(std::get<0>(args)),
|
1224
1401
|
std::move(std::get<1>(args))),
|
1225
1402
|
[](absl::Status status) { return status; });
|