grpc 1.50.0.pre1 → 1.51.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of grpc might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Makefile +131 -42
- data/include/grpc/event_engine/event_engine.h +10 -3
- data/include/grpc/event_engine/slice_buffer.h +17 -0
- data/include/grpc/grpc.h +0 -10
- data/include/grpc/impl/codegen/grpc_types.h +1 -5
- data/include/grpc/impl/codegen/port_platform.h +0 -3
- data/src/core/ext/filters/channel_idle/channel_idle_filter.cc +19 -13
- data/src/core/ext/filters/channel_idle/channel_idle_filter.h +1 -0
- data/src/core/ext/filters/client_channel/backup_poller.cc +3 -3
- data/src/core/ext/filters/client_channel/channel_connectivity.cc +7 -5
- data/src/core/ext/filters/client_channel/client_channel.cc +120 -140
- data/src/core/ext/filters/client_channel/client_channel.h +3 -4
- data/src/core/ext/filters/client_channel/client_channel_channelz.cc +0 -2
- data/src/core/ext/filters/client_channel/client_channel_plugin.cc +1 -1
- data/src/core/ext/filters/client_channel/client_channel_service_config.cc +153 -0
- data/src/core/ext/filters/client_channel/{resolver_result_parsing.h → client_channel_service_config.h} +26 -23
- data/src/core/ext/filters/client_channel/connector.h +1 -1
- data/src/core/ext/filters/client_channel/dynamic_filters.cc +20 -47
- data/src/core/ext/filters/client_channel/dynamic_filters.h +7 -8
- data/src/core/ext/filters/client_channel/health/health_check_client.cc +3 -4
- data/src/core/ext/filters/client_channel/http_proxy.cc +0 -1
- data/src/core/ext/filters/client_channel/lb_policy/address_filtering.cc +3 -4
- data/src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc +5 -0
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc +8 -7
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +35 -44
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc +0 -1
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc +1 -3
- data/src/core/ext/filters/client_channel/lb_policy/oob_backend_metric.cc +3 -4
- data/src/core/ext/filters/client_channel/lb_policy/oob_backend_metric.h +1 -1
- data/src/core/ext/filters/client_channel/lb_policy/outlier_detection/outlier_detection.cc +41 -29
- data/src/core/ext/filters/client_channel/lb_policy/outlier_detection/outlier_detection.h +2 -2
- data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +9 -11
- data/src/core/ext/filters/client_channel/lb_policy/priority/priority.cc +15 -12
- data/src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.cc +8 -10
- data/src/core/ext/filters/client_channel/lb_policy/rls/rls.cc +26 -27
- data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +7 -9
- data/src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc +44 -26
- data/src/core/ext/filters/client_channel/lb_policy/xds/cds.cc +17 -27
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds_attributes.cc +42 -0
- data/src/core/ext/filters/client_channel/lb_policy/xds/{xds.h → xds_attributes.h} +15 -17
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc +13 -7
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc +48 -47
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc +40 -126
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds_wrr_locality.cc +364 -0
- data/src/core/ext/filters/client_channel/resolver/binder/binder_resolver.cc +9 -9
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +23 -32
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc +1 -2
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +22 -23
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +50 -52
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h +1 -1
- data/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +2 -4
- data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +1 -3
- data/src/core/ext/filters/client_channel/resolver/google_c2p/google_c2p_resolver.cc +34 -26
- data/src/core/ext/filters/client_channel/resolver/polling_resolver.cc +3 -4
- data/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc +4 -7
- data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc +63 -46
- data/src/core/ext/filters/client_channel/retry_filter.cc +80 -102
- data/src/core/ext/filters/client_channel/retry_service_config.cc +192 -234
- data/src/core/ext/filters/client_channel/retry_service_config.h +20 -23
- data/src/core/ext/filters/client_channel/retry_throttle.cc +8 -8
- data/src/core/ext/filters/client_channel/retry_throttle.h +8 -7
- data/src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc +2 -2
- data/src/core/ext/filters/client_channel/subchannel.cc +21 -25
- data/src/core/ext/filters/client_channel/subchannel.h +2 -2
- data/src/core/ext/filters/client_channel/subchannel_stream_client.cc +11 -12
- data/src/core/ext/filters/deadline/deadline_filter.cc +13 -14
- data/src/core/ext/filters/fault_injection/fault_injection_filter.cc +1 -1
- data/src/core/ext/filters/fault_injection/fault_injection_filter.h +0 -4
- data/src/core/ext/filters/fault_injection/fault_injection_service_config_parser.cc +118 -0
- data/src/core/ext/filters/fault_injection/{service_config_parser.h → fault_injection_service_config_parser.h} +20 -12
- data/src/core/ext/filters/http/client/http_client_filter.cc +16 -16
- data/src/core/ext/filters/http/client_authority_filter.cc +1 -1
- data/src/core/ext/filters/http/message_compress/message_compress_filter.cc +13 -13
- data/src/core/ext/filters/http/message_compress/message_decompress_filter.cc +34 -34
- data/src/core/ext/filters/http/server/http_server_filter.cc +26 -25
- data/src/core/ext/filters/message_size/message_size_filter.cc +86 -117
- data/src/core/ext/filters/message_size/message_size_filter.h +22 -15
- data/src/core/ext/filters/rbac/rbac_filter.cc +12 -12
- data/src/core/ext/filters/rbac/rbac_service_config_parser.cc +728 -530
- data/src/core/ext/filters/rbac/rbac_service_config_parser.h +4 -3
- data/src/core/ext/filters/server_config_selector/server_config_selector.h +1 -1
- data/src/core/ext/filters/server_config_selector/server_config_selector_filter.cc +6 -7
- data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +17 -21
- data/src/core/ext/transport/chttp2/server/chttp2_server.cc +57 -72
- data/src/core/ext/transport/chttp2/transport/bin_decoder.cc +5 -5
- data/src/core/ext/transport/chttp2/transport/bin_encoder.h +1 -1
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +212 -253
- data/src/core/ext/transport/chttp2/transport/flow_control.cc +42 -11
- data/src/core/ext/transport/chttp2/transport/flow_control.h +4 -3
- data/src/core/ext/transport/chttp2/transport/frame_data.cc +16 -15
- data/src/core/ext/transport/chttp2/transport/frame_data.h +1 -1
- data/src/core/ext/transport/chttp2/transport/frame_goaway.cc +13 -13
- data/src/core/ext/transport/chttp2/transport/frame_ping.cc +4 -3
- data/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +10 -7
- data/src/core/ext/transport/chttp2/transport/frame_settings.cc +15 -17
- data/src/core/ext/transport/chttp2/transport/frame_window_update.cc +5 -4
- data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +5 -6
- data/src/core/ext/transport/chttp2/transport/hpack_encoder.h +1 -1
- data/src/core/ext/transport/chttp2/transport/hpack_encoder_table.cc +2 -1
- data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +31 -39
- data/src/core/ext/transport/chttp2/transport/hpack_parser_table.cc +7 -6
- data/src/core/ext/transport/chttp2/transport/internal.h +24 -8
- data/src/core/ext/transport/chttp2/transport/parsing.cc +51 -52
- data/src/core/ext/transport/chttp2/transport/varint.cc +2 -3
- data/src/core/ext/transport/chttp2/transport/varint.h +11 -8
- data/src/core/ext/transport/chttp2/transport/writing.cc +16 -16
- data/src/core/ext/transport/inproc/inproc_transport.cc +97 -115
- data/src/core/ext/xds/certificate_provider_store.cc +4 -4
- data/src/core/ext/xds/file_watcher_certificate_provider_factory.cc +4 -7
- data/src/core/ext/xds/xds_api.cc +15 -68
- data/src/core/ext/xds/xds_api.h +3 -7
- data/src/core/ext/xds/xds_bootstrap.h +0 -1
- data/src/core/ext/xds/xds_bootstrap_grpc.cc +3 -12
- data/src/core/ext/xds/xds_bootstrap_grpc.h +16 -1
- data/src/core/ext/xds/xds_certificate_provider.cc +22 -25
- data/src/core/ext/xds/xds_channel_stack_modifier.cc +0 -1
- data/src/core/ext/xds/xds_client.cc +122 -90
- data/src/core/ext/xds/xds_client.h +7 -2
- data/src/core/ext/xds/xds_client_grpc.cc +5 -24
- data/src/core/ext/xds/xds_cluster.cc +291 -183
- data/src/core/ext/xds/xds_cluster.h +11 -15
- data/src/core/ext/xds/xds_cluster_specifier_plugin.cc +32 -29
- data/src/core/ext/xds/xds_cluster_specifier_plugin.h +35 -16
- data/src/core/ext/xds/xds_common_types.cc +208 -141
- data/src/core/ext/xds/xds_common_types.h +19 -13
- data/src/core/ext/xds/xds_endpoint.cc +214 -129
- data/src/core/ext/xds/xds_endpoint.h +4 -7
- data/src/core/ext/xds/xds_http_fault_filter.cc +56 -43
- data/src/core/ext/xds/xds_http_fault_filter.h +13 -21
- data/src/core/ext/xds/xds_http_filters.cc +60 -73
- data/src/core/ext/xds/xds_http_filters.h +67 -19
- data/src/core/ext/xds/xds_http_rbac_filter.cc +152 -207
- data/src/core/ext/xds/xds_http_rbac_filter.h +12 -15
- data/src/core/ext/xds/xds_lb_policy_registry.cc +122 -169
- data/src/core/ext/xds/xds_lb_policy_registry.h +10 -11
- data/src/core/ext/xds/xds_listener.cc +459 -417
- data/src/core/ext/xds/xds_listener.h +43 -47
- data/src/core/ext/xds/xds_resource_type.h +3 -11
- data/src/core/ext/xds/xds_resource_type_impl.h +8 -13
- data/src/core/ext/xds/xds_route_config.cc +94 -80
- data/src/core/ext/xds/xds_route_config.h +10 -10
- data/src/core/ext/xds/xds_routing.cc +2 -1
- data/src/core/ext/xds/xds_routing.h +2 -0
- data/src/core/ext/xds/xds_server_config_fetcher.cc +109 -94
- data/src/core/ext/xds/xds_transport_grpc.cc +4 -5
- data/src/core/lib/address_utils/parse_address.cc +11 -10
- data/src/core/lib/channel/channel_args.h +16 -1
- data/src/core/lib/channel/channel_stack.cc +23 -20
- data/src/core/lib/channel/channel_stack.h +17 -4
- data/src/core/lib/channel/channel_stack_builder.cc +4 -7
- data/src/core/lib/channel/channel_stack_builder.h +14 -6
- data/src/core/lib/channel/channel_stack_builder_impl.cc +25 -7
- data/src/core/lib/channel/channel_stack_builder_impl.h +2 -0
- data/src/core/lib/channel/channel_trace.cc +4 -5
- data/src/core/lib/channel/channelz.cc +1 -1
- data/src/core/lib/channel/connected_channel.cc +695 -35
- data/src/core/lib/channel/connected_channel.h +0 -4
- data/src/core/lib/channel/promise_based_filter.cc +1004 -140
- data/src/core/lib/channel/promise_based_filter.h +364 -87
- data/src/core/lib/compression/message_compress.cc +5 -5
- data/src/core/lib/debug/event_log.cc +88 -0
- data/src/core/lib/debug/event_log.h +81 -0
- data/src/core/lib/debug/histogram_view.cc +69 -0
- data/src/core/lib/{slice/slice_refcount.cc → debug/histogram_view.h} +15 -13
- data/src/core/lib/debug/stats.cc +22 -119
- data/src/core/lib/debug/stats.h +29 -35
- data/src/core/lib/debug/stats_data.cc +224 -73
- data/src/core/lib/debug/stats_data.h +263 -122
- data/src/core/lib/event_engine/common_closures.h +71 -0
- data/src/core/lib/event_engine/default_event_engine.cc +38 -15
- data/src/core/lib/event_engine/default_event_engine.h +15 -3
- data/src/core/lib/event_engine/default_event_engine_factory.cc +2 -4
- data/src/core/lib/event_engine/memory_allocator.cc +1 -1
- data/src/core/lib/event_engine/poller.h +10 -4
- data/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc +618 -0
- data/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.h +129 -0
- data/src/core/lib/event_engine/posix_engine/ev_poll_posix.cc +901 -0
- data/src/core/lib/event_engine/posix_engine/ev_poll_posix.h +97 -0
- data/src/core/lib/event_engine/posix_engine/event_poller.h +111 -0
- data/src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc +74 -0
- data/src/core/lib/event_engine/{executor/threaded_executor.cc → posix_engine/event_poller_posix_default.h} +13 -16
- data/src/core/lib/event_engine/posix_engine/internal_errqueue.cc +77 -0
- data/src/core/lib/event_engine/posix_engine/internal_errqueue.h +179 -0
- data/src/core/lib/event_engine/posix_engine/lockfree_event.cc +267 -0
- data/src/core/lib/event_engine/posix_engine/lockfree_event.h +73 -0
- data/src/core/lib/event_engine/posix_engine/posix_endpoint.cc +1270 -0
- data/src/core/lib/event_engine/posix_engine/posix_endpoint.h +682 -0
- data/src/core/lib/event_engine/posix_engine/posix_engine.cc +453 -18
- data/src/core/lib/event_engine/posix_engine/posix_engine.h +148 -24
- data/src/core/lib/event_engine/posix_engine/posix_engine_closure.h +80 -0
- data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.cc +1081 -0
- data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.h +361 -0
- data/src/core/lib/event_engine/posix_engine/timer.h +9 -8
- data/src/core/lib/event_engine/posix_engine/timer_manager.cc +57 -194
- data/src/core/lib/event_engine/posix_engine/timer_manager.h +21 -49
- data/src/core/lib/event_engine/posix_engine/traced_buffer_list.cc +301 -0
- data/src/core/lib/event_engine/posix_engine/traced_buffer_list.h +179 -0
- data/src/core/lib/event_engine/posix_engine/wakeup_fd_eventfd.cc +126 -0
- data/src/core/lib/event_engine/posix_engine/wakeup_fd_eventfd.h +45 -0
- data/src/core/lib/event_engine/posix_engine/wakeup_fd_pipe.cc +151 -0
- data/src/core/lib/event_engine/posix_engine/wakeup_fd_pipe.h +45 -0
- data/src/core/lib/event_engine/posix_engine/wakeup_fd_posix.h +76 -0
- data/src/core/lib/event_engine/posix_engine/wakeup_fd_posix_default.cc +67 -0
- data/src/core/lib/event_engine/posix_engine/wakeup_fd_posix_default.h +37 -0
- data/src/core/lib/event_engine/slice.cc +7 -6
- data/src/core/lib/event_engine/slice_buffer.cc +2 -2
- data/src/core/lib/event_engine/thread_pool.cc +106 -25
- data/src/core/lib/event_engine/thread_pool.h +32 -9
- data/src/core/lib/event_engine/windows/win_socket.cc +7 -7
- data/src/core/lib/event_engine/windows/windows_engine.cc +18 -12
- data/src/core/lib/event_engine/windows/windows_engine.h +8 -4
- data/src/core/lib/experiments/config.cc +1 -1
- data/src/core/lib/experiments/experiments.cc +13 -2
- data/src/core/lib/experiments/experiments.h +8 -1
- data/src/core/lib/gpr/cpu_linux.cc +6 -2
- data/src/core/lib/gpr/log_linux.cc +3 -4
- data/src/core/lib/gpr/string.h +1 -1
- data/src/core/lib/gpr/tmpfile_posix.cc +3 -2
- data/src/core/lib/gprpp/load_file.cc +75 -0
- data/src/core/lib/gprpp/load_file.h +33 -0
- data/src/core/lib/gprpp/per_cpu.h +46 -0
- data/src/core/lib/gprpp/stat_posix.cc +5 -4
- data/src/core/lib/gprpp/stat_windows.cc +3 -2
- data/src/core/lib/gprpp/status_helper.h +1 -3
- data/src/core/lib/gprpp/strerror.cc +41 -0
- data/src/core/{ext/xds/xds_resource_type.cc → lib/gprpp/strerror.h} +9 -13
- data/src/core/lib/gprpp/thd_windows.cc +1 -2
- data/src/core/lib/gprpp/time.cc +3 -4
- data/src/core/lib/gprpp/time.h +13 -2
- data/src/core/lib/gprpp/validation_errors.h +18 -1
- data/src/core/lib/http/httpcli.cc +40 -44
- data/src/core/lib/http/httpcli.h +6 -5
- data/src/core/lib/http/httpcli_security_connector.cc +4 -6
- data/src/core/lib/http/parser.cc +54 -65
- data/src/core/lib/iomgr/buffer_list.cc +105 -116
- data/src/core/lib/iomgr/buffer_list.h +60 -44
- data/src/core/lib/iomgr/call_combiner.cc +11 -10
- data/src/core/lib/iomgr/call_combiner.h +3 -4
- data/src/core/lib/iomgr/cfstream_handle.cc +13 -16
- data/src/core/lib/iomgr/closure.h +49 -5
- data/src/core/lib/iomgr/combiner.cc +2 -2
- data/src/core/lib/iomgr/endpoint.h +1 -1
- data/src/core/lib/iomgr/endpoint_cfstream.cc +26 -25
- data/src/core/lib/iomgr/endpoint_pair_posix.cc +2 -2
- data/src/core/lib/iomgr/error.cc +27 -42
- data/src/core/lib/iomgr/error.h +22 -152
- data/src/core/lib/iomgr/ev_apple.cc +4 -4
- data/src/core/lib/iomgr/ev_epoll1_linux.cc +26 -25
- data/src/core/lib/iomgr/ev_poll_posix.cc +27 -31
- data/src/core/lib/iomgr/exec_ctx.cc +3 -4
- data/src/core/lib/iomgr/exec_ctx.h +2 -3
- data/src/core/lib/iomgr/executor.cc +1 -2
- data/src/core/lib/iomgr/internal_errqueue.cc +3 -1
- data/src/core/lib/iomgr/iocp_windows.cc +1 -0
- data/src/core/lib/iomgr/iomgr_posix.cc +2 -2
- data/src/core/lib/iomgr/iomgr_posix_cfstream.cc +2 -1
- data/src/core/lib/iomgr/iomgr_windows.cc +2 -1
- data/src/core/lib/iomgr/load_file.cc +5 -9
- data/src/core/lib/iomgr/lockfree_event.cc +10 -10
- data/src/core/lib/iomgr/pollset_windows.cc +4 -4
- data/src/core/lib/iomgr/python_util.h +2 -2
- data/src/core/lib/iomgr/resolve_address.cc +8 -3
- data/src/core/lib/iomgr/resolve_address.h +3 -4
- data/src/core/lib/iomgr/resolve_address_impl.h +1 -1
- data/src/core/lib/iomgr/resolve_address_posix.cc +14 -25
- data/src/core/lib/iomgr/resolve_address_posix.h +1 -2
- data/src/core/lib/iomgr/resolve_address_windows.cc +14 -17
- data/src/core/lib/iomgr/resolve_address_windows.h +1 -2
- data/src/core/lib/iomgr/socket_utils_common_posix.cc +30 -29
- data/src/core/lib/iomgr/socket_utils_posix.cc +1 -0
- data/src/core/lib/iomgr/socket_utils_posix.h +2 -2
- data/src/core/lib/iomgr/socket_windows.cc +2 -2
- data/src/core/lib/iomgr/tcp_client_cfstream.cc +6 -10
- data/src/core/lib/iomgr/tcp_client_posix.cc +31 -35
- data/src/core/lib/iomgr/tcp_client_windows.cc +8 -12
- data/src/core/lib/iomgr/tcp_posix.cc +92 -108
- data/src/core/lib/iomgr/tcp_server_posix.cc +34 -34
- data/src/core/lib/iomgr/tcp_server_utils_posix.h +1 -1
- data/src/core/lib/iomgr/tcp_server_utils_posix_common.cc +18 -21
- data/src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.cc +12 -13
- data/src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.cc +1 -1
- data/src/core/lib/iomgr/tcp_server_windows.cc +26 -29
- data/src/core/lib/iomgr/tcp_windows.cc +27 -34
- data/src/core/lib/iomgr/timer.h +8 -8
- data/src/core/lib/iomgr/timer_generic.cc +9 -15
- data/src/core/lib/iomgr/unix_sockets_posix.cc +2 -4
- data/src/core/lib/iomgr/wakeup_fd_eventfd.cc +4 -3
- data/src/core/lib/iomgr/wakeup_fd_pipe.cc +10 -8
- data/src/core/lib/json/json_channel_args.h +42 -0
- data/src/core/lib/json/json_object_loader.cc +7 -2
- data/src/core/lib/json/json_object_loader.h +22 -0
- data/src/core/lib/json/json_util.cc +5 -5
- data/src/core/lib/json/json_util.h +4 -4
- data/src/core/lib/load_balancing/lb_policy.cc +1 -1
- data/src/core/lib/load_balancing/lb_policy.h +4 -0
- data/src/core/lib/load_balancing/subchannel_interface.h +0 -7
- data/src/core/lib/matchers/matchers.cc +3 -4
- data/src/core/lib/promise/activity.cc +16 -2
- data/src/core/lib/promise/activity.h +38 -15
- data/src/core/lib/promise/arena_promise.h +80 -51
- data/src/core/lib/promise/context.h +13 -6
- data/src/core/lib/promise/detail/basic_seq.h +9 -28
- data/src/core/lib/promise/detail/promise_factory.h +58 -10
- data/src/core/lib/promise/detail/status.h +28 -0
- data/src/core/lib/promise/detail/switch.h +1455 -0
- data/src/core/lib/promise/exec_ctx_wakeup_scheduler.h +3 -1
- data/src/core/lib/promise/for_each.h +129 -0
- data/src/core/lib/promise/loop.h +7 -5
- data/src/core/lib/promise/map_pipe.h +87 -0
- data/src/core/lib/promise/pipe.cc +19 -0
- data/src/core/lib/promise/pipe.h +505 -0
- data/src/core/lib/promise/poll.h +13 -0
- data/src/core/lib/promise/seq.h +3 -5
- data/src/core/lib/promise/sleep.cc +5 -4
- data/src/core/lib/promise/sleep.h +1 -2
- data/src/core/lib/promise/try_concurrently.h +341 -0
- data/src/core/lib/promise/try_seq.h +10 -13
- data/src/core/lib/resolver/server_address.cc +1 -0
- data/src/core/lib/resolver/server_address.h +1 -3
- data/src/core/lib/resource_quota/api.cc +0 -1
- data/src/core/lib/resource_quota/arena.cc +19 -0
- data/src/core/lib/resource_quota/arena.h +89 -0
- data/src/core/lib/resource_quota/memory_quota.cc +1 -0
- data/src/core/lib/security/authorization/grpc_authorization_engine.cc +1 -3
- data/src/core/lib/security/authorization/grpc_server_authz_filter.cc +4 -2
- data/src/core/lib/security/authorization/matchers.cc +25 -22
- data/src/core/lib/security/authorization/rbac_policy.cc +2 -3
- data/src/core/lib/security/context/security_context.h +10 -0
- data/src/core/lib/security/credentials/channel_creds_registry_init.cc +3 -4
- data/src/core/lib/security/credentials/composite/composite_credentials.cc +1 -1
- data/src/core/lib/security/credentials/external/aws_external_account_credentials.cc +77 -55
- data/src/core/lib/security/credentials/external/aws_request_signer.cc +4 -3
- data/src/core/lib/security/credentials/external/external_account_credentials.cc +40 -51
- data/src/core/lib/security/credentials/external/file_external_account_credentials.cc +17 -21
- data/src/core/lib/security/credentials/external/url_external_account_credentials.cc +21 -25
- data/src/core/lib/security/credentials/fake/fake_credentials.cc +1 -0
- data/src/core/lib/security/credentials/google_default/google_default_credentials.cc +27 -24
- data/src/core/lib/security/credentials/iam/iam_credentials.cc +1 -0
- data/src/core/lib/security/credentials/jwt/json_token.cc +1 -2
- data/src/core/lib/security/credentials/jwt/jwt_credentials.cc +1 -1
- data/src/core/lib/security/credentials/jwt/jwt_verifier.cc +5 -5
- data/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +24 -30
- data/src/core/lib/security/credentials/plugin/plugin_credentials.cc +6 -5
- data/src/core/lib/security/credentials/plugin/plugin_credentials.h +3 -3
- data/src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.cc +19 -27
- data/src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.h +4 -11
- data/src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc +29 -41
- data/src/core/lib/security/credentials/tls/grpc_tls_certificate_verifier.cc +1 -1
- data/src/core/lib/security/security_connector/alts/alts_security_connector.cc +6 -11
- data/src/core/lib/security/security_connector/fake/fake_security_connector.cc +8 -15
- data/src/core/lib/security/security_connector/insecure/insecure_security_connector.cc +2 -2
- data/src/core/lib/security/security_connector/insecure/insecure_security_connector.h +2 -6
- data/src/core/lib/security/security_connector/load_system_roots_supported.cc +1 -4
- data/src/core/lib/security/security_connector/local/local_security_connector.cc +7 -11
- data/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc +9 -14
- data/src/core/lib/security/security_connector/ssl_utils.cc +5 -7
- data/src/core/lib/security/security_connector/tls/tls_security_connector.cc +21 -27
- data/src/core/lib/security/transport/client_auth_filter.cc +1 -1
- data/src/core/lib/security/transport/secure_endpoint.cc +26 -28
- data/src/core/lib/security/transport/security_handshaker.cc +53 -53
- data/src/core/lib/security/transport/server_auth_filter.cc +21 -21
- data/src/core/lib/security/transport/tsi_error.cc +6 -3
- data/src/core/lib/security/util/json_util.cc +4 -5
- data/src/core/lib/service_config/service_config.h +1 -1
- data/src/core/lib/service_config/service_config_impl.cc +111 -158
- data/src/core/lib/service_config/service_config_impl.h +14 -17
- data/src/core/lib/service_config/service_config_parser.cc +14 -31
- data/src/core/lib/service_config/service_config_parser.h +14 -10
- data/src/core/lib/slice/b64.cc +2 -2
- data/src/core/lib/slice/slice.cc +7 -1
- data/src/core/lib/slice/slice.h +19 -6
- data/src/core/lib/slice/slice_buffer.cc +13 -14
- data/src/core/lib/slice/slice_internal.h +13 -21
- data/src/core/lib/slice/slice_refcount.h +34 -19
- data/src/core/lib/surface/byte_buffer.cc +3 -4
- data/src/core/lib/surface/byte_buffer_reader.cc +4 -4
- data/src/core/lib/surface/call.cc +1366 -239
- data/src/core/lib/surface/call.h +44 -0
- data/src/core/lib/surface/call_details.cc +3 -3
- data/src/core/lib/surface/call_trace.cc +113 -0
- data/src/core/lib/surface/call_trace.h +30 -0
- data/src/core/lib/surface/channel.cc +44 -49
- data/src/core/lib/surface/channel.h +9 -1
- data/src/core/lib/surface/channel_ping.cc +1 -1
- data/src/core/lib/surface/channel_stack_type.cc +4 -0
- data/src/core/lib/surface/channel_stack_type.h +2 -0
- data/src/core/lib/surface/completion_queue.cc +38 -52
- data/src/core/lib/surface/init.cc +8 -39
- data/src/core/lib/surface/init_internally.h +8 -0
- data/src/core/lib/surface/lame_client.cc +10 -8
- data/src/core/lib/surface/server.cc +48 -70
- data/src/core/lib/surface/server.h +3 -4
- data/src/core/lib/surface/validate_metadata.cc +11 -12
- data/src/core/lib/surface/version.cc +2 -2
- data/src/core/lib/transport/connectivity_state.cc +2 -2
- data/src/core/lib/transport/error_utils.cc +34 -28
- data/src/core/lib/transport/error_utils.h +3 -3
- data/src/core/lib/transport/handshaker.cc +14 -14
- data/src/core/lib/transport/handshaker.h +1 -1
- data/src/core/lib/transport/handshaker_factory.h +26 -0
- data/src/core/lib/transport/handshaker_registry.cc +8 -2
- data/src/core/lib/transport/handshaker_registry.h +3 -4
- data/src/core/lib/transport/http_connect_handshaker.cc +23 -24
- data/src/core/lib/transport/metadata_batch.h +17 -1
- data/src/core/lib/transport/parsed_metadata.cc +2 -6
- data/src/core/lib/transport/tcp_connect_handshaker.cc +15 -20
- data/src/core/lib/transport/transport.cc +63 -17
- data/src/core/lib/transport/transport.h +64 -68
- data/src/core/lib/transport/transport_impl.h +1 -1
- data/src/core/lib/transport/transport_op_string.cc +7 -6
- data/src/core/plugin_registry/grpc_plugin_registry.cc +6 -10
- data/src/core/plugin_registry/grpc_plugin_registry_extra.cc +2 -14
- data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +10 -10
- data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +8 -8
- data/src/core/tsi/alts/handshaker/alts_tsi_utils.cc +2 -1
- data/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.cc +7 -7
- data/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.cc +7 -6
- data/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.cc +1 -1
- data/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc +5 -5
- data/src/core/tsi/fake_transport_security.cc +3 -3
- data/src/core/tsi/ssl/key_logging/ssl_key_logging.cc +7 -3
- data/src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc +1 -1
- data/src/core/tsi/ssl/session_cache/ssl_session_openssl.cc +6 -2
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +0 -2
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +0 -3
- data/src/ruby/lib/grpc/version.rb +1 -1
- data/src/ruby/spec/channel_spec.rb +0 -43
- data/src/ruby/spec/generic/active_call_spec.rb +12 -3
- data/third_party/abseil-cpp/absl/cleanup/cleanup.h +140 -0
- data/third_party/abseil-cpp/absl/cleanup/internal/cleanup.h +100 -0
- data/third_party/zlib/compress.c +3 -3
- data/third_party/zlib/crc32.c +21 -12
- data/third_party/zlib/deflate.c +112 -106
- data/third_party/zlib/deflate.h +2 -2
- data/third_party/zlib/gzlib.c +1 -1
- data/third_party/zlib/gzread.c +3 -5
- data/third_party/zlib/gzwrite.c +1 -1
- data/third_party/zlib/infback.c +10 -7
- data/third_party/zlib/inflate.c +5 -2
- data/third_party/zlib/inftrees.c +2 -2
- data/third_party/zlib/inftrees.h +1 -1
- data/third_party/zlib/trees.c +61 -62
- data/third_party/zlib/uncompr.c +2 -2
- data/third_party/zlib/zconf.h +16 -3
- data/third_party/zlib/zlib.h +10 -10
- data/third_party/zlib/zutil.c +9 -7
- data/third_party/zlib/zutil.h +1 -0
- metadata +57 -20
- data/src/core/ext/filters/client_channel/resolver_result_parsing.cc +0 -188
- data/src/core/ext/filters/fault_injection/service_config_parser.cc +0 -187
- data/src/core/lib/event_engine/executor/threaded_executor.h +0 -44
- data/src/core/lib/gpr/murmur_hash.cc +0 -82
- data/src/core/lib/gpr/murmur_hash.h +0 -29
- data/src/core/lib/gpr/tls.h +0 -156
- data/src/core/lib/promise/call_push_pull.h +0 -148
- data/src/core/lib/slice/slice_api.cc +0 -39
- data/src/core/lib/slice/slice_buffer_api.cc +0 -35
- data/src/core/lib/slice/slice_refcount_base.h +0 -60
@@ -20,24 +20,31 @@
|
|
20
20
|
|
21
21
|
#include "src/core/lib/surface/call.h"
|
22
22
|
|
23
|
+
#include <inttypes.h>
|
23
24
|
#include <limits.h>
|
24
25
|
#include <stdlib.h>
|
25
26
|
|
26
27
|
#include <algorithm>
|
27
28
|
#include <atomic>
|
29
|
+
#include <memory>
|
28
30
|
#include <new>
|
29
31
|
#include <string>
|
30
32
|
#include <utility>
|
33
|
+
#include <vector>
|
31
34
|
|
32
35
|
#include "absl/base/thread_annotations.h"
|
36
|
+
#include "absl/cleanup/cleanup.h"
|
33
37
|
#include "absl/meta/type_traits.h"
|
34
38
|
#include "absl/status/status.h"
|
35
39
|
#include "absl/strings/str_cat.h"
|
36
40
|
#include "absl/strings/str_format.h"
|
41
|
+
#include "absl/strings/str_join.h"
|
37
42
|
#include "absl/strings/string_view.h"
|
43
|
+
#include "absl/types/variant.h"
|
38
44
|
|
39
45
|
#include <grpc/byte_buffer.h>
|
40
46
|
#include <grpc/compression.h>
|
47
|
+
#include <grpc/event_engine/event_engine.h>
|
41
48
|
#include <grpc/grpc.h>
|
42
49
|
#include <grpc/impl/codegen/gpr_types.h>
|
43
50
|
#include <grpc/impl/codegen/propagation_bits.h>
|
@@ -49,24 +56,37 @@
|
|
49
56
|
#include <grpc/support/log.h>
|
50
57
|
#include <grpc/support/string_util.h>
|
51
58
|
|
59
|
+
#include "src/core/lib/channel/call_finalization.h"
|
52
60
|
#include "src/core/lib/channel/channel_stack.h"
|
53
61
|
#include "src/core/lib/channel/channelz.h"
|
54
62
|
#include "src/core/lib/channel/context.h"
|
63
|
+
#include "src/core/lib/channel/status_util.h"
|
55
64
|
#include "src/core/lib/compression/compression_internal.h"
|
56
65
|
#include "src/core/lib/debug/stats.h"
|
66
|
+
#include "src/core/lib/debug/stats_data.h"
|
67
|
+
#include "src/core/lib/experiments/experiments.h"
|
57
68
|
#include "src/core/lib/gpr/alloc.h"
|
58
69
|
#include "src/core/lib/gpr/time_precise.h"
|
70
|
+
#include "src/core/lib/gpr/useful.h"
|
71
|
+
#include "src/core/lib/gprpp/bitset.h"
|
59
72
|
#include "src/core/lib/gprpp/cpp_impl_of.h"
|
60
73
|
#include "src/core/lib/gprpp/debug_location.h"
|
61
74
|
#include "src/core/lib/gprpp/ref_counted.h"
|
75
|
+
#include "src/core/lib/gprpp/ref_counted_ptr.h"
|
76
|
+
#include "src/core/lib/gprpp/status_helper.h"
|
62
77
|
#include "src/core/lib/gprpp/sync.h"
|
63
78
|
#include "src/core/lib/iomgr/call_combiner.h"
|
64
79
|
#include "src/core/lib/iomgr/exec_ctx.h"
|
65
80
|
#include "src/core/lib/iomgr/polling_entity.h"
|
81
|
+
#include "src/core/lib/promise/activity.h"
|
82
|
+
#include "src/core/lib/promise/arena_promise.h"
|
83
|
+
#include "src/core/lib/promise/context.h"
|
84
|
+
#include "src/core/lib/promise/latch.h"
|
85
|
+
#include "src/core/lib/promise/pipe.h"
|
86
|
+
#include "src/core/lib/promise/poll.h"
|
66
87
|
#include "src/core/lib/resource_quota/arena.h"
|
67
88
|
#include "src/core/lib/slice/slice_buffer.h"
|
68
89
|
#include "src/core/lib/slice/slice_internal.h"
|
69
|
-
#include "src/core/lib/slice/slice_refcount.h"
|
70
90
|
#include "src/core/lib/surface/api_trace.h"
|
71
91
|
#include "src/core/lib/surface/call_test_only.h"
|
72
92
|
#include "src/core/lib/surface/channel.h"
|
@@ -79,9 +99,14 @@
|
|
79
99
|
|
80
100
|
grpc_core::TraceFlag grpc_call_error_trace(false, "call_error");
|
81
101
|
grpc_core::TraceFlag grpc_compression_trace(false, "compression");
|
102
|
+
grpc_core::TraceFlag grpc_call_trace(false, "call");
|
103
|
+
grpc_core::TraceFlag grpc_call_refcount_trace(false, "call_refcount");
|
82
104
|
|
83
105
|
namespace grpc_core {
|
84
106
|
|
107
|
+
///////////////////////////////////////////////////////////////////////////////
|
108
|
+
// Call
|
109
|
+
|
85
110
|
class Call : public CppImplOf<Call, grpc_call> {
|
86
111
|
public:
|
87
112
|
Arena* arena() { return arena_; }
|
@@ -94,7 +119,7 @@ class Call : public CppImplOf<Call, grpc_call> {
|
|
94
119
|
void CancelWithStatus(grpc_status_code status, const char* description);
|
95
120
|
virtual void CancelWithError(grpc_error_handle error) = 0;
|
96
121
|
virtual void SetCompletionQueue(grpc_completion_queue* cq) = 0;
|
97
|
-
|
122
|
+
char* GetPeer();
|
98
123
|
virtual grpc_call_error StartBatch(const grpc_op* ops, size_t nops,
|
99
124
|
void* notify_tag,
|
100
125
|
bool is_notify_tag_closure) = 0;
|
@@ -116,12 +141,19 @@ class Call : public CppImplOf<Call, grpc_call> {
|
|
116
141
|
// for that functionality be invented)
|
117
142
|
virtual grpc_call_stack* call_stack() = 0;
|
118
143
|
|
144
|
+
gpr_atm* peer_string_atm_ptr() { return &peer_string_; }
|
145
|
+
|
119
146
|
protected:
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
147
|
+
// The maximum number of concurrent batches possible.
|
148
|
+
// Based upon the maximum number of individually queueable ops in the batch
|
149
|
+
// api:
|
150
|
+
// - initial metadata send
|
151
|
+
// - message send
|
152
|
+
// - status/close send (depending on client/server)
|
153
|
+
// - initial metadata recv
|
154
|
+
// - message recv
|
155
|
+
// - status/close recv (depending on client/server)
|
156
|
+
static constexpr size_t kMaxConcurrentBatches = 6;
|
125
157
|
|
126
158
|
struct ParentCall {
|
127
159
|
Mutex child_list_mu;
|
@@ -138,8 +170,25 @@ class Call : public CppImplOf<Call, grpc_call> {
|
|
138
170
|
Call* sibling_prev = nullptr;
|
139
171
|
};
|
140
172
|
|
173
|
+
Call(Arena* arena, bool is_client, Timestamp send_deadline,
|
174
|
+
RefCountedPtr<Channel> channel)
|
175
|
+
: channel_(std::move(channel)),
|
176
|
+
arena_(arena),
|
177
|
+
send_deadline_(send_deadline),
|
178
|
+
is_client_(is_client) {
|
179
|
+
GPR_DEBUG_ASSERT(arena_ != nullptr);
|
180
|
+
GPR_DEBUG_ASSERT(channel_ != nullptr);
|
181
|
+
}
|
182
|
+
virtual ~Call() = default;
|
183
|
+
|
184
|
+
void DeleteThis();
|
185
|
+
|
141
186
|
ParentCall* GetOrCreateParentCall();
|
142
187
|
ParentCall* parent_call();
|
188
|
+
Channel* channel() {
|
189
|
+
GPR_DEBUG_ASSERT(channel_ != nullptr);
|
190
|
+
return channel_.get();
|
191
|
+
}
|
143
192
|
|
144
193
|
absl::Status InitParent(Call* parent, uint32_t propagation_mask);
|
145
194
|
void PublishToParent(Call* parent);
|
@@ -151,7 +200,10 @@ class Call : public CppImplOf<Call, grpc_call> {
|
|
151
200
|
send_deadline_ = send_deadline;
|
152
201
|
}
|
153
202
|
|
203
|
+
void ClearPeerString() { gpr_atm_rel_store(&peer_string_, 0); }
|
204
|
+
|
154
205
|
private:
|
206
|
+
RefCountedPtr<Channel> channel_;
|
155
207
|
Arena* const arena_;
|
156
208
|
std::atomic<ParentCall*> parent_call_{nullptr};
|
157
209
|
ChildCall* child_ = nullptr;
|
@@ -159,11 +211,150 @@ class Call : public CppImplOf<Call, grpc_call> {
|
|
159
211
|
const bool is_client_;
|
160
212
|
// flag indicating that cancellation is inherited
|
161
213
|
bool cancellation_is_inherited_ = false;
|
214
|
+
// A char* indicating the peer name.
|
215
|
+
gpr_atm peer_string_ = 0;
|
162
216
|
};
|
163
217
|
|
218
|
+
Call::ParentCall* Call::GetOrCreateParentCall() {
|
219
|
+
ParentCall* p = parent_call_.load(std::memory_order_acquire);
|
220
|
+
if (p == nullptr) {
|
221
|
+
p = arena_->New<ParentCall>();
|
222
|
+
ParentCall* expected = nullptr;
|
223
|
+
if (!parent_call_.compare_exchange_strong(expected, p,
|
224
|
+
std::memory_order_release,
|
225
|
+
std::memory_order_relaxed)) {
|
226
|
+
p->~ParentCall();
|
227
|
+
p = expected;
|
228
|
+
}
|
229
|
+
}
|
230
|
+
return p;
|
231
|
+
}
|
232
|
+
|
233
|
+
Call::ParentCall* Call::parent_call() {
|
234
|
+
return parent_call_.load(std::memory_order_acquire);
|
235
|
+
}
|
236
|
+
|
237
|
+
absl::Status Call::InitParent(Call* parent, uint32_t propagation_mask) {
|
238
|
+
child_ = arena()->New<ChildCall>(parent);
|
239
|
+
|
240
|
+
parent->InternalRef("child");
|
241
|
+
GPR_ASSERT(is_client_);
|
242
|
+
GPR_ASSERT(!parent->is_client_);
|
243
|
+
|
244
|
+
if (propagation_mask & GRPC_PROPAGATE_DEADLINE) {
|
245
|
+
send_deadline_ = std::min(send_deadline_, parent->send_deadline_);
|
246
|
+
}
|
247
|
+
/* for now GRPC_PROPAGATE_TRACING_CONTEXT *MUST* be passed with
|
248
|
+
* GRPC_PROPAGATE_STATS_CONTEXT */
|
249
|
+
/* TODO(ctiller): This should change to use the appropriate census start_op
|
250
|
+
* call. */
|
251
|
+
if (propagation_mask & GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT) {
|
252
|
+
if (0 == (propagation_mask & GRPC_PROPAGATE_CENSUS_STATS_CONTEXT)) {
|
253
|
+
return absl::UnknownError(
|
254
|
+
"Census tracing propagation requested without Census context "
|
255
|
+
"propagation");
|
256
|
+
}
|
257
|
+
ContextSet(GRPC_CONTEXT_TRACING, parent->ContextGet(GRPC_CONTEXT_TRACING),
|
258
|
+
nullptr);
|
259
|
+
} else if (propagation_mask & GRPC_PROPAGATE_CENSUS_STATS_CONTEXT) {
|
260
|
+
return absl::UnknownError(
|
261
|
+
"Census context propagation requested without Census tracing "
|
262
|
+
"propagation");
|
263
|
+
}
|
264
|
+
if (propagation_mask & GRPC_PROPAGATE_CANCELLATION) {
|
265
|
+
cancellation_is_inherited_ = true;
|
266
|
+
}
|
267
|
+
return absl::OkStatus();
|
268
|
+
}
|
269
|
+
|
270
|
+
void Call::PublishToParent(Call* parent) {
|
271
|
+
ChildCall* cc = child_;
|
272
|
+
ParentCall* pc = parent->GetOrCreateParentCall();
|
273
|
+
MutexLock lock(&pc->child_list_mu);
|
274
|
+
if (pc->first_child == nullptr) {
|
275
|
+
pc->first_child = this;
|
276
|
+
cc->sibling_next = cc->sibling_prev = this;
|
277
|
+
} else {
|
278
|
+
cc->sibling_next = pc->first_child;
|
279
|
+
cc->sibling_prev = pc->first_child->child_->sibling_prev;
|
280
|
+
cc->sibling_next->child_->sibling_prev =
|
281
|
+
cc->sibling_prev->child_->sibling_next = this;
|
282
|
+
}
|
283
|
+
if (parent->Completed()) {
|
284
|
+
CancelWithError(absl::CancelledError());
|
285
|
+
}
|
286
|
+
}
|
287
|
+
|
288
|
+
void Call::MaybeUnpublishFromParent() {
|
289
|
+
ChildCall* cc = child_;
|
290
|
+
if (cc == nullptr) return;
|
291
|
+
|
292
|
+
ParentCall* pc = cc->parent->parent_call();
|
293
|
+
{
|
294
|
+
MutexLock lock(&pc->child_list_mu);
|
295
|
+
if (this == pc->first_child) {
|
296
|
+
pc->first_child = cc->sibling_next;
|
297
|
+
if (this == pc->first_child) {
|
298
|
+
pc->first_child = nullptr;
|
299
|
+
}
|
300
|
+
}
|
301
|
+
cc->sibling_prev->child_->sibling_next = cc->sibling_next;
|
302
|
+
cc->sibling_next->child_->sibling_prev = cc->sibling_prev;
|
303
|
+
}
|
304
|
+
cc->parent->InternalUnref("child");
|
305
|
+
}
|
306
|
+
|
307
|
+
void Call::CancelWithStatus(grpc_status_code status, const char* description) {
|
308
|
+
// copying 'description' is needed to ensure the grpc_call_cancel_with_status
|
309
|
+
// guarantee that can be short-lived.
|
310
|
+
CancelWithError(grpc_error_set_int(
|
311
|
+
grpc_error_set_str(GRPC_ERROR_CREATE(description),
|
312
|
+
StatusStrProperty::kGrpcMessage, description),
|
313
|
+
StatusIntProperty::kRpcStatus, status));
|
314
|
+
}
|
315
|
+
|
316
|
+
void Call::PropagateCancellationToChildren() {
|
317
|
+
ParentCall* pc = parent_call();
|
318
|
+
if (pc != nullptr) {
|
319
|
+
Call* child;
|
320
|
+
MutexLock lock(&pc->child_list_mu);
|
321
|
+
child = pc->first_child;
|
322
|
+
if (child != nullptr) {
|
323
|
+
do {
|
324
|
+
Call* next_child_call = child->child_->sibling_next;
|
325
|
+
if (child->cancellation_is_inherited_) {
|
326
|
+
child->InternalRef("propagate_cancel");
|
327
|
+
child->CancelWithError(absl::CancelledError());
|
328
|
+
child->InternalUnref("propagate_cancel");
|
329
|
+
}
|
330
|
+
child = next_child_call;
|
331
|
+
} while (child != pc->first_child);
|
332
|
+
}
|
333
|
+
}
|
334
|
+
}
|
335
|
+
|
336
|
+
char* Call::GetPeer() {
|
337
|
+
char* peer_string = reinterpret_cast<char*>(gpr_atm_acq_load(&peer_string_));
|
338
|
+
if (peer_string != nullptr) return gpr_strdup(peer_string);
|
339
|
+
peer_string = grpc_channel_get_target(channel_->c_ptr());
|
340
|
+
if (peer_string != nullptr) return peer_string;
|
341
|
+
return gpr_strdup("unknown");
|
342
|
+
}
|
343
|
+
|
344
|
+
void Call::DeleteThis() {
|
345
|
+
RefCountedPtr<Channel> channel = std::move(channel_);
|
346
|
+
Arena* arena = arena_;
|
347
|
+
this->~Call();
|
348
|
+
channel->UpdateCallSizeEstimate(arena->Destroy());
|
349
|
+
}
|
350
|
+
|
351
|
+
///////////////////////////////////////////////////////////////////////////////
|
352
|
+
// FilterStackCall
|
353
|
+
// To be removed once promise conversion is complete
|
354
|
+
|
164
355
|
class FilterStackCall final : public Call {
|
165
356
|
public:
|
166
|
-
~FilterStackCall() {
|
357
|
+
~FilterStackCall() override {
|
167
358
|
for (int i = 0; i < GRPC_CONTEXT_COUNT; ++i) {
|
168
359
|
if (context_[i].destroy) {
|
169
360
|
context_[i].destroy(context_[i].value);
|
@@ -198,7 +389,6 @@ class FilterStackCall final : public Call {
|
|
198
389
|
|
199
390
|
void CancelWithError(grpc_error_handle error) override;
|
200
391
|
void SetCompletionQueue(grpc_completion_queue* cq) override;
|
201
|
-
char* GetPeer() override;
|
202
392
|
grpc_call_error StartBatch(const grpc_op* ops, size_t nops, void* notify_tag,
|
203
393
|
bool is_notify_tag_closure) override;
|
204
394
|
void ExternalRef() override { ext_ref_.Ref(); }
|
@@ -256,17 +446,6 @@ class FilterStackCall final : public Call {
|
|
256
446
|
}
|
257
447
|
|
258
448
|
private:
|
259
|
-
// The maximum number of concurrent batches possible.
|
260
|
-
// Based upon the maximum number of individually queueable ops in the batch
|
261
|
-
// api:
|
262
|
-
// - initial metadata send
|
263
|
-
// - message send
|
264
|
-
// - status/close send (depending on client/server)
|
265
|
-
// - initial metadata recv
|
266
|
-
// - message recv
|
267
|
-
// - status/close recv (depending on client/server)
|
268
|
-
static constexpr size_t kMaxConcurrentBatches = 6;
|
269
|
-
|
270
449
|
static constexpr gpr_atm kRecvNone = 0;
|
271
450
|
static constexpr gpr_atm kRecvInitialMetadataFirst = 1;
|
272
451
|
|
@@ -314,9 +493,9 @@ class FilterStackCall final : public Call {
|
|
314
493
|
};
|
315
494
|
|
316
495
|
FilterStackCall(Arena* arena, const grpc_call_create_args& args)
|
317
|
-
: Call(arena, args.server_transport_data == nullptr, args.send_deadline
|
496
|
+
: Call(arena, args.server_transport_data == nullptr, args.send_deadline,
|
497
|
+
args.channel->Ref()),
|
318
498
|
cq_(args.cq),
|
319
|
-
channel_(args.channel->Ref()),
|
320
499
|
stream_op_payload_(context_) {}
|
321
500
|
|
322
501
|
static void ReleaseCall(void* call, grpc_error_handle);
|
@@ -347,7 +526,6 @@ class FilterStackCall final : public Call {
|
|
347
526
|
CallCombiner call_combiner_;
|
348
527
|
grpc_completion_queue* cq_;
|
349
528
|
grpc_polling_entity pollent_;
|
350
|
-
RefCountedPtr<Channel> channel_;
|
351
529
|
gpr_cycle_counter start_time_ = gpr_get_cycle_counter();
|
352
530
|
|
353
531
|
/** has grpc_call_unref been called */
|
@@ -376,9 +554,6 @@ class FilterStackCall final : public Call {
|
|
376
554
|
Element 0 is initial metadata, element 1 is trailing metadata. */
|
377
555
|
grpc_metadata_array* buffered_metadata_[2] = {};
|
378
556
|
|
379
|
-
// A char* indicating the peer name.
|
380
|
-
gpr_atm peer_string_ = 0;
|
381
|
-
|
382
557
|
/* Call data useful used for reporting. Only valid after the call has
|
383
558
|
* completed */
|
384
559
|
grpc_call_final_info final_info_;
|
@@ -443,95 +618,25 @@ class FilterStackCall final : public Call {
|
|
443
618
|
gpr_atm recv_state_ = 0;
|
444
619
|
};
|
445
620
|
|
446
|
-
Call::ParentCall* Call::GetOrCreateParentCall() {
|
447
|
-
ParentCall* p = parent_call_.load(std::memory_order_acquire);
|
448
|
-
if (p == nullptr) {
|
449
|
-
p = arena_->New<ParentCall>();
|
450
|
-
ParentCall* expected = nullptr;
|
451
|
-
if (!parent_call_.compare_exchange_strong(expected, p,
|
452
|
-
std::memory_order_release,
|
453
|
-
std::memory_order_relaxed)) {
|
454
|
-
p->~ParentCall();
|
455
|
-
p = expected;
|
456
|
-
}
|
457
|
-
}
|
458
|
-
return p;
|
459
|
-
}
|
460
|
-
|
461
|
-
Call::ParentCall* Call::parent_call() {
|
462
|
-
return parent_call_.load(std::memory_order_acquire);
|
463
|
-
}
|
464
|
-
|
465
|
-
absl::Status Call::InitParent(Call* parent, uint32_t propagation_mask) {
|
466
|
-
child_ = arena()->New<ChildCall>(parent);
|
467
|
-
|
468
|
-
parent->InternalRef("child");
|
469
|
-
GPR_ASSERT(is_client_);
|
470
|
-
GPR_ASSERT(!parent->is_client_);
|
471
|
-
|
472
|
-
if (propagation_mask & GRPC_PROPAGATE_DEADLINE) {
|
473
|
-
send_deadline_ = std::min(send_deadline_, parent->send_deadline_);
|
474
|
-
}
|
475
|
-
/* for now GRPC_PROPAGATE_TRACING_CONTEXT *MUST* be passed with
|
476
|
-
* GRPC_PROPAGATE_STATS_CONTEXT */
|
477
|
-
/* TODO(ctiller): This should change to use the appropriate census start_op
|
478
|
-
* call. */
|
479
|
-
if (propagation_mask & GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT) {
|
480
|
-
if (0 == (propagation_mask & GRPC_PROPAGATE_CENSUS_STATS_CONTEXT)) {
|
481
|
-
return absl::UnknownError(
|
482
|
-
"Census tracing propagation requested without Census context "
|
483
|
-
"propagation");
|
484
|
-
}
|
485
|
-
ContextSet(GRPC_CONTEXT_TRACING, parent->ContextGet(GRPC_CONTEXT_TRACING),
|
486
|
-
nullptr);
|
487
|
-
} else if (propagation_mask & GRPC_PROPAGATE_CENSUS_STATS_CONTEXT) {
|
488
|
-
return absl::UnknownError(
|
489
|
-
"Census context propagation requested without Census tracing "
|
490
|
-
"propagation");
|
491
|
-
}
|
492
|
-
if (propagation_mask & GRPC_PROPAGATE_CANCELLATION) {
|
493
|
-
cancellation_is_inherited_ = true;
|
494
|
-
}
|
495
|
-
return absl::OkStatus();
|
496
|
-
}
|
497
|
-
|
498
|
-
void Call::PublishToParent(Call* parent) {
|
499
|
-
ChildCall* cc = child_;
|
500
|
-
ParentCall* pc = parent->GetOrCreateParentCall();
|
501
|
-
MutexLock lock(&pc->child_list_mu);
|
502
|
-
if (pc->first_child == nullptr) {
|
503
|
-
pc->first_child = this;
|
504
|
-
cc->sibling_next = cc->sibling_prev = this;
|
505
|
-
} else {
|
506
|
-
cc->sibling_next = pc->first_child;
|
507
|
-
cc->sibling_prev = pc->first_child->child_->sibling_prev;
|
508
|
-
cc->sibling_next->child_->sibling_prev =
|
509
|
-
cc->sibling_prev->child_->sibling_next = this;
|
510
|
-
}
|
511
|
-
if (parent->Completed()) {
|
512
|
-
CancelWithError(GRPC_ERROR_CANCELLED);
|
513
|
-
}
|
514
|
-
}
|
515
|
-
|
516
621
|
grpc_error_handle FilterStackCall::Create(grpc_call_create_args* args,
|
517
622
|
grpc_call** out_call) {
|
518
623
|
Channel* channel = args->channel.get();
|
519
624
|
|
520
625
|
auto add_init_error = [](grpc_error_handle* composite,
|
521
626
|
grpc_error_handle new_err) {
|
522
|
-
if (
|
523
|
-
if (
|
524
|
-
*composite =
|
627
|
+
if (new_err.ok()) return;
|
628
|
+
if (composite->ok()) {
|
629
|
+
*composite = GRPC_ERROR_CREATE("Call creation failed");
|
525
630
|
}
|
526
631
|
*composite = grpc_error_add_child(*composite, new_err);
|
527
632
|
};
|
528
633
|
|
529
634
|
Arena* arena;
|
530
635
|
FilterStackCall* call;
|
531
|
-
grpc_error_handle error
|
636
|
+
grpc_error_handle error;
|
532
637
|
grpc_channel_stack* channel_stack = channel->channel_stack();
|
533
638
|
size_t initial_size = channel->CallSizeEstimate();
|
534
|
-
|
639
|
+
global_stats().IncrementCallInitialSize(initial_size);
|
535
640
|
size_t call_alloc_size =
|
536
641
|
GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(FilterStackCall)) +
|
537
642
|
channel_stack->call_stack_size;
|
@@ -548,8 +653,8 @@ grpc_error_handle FilterStackCall::Create(grpc_call_create_args* args,
|
|
548
653
|
call->final_op_.client.status_details = nullptr;
|
549
654
|
call->final_op_.client.status = nullptr;
|
550
655
|
call->final_op_.client.error_string = nullptr;
|
551
|
-
|
552
|
-
path =
|
656
|
+
global_stats().IncrementClientCallsCreated();
|
657
|
+
path = CSliceRef(args->path->c_slice());
|
553
658
|
call->send_initial_metadata_.Set(HttpPathMetadata(),
|
554
659
|
std::move(*args->path));
|
555
660
|
if (args->authority.has_value()) {
|
@@ -557,7 +662,7 @@ grpc_error_handle FilterStackCall::Create(grpc_call_create_args* args,
|
|
557
662
|
std::move(*args->authority));
|
558
663
|
}
|
559
664
|
} else {
|
560
|
-
|
665
|
+
global_stats().IncrementServerCallsCreated();
|
561
666
|
call->final_op_.server.cancelled = nullptr;
|
562
667
|
call->final_op_.server.core_server = args->server;
|
563
668
|
}
|
@@ -580,8 +685,8 @@ grpc_error_handle FilterStackCall::Create(grpc_call_create_args* args,
|
|
580
685
|
call->PublishToParent(parent);
|
581
686
|
}
|
582
687
|
|
583
|
-
if (!
|
584
|
-
call->CancelWithError(
|
688
|
+
if (!error.ok()) {
|
689
|
+
call->CancelWithError(error);
|
585
690
|
}
|
586
691
|
if (args->cq != nullptr) {
|
587
692
|
GPR_ASSERT(args->pollset_set_alternative == nullptr &&
|
@@ -613,7 +718,7 @@ grpc_error_handle FilterStackCall::Create(grpc_call_create_args* args,
|
|
613
718
|
}
|
614
719
|
}
|
615
720
|
|
616
|
-
|
721
|
+
CSliceUnref(path);
|
617
722
|
|
618
723
|
return error;
|
619
724
|
}
|
@@ -632,11 +737,7 @@ void FilterStackCall::SetCompletionQueue(grpc_completion_queue* cq) {
|
|
632
737
|
}
|
633
738
|
|
634
739
|
void FilterStackCall::ReleaseCall(void* call, grpc_error_handle /*error*/) {
|
635
|
-
|
636
|
-
RefCountedPtr<Channel> channel = std::move(c->channel_);
|
637
|
-
Arena* arena = c->arena();
|
638
|
-
c->~FilterStackCall();
|
639
|
-
channel->UpdateCallSizeEstimate(arena->Destroy());
|
740
|
+
static_cast<FilterStackCall*>(call)->DeleteThis();
|
640
741
|
}
|
641
742
|
|
642
743
|
void FilterStackCall::DestroyCall(void* call, grpc_error_handle /*error*/) {
|
@@ -656,7 +757,7 @@ void FilterStackCall::DestroyCall(void* call, grpc_error_handle /*error*/) {
|
|
656
757
|
grpc_error_get_status(status_error, c->send_deadline(),
|
657
758
|
&c->final_info_.final_status, nullptr, nullptr,
|
658
759
|
&(c->final_info_.error_string));
|
659
|
-
c->status_error_.set(
|
760
|
+
c->status_error_.set(absl::OkStatus());
|
660
761
|
c->final_info_.stats.latency =
|
661
762
|
gpr_cycle_counter_sub(gpr_get_cycle_counter(), c->start_time_);
|
662
763
|
grpc_call_stack_destroy(c->call_stack(), &c->final_info_,
|
@@ -664,25 +765,6 @@ void FilterStackCall::DestroyCall(void* call, grpc_error_handle /*error*/) {
|
|
664
765
|
grpc_schedule_on_exec_ctx));
|
665
766
|
}
|
666
767
|
|
667
|
-
void Call::MaybeUnpublishFromParent() {
|
668
|
-
ChildCall* cc = child_;
|
669
|
-
if (cc == nullptr) return;
|
670
|
-
|
671
|
-
ParentCall* pc = cc->parent->parent_call();
|
672
|
-
{
|
673
|
-
MutexLock lock(&pc->child_list_mu);
|
674
|
-
if (this == pc->first_child) {
|
675
|
-
pc->first_child = cc->sibling_next;
|
676
|
-
if (this == pc->first_child) {
|
677
|
-
pc->first_child = nullptr;
|
678
|
-
}
|
679
|
-
}
|
680
|
-
cc->sibling_prev->child_->sibling_next = cc->sibling_next;
|
681
|
-
cc->sibling_next->child_->sibling_prev = cc->sibling_prev;
|
682
|
-
}
|
683
|
-
cc->parent->InternalUnref("child");
|
684
|
-
}
|
685
|
-
|
686
768
|
void FilterStackCall::ExternalUnref() {
|
687
769
|
if (GPR_LIKELY(!ext_ref_.Unref())) return;
|
688
770
|
|
@@ -697,7 +779,7 @@ void FilterStackCall::ExternalUnref() {
|
|
697
779
|
destroy_called_ = true;
|
698
780
|
bool cancel = gpr_atm_acq_load(&received_final_op_atm_) == 0;
|
699
781
|
if (cancel) {
|
700
|
-
CancelWithError(
|
782
|
+
CancelWithError(absl::CancelledError());
|
701
783
|
} else {
|
702
784
|
// Unset the call combiner cancellation closure. This has the
|
703
785
|
// effect of scheduling the previously set cancellation closure, if
|
@@ -708,14 +790,6 @@ void FilterStackCall::ExternalUnref() {
|
|
708
790
|
InternalUnref("destroy");
|
709
791
|
}
|
710
792
|
|
711
|
-
char* FilterStackCall::GetPeer() {
|
712
|
-
char* peer_string = reinterpret_cast<char*>(gpr_atm_acq_load(&peer_string_));
|
713
|
-
if (peer_string != nullptr) return gpr_strdup(peer_string);
|
714
|
-
peer_string = grpc_channel_get_target(channel_->c_ptr());
|
715
|
-
if (peer_string != nullptr) return peer_string;
|
716
|
-
return gpr_strdup("unknown");
|
717
|
-
}
|
718
|
-
|
719
793
|
// start_batch_closure points to a caller-allocated closure to be used
|
720
794
|
// for entering the call combiner.
|
721
795
|
void FilterStackCall::ExecuteBatch(grpc_transport_stream_op_batch* batch,
|
@@ -735,7 +809,7 @@ void FilterStackCall::ExecuteBatch(grpc_transport_stream_op_batch* batch,
|
|
735
809
|
GRPC_CLOSURE_INIT(start_batch_closure, execute_batch_in_call_combiner, batch,
|
736
810
|
grpc_schedule_on_exec_ctx);
|
737
811
|
GRPC_CALL_COMBINER_START(call_combiner(), start_batch_closure,
|
738
|
-
|
812
|
+
absl::OkStatus(), "executing batch");
|
739
813
|
}
|
740
814
|
|
741
815
|
namespace {
|
@@ -758,16 +832,15 @@ static void done_termination(void* arg, grpc_error_handle /*error*/) {
|
|
758
832
|
|
759
833
|
void FilterStackCall::CancelWithError(grpc_error_handle error) {
|
760
834
|
if (!gpr_atm_rel_cas(&cancelled_with_error_, 0, 1)) {
|
761
|
-
GRPC_ERROR_UNREF(error);
|
762
835
|
return;
|
763
836
|
}
|
764
|
-
|
837
|
+
ClearPeerString();
|
765
838
|
InternalRef("termination");
|
766
839
|
// Inform the call combiner of the cancellation, so that it can cancel
|
767
840
|
// any in-flight asynchronous actions that may be holding the call
|
768
841
|
// combiner. This ensures that the cancel_stream batch can be sent
|
769
842
|
// down the filter stack in a timely manner.
|
770
|
-
call_combiner_.Cancel(
|
843
|
+
call_combiner_.Cancel(error);
|
771
844
|
CancelState* state = new CancelState;
|
772
845
|
state->call = this;
|
773
846
|
GRPC_CLOSURE_INIT(&state->finish_batch, done_termination, state,
|
@@ -779,19 +852,10 @@ void FilterStackCall::CancelWithError(grpc_error_handle error) {
|
|
779
852
|
ExecuteBatch(op, &state->start_batch);
|
780
853
|
}
|
781
854
|
|
782
|
-
void Call::CancelWithStatus(grpc_status_code status, const char* description) {
|
783
|
-
// copying 'description' is needed to ensure the grpc_call_cancel_with_status
|
784
|
-
// guarantee that can be short-lived.
|
785
|
-
CancelWithError(grpc_error_set_int(
|
786
|
-
grpc_error_set_str(GRPC_ERROR_CREATE_FROM_COPIED_STRING(description),
|
787
|
-
GRPC_ERROR_STR_GRPC_MESSAGE, description),
|
788
|
-
GRPC_ERROR_INT_GRPC_STATUS, status));
|
789
|
-
}
|
790
|
-
|
791
855
|
void FilterStackCall::SetFinalStatus(grpc_error_handle error) {
|
792
856
|
if (GRPC_TRACE_FLAG_ENABLED(grpc_call_error_trace)) {
|
793
857
|
gpr_log(GPR_DEBUG, "set_final_status %s", is_client() ? "CLI" : "SVR");
|
794
|
-
gpr_log(GPR_DEBUG, "%s",
|
858
|
+
gpr_log(GPR_DEBUG, "%s", StatusToString(error).c_str());
|
795
859
|
}
|
796
860
|
if (is_client()) {
|
797
861
|
std::string status_details;
|
@@ -801,8 +865,7 @@ void FilterStackCall::SetFinalStatus(grpc_error_handle error) {
|
|
801
865
|
*final_op_.client.status_details =
|
802
866
|
grpc_slice_from_cpp_string(std::move(status_details));
|
803
867
|
status_error_.set(error);
|
804
|
-
|
805
|
-
channelz::ChannelNode* channelz_channel = channel_->channelz_node();
|
868
|
+
channelz::ChannelNode* channelz_channel = channel()->channelz_node();
|
806
869
|
if (channelz_channel != nullptr) {
|
807
870
|
if (*final_op_.client.status != GRPC_STATUS_OK) {
|
808
871
|
channelz_channel->RecordCallFailed();
|
@@ -812,7 +875,7 @@ void FilterStackCall::SetFinalStatus(grpc_error_handle error) {
|
|
812
875
|
}
|
813
876
|
} else {
|
814
877
|
*final_op_.server.cancelled =
|
815
|
-
!
|
878
|
+
!error.ok() || !sent_server_trailing_metadata_;
|
816
879
|
channelz::ServerNode* channelz_node =
|
817
880
|
final_op_.server.core_server->channelz_node();
|
818
881
|
if (channelz_node != nullptr) {
|
@@ -822,7 +885,6 @@ void FilterStackCall::SetFinalStatus(grpc_error_handle error) {
|
|
822
885
|
channelz_node->RecordCallSucceeded();
|
823
886
|
}
|
824
887
|
}
|
825
|
-
GRPC_ERROR_UNREF(error);
|
826
888
|
}
|
827
889
|
}
|
828
890
|
|
@@ -848,8 +910,7 @@ bool FilterStackCall::PrepareApplicationMetadata(size_t count,
|
|
848
910
|
// Filter "content-length metadata"
|
849
911
|
continue;
|
850
912
|
}
|
851
|
-
batch->Append(StringViewFromSlice(md->key),
|
852
|
-
Slice(grpc_slice_ref_internal(md->value)),
|
913
|
+
batch->Append(StringViewFromSlice(md->key), Slice(CSliceRef(md->value)),
|
853
914
|
[md](absl::string_view error, const Slice& value) {
|
854
915
|
gpr_log(GPR_DEBUG, "Append error: %s",
|
855
916
|
absl::StrCat("key=", StringViewFromSlice(md->key),
|
@@ -945,39 +1006,37 @@ void FilterStackCall::RecvInitialFilter(grpc_metadata_batch* b) {
|
|
945
1006
|
|
946
1007
|
void FilterStackCall::RecvTrailingFilter(grpc_metadata_batch* b,
|
947
1008
|
grpc_error_handle batch_error) {
|
948
|
-
if (!
|
1009
|
+
if (!batch_error.ok()) {
|
949
1010
|
SetFinalStatus(batch_error);
|
950
1011
|
} else {
|
951
1012
|
absl::optional<grpc_status_code> grpc_status =
|
952
1013
|
b->Take(GrpcStatusMetadata());
|
953
1014
|
if (grpc_status.has_value()) {
|
954
1015
|
grpc_status_code status_code = *grpc_status;
|
955
|
-
grpc_error_handle error
|
1016
|
+
grpc_error_handle error;
|
956
1017
|
if (status_code != GRPC_STATUS_OK) {
|
957
1018
|
char* peer = GetPeer();
|
958
1019
|
error = grpc_error_set_int(
|
959
|
-
|
960
|
-
|
961
|
-
GRPC_ERROR_INT_GRPC_STATUS, static_cast<intptr_t>(status_code));
|
1020
|
+
GRPC_ERROR_CREATE(absl::StrCat("Error received from peer ", peer)),
|
1021
|
+
StatusIntProperty::kRpcStatus, static_cast<intptr_t>(status_code));
|
962
1022
|
gpr_free(peer);
|
963
1023
|
}
|
964
1024
|
auto grpc_message = b->Take(GrpcMessageMetadata());
|
965
1025
|
if (grpc_message.has_value()) {
|
966
|
-
error = grpc_error_set_str(error,
|
1026
|
+
error = grpc_error_set_str(error, StatusStrProperty::kGrpcMessage,
|
967
1027
|
grpc_message->as_string_view());
|
968
|
-
} else if (!
|
969
|
-
error = grpc_error_set_str(error,
|
1028
|
+
} else if (!error.ok()) {
|
1029
|
+
error = grpc_error_set_str(error, StatusStrProperty::kGrpcMessage, "");
|
970
1030
|
}
|
971
|
-
SetFinalStatus(
|
972
|
-
GRPC_ERROR_UNREF(error);
|
1031
|
+
SetFinalStatus(error);
|
973
1032
|
} else if (!is_client()) {
|
974
|
-
SetFinalStatus(
|
1033
|
+
SetFinalStatus(absl::OkStatus());
|
975
1034
|
} else {
|
976
1035
|
gpr_log(GPR_DEBUG,
|
977
1036
|
"Received trailing metadata with no error and no status");
|
978
|
-
SetFinalStatus(grpc_error_set_int(
|
979
|
-
|
980
|
-
|
1037
|
+
SetFinalStatus(grpc_error_set_int(GRPC_ERROR_CREATE("No status received"),
|
1038
|
+
StatusIntProperty::kRpcStatus,
|
1039
|
+
GRPC_STATUS_UNKNOWN));
|
981
1040
|
}
|
982
1041
|
}
|
983
1042
|
PublishAppMetadata(b, true);
|
@@ -1041,38 +1100,17 @@ FilterStackCall::BatchControl* FilterStackCall::ReuseOrAllocateBatchControl(
|
|
1041
1100
|
return bctl;
|
1042
1101
|
}
|
1043
1102
|
|
1044
|
-
void Call::PropagateCancellationToChildren() {
|
1045
|
-
ParentCall* pc = parent_call();
|
1046
|
-
if (pc != nullptr) {
|
1047
|
-
Call* child;
|
1048
|
-
MutexLock lock(&pc->child_list_mu);
|
1049
|
-
child = pc->first_child;
|
1050
|
-
if (child != nullptr) {
|
1051
|
-
do {
|
1052
|
-
Call* next_child_call = child->child_->sibling_next;
|
1053
|
-
if (child->cancellation_is_inherited_) {
|
1054
|
-
child->InternalRef("propagate_cancel");
|
1055
|
-
child->CancelWithError(GRPC_ERROR_CANCELLED);
|
1056
|
-
child->InternalUnref("propagate_cancel");
|
1057
|
-
}
|
1058
|
-
child = next_child_call;
|
1059
|
-
} while (child != pc->first_child);
|
1060
|
-
}
|
1061
|
-
}
|
1062
|
-
}
|
1063
|
-
|
1064
1103
|
void FilterStackCall::BatchControl::PostCompletion() {
|
1065
1104
|
FilterStackCall* call = call_;
|
1066
|
-
grpc_error_handle error =
|
1105
|
+
grpc_error_handle error = batch_error_.get();
|
1067
1106
|
|
1068
1107
|
if (op_.send_initial_metadata) {
|
1069
1108
|
call->send_initial_metadata_.Clear();
|
1070
1109
|
}
|
1071
1110
|
if (op_.send_message) {
|
1072
|
-
if (op_.payload->send_message.stream_write_closed &&
|
1073
|
-
GRPC_ERROR_IS_NONE(error)) {
|
1111
|
+
if (op_.payload->send_message.stream_write_closed && error.ok()) {
|
1074
1112
|
error = grpc_error_add_child(
|
1075
|
-
error,
|
1113
|
+
error, GRPC_ERROR_CREATE(
|
1076
1114
|
"Attempt to send message after stream was closed."));
|
1077
1115
|
}
|
1078
1116
|
call->sending_message_ = false;
|
@@ -1085,15 +1123,13 @@ void FilterStackCall::BatchControl::PostCompletion() {
|
|
1085
1123
|
/* propagate cancellation to any interested children */
|
1086
1124
|
gpr_atm_rel_store(&call->received_final_op_atm_, 1);
|
1087
1125
|
call->PropagateCancellationToChildren();
|
1088
|
-
|
1089
|
-
error = GRPC_ERROR_NONE;
|
1126
|
+
error = absl::OkStatus();
|
1090
1127
|
}
|
1091
|
-
if (!
|
1092
|
-
*call->receiving_buffer_ != nullptr) {
|
1128
|
+
if (!error.ok() && op_.recv_message && *call->receiving_buffer_ != nullptr) {
|
1093
1129
|
grpc_byte_buffer_destroy(*call->receiving_buffer_);
|
1094
1130
|
*call->receiving_buffer_ = nullptr;
|
1095
1131
|
}
|
1096
|
-
batch_error_.set(
|
1132
|
+
batch_error_.set(absl::OkStatus());
|
1097
1133
|
|
1098
1134
|
if (completion_data_.notify_tag.is_closure) {
|
1099
1135
|
/* unrefs error */
|
@@ -1149,18 +1185,17 @@ void FilterStackCall::BatchControl::ProcessDataAfterMetadata() {
|
|
1149
1185
|
void FilterStackCall::BatchControl::ReceivingStreamReady(
|
1150
1186
|
grpc_error_handle error) {
|
1151
1187
|
FilterStackCall* call = call_;
|
1152
|
-
if (!
|
1188
|
+
if (!error.ok()) {
|
1153
1189
|
call->receiving_slice_buffer_.reset();
|
1154
1190
|
if (batch_error_.ok()) {
|
1155
1191
|
batch_error_.set(error);
|
1156
1192
|
}
|
1157
|
-
call->CancelWithError(
|
1193
|
+
call->CancelWithError(error);
|
1158
1194
|
}
|
1159
1195
|
/* If recv_state is kRecvNone, we will save the batch_control
|
1160
1196
|
* object with rel_cas, and will not use it after the cas. Its corresponding
|
1161
1197
|
* acq_load is in receiving_initial_metadata_ready() */
|
1162
|
-
if (!
|
1163
|
-
!call->receiving_slice_buffer_.has_value() ||
|
1198
|
+
if (!error.ok() || !call->receiving_slice_buffer_.has_value() ||
|
1164
1199
|
!gpr_atm_rel_cas(&call->recv_state_, kRecvNone,
|
1165
1200
|
reinterpret_cast<gpr_atm>(this))) {
|
1166
1201
|
ProcessDataAfterMetadata();
|
@@ -1192,7 +1227,7 @@ void FilterStackCall::BatchControl::ValidateFilteredMetadata() {
|
|
1192
1227
|
FilterStackCall* call = call_;
|
1193
1228
|
|
1194
1229
|
const grpc_compression_options compression_options =
|
1195
|
-
call->
|
1230
|
+
call->channel()->compression_options();
|
1196
1231
|
const grpc_compression_algorithm compression_algorithm =
|
1197
1232
|
call->incoming_compression_algorithm_;
|
1198
1233
|
if (GPR_UNLIKELY(!CompressionAlgorithmSet::FromUint32(
|
@@ -1217,7 +1252,7 @@ void FilterStackCall::BatchControl::ReceivingInitialMetadataReady(
|
|
1217
1252
|
|
1218
1253
|
GRPC_CALL_COMBINER_STOP(call->call_combiner(), "recv_initial_metadata_ready");
|
1219
1254
|
|
1220
|
-
if (
|
1255
|
+
if (error.ok()) {
|
1221
1256
|
grpc_metadata_batch* md = &call->recv_initial_metadata_;
|
1222
1257
|
call->RecvInitialFilter(md);
|
1223
1258
|
|
@@ -1232,7 +1267,7 @@ void FilterStackCall::BatchControl::ReceivingInitialMetadataReady(
|
|
1232
1267
|
if (batch_error_.ok()) {
|
1233
1268
|
batch_error_.set(error);
|
1234
1269
|
}
|
1235
|
-
call->CancelWithError(
|
1270
|
+
call->CancelWithError(error);
|
1236
1271
|
}
|
1237
1272
|
|
1238
1273
|
grpc_closure* saved_rsr_closure = nullptr;
|
@@ -1263,7 +1298,7 @@ void FilterStackCall::BatchControl::ReceivingInitialMetadataReady(
|
|
1263
1298
|
}
|
1264
1299
|
}
|
1265
1300
|
if (saved_rsr_closure != nullptr) {
|
1266
|
-
Closure::Run(DEBUG_LOCATION, saved_rsr_closure,
|
1301
|
+
Closure::Run(DEBUG_LOCATION, saved_rsr_closure, error);
|
1267
1302
|
}
|
1268
1303
|
|
1269
1304
|
FinishStep();
|
@@ -1274,7 +1309,7 @@ void FilterStackCall::BatchControl::ReceivingTrailingMetadataReady(
|
|
1274
1309
|
GRPC_CALL_COMBINER_STOP(call_->call_combiner(),
|
1275
1310
|
"recv_trailing_metadata_ready");
|
1276
1311
|
grpc_metadata_batch* md = &call_->recv_trailing_metadata_;
|
1277
|
-
call_->RecvTrailingFilter(md,
|
1312
|
+
call_->RecvTrailingFilter(md, error);
|
1278
1313
|
FinishStep();
|
1279
1314
|
}
|
1280
1315
|
|
@@ -1283,12 +1318,30 @@ void FilterStackCall::BatchControl::FinishBatch(grpc_error_handle error) {
|
|
1283
1318
|
if (batch_error_.ok()) {
|
1284
1319
|
batch_error_.set(error);
|
1285
1320
|
}
|
1286
|
-
if (!
|
1287
|
-
call_->CancelWithError(
|
1321
|
+
if (!error.ok()) {
|
1322
|
+
call_->CancelWithError(error);
|
1288
1323
|
}
|
1289
1324
|
FinishStep();
|
1290
1325
|
}
|
1291
1326
|
|
1327
|
+
namespace {
|
1328
|
+
void EndOpImmediately(grpc_completion_queue* cq, void* notify_tag,
|
1329
|
+
bool is_notify_tag_closure) {
|
1330
|
+
if (!is_notify_tag_closure) {
|
1331
|
+
GPR_ASSERT(grpc_cq_begin_op(cq, notify_tag));
|
1332
|
+
grpc_cq_end_op(
|
1333
|
+
cq, notify_tag, absl::OkStatus(),
|
1334
|
+
[](void*, grpc_cq_completion* completion) { gpr_free(completion); },
|
1335
|
+
nullptr,
|
1336
|
+
static_cast<grpc_cq_completion*>(
|
1337
|
+
gpr_malloc(sizeof(grpc_cq_completion))));
|
1338
|
+
} else {
|
1339
|
+
Closure::Run(DEBUG_LOCATION, static_cast<grpc_closure*>(notify_tag),
|
1340
|
+
absl::OkStatus());
|
1341
|
+
}
|
1342
|
+
}
|
1343
|
+
} // namespace
|
1344
|
+
|
1292
1345
|
grpc_call_error FilterStackCall::StartBatch(const grpc_op* ops, size_t nops,
|
1293
1346
|
void* notify_tag,
|
1294
1347
|
bool is_notify_tag_closure) {
|
@@ -1312,18 +1365,7 @@ grpc_call_error FilterStackCall::StartBatch(const grpc_op* ops, size_t nops,
|
|
1312
1365
|
GRPC_CALL_LOG_BATCH(GPR_INFO, ops, nops);
|
1313
1366
|
|
1314
1367
|
if (nops == 0) {
|
1315
|
-
|
1316
|
-
GPR_ASSERT(grpc_cq_begin_op(cq_, notify_tag));
|
1317
|
-
grpc_cq_end_op(
|
1318
|
-
cq_, notify_tag, GRPC_ERROR_NONE,
|
1319
|
-
[](void*, grpc_cq_completion* completion) { gpr_free(completion); },
|
1320
|
-
nullptr,
|
1321
|
-
static_cast<grpc_cq_completion*>(
|
1322
|
-
gpr_malloc(sizeof(grpc_cq_completion))));
|
1323
|
-
} else {
|
1324
|
-
Closure::Run(DEBUG_LOCATION, static_cast<grpc_closure*>(notify_tag),
|
1325
|
-
GRPC_ERROR_NONE);
|
1326
|
-
}
|
1368
|
+
EndOpImmediately(cq_, notify_tag, is_notify_tag_closure);
|
1327
1369
|
error = GRPC_CALL_OK;
|
1328
1370
|
goto done;
|
1329
1371
|
}
|
@@ -1371,7 +1413,7 @@ grpc_call_error FilterStackCall::StartBatch(const grpc_op* ops, size_t nops,
|
|
1371
1413
|
level_set = true;
|
1372
1414
|
} else {
|
1373
1415
|
const grpc_compression_options copts =
|
1374
|
-
|
1416
|
+
channel()->compression_options();
|
1375
1417
|
if (copts.default_level.is_set) {
|
1376
1418
|
level_set = true;
|
1377
1419
|
effective_compression_level = copts.default_level.level;
|
@@ -1416,7 +1458,8 @@ grpc_call_error FilterStackCall::StartBatch(const grpc_op* ops, size_t nops,
|
|
1416
1458
|
stream_op_payload->send_initial_metadata.send_initial_metadata =
|
1417
1459
|
&send_initial_metadata_;
|
1418
1460
|
if (is_client()) {
|
1419
|
-
stream_op_payload->send_initial_metadata.peer_string =
|
1461
|
+
stream_op_payload->send_initial_metadata.peer_string =
|
1462
|
+
peer_string_atm_ptr();
|
1420
1463
|
}
|
1421
1464
|
has_send_ops = true;
|
1422
1465
|
break;
|
@@ -1505,11 +1548,10 @@ grpc_call_error FilterStackCall::StartBatch(const grpc_op* ops, size_t nops,
|
|
1505
1548
|
|
1506
1549
|
grpc_error_handle status_error =
|
1507
1550
|
op->data.send_status_from_server.status == GRPC_STATUS_OK
|
1508
|
-
?
|
1551
|
+
? absl::OkStatus()
|
1509
1552
|
: grpc_error_set_int(
|
1510
|
-
|
1511
|
-
|
1512
|
-
GRPC_ERROR_INT_GRPC_STATUS,
|
1553
|
+
GRPC_ERROR_CREATE("Server returned error"),
|
1554
|
+
StatusIntProperty::kRpcStatus,
|
1513
1555
|
static_cast<intptr_t>(
|
1514
1556
|
op->data.send_status_from_server.status));
|
1515
1557
|
if (op->data.send_status_from_server.status_details != nullptr) {
|
@@ -1517,16 +1559,15 @@ grpc_call_error FilterStackCall::StartBatch(const grpc_op* ops, size_t nops,
|
|
1517
1559
|
GrpcMessageMetadata(),
|
1518
1560
|
Slice(grpc_slice_copy(
|
1519
1561
|
*op->data.send_status_from_server.status_details)));
|
1520
|
-
if (!
|
1562
|
+
if (!status_error.ok()) {
|
1521
1563
|
status_error = grpc_error_set_str(
|
1522
|
-
status_error,
|
1564
|
+
status_error, StatusStrProperty::kGrpcMessage,
|
1523
1565
|
StringViewFromSlice(
|
1524
1566
|
*op->data.send_status_from_server.status_details));
|
1525
1567
|
}
|
1526
1568
|
}
|
1527
1569
|
|
1528
1570
|
status_error_.set(status_error);
|
1529
|
-
GRPC_ERROR_UNREF(status_error);
|
1530
1571
|
|
1531
1572
|
send_trailing_metadata_.Set(GrpcStatusMetadata(),
|
1532
1573
|
op->data.send_status_from_server.status);
|
@@ -1569,7 +1610,8 @@ grpc_call_error FilterStackCall::StartBatch(const grpc_op* ops, size_t nops,
|
|
1569
1610
|
stream_op_payload->recv_initial_metadata.trailing_metadata_available =
|
1570
1611
|
&is_trailers_only_;
|
1571
1612
|
} else {
|
1572
|
-
stream_op_payload->recv_initial_metadata.peer_string =
|
1613
|
+
stream_op_payload->recv_initial_metadata.peer_string =
|
1614
|
+
peer_string_atm_ptr();
|
1573
1615
|
}
|
1574
1616
|
++num_recv_ops;
|
1575
1617
|
break;
|
@@ -1740,8 +1782,1085 @@ void FilterStackCall::ContextSet(grpc_context_index elem, void* value,
|
|
1740
1782
|
context_[elem].destroy = destroy;
|
1741
1783
|
}
|
1742
1784
|
|
1785
|
+
///////////////////////////////////////////////////////////////////////////////
|
1786
|
+
// Metadata validation helpers
|
1787
|
+
|
1788
|
+
namespace {
|
1789
|
+
bool ValidateMetadata(size_t count, grpc_metadata* metadata) {
|
1790
|
+
for (size_t i = 0; i < count; i++) {
|
1791
|
+
grpc_metadata* md = &metadata[i];
|
1792
|
+
if (!GRPC_LOG_IF_ERROR("validate_metadata",
|
1793
|
+
grpc_validate_header_key_is_legal(md->key))) {
|
1794
|
+
return false;
|
1795
|
+
} else if (!grpc_is_binary_header_internal(md->key) &&
|
1796
|
+
!GRPC_LOG_IF_ERROR(
|
1797
|
+
"validate_metadata",
|
1798
|
+
grpc_validate_header_nonbin_value_is_legal(md->value))) {
|
1799
|
+
return false;
|
1800
|
+
} else if (GRPC_SLICE_LENGTH(md->value) >= UINT32_MAX) {
|
1801
|
+
// HTTP2 hpack encoding has a maximum limit.
|
1802
|
+
return false;
|
1803
|
+
}
|
1804
|
+
}
|
1805
|
+
return true;
|
1806
|
+
}
|
1807
|
+
} // namespace
|
1808
|
+
|
1809
|
+
///////////////////////////////////////////////////////////////////////////////
|
1810
|
+
// PromiseBasedCall
|
1811
|
+
// Will be folded into Call once the promise conversion is done
|
1812
|
+
|
1813
|
+
class PromiseBasedCall : public Call, public Activity, public Wakeable {
|
1814
|
+
public:
|
1815
|
+
PromiseBasedCall(Arena* arena, const grpc_call_create_args& args);
|
1816
|
+
|
1817
|
+
void ContextSet(grpc_context_index elem, void* value,
|
1818
|
+
void (*destroy)(void* value)) override;
|
1819
|
+
void* ContextGet(grpc_context_index elem) const override;
|
1820
|
+
void SetCompletionQueue(grpc_completion_queue* cq) override;
|
1821
|
+
|
1822
|
+
// Implementation of call refcounting: move this to DualRefCounted once we
|
1823
|
+
// don't need to maintain FilterStackCall compatibility
|
1824
|
+
void ExternalRef() final {
|
1825
|
+
refs_.fetch_add(MakeRefPair(1, 0), std::memory_order_relaxed);
|
1826
|
+
}
|
1827
|
+
void ExternalUnref() final {
|
1828
|
+
const uint64_t prev_ref_pair =
|
1829
|
+
refs_.fetch_add(MakeRefPair(-1, 1), std::memory_order_acq_rel);
|
1830
|
+
const uint32_t strong_refs = GetStrongRefs(prev_ref_pair);
|
1831
|
+
if (GPR_UNLIKELY(strong_refs == 1)) {
|
1832
|
+
Orphan();
|
1833
|
+
}
|
1834
|
+
// Now drop the weak ref.
|
1835
|
+
InternalUnref("external_ref");
|
1836
|
+
}
|
1837
|
+
void InternalRef(const char*) final {
|
1838
|
+
refs_.fetch_add(MakeRefPair(0, 1), std::memory_order_relaxed);
|
1839
|
+
}
|
1840
|
+
void InternalUnref(const char*) final {
|
1841
|
+
const uint64_t prev_ref_pair =
|
1842
|
+
refs_.fetch_sub(MakeRefPair(0, 1), std::memory_order_acq_rel);
|
1843
|
+
if (GPR_UNLIKELY(prev_ref_pair == MakeRefPair(0, 1))) {
|
1844
|
+
DeleteThis();
|
1845
|
+
}
|
1846
|
+
}
|
1847
|
+
|
1848
|
+
// Activity methods
|
1849
|
+
void ForceImmediateRepoll() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_) override;
|
1850
|
+
Waker MakeOwningWaker() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_) override {
|
1851
|
+
InternalRef("wakeup");
|
1852
|
+
// If ASAN is defined, we leverage it to detect dropped Waker objects.
|
1853
|
+
// Usually Waker must be destroyed or woken up, but (especially with arenas)
|
1854
|
+
// it's not uncommon to create a Waker and then do neither. In that case it's
|
1855
|
+
// incredibly fraught to diagnose where the dropped reference to this object was
|
1856
|
+
// created. Instead, leverage ASAN and create a new object per expected wakeup.
|
1857
|
+
// Now when we drop such an object ASAN will fail and we'll get a callstack to
|
1858
|
+
// the creation of the waker in question.
|
1859
|
+
#if defined(__has_feature)
|
1860
|
+
#if __has_feature(address_sanitizer)
|
1861
|
+
#define GRPC_CALL_USES_ASAN_WAKER
|
1862
|
+
class AsanWaker final : public Wakeable {
|
1863
|
+
public:
|
1864
|
+
explicit AsanWaker(PromiseBasedCall* call) : call_(call) {}
|
1865
|
+
|
1866
|
+
void Wakeup() override {
|
1867
|
+
call_->Wakeup();
|
1868
|
+
delete this;
|
1869
|
+
}
|
1870
|
+
|
1871
|
+
void Drop() override {
|
1872
|
+
call_->Drop();
|
1873
|
+
delete this;
|
1874
|
+
}
|
1875
|
+
|
1876
|
+
std::string ActivityDebugTag() const override {
|
1877
|
+
return call_->DebugTag();
|
1878
|
+
}
|
1879
|
+
|
1880
|
+
private:
|
1881
|
+
PromiseBasedCall* call_;
|
1882
|
+
};
|
1883
|
+
return Waker(new AsanWaker(this));
|
1884
|
+
#endif
|
1885
|
+
#endif
|
1886
|
+
#ifndef GRPC_CALL_USES_ASAN_WAKER
|
1887
|
+
return Waker(this);
|
1888
|
+
#endif
|
1889
|
+
}
|
1890
|
+
Waker MakeNonOwningWaker() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_) override;
|
1891
|
+
|
1892
|
+
// Wakeable methods
|
1893
|
+
void Wakeup() override {
|
1894
|
+
channel()->event_engine()->Run([this] {
|
1895
|
+
ApplicationCallbackExecCtx app_exec_ctx;
|
1896
|
+
ExecCtx exec_ctx;
|
1897
|
+
{
|
1898
|
+
ScopedContext activity_context(this);
|
1899
|
+
MutexLock lock(&mu_);
|
1900
|
+
Update();
|
1901
|
+
}
|
1902
|
+
InternalUnref("wakeup");
|
1903
|
+
});
|
1904
|
+
}
|
1905
|
+
void Drop() override { InternalUnref("wakeup"); }
|
1906
|
+
|
1907
|
+
void RunInContext(absl::AnyInvocable<void()> fn) {
|
1908
|
+
if (Activity::current() == this) {
|
1909
|
+
fn();
|
1910
|
+
} else {
|
1911
|
+
InternalRef("in_context");
|
1912
|
+
channel()->event_engine()->Run([this, fn = std::move(fn)]() mutable {
|
1913
|
+
ApplicationCallbackExecCtx app_exec_ctx;
|
1914
|
+
ExecCtx exec_ctx;
|
1915
|
+
{
|
1916
|
+
ScopedContext activity_context(this);
|
1917
|
+
MutexLock lock(&mu_);
|
1918
|
+
fn();
|
1919
|
+
Update();
|
1920
|
+
}
|
1921
|
+
InternalUnref("in_context");
|
1922
|
+
});
|
1923
|
+
}
|
1924
|
+
}
|
1925
|
+
|
1926
|
+
grpc_compression_algorithm test_only_compression_algorithm() override {
|
1927
|
+
abort();
|
1928
|
+
}
|
1929
|
+
uint32_t test_only_message_flags() override { abort(); }
|
1930
|
+
uint32_t test_only_encodings_accepted_by_peer() override { abort(); }
|
1931
|
+
grpc_compression_algorithm compression_for_level(
|
1932
|
+
grpc_compression_level) override {
|
1933
|
+
abort();
|
1934
|
+
}
|
1935
|
+
|
1936
|
+
// This should return nullptr for the promise stack (and alternative means
|
1937
|
+
// for that functionality be invented)
|
1938
|
+
grpc_call_stack* call_stack() override { return nullptr; }
|
1939
|
+
|
1940
|
+
protected:
|
1941
|
+
class ScopedContext
|
1942
|
+
: public ScopedActivity,
|
1943
|
+
public promise_detail::Context<Arena>,
|
1944
|
+
public promise_detail::Context<grpc_call_context_element>,
|
1945
|
+
public promise_detail::Context<CallContext>,
|
1946
|
+
public promise_detail::Context<CallFinalization> {
|
1947
|
+
public:
|
1948
|
+
explicit ScopedContext(PromiseBasedCall* call)
|
1949
|
+
: ScopedActivity(call),
|
1950
|
+
promise_detail::Context<Arena>(call->arena()),
|
1951
|
+
promise_detail::Context<grpc_call_context_element>(call->context_),
|
1952
|
+
promise_detail::Context<CallContext>(&call->call_context_),
|
1953
|
+
promise_detail::Context<CallFinalization>(&call->finalization_) {}
|
1954
|
+
};
|
1955
|
+
|
1956
|
+
class Completion {
|
1957
|
+
public:
|
1958
|
+
Completion() : index_(kNullIndex) {}
|
1959
|
+
~Completion() { GPR_ASSERT(index_ == kNullIndex); }
|
1960
|
+
explicit Completion(uint8_t index) : index_(index) {}
|
1961
|
+
Completion(const Completion& other) = delete;
|
1962
|
+
Completion& operator=(const Completion& other) = delete;
|
1963
|
+
Completion(Completion&& other) noexcept : index_(other.index_) {
|
1964
|
+
other.index_ = kNullIndex;
|
1965
|
+
}
|
1966
|
+
Completion& operator=(Completion&& other) noexcept {
|
1967
|
+
GPR_ASSERT(index_ == kNullIndex);
|
1968
|
+
index_ = other.index_;
|
1969
|
+
other.index_ = kNullIndex;
|
1970
|
+
return *this;
|
1971
|
+
}
|
1972
|
+
|
1973
|
+
uint8_t index() const { return index_; }
|
1974
|
+
uint8_t TakeIndex() { return std::exchange(index_, kNullIndex); }
|
1975
|
+
bool has_value() const { return index_ != kNullIndex; }
|
1976
|
+
|
1977
|
+
std::string ToString() const {
|
1978
|
+
return index_ == kNullIndex ? "null"
|
1979
|
+
: std::to_string(static_cast<int>(index_));
|
1980
|
+
}
|
1981
|
+
|
1982
|
+
private:
|
1983
|
+
enum : uint8_t { kNullIndex = 0xff };
|
1984
|
+
uint8_t index_;
|
1985
|
+
};
|
1986
|
+
|
1987
|
+
~PromiseBasedCall() override {
|
1988
|
+
if (non_owning_wakeable_) non_owning_wakeable_->DropActivity();
|
1989
|
+
if (cq_) GRPC_CQ_INTERNAL_UNREF(cq_, "bind");
|
1990
|
+
}
|
1991
|
+
|
1992
|
+
// Enumerates why a Completion is still pending
|
1993
|
+
enum class PendingOp {
|
1994
|
+
// We're in the midst of starting a batch of operations
|
1995
|
+
kStartingBatch = 0,
|
1996
|
+
// The following correspond with the batch operations from above
|
1997
|
+
kReceiveInitialMetadata,
|
1998
|
+
kReceiveStatusOnClient,
|
1999
|
+
kSendMessage,
|
2000
|
+
kReceiveMessage,
|
2001
|
+
};
|
2002
|
+
|
2003
|
+
static constexpr const char* PendingOpString(PendingOp reason) {
|
2004
|
+
switch (reason) {
|
2005
|
+
case PendingOp::kStartingBatch:
|
2006
|
+
return "StartingBatch";
|
2007
|
+
case PendingOp::kReceiveInitialMetadata:
|
2008
|
+
return "ReceiveInitialMetadata";
|
2009
|
+
case PendingOp::kReceiveStatusOnClient:
|
2010
|
+
return "ReceiveStatusOnClient";
|
2011
|
+
case PendingOp::kSendMessage:
|
2012
|
+
return "SendMessage";
|
2013
|
+
case PendingOp::kReceiveMessage:
|
2014
|
+
return "ReceiveMessage";
|
2015
|
+
}
|
2016
|
+
return "Unknown";
|
2017
|
+
}
|
2018
|
+
|
2019
|
+
static constexpr uint8_t PendingOpBit(PendingOp reason) {
|
2020
|
+
return 1 << static_cast<int>(reason);
|
2021
|
+
}
|
2022
|
+
|
2023
|
+
Mutex* mu() const ABSL_LOCK_RETURNED(mu_) { return &mu_; }
|
2024
|
+
|
2025
|
+
// Begin work on a completion, recording the tag/closure to notify.
|
2026
|
+
// Use the op selected in \a ops to determine the index to allocate into.
|
2027
|
+
// Starts the "StartingBatch" PendingOp immediately.
|
2028
|
+
// Assumes at least one operation in \a ops.
|
2029
|
+
Completion StartCompletion(void* tag, bool is_closure, const grpc_op* ops)
|
2030
|
+
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_);
|
2031
|
+
// Add one pending op to the completion, and return it.
|
2032
|
+
Completion AddOpToCompletion(const Completion& completion, PendingOp reason)
|
2033
|
+
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_);
|
2034
|
+
// Finish one op on the completion. Must have been previously been added.
|
2035
|
+
// The completion as a whole finishes when all pending ops finish.
|
2036
|
+
void FinishOpOnCompletion(Completion* completion, PendingOp reason)
|
2037
|
+
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_);
|
2038
|
+
// Mark the completion as failed. Does not finish it.
|
2039
|
+
void FailCompletion(const Completion& completion);
|
2040
|
+
// Run the promise polling loop until it stalls.
|
2041
|
+
void Update() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_);
|
2042
|
+
// Update the promise state once.
|
2043
|
+
virtual void UpdateOnce() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_) = 0;
|
2044
|
+
// Accept the stats from the context (call once we have proof the transport is
|
2045
|
+
// done with them).
|
2046
|
+
// Right now this means that promise based calls do not record correct stats
|
2047
|
+
// with census if they are cancelled.
|
2048
|
+
// TODO(ctiller): this should be remedied before promise based calls are
|
2049
|
+
// dexperimentalized.
|
2050
|
+
void AcceptTransportStatsFromContext() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_) {
|
2051
|
+
final_stats_ = *call_context_.call_stats();
|
2052
|
+
}
|
2053
|
+
|
2054
|
+
grpc_completion_queue* cq() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_) { return cq_; }
|
2055
|
+
|
2056
|
+
void CToMetadata(grpc_metadata* metadata, size_t count,
|
2057
|
+
grpc_metadata_batch* batch);
|
2058
|
+
|
2059
|
+
std::string ActivityDebugTag() const override { return DebugTag(); }
|
2060
|
+
|
2061
|
+
// At the end of the call run any finalization actions.
|
2062
|
+
void RunFinalization(grpc_status_code status, const char* status_details) {
|
2063
|
+
grpc_call_final_info final_info;
|
2064
|
+
final_info.stats = final_stats_;
|
2065
|
+
final_info.final_status = status;
|
2066
|
+
final_info.error_string = status_details;
|
2067
|
+
finalization_.Run(&final_info);
|
2068
|
+
}
|
2069
|
+
|
2070
|
+
private:
|
2071
|
+
union CompletionInfo {
|
2072
|
+
struct Pending {
|
2073
|
+
// Bitmask of PendingOps
|
2074
|
+
uint8_t pending_op_bits;
|
2075
|
+
bool is_closure;
|
2076
|
+
bool success;
|
2077
|
+
void* tag;
|
2078
|
+
} pending;
|
2079
|
+
grpc_cq_completion completion;
|
2080
|
+
};
|
2081
|
+
|
2082
|
+
class NonOwningWakable final : public Wakeable {
|
2083
|
+
public:
|
2084
|
+
explicit NonOwningWakable(PromiseBasedCall* call) : call_(call) {}
|
2085
|
+
|
2086
|
+
// Ref the Handle (not the activity).
|
2087
|
+
void Ref() { refs_.fetch_add(1, std::memory_order_relaxed); }
|
2088
|
+
|
2089
|
+
// Activity is going away... drop its reference and sever the connection
|
2090
|
+
// back.
|
2091
|
+
void DropActivity() ABSL_LOCKS_EXCLUDED(mu_) {
|
2092
|
+
auto unref = absl::MakeCleanup([this]() { Unref(); });
|
2093
|
+
MutexLock lock(&mu_);
|
2094
|
+
GPR_ASSERT(call_ != nullptr);
|
2095
|
+
call_ = nullptr;
|
2096
|
+
}
|
2097
|
+
|
2098
|
+
// Activity needs to wake up (if it still exists!) - wake it up, and drop
|
2099
|
+
// the ref that was kept for this handle.
|
2100
|
+
void Wakeup() override ABSL_LOCKS_EXCLUDED(mu_) {
|
2101
|
+
// Drop the ref to the handle at end of scope (we have one ref = one
|
2102
|
+
// wakeup semantics).
|
2103
|
+
auto unref = absl::MakeCleanup([this]() { Unref(); });
|
2104
|
+
ReleasableMutexLock lock(&mu_);
|
2105
|
+
// Note that activity refcount can drop to zero, but we could win the lock
|
2106
|
+
// against DropActivity, so we need to only increase activities refcount
|
2107
|
+
// if it is non-zero.
|
2108
|
+
if (call_ != nullptr && call_->RefIfNonZero()) {
|
2109
|
+
PromiseBasedCall* call = call_;
|
2110
|
+
lock.Release();
|
2111
|
+
// Activity still exists and we have a reference: wake it up, which will
|
2112
|
+
// drop the ref.
|
2113
|
+
call->Wakeup();
|
2114
|
+
}
|
2115
|
+
}
|
2116
|
+
|
2117
|
+
std::string ActivityDebugTag() const override {
|
2118
|
+
MutexLock lock(&mu_);
|
2119
|
+
return call_ == nullptr ? "<unknown>" : call_->DebugTag();
|
2120
|
+
}
|
2121
|
+
|
2122
|
+
void Drop() override { Unref(); }
|
2123
|
+
|
2124
|
+
private:
|
2125
|
+
// Unref the Handle (not the activity).
|
2126
|
+
void Unref() {
|
2127
|
+
if (1 == refs_.fetch_sub(1, std::memory_order_acq_rel)) {
|
2128
|
+
delete this;
|
2129
|
+
}
|
2130
|
+
}
|
2131
|
+
|
2132
|
+
mutable Mutex mu_;
|
2133
|
+
// We have two initial refs: one for the wakeup that this is created for,
|
2134
|
+
// and will be dropped by Wakeup, and the other for the activity which is
|
2135
|
+
// dropped by DropActivity.
|
2136
|
+
std::atomic<size_t> refs_{2};
|
2137
|
+
PromiseBasedCall* call_ ABSL_GUARDED_BY(mu_);
|
2138
|
+
};
|
2139
|
+
|
2140
|
+
static void OnDestroy(void* arg, grpc_error_handle) {
|
2141
|
+
auto* call = static_cast<PromiseBasedCall*>(arg);
|
2142
|
+
ScopedContext context(call);
|
2143
|
+
call->DeleteThis();
|
2144
|
+
}
|
2145
|
+
|
2146
|
+
// First 32 bits are strong refs, next 32 bits are weak refs.
|
2147
|
+
static uint64_t MakeRefPair(uint32_t strong, uint32_t weak) {
|
2148
|
+
return (static_cast<uint64_t>(strong) << 32) + static_cast<int64_t>(weak);
|
2149
|
+
}
|
2150
|
+
static uint32_t GetStrongRefs(uint64_t ref_pair) {
|
2151
|
+
return static_cast<uint32_t>(ref_pair >> 32);
|
2152
|
+
}
|
2153
|
+
static uint32_t GetWeakRefs(uint64_t ref_pair) {
|
2154
|
+
return static_cast<uint32_t>(ref_pair & 0xffffffffu);
|
2155
|
+
}
|
2156
|
+
|
2157
|
+
bool RefIfNonZero() {
|
2158
|
+
uint64_t prev_ref_pair = refs_.load(std::memory_order_acquire);
|
2159
|
+
do {
|
2160
|
+
const uint32_t strong_refs = GetStrongRefs(prev_ref_pair);
|
2161
|
+
if (strong_refs == 0) return false;
|
2162
|
+
} while (!refs_.compare_exchange_weak(
|
2163
|
+
prev_ref_pair, prev_ref_pair + MakeRefPair(1, 0),
|
2164
|
+
std::memory_order_acq_rel, std::memory_order_acquire));
|
2165
|
+
return true;
|
2166
|
+
}
|
2167
|
+
|
2168
|
+
mutable Mutex mu_;
|
2169
|
+
std::atomic<uint64_t> refs_{MakeRefPair(1, 0)};
|
2170
|
+
CallContext call_context_{this};
|
2171
|
+
bool keep_polling_ ABSL_GUARDED_BY(mu()) = false;
|
2172
|
+
|
2173
|
+
/* Contexts for various subsystems (security, tracing, ...). */
|
2174
|
+
grpc_call_context_element context_[GRPC_CONTEXT_COUNT] = {};
|
2175
|
+
grpc_completion_queue* cq_ ABSL_GUARDED_BY(mu_);
|
2176
|
+
NonOwningWakable* non_owning_wakeable_ ABSL_GUARDED_BY(mu_) = nullptr;
|
2177
|
+
CompletionInfo completion_info_[6];
|
2178
|
+
grpc_call_stats final_stats_{};
|
2179
|
+
CallFinalization finalization_;
|
2180
|
+
};
|
2181
|
+
|
2182
|
+
template <typename T>
|
2183
|
+
grpc_error_handle MakePromiseBasedCall(grpc_call_create_args* args,
|
2184
|
+
grpc_call** out_call) {
|
2185
|
+
Channel* channel = args->channel.get();
|
2186
|
+
|
2187
|
+
auto alloc = Arena::CreateWithAlloc(channel->CallSizeEstimate(), sizeof(T),
|
2188
|
+
channel->allocator());
|
2189
|
+
PromiseBasedCall* call = new (alloc.second) T(alloc.first, args);
|
2190
|
+
*out_call = call->c_ptr();
|
2191
|
+
GPR_DEBUG_ASSERT(Call::FromC(*out_call) == call);
|
2192
|
+
return absl::OkStatus();
|
2193
|
+
}
|
2194
|
+
|
2195
|
+
PromiseBasedCall::PromiseBasedCall(Arena* arena,
|
2196
|
+
const grpc_call_create_args& args)
|
2197
|
+
: Call(arena, args.server_transport_data == nullptr, args.send_deadline,
|
2198
|
+
args.channel->Ref()),
|
2199
|
+
cq_(args.cq) {
|
2200
|
+
if (args.cq != nullptr) {
|
2201
|
+
GPR_ASSERT(args.pollset_set_alternative == nullptr &&
|
2202
|
+
"Only one of 'cq' and 'pollset_set_alternative' should be "
|
2203
|
+
"non-nullptr.");
|
2204
|
+
GRPC_CQ_INTERNAL_REF(args.cq, "bind");
|
2205
|
+
call_context_.pollent_ =
|
2206
|
+
grpc_polling_entity_create_from_pollset(grpc_cq_pollset(args.cq));
|
2207
|
+
}
|
2208
|
+
if (args.pollset_set_alternative != nullptr) {
|
2209
|
+
call_context_.pollent_ = grpc_polling_entity_create_from_pollset_set(
|
2210
|
+
args.pollset_set_alternative);
|
2211
|
+
}
|
2212
|
+
}
|
2213
|
+
|
2214
|
+
Waker PromiseBasedCall::MakeNonOwningWaker() {
|
2215
|
+
if (non_owning_wakeable_ == nullptr) {
|
2216
|
+
non_owning_wakeable_ = new NonOwningWakable(this);
|
2217
|
+
} else {
|
2218
|
+
non_owning_wakeable_->Ref();
|
2219
|
+
}
|
2220
|
+
return Waker(non_owning_wakeable_);
|
2221
|
+
}
|
2222
|
+
|
2223
|
+
void PromiseBasedCall::CToMetadata(grpc_metadata* metadata, size_t count,
|
2224
|
+
grpc_metadata_batch* b) {
|
2225
|
+
for (size_t i = 0; i < count; i++) {
|
2226
|
+
grpc_metadata* md = &metadata[i];
|
2227
|
+
auto key = StringViewFromSlice(md->key);
|
2228
|
+
// Filter "content-length metadata"
|
2229
|
+
if (key == "content-length") continue;
|
2230
|
+
b->Append(key, Slice(CSliceRef(md->value)),
|
2231
|
+
[md](absl::string_view error, const Slice& value) {
|
2232
|
+
gpr_log(GPR_DEBUG, "Append error: %s",
|
2233
|
+
absl::StrCat("key=", StringViewFromSlice(md->key),
|
2234
|
+
" error=", error,
|
2235
|
+
" value=", value.as_string_view())
|
2236
|
+
.c_str());
|
2237
|
+
});
|
2238
|
+
}
|
2239
|
+
}
|
2240
|
+
|
2241
|
+
void PromiseBasedCall::ContextSet(grpc_context_index elem, void* value,
|
2242
|
+
void (*destroy)(void*)) {
|
2243
|
+
if (context_[elem].destroy != nullptr) {
|
2244
|
+
context_[elem].destroy(context_[elem].value);
|
2245
|
+
}
|
2246
|
+
context_[elem].value = value;
|
2247
|
+
context_[elem].destroy = destroy;
|
2248
|
+
}
|
2249
|
+
|
2250
|
+
void* PromiseBasedCall::ContextGet(grpc_context_index elem) const {
|
2251
|
+
return context_[elem].value;
|
2252
|
+
}
|
2253
|
+
|
2254
|
+
PromiseBasedCall::Completion PromiseBasedCall::StartCompletion(
|
2255
|
+
void* tag, bool is_closure, const grpc_op* ops) {
|
2256
|
+
Completion c(BatchSlotForOp(ops[0].op));
|
2257
|
+
if (grpc_call_trace.enabled()) {
|
2258
|
+
gpr_log(GPR_INFO, "%sStartCompletion %s tag=%p", DebugTag().c_str(),
|
2259
|
+
c.ToString().c_str(), tag);
|
2260
|
+
}
|
2261
|
+
if (!is_closure) {
|
2262
|
+
grpc_cq_begin_op(cq(), tag);
|
2263
|
+
}
|
2264
|
+
completion_info_[c.index()].pending = {
|
2265
|
+
PendingOpBit(PendingOp::kStartingBatch), is_closure, true, tag};
|
2266
|
+
return c;
|
2267
|
+
}
|
2268
|
+
|
2269
|
+
PromiseBasedCall::Completion PromiseBasedCall::AddOpToCompletion(
|
2270
|
+
const Completion& completion, PendingOp reason) {
|
2271
|
+
if (grpc_call_trace.enabled()) {
|
2272
|
+
gpr_log(GPR_INFO, "%sAddOpToCompletion %s %s", DebugTag().c_str(),
|
2273
|
+
completion.ToString().c_str(), PendingOpString(reason));
|
2274
|
+
}
|
2275
|
+
auto& pending_op_bits =
|
2276
|
+
completion_info_[completion.index()].pending.pending_op_bits;
|
2277
|
+
GPR_ASSERT((pending_op_bits & PendingOpBit(reason)) == 0);
|
2278
|
+
pending_op_bits |= PendingOpBit(reason);
|
2279
|
+
return Completion(completion.index());
|
2280
|
+
}
|
2281
|
+
|
2282
|
+
void PromiseBasedCall::FailCompletion(const Completion& completion) {
|
2283
|
+
if (grpc_call_trace.enabled()) {
|
2284
|
+
gpr_log(GPR_INFO, "%sFailCompletion %s", DebugTag().c_str(),
|
2285
|
+
completion.ToString().c_str());
|
2286
|
+
}
|
2287
|
+
completion_info_[completion.index()].pending.success = false;
|
2288
|
+
}
|
2289
|
+
|
2290
|
+
void PromiseBasedCall::FinishOpOnCompletion(Completion* completion,
|
2291
|
+
PendingOp reason) {
|
2292
|
+
if (grpc_call_trace.enabled()) {
|
2293
|
+
auto pending_op_bits =
|
2294
|
+
completion_info_[completion->index()].pending.pending_op_bits;
|
2295
|
+
bool success = completion_info_[completion->index()].pending.success;
|
2296
|
+
std::vector<const char*> pending;
|
2297
|
+
for (size_t i = 0; i < 8 * sizeof(pending_op_bits); i++) {
|
2298
|
+
if (static_cast<PendingOp>(i) == reason) continue;
|
2299
|
+
if (pending_op_bits & (1 << i)) {
|
2300
|
+
pending.push_back(PendingOpString(static_cast<PendingOp>(i)));
|
2301
|
+
}
|
2302
|
+
}
|
2303
|
+
gpr_log(
|
2304
|
+
GPR_INFO, "%sFinishOpOnCompletion %s %s %s", DebugTag().c_str(),
|
2305
|
+
completion->ToString().c_str(), PendingOpString(reason),
|
2306
|
+
(pending.empty()
|
2307
|
+
? (success ? std::string("done") : std::string("failed"))
|
2308
|
+
: absl::StrFormat("pending_ops={%s}", absl::StrJoin(pending, ",")))
|
2309
|
+
.c_str());
|
2310
|
+
}
|
2311
|
+
const uint8_t i = completion->TakeIndex();
|
2312
|
+
GPR_ASSERT(i < GPR_ARRAY_SIZE(completion_info_));
|
2313
|
+
CompletionInfo::Pending& pending = completion_info_[i].pending;
|
2314
|
+
GPR_ASSERT(pending.pending_op_bits & PendingOpBit(reason));
|
2315
|
+
pending.pending_op_bits &= ~PendingOpBit(reason);
|
2316
|
+
auto error = pending.success ? absl::OkStatus() : absl::CancelledError();
|
2317
|
+
if (pending.pending_op_bits == 0) {
|
2318
|
+
if (pending.is_closure) {
|
2319
|
+
ExecCtx::Run(DEBUG_LOCATION, static_cast<grpc_closure*>(pending.tag),
|
2320
|
+
error);
|
2321
|
+
} else {
|
2322
|
+
grpc_cq_end_op(
|
2323
|
+
cq(), pending.tag, error, [](void*, grpc_cq_completion*) {}, nullptr,
|
2324
|
+
&completion_info_[i].completion);
|
2325
|
+
}
|
2326
|
+
}
|
2327
|
+
}
|
2328
|
+
|
2329
|
+
void PromiseBasedCall::Update() {
|
2330
|
+
keep_polling_ = false;
|
2331
|
+
do {
|
2332
|
+
UpdateOnce();
|
2333
|
+
} while (std::exchange(keep_polling_, false));
|
2334
|
+
}
|
2335
|
+
|
2336
|
+
void PromiseBasedCall::ForceImmediateRepoll() { keep_polling_ = true; }
|
2337
|
+
|
2338
|
+
void PromiseBasedCall::SetCompletionQueue(grpc_completion_queue* cq) {
|
2339
|
+
MutexLock lock(&mu_);
|
2340
|
+
cq_ = cq;
|
2341
|
+
GRPC_CQ_INTERNAL_REF(cq, "bind");
|
2342
|
+
call_context_.pollent_ =
|
2343
|
+
grpc_polling_entity_create_from_pollset(grpc_cq_pollset(cq));
|
2344
|
+
}
|
2345
|
+
|
2346
|
+
///////////////////////////////////////////////////////////////////////////////
|
2347
|
+
// CallContext
|
2348
|
+
|
2349
|
+
void CallContext::RunInContext(absl::AnyInvocable<void()> fn) {
|
2350
|
+
call_->RunInContext(std::move(fn));
|
2351
|
+
}
|
2352
|
+
|
2353
|
+
void CallContext::IncrementRefCount(const char* reason) {
|
2354
|
+
call_->InternalRef(reason);
|
2355
|
+
}
|
2356
|
+
|
2357
|
+
void CallContext::Unref(const char* reason) { call_->InternalUnref(reason); }
|
2358
|
+
|
2359
|
+
///////////////////////////////////////////////////////////////////////////////
|
2360
|
+
// ClientPromiseBasedCall
|
2361
|
+
|
2362
|
+
class ClientPromiseBasedCall final : public PromiseBasedCall {
|
2363
|
+
public:
|
2364
|
+
ClientPromiseBasedCall(Arena* arena, grpc_call_create_args* args)
|
2365
|
+
: PromiseBasedCall(arena, *args) {
|
2366
|
+
global_stats().IncrementClientCallsCreated();
|
2367
|
+
ScopedContext context(this);
|
2368
|
+
send_initial_metadata_ =
|
2369
|
+
GetContext<Arena>()->MakePooled<ClientMetadata>(GetContext<Arena>());
|
2370
|
+
send_initial_metadata_->Set(HttpPathMetadata(), std::move(*args->path));
|
2371
|
+
if (args->authority.has_value()) {
|
2372
|
+
send_initial_metadata_->Set(HttpAuthorityMetadata(),
|
2373
|
+
std::move(*args->authority));
|
2374
|
+
}
|
2375
|
+
if (auto* channelz_channel = channel()->channelz_node()) {
|
2376
|
+
channelz_channel->RecordCallStarted();
|
2377
|
+
}
|
2378
|
+
}
|
2379
|
+
|
2380
|
+
~ClientPromiseBasedCall() override {
|
2381
|
+
ScopedContext context(this);
|
2382
|
+
send_initial_metadata_.reset();
|
2383
|
+
recv_status_on_client_ = absl::monostate();
|
2384
|
+
promise_ = ArenaPromise<ServerMetadataHandle>();
|
2385
|
+
// Need to destroy the pipes under the ScopedContext above, so we move them
|
2386
|
+
// out here and then allow the destructors to run at end of scope, but
|
2387
|
+
// before context.
|
2388
|
+
auto c2s = std::move(client_to_server_messages_);
|
2389
|
+
auto s2c = std::move(server_to_client_messages_);
|
2390
|
+
}
|
2391
|
+
|
2392
|
+
absl::string_view GetServerAuthority() const override { abort(); }
|
2393
|
+
void CancelWithError(grpc_error_handle error) override;
|
2394
|
+
bool Completed() override;
|
2395
|
+
void Orphan() override {
|
2396
|
+
MutexLock lock(mu());
|
2397
|
+
ScopedContext ctx(this);
|
2398
|
+
if (!completed_) Finish(ServerMetadataFromStatus(absl::CancelledError()));
|
2399
|
+
}
|
2400
|
+
bool is_trailers_only() const override {
|
2401
|
+
MutexLock lock(mu());
|
2402
|
+
return is_trailers_only_;
|
2403
|
+
}
|
2404
|
+
bool failed_before_recv_message() const override { abort(); }
|
2405
|
+
|
2406
|
+
grpc_call_error StartBatch(const grpc_op* ops, size_t nops, void* notify_tag,
|
2407
|
+
bool is_notify_tag_closure) override;
|
2408
|
+
|
2409
|
+
std::string DebugTag() const override {
|
2410
|
+
return absl::StrFormat("CLIENT_CALL[%p]: ", this);
|
2411
|
+
}
|
2412
|
+
|
2413
|
+
private:
|
2414
|
+
// Poll the underlying promise (and sundry objects) once.
|
2415
|
+
void UpdateOnce() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu()) override;
|
2416
|
+
// Finish the call with the given status/trailing metadata.
|
2417
|
+
void Finish(ServerMetadataHandle trailing_metadata)
|
2418
|
+
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu());
|
2419
|
+
// Validate that a set of ops is valid for a client call.
|
2420
|
+
grpc_call_error ValidateBatch(const grpc_op* ops, size_t nops) const
|
2421
|
+
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu());
|
2422
|
+
// Commit a valid batch of operations to be executed.
|
2423
|
+
void CommitBatch(const grpc_op* ops, size_t nops,
|
2424
|
+
const Completion& completion)
|
2425
|
+
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu());
|
2426
|
+
// Start the underlying promise.
|
2427
|
+
void StartPromise(ClientMetadataHandle client_initial_metadata)
|
2428
|
+
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu());
|
2429
|
+
// Publish some metadata out to the application.
|
2430
|
+
static void PublishMetadataArray(grpc_metadata_array* array,
|
2431
|
+
ServerMetadata* md);
|
2432
|
+
// Publish status out to the application.
|
2433
|
+
void PublishStatus(
|
2434
|
+
grpc_op::grpc_op_data::grpc_op_recv_status_on_client op_args,
|
2435
|
+
ServerMetadataHandle trailing_metadata)
|
2436
|
+
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu());
|
2437
|
+
// Publish server initial metadata out to the application.
|
2438
|
+
void PublishInitialMetadata(ServerMetadata* metadata)
|
2439
|
+
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu());
|
2440
|
+
|
2441
|
+
ArenaPromise<ServerMetadataHandle> promise_ ABSL_GUARDED_BY(mu());
|
2442
|
+
Latch<ServerMetadata*> server_initial_metadata_ ABSL_GUARDED_BY(mu());
|
2443
|
+
Pipe<MessageHandle> client_to_server_messages_ ABSL_GUARDED_BY(mu()){arena()};
|
2444
|
+
Pipe<MessageHandle> server_to_client_messages_ ABSL_GUARDED_BY(mu()){arena()};
|
2445
|
+
|
2446
|
+
ClientMetadataHandle send_initial_metadata_;
|
2447
|
+
grpc_metadata_array* recv_initial_metadata_ ABSL_GUARDED_BY(mu()) = nullptr;
|
2448
|
+
grpc_byte_buffer** recv_message_ ABSL_GUARDED_BY(mu()) = nullptr;
|
2449
|
+
absl::variant<absl::monostate,
|
2450
|
+
grpc_op::grpc_op_data::grpc_op_recv_status_on_client,
|
2451
|
+
ServerMetadataHandle>
|
2452
|
+
recv_status_on_client_ ABSL_GUARDED_BY(mu());
|
2453
|
+
absl::optional<PipeSender<MessageHandle>::PushType> outstanding_send_
|
2454
|
+
ABSL_GUARDED_BY(mu());
|
2455
|
+
absl::optional<PipeReceiver<MessageHandle>::NextType> outstanding_recv_
|
2456
|
+
ABSL_GUARDED_BY(mu());
|
2457
|
+
absl::optional<Latch<ServerMetadata*>::WaitPromise>
|
2458
|
+
server_initial_metadata_ready_;
|
2459
|
+
absl::optional<grpc_compression_algorithm> incoming_compression_algorithm_;
|
2460
|
+
Completion recv_initial_metadata_completion_ ABSL_GUARDED_BY(mu());
|
2461
|
+
Completion recv_status_on_client_completion_ ABSL_GUARDED_BY(mu());
|
2462
|
+
Completion send_message_completion_ ABSL_GUARDED_BY(mu());
|
2463
|
+
Completion recv_message_completion_ ABSL_GUARDED_BY(mu());
|
2464
|
+
bool completed_ ABSL_GUARDED_BY(mu()) = false;
|
2465
|
+
bool is_trailers_only_ ABSL_GUARDED_BY(mu());
|
2466
|
+
};
|
2467
|
+
|
2468
|
+
void ClientPromiseBasedCall::StartPromise(
|
2469
|
+
ClientMetadataHandle client_initial_metadata) {
|
2470
|
+
GPR_ASSERT(!promise_.has_value());
|
2471
|
+
promise_ = channel()->channel_stack()->MakeClientCallPromise(CallArgs{
|
2472
|
+
std::move(client_initial_metadata),
|
2473
|
+
&server_initial_metadata_,
|
2474
|
+
&client_to_server_messages_.receiver,
|
2475
|
+
&server_to_client_messages_.sender,
|
2476
|
+
});
|
2477
|
+
}
|
2478
|
+
|
2479
|
+
void ClientPromiseBasedCall::CancelWithError(grpc_error_handle error) {
|
2480
|
+
MutexLock lock(mu());
|
2481
|
+
ScopedContext context(this);
|
2482
|
+
Finish(ServerMetadataFromStatus(grpc_error_to_absl_status(error)));
|
2483
|
+
}
|
2484
|
+
|
2485
|
+
grpc_call_error ClientPromiseBasedCall::ValidateBatch(const grpc_op* ops,
|
2486
|
+
size_t nops) const {
|
2487
|
+
BitSet<8> got_ops;
|
2488
|
+
for (size_t op_idx = 0; op_idx < nops; op_idx++) {
|
2489
|
+
const grpc_op& op = ops[op_idx];
|
2490
|
+
switch (op.op) {
|
2491
|
+
case GRPC_OP_SEND_INITIAL_METADATA:
|
2492
|
+
if (!AreInitialMetadataFlagsValid(op.flags)) {
|
2493
|
+
return GRPC_CALL_ERROR_INVALID_FLAGS;
|
2494
|
+
}
|
2495
|
+
if (!ValidateMetadata(op.data.send_initial_metadata.count,
|
2496
|
+
op.data.send_initial_metadata.metadata)) {
|
2497
|
+
return GRPC_CALL_ERROR_INVALID_METADATA;
|
2498
|
+
}
|
2499
|
+
break;
|
2500
|
+
case GRPC_OP_SEND_MESSAGE:
|
2501
|
+
if (!AreWriteFlagsValid(op.flags)) {
|
2502
|
+
return GRPC_CALL_ERROR_INVALID_FLAGS;
|
2503
|
+
}
|
2504
|
+
break;
|
2505
|
+
case GRPC_OP_RECV_INITIAL_METADATA:
|
2506
|
+
case GRPC_OP_RECV_MESSAGE:
|
2507
|
+
case GRPC_OP_SEND_CLOSE_FROM_CLIENT:
|
2508
|
+
case GRPC_OP_RECV_STATUS_ON_CLIENT:
|
2509
|
+
if (op.flags != 0) return GRPC_CALL_ERROR_INVALID_FLAGS;
|
2510
|
+
break;
|
2511
|
+
case GRPC_OP_RECV_CLOSE_ON_SERVER:
|
2512
|
+
case GRPC_OP_SEND_STATUS_FROM_SERVER:
|
2513
|
+
return GRPC_CALL_ERROR_NOT_ON_CLIENT;
|
2514
|
+
}
|
2515
|
+
if (got_ops.is_set(op.op)) return GRPC_CALL_ERROR_TOO_MANY_OPERATIONS;
|
2516
|
+
got_ops.set(op.op);
|
2517
|
+
}
|
2518
|
+
return GRPC_CALL_OK;
|
2519
|
+
}
|
2520
|
+
|
2521
|
+
void ClientPromiseBasedCall::CommitBatch(const grpc_op* ops, size_t nops,
|
2522
|
+
const Completion& completion) {
|
2523
|
+
for (size_t op_idx = 0; op_idx < nops; op_idx++) {
|
2524
|
+
const grpc_op& op = ops[op_idx];
|
2525
|
+
switch (op.op) {
|
2526
|
+
case GRPC_OP_SEND_INITIAL_METADATA: {
|
2527
|
+
// compression not implemented
|
2528
|
+
GPR_ASSERT(
|
2529
|
+
!op.data.send_initial_metadata.maybe_compression_level.is_set);
|
2530
|
+
if (!completed_) {
|
2531
|
+
CToMetadata(op.data.send_initial_metadata.metadata,
|
2532
|
+
op.data.send_initial_metadata.count,
|
2533
|
+
send_initial_metadata_.get());
|
2534
|
+
StartPromise(std::move(send_initial_metadata_));
|
2535
|
+
}
|
2536
|
+
} break;
|
2537
|
+
case GRPC_OP_RECV_INITIAL_METADATA: {
|
2538
|
+
recv_initial_metadata_ =
|
2539
|
+
op.data.recv_initial_metadata.recv_initial_metadata;
|
2540
|
+
server_initial_metadata_ready_ = server_initial_metadata_.Wait();
|
2541
|
+
recv_initial_metadata_completion_ =
|
2542
|
+
AddOpToCompletion(completion, PendingOp::kReceiveInitialMetadata);
|
2543
|
+
} break;
|
2544
|
+
case GRPC_OP_RECV_STATUS_ON_CLIENT: {
|
2545
|
+
recv_status_on_client_completion_ =
|
2546
|
+
AddOpToCompletion(completion, PendingOp::kReceiveStatusOnClient);
|
2547
|
+
if (auto* finished_metadata =
|
2548
|
+
absl::get_if<ServerMetadataHandle>(&recv_status_on_client_)) {
|
2549
|
+
PublishStatus(op.data.recv_status_on_client,
|
2550
|
+
std::move(*finished_metadata));
|
2551
|
+
} else {
|
2552
|
+
recv_status_on_client_ = op.data.recv_status_on_client;
|
2553
|
+
}
|
2554
|
+
} break;
|
2555
|
+
case GRPC_OP_SEND_MESSAGE: {
|
2556
|
+
GPR_ASSERT(!outstanding_send_.has_value());
|
2557
|
+
if (!completed_) {
|
2558
|
+
send_message_completion_ =
|
2559
|
+
AddOpToCompletion(completion, PendingOp::kSendMessage);
|
2560
|
+
SliceBuffer send;
|
2561
|
+
grpc_slice_buffer_swap(
|
2562
|
+
&op.data.send_message.send_message->data.raw.slice_buffer,
|
2563
|
+
send.c_slice_buffer());
|
2564
|
+
outstanding_send_.emplace(client_to_server_messages_.sender.Push(
|
2565
|
+
GetContext<Arena>()->MakePooled<Message>(std::move(send),
|
2566
|
+
op.flags)));
|
2567
|
+
} else {
|
2568
|
+
FailCompletion(completion);
|
2569
|
+
}
|
2570
|
+
} break;
|
2571
|
+
case GRPC_OP_RECV_MESSAGE: {
|
2572
|
+
GPR_ASSERT(!outstanding_recv_.has_value());
|
2573
|
+
recv_message_ = op.data.recv_message.recv_message;
|
2574
|
+
recv_message_completion_ =
|
2575
|
+
AddOpToCompletion(completion, PendingOp::kReceiveMessage);
|
2576
|
+
outstanding_recv_.emplace(server_to_client_messages_.receiver.Next());
|
2577
|
+
} break;
|
2578
|
+
case GRPC_OP_SEND_CLOSE_FROM_CLIENT: {
|
2579
|
+
client_to_server_messages_.sender.Close();
|
2580
|
+
} break;
|
2581
|
+
case GRPC_OP_SEND_STATUS_FROM_SERVER:
|
2582
|
+
case GRPC_OP_RECV_CLOSE_ON_SERVER:
|
2583
|
+
abort(); // unreachable
|
2584
|
+
}
|
2585
|
+
}
|
2586
|
+
}
|
2587
|
+
|
2588
|
+
grpc_call_error ClientPromiseBasedCall::StartBatch(const grpc_op* ops,
|
2589
|
+
size_t nops,
|
2590
|
+
void* notify_tag,
|
2591
|
+
bool is_notify_tag_closure) {
|
2592
|
+
MutexLock lock(mu());
|
2593
|
+
ScopedContext activity_context(this);
|
2594
|
+
if (nops == 0) {
|
2595
|
+
EndOpImmediately(cq(), notify_tag, is_notify_tag_closure);
|
2596
|
+
return GRPC_CALL_OK;
|
2597
|
+
}
|
2598
|
+
const grpc_call_error validation_result = ValidateBatch(ops, nops);
|
2599
|
+
if (validation_result != GRPC_CALL_OK) {
|
2600
|
+
return validation_result;
|
2601
|
+
}
|
2602
|
+
Completion completion =
|
2603
|
+
StartCompletion(notify_tag, is_notify_tag_closure, ops);
|
2604
|
+
CommitBatch(ops, nops, completion);
|
2605
|
+
Update();
|
2606
|
+
FinishOpOnCompletion(&completion, PendingOp::kStartingBatch);
|
2607
|
+
return GRPC_CALL_OK;
|
2608
|
+
}
|
2609
|
+
|
2610
|
+
void ClientPromiseBasedCall::PublishInitialMetadata(ServerMetadata* metadata) {
|
2611
|
+
incoming_compression_algorithm_ =
|
2612
|
+
metadata->Take(GrpcEncodingMetadata()).value_or(GRPC_COMPRESS_NONE);
|
2613
|
+
server_initial_metadata_ready_.reset();
|
2614
|
+
GPR_ASSERT(recv_initial_metadata_ != nullptr);
|
2615
|
+
PublishMetadataArray(std::exchange(recv_initial_metadata_, nullptr),
|
2616
|
+
metadata);
|
2617
|
+
FinishOpOnCompletion(&recv_initial_metadata_completion_,
|
2618
|
+
PendingOp::kReceiveInitialMetadata);
|
2619
|
+
}
|
2620
|
+
|
2621
|
+
void ClientPromiseBasedCall::UpdateOnce() {
|
2622
|
+
if (grpc_call_trace.enabled()) {
|
2623
|
+
auto present_and_completion_text =
|
2624
|
+
[](const char* caption, bool has,
|
2625
|
+
const Completion& completion) -> std::string {
|
2626
|
+
if (has) {
|
2627
|
+
if (completion.has_value()) {
|
2628
|
+
return absl::StrCat(caption, ":",
|
2629
|
+
static_cast<int>(completion.index()), " ");
|
2630
|
+
} else {
|
2631
|
+
return absl::StrCat(caption,
|
2632
|
+
":!!BUG:operation is present, no completion!! ");
|
2633
|
+
}
|
2634
|
+
} else {
|
2635
|
+
if (!completion.has_value()) {
|
2636
|
+
return "";
|
2637
|
+
} else {
|
2638
|
+
return absl::StrCat(
|
2639
|
+
caption, ":no-op:", static_cast<int>(completion.index()), " ");
|
2640
|
+
}
|
2641
|
+
}
|
2642
|
+
};
|
2643
|
+
gpr_log(
|
2644
|
+
GPR_INFO, "%sUpdateOnce: %s%s%shas_promise=%s", DebugTag().c_str(),
|
2645
|
+
present_and_completion_text("server_initial_metadata_ready",
|
2646
|
+
server_initial_metadata_ready_.has_value(),
|
2647
|
+
recv_initial_metadata_completion_)
|
2648
|
+
.c_str(),
|
2649
|
+
present_and_completion_text("outstanding_send",
|
2650
|
+
outstanding_send_.has_value(),
|
2651
|
+
send_message_completion_)
|
2652
|
+
.c_str(),
|
2653
|
+
present_and_completion_text("outstanding_recv",
|
2654
|
+
outstanding_recv_.has_value(),
|
2655
|
+
recv_message_completion_)
|
2656
|
+
.c_str(),
|
2657
|
+
promise_.has_value() ? "true" : "false");
|
2658
|
+
}
|
2659
|
+
if (send_message_completion_.has_value()) {
|
2660
|
+
FinishOpOnCompletion(&send_message_completion_, PendingOp::kSendMessage);
|
2661
|
+
}
|
2662
|
+
if (server_initial_metadata_ready_.has_value()) {
|
2663
|
+
Poll<ServerMetadata**> r = (*server_initial_metadata_ready_)();
|
2664
|
+
if (ServerMetadata*** server_initial_metadata =
|
2665
|
+
absl::get_if<ServerMetadata**>(&r)) {
|
2666
|
+
PublishInitialMetadata(**server_initial_metadata);
|
2667
|
+
} else if (completed_) {
|
2668
|
+
ServerMetadata no_metadata{GetContext<Arena>()};
|
2669
|
+
PublishInitialMetadata(&no_metadata);
|
2670
|
+
}
|
2671
|
+
}
|
2672
|
+
if (outstanding_send_.has_value()) {
|
2673
|
+
Poll<bool> r = (*outstanding_send_)();
|
2674
|
+
if (const bool* result = absl::get_if<bool>(&r)) {
|
2675
|
+
outstanding_send_.reset();
|
2676
|
+
if (!*result) {
|
2677
|
+
FailCompletion(send_message_completion_);
|
2678
|
+
Finish(ServerMetadataFromStatus(absl::Status(
|
2679
|
+
absl::StatusCode::kInternal, "Failed to send message to server")));
|
2680
|
+
}
|
2681
|
+
}
|
2682
|
+
}
|
2683
|
+
if (promise_.has_value()) {
|
2684
|
+
Poll<ServerMetadataHandle> r = promise_();
|
2685
|
+
if (grpc_call_trace.enabled()) {
|
2686
|
+
gpr_log(GPR_INFO, "%sUpdateOnce: promise returns %s", DebugTag().c_str(),
|
2687
|
+
PollToString(r, [](const ServerMetadataHandle& h) {
|
2688
|
+
return h->DebugString();
|
2689
|
+
}).c_str());
|
2690
|
+
}
|
2691
|
+
if (auto* result = absl::get_if<ServerMetadataHandle>(&r)) {
|
2692
|
+
AcceptTransportStatsFromContext();
|
2693
|
+
Finish(std::move(*result));
|
2694
|
+
}
|
2695
|
+
}
|
2696
|
+
if (incoming_compression_algorithm_.has_value() &&
|
2697
|
+
outstanding_recv_.has_value()) {
|
2698
|
+
Poll<NextResult<MessageHandle>> r = (*outstanding_recv_)();
|
2699
|
+
if (auto* result = absl::get_if<NextResult<MessageHandle>>(&r)) {
|
2700
|
+
outstanding_recv_.reset();
|
2701
|
+
if (result->has_value()) {
|
2702
|
+
MessageHandle& message = **result;
|
2703
|
+
if ((message->flags() & GRPC_WRITE_INTERNAL_COMPRESS) &&
|
2704
|
+
(incoming_compression_algorithm_ != GRPC_COMPRESS_NONE)) {
|
2705
|
+
*recv_message_ = grpc_raw_compressed_byte_buffer_create(
|
2706
|
+
nullptr, 0, *incoming_compression_algorithm_);
|
2707
|
+
} else {
|
2708
|
+
*recv_message_ = grpc_raw_byte_buffer_create(nullptr, 0);
|
2709
|
+
}
|
2710
|
+
grpc_slice_buffer_move_into(message->payload()->c_slice_buffer(),
|
2711
|
+
&(*recv_message_)->data.raw.slice_buffer);
|
2712
|
+
if (grpc_call_trace.enabled()) {
|
2713
|
+
gpr_log(GPR_INFO,
|
2714
|
+
"%sUpdateOnce: outstanding_recv finishes: received %" PRIdPTR
|
2715
|
+
" byte message",
|
2716
|
+
DebugTag().c_str(),
|
2717
|
+
(*recv_message_)->data.raw.slice_buffer.length);
|
2718
|
+
}
|
2719
|
+
} else {
|
2720
|
+
if (grpc_call_trace.enabled()) {
|
2721
|
+
gpr_log(
|
2722
|
+
GPR_INFO,
|
2723
|
+
"%sUpdateOnce: outstanding_recv finishes: received end-of-stream",
|
2724
|
+
DebugTag().c_str());
|
2725
|
+
}
|
2726
|
+
*recv_message_ = nullptr;
|
2727
|
+
}
|
2728
|
+
FinishOpOnCompletion(&recv_message_completion_,
|
2729
|
+
PendingOp::kReceiveMessage);
|
2730
|
+
} else if (completed_) {
|
2731
|
+
if (grpc_call_trace.enabled()) {
|
2732
|
+
gpr_log(GPR_INFO,
|
2733
|
+
"%sUpdateOnce: outstanding_recv finishes: promise has "
|
2734
|
+
"completed without queuing a message, forcing end-of-stream",
|
2735
|
+
DebugTag().c_str());
|
2736
|
+
}
|
2737
|
+
outstanding_recv_.reset();
|
2738
|
+
*recv_message_ = nullptr;
|
2739
|
+
FinishOpOnCompletion(&recv_message_completion_,
|
2740
|
+
PendingOp::kReceiveMessage);
|
2741
|
+
}
|
2742
|
+
}
|
2743
|
+
}
|
2744
|
+
|
2745
|
+
void ClientPromiseBasedCall::Finish(ServerMetadataHandle trailing_metadata) {
|
2746
|
+
if (grpc_call_trace.enabled()) {
|
2747
|
+
gpr_log(GPR_INFO, "%sFinish: %s", DebugTag().c_str(),
|
2748
|
+
trailing_metadata->DebugString().c_str());
|
2749
|
+
}
|
2750
|
+
promise_ = ArenaPromise<ServerMetadataHandle>();
|
2751
|
+
completed_ = true;
|
2752
|
+
if (recv_initial_metadata_ != nullptr) {
|
2753
|
+
ForceImmediateRepoll();
|
2754
|
+
}
|
2755
|
+
const bool pending_initial_metadata =
|
2756
|
+
server_initial_metadata_ready_.has_value();
|
2757
|
+
server_initial_metadata_ready_.reset();
|
2758
|
+
Poll<ServerMetadata**> r = server_initial_metadata_.Wait()();
|
2759
|
+
if (auto* result = absl::get_if<ServerMetadata**>(&r)) {
|
2760
|
+
if (pending_initial_metadata) PublishInitialMetadata(**result);
|
2761
|
+
is_trailers_only_ = false;
|
2762
|
+
} else {
|
2763
|
+
if (pending_initial_metadata) {
|
2764
|
+
ServerMetadata no_metadata{GetContext<Arena>()};
|
2765
|
+
PublishInitialMetadata(&no_metadata);
|
2766
|
+
}
|
2767
|
+
is_trailers_only_ = true;
|
2768
|
+
}
|
2769
|
+
if (auto* channelz_channel = channel()->channelz_node()) {
|
2770
|
+
if (trailing_metadata->get(GrpcStatusMetadata())
|
2771
|
+
.value_or(GRPC_STATUS_UNKNOWN) == GRPC_STATUS_OK) {
|
2772
|
+
channelz_channel->RecordCallSucceeded();
|
2773
|
+
} else {
|
2774
|
+
channelz_channel->RecordCallFailed();
|
2775
|
+
}
|
2776
|
+
}
|
2777
|
+
if (auto* status_request =
|
2778
|
+
absl::get_if<grpc_op::grpc_op_data::grpc_op_recv_status_on_client>(
|
2779
|
+
&recv_status_on_client_)) {
|
2780
|
+
PublishStatus(*status_request, std::move(trailing_metadata));
|
2781
|
+
} else {
|
2782
|
+
recv_status_on_client_ = std::move(trailing_metadata);
|
2783
|
+
}
|
2784
|
+
}
|
2785
|
+
|
2786
|
+
namespace {
|
2787
|
+
std::string MakeErrorString(const ServerMetadata* trailing_metadata) {
|
2788
|
+
std::string out = absl::StrCat(
|
2789
|
+
trailing_metadata->get(GrpcStatusFromWire()).value_or(false)
|
2790
|
+
? "Error received from peer"
|
2791
|
+
: "Error generated by client",
|
2792
|
+
"grpc_status: ",
|
2793
|
+
grpc_status_code_to_string(trailing_metadata->get(GrpcStatusMetadata())
|
2794
|
+
.value_or(GRPC_STATUS_UNKNOWN)));
|
2795
|
+
if (const Slice* message =
|
2796
|
+
trailing_metadata->get_pointer(GrpcMessageMetadata())) {
|
2797
|
+
absl::StrAppend(&out, "\ngrpc_message: ", message->as_string_view());
|
2798
|
+
}
|
2799
|
+
if (auto annotations = trailing_metadata->get_pointer(GrpcStatusContext())) {
|
2800
|
+
absl::StrAppend(&out, "\nStatus Context:");
|
2801
|
+
for (const std::string& annotation : *annotations) {
|
2802
|
+
absl::StrAppend(&out, "\n ", annotation);
|
2803
|
+
}
|
2804
|
+
}
|
2805
|
+
return out;
|
2806
|
+
}
|
2807
|
+
} // namespace
|
2808
|
+
|
2809
|
+
void ClientPromiseBasedCall::PublishStatus(
|
2810
|
+
grpc_op::grpc_op_data::grpc_op_recv_status_on_client op_args,
|
2811
|
+
ServerMetadataHandle trailing_metadata) {
|
2812
|
+
const grpc_status_code status = trailing_metadata->get(GrpcStatusMetadata())
|
2813
|
+
.value_or(GRPC_STATUS_UNKNOWN);
|
2814
|
+
*op_args.status = status;
|
2815
|
+
absl::string_view message_string;
|
2816
|
+
if (Slice* message = trailing_metadata->get_pointer(GrpcMessageMetadata())) {
|
2817
|
+
message_string = message->as_string_view();
|
2818
|
+
*op_args.status_details = message->Ref().TakeCSlice();
|
2819
|
+
} else {
|
2820
|
+
*op_args.status_details = grpc_empty_slice();
|
2821
|
+
}
|
2822
|
+
if (message_string.empty()) {
|
2823
|
+
RunFinalization(status, nullptr);
|
2824
|
+
} else {
|
2825
|
+
std::string error_string(message_string);
|
2826
|
+
RunFinalization(status, error_string.c_str());
|
2827
|
+
}
|
2828
|
+
if (op_args.error_string != nullptr && status != GRPC_STATUS_OK) {
|
2829
|
+
*op_args.error_string =
|
2830
|
+
gpr_strdup(MakeErrorString(trailing_metadata.get()).c_str());
|
2831
|
+
}
|
2832
|
+
PublishMetadataArray(op_args.trailing_metadata, trailing_metadata.get());
|
2833
|
+
FinishOpOnCompletion(&recv_status_on_client_completion_,
|
2834
|
+
PendingOp::kReceiveStatusOnClient);
|
2835
|
+
}
|
2836
|
+
|
2837
|
+
void ClientPromiseBasedCall::PublishMetadataArray(grpc_metadata_array* array,
|
2838
|
+
ServerMetadata* md) {
|
2839
|
+
const auto md_count = md->count();
|
2840
|
+
if (md_count > array->capacity) {
|
2841
|
+
array->capacity =
|
2842
|
+
std::max(array->capacity + md->count(), array->capacity * 3 / 2);
|
2843
|
+
array->metadata = static_cast<grpc_metadata*>(
|
2844
|
+
gpr_realloc(array->metadata, sizeof(grpc_metadata) * array->capacity));
|
2845
|
+
}
|
2846
|
+
PublishToAppEncoder encoder(array);
|
2847
|
+
md->Encode(&encoder);
|
2848
|
+
}
|
2849
|
+
|
2850
|
+
bool ClientPromiseBasedCall::Completed() {
|
2851
|
+
MutexLock lock(mu());
|
2852
|
+
return completed_;
|
2853
|
+
}
|
2854
|
+
|
2855
|
+
gpr_atm* CallContext::peer_string_atm_ptr() {
|
2856
|
+
return call_->peer_string_atm_ptr();
|
2857
|
+
}
|
2858
|
+
|
1743
2859
|
} // namespace grpc_core
|
1744
2860
|
|
2861
|
+
///////////////////////////////////////////////////////////////////////////////
|
2862
|
+
// C-based API
|
2863
|
+
|
1745
2864
|
void* grpc_call_arena_alloc(grpc_call* call, size_t size) {
|
1746
2865
|
grpc_core::ExecCtx exec_ctx;
|
1747
2866
|
return grpc_core::Call::FromC(call)->arena()->Alloc(size);
|
@@ -1753,6 +2872,13 @@ size_t grpc_call_get_initial_size_estimate() {
|
|
1753
2872
|
|
1754
2873
|
grpc_error_handle grpc_call_create(grpc_call_create_args* args,
|
1755
2874
|
grpc_call** out_call) {
|
2875
|
+
if (grpc_core::IsPromiseBasedClientCallEnabled() &&
|
2876
|
+
args->channel->is_promising()) {
|
2877
|
+
if (args->server_transport_data == nullptr) {
|
2878
|
+
return grpc_core::MakePromiseBasedCall<grpc_core::ClientPromiseBasedCall>(
|
2879
|
+
args, out_call);
|
2880
|
+
}
|
2881
|
+
}
|
1756
2882
|
return grpc_core::FilterStackCall::Create(args, out_call);
|
1757
2883
|
}
|
1758
2884
|
|
@@ -1764,6 +2890,7 @@ void grpc_call_set_completion_queue(grpc_call* call,
|
|
1764
2890
|
void grpc_call_ref(grpc_call* c) { grpc_core::Call::FromC(c)->ExternalRef(); }
|
1765
2891
|
|
1766
2892
|
void grpc_call_unref(grpc_call* c) {
|
2893
|
+
grpc_core::ExecCtx exec_ctx;
|
1767
2894
|
grpc_core::Call::FromC(c)->ExternalUnref();
|
1768
2895
|
}
|
1769
2896
|
|
@@ -1780,7 +2907,7 @@ grpc_call_error grpc_call_cancel(grpc_call* call, void* reserved) {
|
|
1780
2907
|
GPR_ASSERT(reserved == nullptr);
|
1781
2908
|
grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
|
1782
2909
|
grpc_core::ExecCtx exec_ctx;
|
1783
|
-
grpc_core::Call::FromC(call)->CancelWithError(
|
2910
|
+
grpc_core::Call::FromC(call)->CancelWithError(absl::CancelledError());
|
1784
2911
|
return GRPC_CALL_OK;
|
1785
2912
|
}
|
1786
2913
|
|
@@ -1800,7 +2927,7 @@ grpc_call_error grpc_call_cancel_with_status(grpc_call* c,
|
|
1800
2927
|
}
|
1801
2928
|
|
1802
2929
|
void grpc_call_cancel_internal(grpc_call* call) {
|
1803
|
-
grpc_core::Call::FromC(call)->CancelWithError(
|
2930
|
+
grpc_core::Call::FromC(call)->CancelWithError(absl::CancelledError());
|
1804
2931
|
}
|
1805
2932
|
|
1806
2933
|
grpc_compression_algorithm grpc_call_test_only_get_compression_algorithm(
|