Compare commits

...

13 Commits

Author SHA1 Message Date
Hannah Shi 52d0c6c326
Merge release 1.73.x to main (#336)
* remove cronet files

* remove cronet files

* Sync c-core 1.72.0-pre1

* use c++17 for swift package

* update ios deployment target to 15.0

* Sync c-core 1.72.0

* Sync c-core 1.73.0-pre1

* include additional files

* Re-sync c-core 1.73.0-pre1

* exclude inc files from swift package

* upgrade abseil swift to 0.20250127.1 (#330)

* Sync c-core 1.73.0-pre2

* Sync c-core 1.73.0

* Sync c-core 1.73.1
2025-07-12 16:19:13 -07:00
Hannah Shi d88573fd5f
Merge from 1.73.x (#329)
* remove cronet files

* remove cronet files

* Sync c-core 1.72.0-pre1

* use c++17 for swift package

* update ios deployment target to 15.0

* Sync c-core 1.72.0

* Sync c-core 1.73.0-pre1

* include additional files

* Re-sync c-core 1.73.0-pre1

* exclude inc files from swift package
2025-05-24 11:39:33 -07:00
Hannah Shi e584a88115 Re-sync c-core 1.73.0-pre1 2025-05-24 09:40:48 -07:00
Hannah Shi 96ddc18603 include additional files 2025-05-24 09:40:48 -07:00
Hannah Shi fcb8b99697 Sync c-core 1.73.0-pre1 2025-05-24 09:40:48 -07:00
Hannah Shi 9849f527f0 Sync c-core 1.72.0 2025-05-24 09:40:48 -07:00
Hannah Shi 30bd3c9d49 Sync c-core 1.72.0-pre1 2025-05-24 09:40:48 -07:00
Hannah Shi 78593d170e update ios deployment target to 15.0 2025-04-24 18:00:28 -07:00
Hannah Shi c92e41c10b use c++17 for swift package 2025-04-23 13:32:00 -07:00
Hannah Shi b641ac3789 remove cronet files 2025-04-09 15:51:16 -07:00
Hannah Shi 5c9cda2cf6 remove cronet files 2025-04-09 15:51:16 -07:00
Hannah Shi 6797fe4c02 update github workflow to use macos-14 2025-04-09 14:34:57 -07:00
dennycd 263faa1c99 Native source sync at revision @474418c 2025-04-09 10:40:34 -07:00
1370 changed files with 59564 additions and 40904 deletions

View File

@ -23,7 +23,7 @@ env:
jobs:
release-cocoapod:
runs-on: macos-12
runs-on: macos-14
steps:
- name: Repo checkout
uses: actions/checkout@v3

View File

@ -24,7 +24,7 @@ let package = Package(
],
dependencies: [
.package(url: "https://github.com/firebase/abseil-cpp-SwiftPM.git", "0.20240722.0"..<"0.20240723.0"),
.package(url: "https://github.com/firebase/abseil-cpp-SwiftPM.git", "0.20250127.0"..<"0.20250128.0"),
.package(url: "https://github.com/firebase/boringssl-SwiftPM.git", "0.32.0"..<"0.33.0"),
],
@ -41,14 +41,13 @@ let package = Package(
"src/cpp/",
"third_party/upb/upb/port/def.inc",
"third_party/upb/upb/port/undef.inc",
"third_party/utf8_range/utf8_range_sse.inc",
"third_party/utf8_range/utf8_range_neon.inc",
"third_party/re2/LICENSE",
"third_party/utf8_range/LICENSE",
"third_party/xxhash/LICENSE",
"third_party/zlib/LICENSE",
"tests",
"include/grpc/grpc_cronet.h",
"src/core/ext/transport/cronet/",
"third_party/objective_c/Cronet/bidirectional_stream_c.h",
],
sources: [
@ -85,8 +84,8 @@ let package = Package(
path: basePath,
exclude: [
"tests",
"include/grpcpp/security/cronet_credentials.h",
"src/cpp/client/cronet_credentials.cc",
"include/grpcpp/ports_undef.inc",
"include/grpcpp/ports_def.inc",
],
sources: [
"src/cpp/",
@ -111,5 +110,5 @@ let package = Package(
),
],
cLanguageStandard: .gnu11,
cxxLanguageStandard: .cxx14
cxxLanguageStandard: .cxx17
)

View File

@ -22,7 +22,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-C++'
# TODO (mxyan): use version that match gRPC version when pod is stabilized
version = '1.70.0-dev'
version = '1.73.1'
s.version = version
s.summary = 'gRPC C++ library'
s.homepage = 'https://grpc.io'
@ -34,8 +34,8 @@ Pod::Spec.new do |s|
:tag => "v#{version}",
}
s.ios.deployment_target = '11.0'
s.osx.deployment_target = '10.14'
s.ios.deployment_target = '15.0'
s.osx.deployment_target = '11.0'
s.tvos.deployment_target = '13.0'
s.watchos.deployment_target = '6.0'
s.visionos.deployment_target = '1.0'
@ -181,6 +181,8 @@ Pod::Spec.new do |s|
'include/grpcpp/impl/status.h',
'include/grpcpp/impl/sync.h',
'include/grpcpp/passive_listener.h',
'include/grpcpp/ports_def.inc',
'include/grpcpp/ports_undef.inc',
'include/grpcpp/resource_quota.h',
'include/grpcpp/security/audit_logging.h',
'include/grpcpp/security/auth_context.h',
@ -230,7 +232,7 @@ Pod::Spec.new do |s|
ss.dependency "#{s.name}/Privacy", version
ss.dependency "#{s.name}/Interface", version
ss.dependency 'gRPC-Core', version
abseil_version = '~> 1.20240722.0'
abseil_version = '~> 1.20250127.1'
ss.dependency 'abseil/algorithm/container', abseil_version
ss.dependency 'abseil/base/base', abseil_version
ss.dependency 'abseil/base/config', abseil_version
@ -238,6 +240,7 @@ Pod::Spec.new do |s|
ss.dependency 'abseil/base/log_severity', abseil_version
ss.dependency 'abseil/base/no_destructor', abseil_version
ss.dependency 'abseil/cleanup/cleanup', abseil_version
ss.dependency 'abseil/container/btree', abseil_version
ss.dependency 'abseil/container/flat_hash_map', abseil_version
ss.dependency 'abseil/container/flat_hash_set', abseil_version
ss.dependency 'abseil/container/inlined_vector', abseil_version
@ -267,13 +270,32 @@ Pod::Spec.new do |s|
ss.dependency 'abseil/time/time', abseil_version
ss.dependency 'abseil/types/optional', abseil_version
ss.dependency 'abseil/types/span', abseil_version
ss.dependency 'abseil/types/variant', abseil_version
ss.dependency 'abseil/utility/utility', abseil_version
ss.source_files = 'src/core/call/request_buffer.h',
ss.source_files = 'src/core/call/call_arena_allocator.h',
'src/core/call/call_destination.h',
'src/core/call/call_filters.h',
'src/core/call/call_finalization.h',
'src/core/call/call_spine.h',
'src/core/call/call_state.h',
'src/core/call/client_call.h',
'src/core/call/custom_metadata.h',
'src/core/call/interception_chain.h',
'src/core/call/message.h',
'src/core/call/metadata.h',
'src/core/call/metadata_batch.h',
'src/core/call/metadata_compression_traits.h',
'src/core/call/metadata_info.h',
'src/core/call/parsed_metadata.h',
'src/core/call/request_buffer.h',
'src/core/call/security_context.h',
'src/core/call/server_call.h',
'src/core/call/simple_slice_based_metadata.h',
'src/core/call/status_util.h',
'src/core/channelz/channel_trace.h',
'src/core/channelz/channelz.h',
'src/core/channelz/channelz_registry.h',
'src/core/channelz/ztrace_collector.h',
'src/core/client_channel/backup_poller.h',
'src/core/client_channel/client_channel.h',
'src/core/client_channel/client_channel_args.h',
@ -301,6 +323,54 @@ Pod::Spec.new do |s|
'src/core/config/config_vars.h',
'src/core/config/core_configuration.h',
'src/core/config/load_config.h',
'src/core/credentials/call/call_credentials.h',
'src/core/credentials/call/call_creds_util.h',
'src/core/credentials/call/composite/composite_call_credentials.h',
'src/core/credentials/call/external/aws_external_account_credentials.h',
'src/core/credentials/call/external/aws_request_signer.h',
'src/core/credentials/call/external/external_account_credentials.h',
'src/core/credentials/call/external/file_external_account_credentials.h',
'src/core/credentials/call/external/url_external_account_credentials.h',
'src/core/credentials/call/gcp_service_account_identity/gcp_service_account_identity_credentials.h',
'src/core/credentials/call/iam/iam_credentials.h',
'src/core/credentials/call/json_util.h',
'src/core/credentials/call/jwt/json_token.h',
'src/core/credentials/call/jwt/jwt_credentials.h',
'src/core/credentials/call/jwt/jwt_verifier.h',
'src/core/credentials/call/oauth2/oauth2_credentials.h',
'src/core/credentials/call/plugin/plugin_credentials.h',
'src/core/credentials/call/token_fetcher/token_fetcher_credentials.h',
'src/core/credentials/transport/alts/alts_credentials.h',
'src/core/credentials/transport/alts/alts_security_connector.h',
'src/core/credentials/transport/alts/check_gcp_environment.h',
'src/core/credentials/transport/alts/grpc_alts_credentials_options.h',
'src/core/credentials/transport/channel_creds_registry.h',
'src/core/credentials/transport/composite/composite_channel_credentials.h',
'src/core/credentials/transport/fake/fake_credentials.h',
'src/core/credentials/transport/fake/fake_security_connector.h',
'src/core/credentials/transport/google_default/google_default_credentials.h',
'src/core/credentials/transport/insecure/insecure_credentials.h',
'src/core/credentials/transport/insecure/insecure_security_connector.h',
'src/core/credentials/transport/local/local_credentials.h',
'src/core/credentials/transport/local/local_security_connector.h',
'src/core/credentials/transport/security_connector.h',
'src/core/credentials/transport/ssl/ssl_credentials.h',
'src/core/credentials/transport/ssl/ssl_security_connector.h',
'src/core/credentials/transport/tls/certificate_provider_factory.h',
'src/core/credentials/transport/tls/certificate_provider_registry.h',
'src/core/credentials/transport/tls/grpc_tls_certificate_distributor.h',
'src/core/credentials/transport/tls/grpc_tls_certificate_provider.h',
'src/core/credentials/transport/tls/grpc_tls_certificate_verifier.h',
'src/core/credentials/transport/tls/grpc_tls_credentials_options.h',
'src/core/credentials/transport/tls/grpc_tls_crl_provider.h',
'src/core/credentials/transport/tls/load_system_roots.h',
'src/core/credentials/transport/tls/load_system_roots_supported.h',
'src/core/credentials/transport/tls/ssl_utils.h',
'src/core/credentials/transport/tls/tls_credentials.h',
'src/core/credentials/transport/tls/tls_security_connector.h',
'src/core/credentials/transport/tls/tls_utils.h',
'src/core/credentials/transport/transport_credentials.h',
'src/core/credentials/transport/xds/xds_credentials.h',
'src/core/ext/filters/backend_metrics/backend_metric_filter.h',
'src/core/ext/filters/backend_metrics/backend_metric_provider.h',
'src/core/ext/filters/channel_idle/idle_filter_state.h',
@ -325,7 +395,6 @@ Pod::Spec.new do |s|
'src/core/ext/transport/chttp2/transport/bin_encoder.h',
'src/core/ext/transport/chttp2/transport/call_tracer_wrapper.h',
'src/core/ext/transport/chttp2/transport/chttp2_transport.h',
'src/core/ext/transport/chttp2/transport/context_list_entry.h',
'src/core/ext/transport/chttp2/transport/decode_huff.h',
'src/core/ext/transport/chttp2/transport/flow_control.h',
'src/core/ext/transport/chttp2/transport/frame.h',
@ -343,8 +412,11 @@ Pod::Spec.new do |s|
'src/core/ext/transport/chttp2/transport/hpack_parser.h',
'src/core/ext/transport/chttp2/transport/hpack_parser_table.h',
'src/core/ext/transport/chttp2/transport/http2_settings.h',
'src/core/ext/transport/chttp2/transport/http2_status.h',
'src/core/ext/transport/chttp2/transport/http2_ztrace_collector.h',
'src/core/ext/transport/chttp2/transport/huffsyms.h',
'src/core/ext/transport/chttp2/transport/internal.h',
'src/core/ext/transport/chttp2/transport/internal_channel_arg_names.h',
'src/core/ext/transport/chttp2/transport/legacy_frame.h',
'src/core/ext/transport/chttp2/transport/ping_abuse_policy.h',
'src/core/ext/transport/chttp2/transport/ping_callbacks.h',
@ -538,6 +610,8 @@ Pod::Spec.new do |s|
'src/core/ext/upb-gen/envoy/type/http/v3/cookie.upb_minitable.h',
'src/core/ext/upb-gen/envoy/type/http/v3/path_transformation.upb.h',
'src/core/ext/upb-gen/envoy/type/http/v3/path_transformation.upb_minitable.h',
'src/core/ext/upb-gen/envoy/type/matcher/v3/address.upb.h',
'src/core/ext/upb-gen/envoy/type/matcher/v3/address.upb_minitable.h',
'src/core/ext/upb-gen/envoy/type/matcher/v3/filter_state.upb.h',
'src/core/ext/upb-gen/envoy/type/matcher/v3/filter_state.upb_minitable.h',
'src/core/ext/upb-gen/envoy/type/matcher/v3/http_inputs.upb.h',
@ -773,6 +847,7 @@ Pod::Spec.new do |s|
'src/core/ext/upbdefs-gen/envoy/service/status/v3/csds.upbdefs.h',
'src/core/ext/upbdefs-gen/envoy/type/http/v3/cookie.upbdefs.h',
'src/core/ext/upbdefs-gen/envoy/type/http/v3/path_transformation.upbdefs.h',
'src/core/ext/upbdefs-gen/envoy/type/matcher/v3/address.upbdefs.h',
'src/core/ext/upbdefs-gen/envoy/type/matcher/v3/filter_state.upbdefs.h',
'src/core/ext/upbdefs-gen/envoy/type/matcher/v3/http_inputs.upbdefs.h',
'src/core/ext/upbdefs-gen/envoy/type/matcher/v3/metadata.upbdefs.h',
@ -839,6 +914,7 @@ Pod::Spec.new do |s|
'src/core/ext/upbdefs-gen/xds/type/v3/cel.upbdefs.h',
'src/core/ext/upbdefs-gen/xds/type/v3/range.upbdefs.h',
'src/core/ext/upbdefs-gen/xds/type/v3/typed_struct.upbdefs.h',
'src/core/filter/auth/auth_filters.h',
'src/core/filter/blackboard.h',
'src/core/filter/filter_args.h',
'src/core/handshaker/endpoint_info/endpoint_info_handshaker.h',
@ -855,7 +931,6 @@ Pod::Spec.new do |s|
'src/core/handshaker/tcp_connect/tcp_connect_handshaker.h',
'src/core/lib/address_utils/parse_address.h',
'src/core/lib/address_utils/sockaddr_utils.h',
'src/core/lib/channel/call_finalization.h',
'src/core/lib/channel/channel_args.h',
'src/core/lib/channel/channel_args_preconditioning.h',
'src/core/lib/channel/channel_fwd.h',
@ -864,7 +939,6 @@ Pod::Spec.new do |s|
'src/core/lib/channel/channel_stack_builder_impl.h',
'src/core/lib/channel/connected_channel.h',
'src/core/lib/channel/promise_based_filter.h',
'src/core/lib/channel/status_util.h',
'src/core/lib/compression/compression_internal.h',
'src/core/lib/compression/message_compress.h',
'src/core/lib/debug/trace.h',
@ -880,9 +954,13 @@ Pod::Spec.new do |s|
'src/core/lib/event_engine/default_event_engine.h',
'src/core/lib/event_engine/default_event_engine_factory.h',
'src/core/lib/event_engine/event_engine_context.h',
'src/core/lib/event_engine/extensions/blocking_dns.h',
'src/core/lib/event_engine/extensions/can_track_errors.h',
'src/core/lib/event_engine/extensions/channelz.h',
'src/core/lib/event_engine/extensions/chaotic_good_extension.h',
'src/core/lib/event_engine/extensions/iomgr_compatible.h',
'src/core/lib/event_engine/extensions/supports_fd.h',
'src/core/lib/event_engine/extensions/supports_win_sockets.h',
'src/core/lib/event_engine/extensions/tcp_trace.h',
'src/core/lib/event_engine/forkable.h',
'src/core/lib/event_engine/grpc_polled_fd.h',
@ -956,7 +1034,6 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/event_engine_shims/endpoint.h',
'src/core/lib/iomgr/event_engine_shims/tcp_client.h',
'src/core/lib/iomgr/exec_ctx.h',
'src/core/lib/iomgr/executor.h',
'src/core/lib/iomgr/internal_errqueue.h',
'src/core/lib/iomgr/iocp_windows.h',
'src/core/lib/iomgr/iomgr.h',
@ -1045,54 +1122,6 @@ Pod::Spec.new do |s|
'src/core/lib/security/authorization/matchers.h',
'src/core/lib/security/authorization/rbac_policy.h',
'src/core/lib/security/authorization/stdout_logger.h',
'src/core/lib/security/certificate_provider/certificate_provider_factory.h',
'src/core/lib/security/certificate_provider/certificate_provider_registry.h',
'src/core/lib/security/context/security_context.h',
'src/core/lib/security/credentials/alts/alts_credentials.h',
'src/core/lib/security/credentials/alts/check_gcp_environment.h',
'src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h',
'src/core/lib/security/credentials/call_creds_util.h',
'src/core/lib/security/credentials/channel_creds_registry.h',
'src/core/lib/security/credentials/composite/composite_credentials.h',
'src/core/lib/security/credentials/credentials.h',
'src/core/lib/security/credentials/external/aws_external_account_credentials.h',
'src/core/lib/security/credentials/external/aws_request_signer.h',
'src/core/lib/security/credentials/external/external_account_credentials.h',
'src/core/lib/security/credentials/external/file_external_account_credentials.h',
'src/core/lib/security/credentials/external/url_external_account_credentials.h',
'src/core/lib/security/credentials/fake/fake_credentials.h',
'src/core/lib/security/credentials/gcp_service_account_identity/gcp_service_account_identity_credentials.h',
'src/core/lib/security/credentials/google_default/google_default_credentials.h',
'src/core/lib/security/credentials/iam/iam_credentials.h',
'src/core/lib/security/credentials/insecure/insecure_credentials.h',
'src/core/lib/security/credentials/jwt/json_token.h',
'src/core/lib/security/credentials/jwt/jwt_credentials.h',
'src/core/lib/security/credentials/jwt/jwt_verifier.h',
'src/core/lib/security/credentials/local/local_credentials.h',
'src/core/lib/security/credentials/oauth2/oauth2_credentials.h',
'src/core/lib/security/credentials/plugin/plugin_credentials.h',
'src/core/lib/security/credentials/ssl/ssl_credentials.h',
'src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.h',
'src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h',
'src/core/lib/security/credentials/tls/grpc_tls_certificate_verifier.h',
'src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h',
'src/core/lib/security/credentials/tls/grpc_tls_crl_provider.h',
'src/core/lib/security/credentials/tls/tls_credentials.h',
'src/core/lib/security/credentials/tls/tls_utils.h',
'src/core/lib/security/credentials/token_fetcher/token_fetcher_credentials.h',
'src/core/lib/security/credentials/xds/xds_credentials.h',
'src/core/lib/security/security_connector/alts/alts_security_connector.h',
'src/core/lib/security/security_connector/fake/fake_security_connector.h',
'src/core/lib/security/security_connector/insecure/insecure_security_connector.h',
'src/core/lib/security/security_connector/load_system_roots.h',
'src/core/lib/security/security_connector/load_system_roots_supported.h',
'src/core/lib/security/security_connector/local/local_security_connector.h',
'src/core/lib/security/security_connector/security_connector.h',
'src/core/lib/security/security_connector/ssl/ssl_security_connector.h',
'src/core/lib/security/security_connector/ssl_utils.h',
'src/core/lib/security/security_connector/tls/tls_security_connector.h',
'src/core/lib/security/transport/auth_filters.h',
'src/core/lib/security/util/json_util.h',
'src/core/lib/slice/percent_encoding.h',
'src/core/lib/slice/slice.h',
'src/core/lib/slice/slice_buffer.h',
@ -1106,7 +1135,6 @@ Pod::Spec.new do |s|
'src/core/lib/surface/channel_create.h',
'src/core/lib/surface/channel_init.h',
'src/core/lib/surface/channel_stack_type.h',
'src/core/lib/surface/client_call.h',
'src/core/lib/surface/completion_queue.h',
'src/core/lib/surface/completion_queue_factory.h',
'src/core/lib/surface/connection_context.h',
@ -1116,27 +1144,11 @@ Pod::Spec.new do |s|
'src/core/lib/surface/init_internally.h',
'src/core/lib/surface/lame_client.h',
'src/core/lib/surface/legacy_channel.h',
'src/core/lib/surface/server_call.h',
'src/core/lib/surface/validate_metadata.h',
'src/core/lib/transport/bdp_estimator.h',
'src/core/lib/transport/call_arena_allocator.h',
'src/core/lib/transport/call_destination.h',
'src/core/lib/transport/call_filters.h',
'src/core/lib/transport/call_final_info.h',
'src/core/lib/transport/call_spine.h',
'src/core/lib/transport/call_state.h',
'src/core/lib/transport/connectivity_state.h',
'src/core/lib/transport/custom_metadata.h',
'src/core/lib/transport/error_utils.h',
'src/core/lib/transport/http2_errors.h',
'src/core/lib/transport/interception_chain.h',
'src/core/lib/transport/message.h',
'src/core/lib/transport/metadata.h',
'src/core/lib/transport/metadata_batch.h',
'src/core/lib/transport/metadata_compression_traits.h',
'src/core/lib/transport/metadata_info.h',
'src/core/lib/transport/parsed_metadata.h',
'src/core/lib/transport/simple_slice_based_metadata.h',
'src/core/lib/transport/status_conversion.h',
'src/core/lib/transport/timeout_encoding.h',
'src/core/lib/transport/transport.h',
@ -1197,11 +1209,16 @@ Pod::Spec.new do |s|
'src/core/service_config/service_config_impl.h',
'src/core/service_config/service_config_parser.h',
'src/core/telemetry/call_tracer.h',
'src/core/telemetry/context_list_entry.h',
'src/core/telemetry/default_tcp_tracer.h',
'src/core/telemetry/histogram_view.h',
'src/core/telemetry/metrics.h',
'src/core/telemetry/stats.h',
'src/core/telemetry/stats_data.h',
'src/core/telemetry/tcp_tracer.h',
'src/core/transport/auth_context.h',
'src/core/transport/endpoint_transport.h',
'src/core/transport/endpoint_transport_client_channel_factory.h',
'src/core/tsi/alts/crypt/gsec.h',
'src/core/tsi/alts/frame_protector/alts_counter.h',
'src/core/tsi/alts/frame_protector/alts_crypter.h',
@ -1236,6 +1253,7 @@ Pod::Spec.new do |s|
'src/core/util/avl.h',
'src/core/util/backoff.h',
'src/core/util/bitset.h',
'src/core/util/check_class_size.h',
'src/core/util/chunked_vector.h',
'src/core/util/construct_destruct.h',
'src/core/util/cpp_impl_of.h',
@ -1249,6 +1267,7 @@ Pod::Spec.new do |s|
'src/core/util/event_log.h',
'src/core/util/examine_stack.h',
'src/core/util/fork.h',
'src/core/util/function_signature.h',
'src/core/util/gcp_metadata_query.h',
'src/core/util/gethostname.h',
'src/core/util/glob.h',
@ -1285,6 +1304,7 @@ Pod::Spec.new do |s|
'src/core/util/ref_counted_ptr.h',
'src/core/util/ref_counted_string.h',
'src/core/util/ring_buffer.h',
'src/core/util/shared_bit_gen.h',
'src/core/util/single_set_ptr.h',
'src/core/util/sorted_pack.h',
'src/core/util/spinlock.h',
@ -1309,6 +1329,7 @@ Pod::Spec.new do |s|
'src/core/util/useful.h',
'src/core/util/uuid_v4.h',
'src/core/util/validation_errors.h',
'src/core/util/wait_for_single_owner.h',
'src/core/util/work_serializer.h',
'src/core/util/xxhash_inline.h',
'src/core/xds/grpc/certificate_provider_store.h',
@ -1341,6 +1362,7 @@ Pod::Spec.new do |s|
'src/core/xds/grpc/xds_route_config_parser.h',
'src/core/xds/grpc/xds_routing.h',
'src/core/xds/grpc/xds_server_grpc.h',
'src/core/xds/grpc/xds_server_grpc_interface.h',
'src/core/xds/grpc/xds_transport_grpc.h',
'src/core/xds/xds_client/lrs_client.h',
'src/core/xds/xds_client/xds_api.h',
@ -1464,8 +1486,8 @@ Pod::Spec.new do |s|
'third_party/upb/upb/message/copy.h',
'third_party/upb/upb/message/internal/accessors.h',
'third_party/upb/upb/message/internal/array.h',
'third_party/upb/upb/message/internal/compare_unknown.h',
'third_party/upb/upb/message/internal/extension.h',
'third_party/upb/upb/message/internal/iterator.h',
'third_party/upb/upb/message/internal/map.h',
'third_party/upb/upb/message/internal/map_entry.h',
'third_party/upb/upb/message/internal/map_sorter.h',
@ -1553,6 +1575,8 @@ Pod::Spec.new do |s|
'third_party/upb/upb/wire/reader.h',
'third_party/upb/upb/wire/types.h',
'third_party/utf8_range/utf8_range.h',
'third_party/utf8_range/utf8_range_neon.inc',
'third_party/utf8_range/utf8_range_sse.inc',
'third_party/xxhash/xxhash.h',
'third_party/zlib/crc32.h',
'third_party/zlib/deflate.h',
@ -1566,10 +1590,30 @@ Pod::Spec.new do |s|
'third_party/zlib/zlib.h',
'third_party/zlib/zutil.h'
ss.private_header_files = 'src/core/call/request_buffer.h',
ss.private_header_files = 'src/core/call/call_arena_allocator.h',
'src/core/call/call_destination.h',
'src/core/call/call_filters.h',
'src/core/call/call_finalization.h',
'src/core/call/call_spine.h',
'src/core/call/call_state.h',
'src/core/call/client_call.h',
'src/core/call/custom_metadata.h',
'src/core/call/interception_chain.h',
'src/core/call/message.h',
'src/core/call/metadata.h',
'src/core/call/metadata_batch.h',
'src/core/call/metadata_compression_traits.h',
'src/core/call/metadata_info.h',
'src/core/call/parsed_metadata.h',
'src/core/call/request_buffer.h',
'src/core/call/security_context.h',
'src/core/call/server_call.h',
'src/core/call/simple_slice_based_metadata.h',
'src/core/call/status_util.h',
'src/core/channelz/channel_trace.h',
'src/core/channelz/channelz.h',
'src/core/channelz/channelz_registry.h',
'src/core/channelz/ztrace_collector.h',
'src/core/client_channel/backup_poller.h',
'src/core/client_channel/client_channel.h',
'src/core/client_channel/client_channel_args.h',
@ -1597,6 +1641,54 @@ Pod::Spec.new do |s|
'src/core/config/config_vars.h',
'src/core/config/core_configuration.h',
'src/core/config/load_config.h',
'src/core/credentials/call/call_credentials.h',
'src/core/credentials/call/call_creds_util.h',
'src/core/credentials/call/composite/composite_call_credentials.h',
'src/core/credentials/call/external/aws_external_account_credentials.h',
'src/core/credentials/call/external/aws_request_signer.h',
'src/core/credentials/call/external/external_account_credentials.h',
'src/core/credentials/call/external/file_external_account_credentials.h',
'src/core/credentials/call/external/url_external_account_credentials.h',
'src/core/credentials/call/gcp_service_account_identity/gcp_service_account_identity_credentials.h',
'src/core/credentials/call/iam/iam_credentials.h',
'src/core/credentials/call/json_util.h',
'src/core/credentials/call/jwt/json_token.h',
'src/core/credentials/call/jwt/jwt_credentials.h',
'src/core/credentials/call/jwt/jwt_verifier.h',
'src/core/credentials/call/oauth2/oauth2_credentials.h',
'src/core/credentials/call/plugin/plugin_credentials.h',
'src/core/credentials/call/token_fetcher/token_fetcher_credentials.h',
'src/core/credentials/transport/alts/alts_credentials.h',
'src/core/credentials/transport/alts/alts_security_connector.h',
'src/core/credentials/transport/alts/check_gcp_environment.h',
'src/core/credentials/transport/alts/grpc_alts_credentials_options.h',
'src/core/credentials/transport/channel_creds_registry.h',
'src/core/credentials/transport/composite/composite_channel_credentials.h',
'src/core/credentials/transport/fake/fake_credentials.h',
'src/core/credentials/transport/fake/fake_security_connector.h',
'src/core/credentials/transport/google_default/google_default_credentials.h',
'src/core/credentials/transport/insecure/insecure_credentials.h',
'src/core/credentials/transport/insecure/insecure_security_connector.h',
'src/core/credentials/transport/local/local_credentials.h',
'src/core/credentials/transport/local/local_security_connector.h',
'src/core/credentials/transport/security_connector.h',
'src/core/credentials/transport/ssl/ssl_credentials.h',
'src/core/credentials/transport/ssl/ssl_security_connector.h',
'src/core/credentials/transport/tls/certificate_provider_factory.h',
'src/core/credentials/transport/tls/certificate_provider_registry.h',
'src/core/credentials/transport/tls/grpc_tls_certificate_distributor.h',
'src/core/credentials/transport/tls/grpc_tls_certificate_provider.h',
'src/core/credentials/transport/tls/grpc_tls_certificate_verifier.h',
'src/core/credentials/transport/tls/grpc_tls_credentials_options.h',
'src/core/credentials/transport/tls/grpc_tls_crl_provider.h',
'src/core/credentials/transport/tls/load_system_roots.h',
'src/core/credentials/transport/tls/load_system_roots_supported.h',
'src/core/credentials/transport/tls/ssl_utils.h',
'src/core/credentials/transport/tls/tls_credentials.h',
'src/core/credentials/transport/tls/tls_security_connector.h',
'src/core/credentials/transport/tls/tls_utils.h',
'src/core/credentials/transport/transport_credentials.h',
'src/core/credentials/transport/xds/xds_credentials.h',
'src/core/ext/filters/backend_metrics/backend_metric_filter.h',
'src/core/ext/filters/backend_metrics/backend_metric_provider.h',
'src/core/ext/filters/channel_idle/idle_filter_state.h',
@ -1621,7 +1713,6 @@ Pod::Spec.new do |s|
'src/core/ext/transport/chttp2/transport/bin_encoder.h',
'src/core/ext/transport/chttp2/transport/call_tracer_wrapper.h',
'src/core/ext/transport/chttp2/transport/chttp2_transport.h',
'src/core/ext/transport/chttp2/transport/context_list_entry.h',
'src/core/ext/transport/chttp2/transport/decode_huff.h',
'src/core/ext/transport/chttp2/transport/flow_control.h',
'src/core/ext/transport/chttp2/transport/frame.h',
@ -1639,8 +1730,11 @@ Pod::Spec.new do |s|
'src/core/ext/transport/chttp2/transport/hpack_parser.h',
'src/core/ext/transport/chttp2/transport/hpack_parser_table.h',
'src/core/ext/transport/chttp2/transport/http2_settings.h',
'src/core/ext/transport/chttp2/transport/http2_status.h',
'src/core/ext/transport/chttp2/transport/http2_ztrace_collector.h',
'src/core/ext/transport/chttp2/transport/huffsyms.h',
'src/core/ext/transport/chttp2/transport/internal.h',
'src/core/ext/transport/chttp2/transport/internal_channel_arg_names.h',
'src/core/ext/transport/chttp2/transport/legacy_frame.h',
'src/core/ext/transport/chttp2/transport/ping_abuse_policy.h',
'src/core/ext/transport/chttp2/transport/ping_callbacks.h',
@ -1834,6 +1928,8 @@ Pod::Spec.new do |s|
'src/core/ext/upb-gen/envoy/type/http/v3/cookie.upb_minitable.h',
'src/core/ext/upb-gen/envoy/type/http/v3/path_transformation.upb.h',
'src/core/ext/upb-gen/envoy/type/http/v3/path_transformation.upb_minitable.h',
'src/core/ext/upb-gen/envoy/type/matcher/v3/address.upb.h',
'src/core/ext/upb-gen/envoy/type/matcher/v3/address.upb_minitable.h',
'src/core/ext/upb-gen/envoy/type/matcher/v3/filter_state.upb.h',
'src/core/ext/upb-gen/envoy/type/matcher/v3/filter_state.upb_minitable.h',
'src/core/ext/upb-gen/envoy/type/matcher/v3/http_inputs.upb.h',
@ -2069,6 +2165,7 @@ Pod::Spec.new do |s|
'src/core/ext/upbdefs-gen/envoy/service/status/v3/csds.upbdefs.h',
'src/core/ext/upbdefs-gen/envoy/type/http/v3/cookie.upbdefs.h',
'src/core/ext/upbdefs-gen/envoy/type/http/v3/path_transformation.upbdefs.h',
'src/core/ext/upbdefs-gen/envoy/type/matcher/v3/address.upbdefs.h',
'src/core/ext/upbdefs-gen/envoy/type/matcher/v3/filter_state.upbdefs.h',
'src/core/ext/upbdefs-gen/envoy/type/matcher/v3/http_inputs.upbdefs.h',
'src/core/ext/upbdefs-gen/envoy/type/matcher/v3/metadata.upbdefs.h',
@ -2135,6 +2232,7 @@ Pod::Spec.new do |s|
'src/core/ext/upbdefs-gen/xds/type/v3/cel.upbdefs.h',
'src/core/ext/upbdefs-gen/xds/type/v3/range.upbdefs.h',
'src/core/ext/upbdefs-gen/xds/type/v3/typed_struct.upbdefs.h',
'src/core/filter/auth/auth_filters.h',
'src/core/filter/blackboard.h',
'src/core/filter/filter_args.h',
'src/core/handshaker/endpoint_info/endpoint_info_handshaker.h',
@ -2151,7 +2249,6 @@ Pod::Spec.new do |s|
'src/core/handshaker/tcp_connect/tcp_connect_handshaker.h',
'src/core/lib/address_utils/parse_address.h',
'src/core/lib/address_utils/sockaddr_utils.h',
'src/core/lib/channel/call_finalization.h',
'src/core/lib/channel/channel_args.h',
'src/core/lib/channel/channel_args_preconditioning.h',
'src/core/lib/channel/channel_fwd.h',
@ -2160,7 +2257,6 @@ Pod::Spec.new do |s|
'src/core/lib/channel/channel_stack_builder_impl.h',
'src/core/lib/channel/connected_channel.h',
'src/core/lib/channel/promise_based_filter.h',
'src/core/lib/channel/status_util.h',
'src/core/lib/compression/compression_internal.h',
'src/core/lib/compression/message_compress.h',
'src/core/lib/debug/trace.h',
@ -2176,9 +2272,13 @@ Pod::Spec.new do |s|
'src/core/lib/event_engine/default_event_engine.h',
'src/core/lib/event_engine/default_event_engine_factory.h',
'src/core/lib/event_engine/event_engine_context.h',
'src/core/lib/event_engine/extensions/blocking_dns.h',
'src/core/lib/event_engine/extensions/can_track_errors.h',
'src/core/lib/event_engine/extensions/channelz.h',
'src/core/lib/event_engine/extensions/chaotic_good_extension.h',
'src/core/lib/event_engine/extensions/iomgr_compatible.h',
'src/core/lib/event_engine/extensions/supports_fd.h',
'src/core/lib/event_engine/extensions/supports_win_sockets.h',
'src/core/lib/event_engine/extensions/tcp_trace.h',
'src/core/lib/event_engine/forkable.h',
'src/core/lib/event_engine/grpc_polled_fd.h',
@ -2252,7 +2352,6 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/event_engine_shims/endpoint.h',
'src/core/lib/iomgr/event_engine_shims/tcp_client.h',
'src/core/lib/iomgr/exec_ctx.h',
'src/core/lib/iomgr/executor.h',
'src/core/lib/iomgr/internal_errqueue.h',
'src/core/lib/iomgr/iocp_windows.h',
'src/core/lib/iomgr/iomgr.h',
@ -2341,54 +2440,6 @@ Pod::Spec.new do |s|
'src/core/lib/security/authorization/matchers.h',
'src/core/lib/security/authorization/rbac_policy.h',
'src/core/lib/security/authorization/stdout_logger.h',
'src/core/lib/security/certificate_provider/certificate_provider_factory.h',
'src/core/lib/security/certificate_provider/certificate_provider_registry.h',
'src/core/lib/security/context/security_context.h',
'src/core/lib/security/credentials/alts/alts_credentials.h',
'src/core/lib/security/credentials/alts/check_gcp_environment.h',
'src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h',
'src/core/lib/security/credentials/call_creds_util.h',
'src/core/lib/security/credentials/channel_creds_registry.h',
'src/core/lib/security/credentials/composite/composite_credentials.h',
'src/core/lib/security/credentials/credentials.h',
'src/core/lib/security/credentials/external/aws_external_account_credentials.h',
'src/core/lib/security/credentials/external/aws_request_signer.h',
'src/core/lib/security/credentials/external/external_account_credentials.h',
'src/core/lib/security/credentials/external/file_external_account_credentials.h',
'src/core/lib/security/credentials/external/url_external_account_credentials.h',
'src/core/lib/security/credentials/fake/fake_credentials.h',
'src/core/lib/security/credentials/gcp_service_account_identity/gcp_service_account_identity_credentials.h',
'src/core/lib/security/credentials/google_default/google_default_credentials.h',
'src/core/lib/security/credentials/iam/iam_credentials.h',
'src/core/lib/security/credentials/insecure/insecure_credentials.h',
'src/core/lib/security/credentials/jwt/json_token.h',
'src/core/lib/security/credentials/jwt/jwt_credentials.h',
'src/core/lib/security/credentials/jwt/jwt_verifier.h',
'src/core/lib/security/credentials/local/local_credentials.h',
'src/core/lib/security/credentials/oauth2/oauth2_credentials.h',
'src/core/lib/security/credentials/plugin/plugin_credentials.h',
'src/core/lib/security/credentials/ssl/ssl_credentials.h',
'src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.h',
'src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h',
'src/core/lib/security/credentials/tls/grpc_tls_certificate_verifier.h',
'src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h',
'src/core/lib/security/credentials/tls/grpc_tls_crl_provider.h',
'src/core/lib/security/credentials/tls/tls_credentials.h',
'src/core/lib/security/credentials/tls/tls_utils.h',
'src/core/lib/security/credentials/token_fetcher/token_fetcher_credentials.h',
'src/core/lib/security/credentials/xds/xds_credentials.h',
'src/core/lib/security/security_connector/alts/alts_security_connector.h',
'src/core/lib/security/security_connector/fake/fake_security_connector.h',
'src/core/lib/security/security_connector/insecure/insecure_security_connector.h',
'src/core/lib/security/security_connector/load_system_roots.h',
'src/core/lib/security/security_connector/load_system_roots_supported.h',
'src/core/lib/security/security_connector/local/local_security_connector.h',
'src/core/lib/security/security_connector/security_connector.h',
'src/core/lib/security/security_connector/ssl/ssl_security_connector.h',
'src/core/lib/security/security_connector/ssl_utils.h',
'src/core/lib/security/security_connector/tls/tls_security_connector.h',
'src/core/lib/security/transport/auth_filters.h',
'src/core/lib/security/util/json_util.h',
'src/core/lib/slice/percent_encoding.h',
'src/core/lib/slice/slice.h',
'src/core/lib/slice/slice_buffer.h',
@ -2402,7 +2453,6 @@ Pod::Spec.new do |s|
'src/core/lib/surface/channel_create.h',
'src/core/lib/surface/channel_init.h',
'src/core/lib/surface/channel_stack_type.h',
'src/core/lib/surface/client_call.h',
'src/core/lib/surface/completion_queue.h',
'src/core/lib/surface/completion_queue_factory.h',
'src/core/lib/surface/connection_context.h',
@ -2412,27 +2462,11 @@ Pod::Spec.new do |s|
'src/core/lib/surface/init_internally.h',
'src/core/lib/surface/lame_client.h',
'src/core/lib/surface/legacy_channel.h',
'src/core/lib/surface/server_call.h',
'src/core/lib/surface/validate_metadata.h',
'src/core/lib/transport/bdp_estimator.h',
'src/core/lib/transport/call_arena_allocator.h',
'src/core/lib/transport/call_destination.h',
'src/core/lib/transport/call_filters.h',
'src/core/lib/transport/call_final_info.h',
'src/core/lib/transport/call_spine.h',
'src/core/lib/transport/call_state.h',
'src/core/lib/transport/connectivity_state.h',
'src/core/lib/transport/custom_metadata.h',
'src/core/lib/transport/error_utils.h',
'src/core/lib/transport/http2_errors.h',
'src/core/lib/transport/interception_chain.h',
'src/core/lib/transport/message.h',
'src/core/lib/transport/metadata.h',
'src/core/lib/transport/metadata_batch.h',
'src/core/lib/transport/metadata_compression_traits.h',
'src/core/lib/transport/metadata_info.h',
'src/core/lib/transport/parsed_metadata.h',
'src/core/lib/transport/simple_slice_based_metadata.h',
'src/core/lib/transport/status_conversion.h',
'src/core/lib/transport/timeout_encoding.h',
'src/core/lib/transport/transport.h',
@ -2493,11 +2527,16 @@ Pod::Spec.new do |s|
'src/core/service_config/service_config_impl.h',
'src/core/service_config/service_config_parser.h',
'src/core/telemetry/call_tracer.h',
'src/core/telemetry/context_list_entry.h',
'src/core/telemetry/default_tcp_tracer.h',
'src/core/telemetry/histogram_view.h',
'src/core/telemetry/metrics.h',
'src/core/telemetry/stats.h',
'src/core/telemetry/stats_data.h',
'src/core/telemetry/tcp_tracer.h',
'src/core/transport/auth_context.h',
'src/core/transport/endpoint_transport.h',
'src/core/transport/endpoint_transport_client_channel_factory.h',
'src/core/tsi/alts/crypt/gsec.h',
'src/core/tsi/alts/frame_protector/alts_counter.h',
'src/core/tsi/alts/frame_protector/alts_crypter.h',
@ -2532,6 +2571,7 @@ Pod::Spec.new do |s|
'src/core/util/avl.h',
'src/core/util/backoff.h',
'src/core/util/bitset.h',
'src/core/util/check_class_size.h',
'src/core/util/chunked_vector.h',
'src/core/util/construct_destruct.h',
'src/core/util/cpp_impl_of.h',
@ -2545,6 +2585,7 @@ Pod::Spec.new do |s|
'src/core/util/event_log.h',
'src/core/util/examine_stack.h',
'src/core/util/fork.h',
'src/core/util/function_signature.h',
'src/core/util/gcp_metadata_query.h',
'src/core/util/gethostname.h',
'src/core/util/glob.h',
@ -2581,6 +2622,7 @@ Pod::Spec.new do |s|
'src/core/util/ref_counted_ptr.h',
'src/core/util/ref_counted_string.h',
'src/core/util/ring_buffer.h',
'src/core/util/shared_bit_gen.h',
'src/core/util/single_set_ptr.h',
'src/core/util/sorted_pack.h',
'src/core/util/spinlock.h',
@ -2605,6 +2647,7 @@ Pod::Spec.new do |s|
'src/core/util/useful.h',
'src/core/util/uuid_v4.h',
'src/core/util/validation_errors.h',
'src/core/util/wait_for_single_owner.h',
'src/core/util/work_serializer.h',
'src/core/util/xxhash_inline.h',
'src/core/xds/grpc/certificate_provider_store.h',
@ -2637,6 +2680,7 @@ Pod::Spec.new do |s|
'src/core/xds/grpc/xds_route_config_parser.h',
'src/core/xds/grpc/xds_routing.h',
'src/core/xds/grpc/xds_server_grpc.h',
'src/core/xds/grpc/xds_server_grpc_interface.h',
'src/core/xds/grpc/xds_transport_grpc.h',
'src/core/xds/xds_client/lrs_client.h',
'src/core/xds/xds_client/xds_api.h',
@ -2710,8 +2754,8 @@ Pod::Spec.new do |s|
'third_party/upb/upb/message/copy.h',
'third_party/upb/upb/message/internal/accessors.h',
'third_party/upb/upb/message/internal/array.h',
'third_party/upb/upb/message/internal/compare_unknown.h',
'third_party/upb/upb/message/internal/extension.h',
'third_party/upb/upb/message/internal/iterator.h',
'third_party/upb/upb/message/internal/map.h',
'third_party/upb/upb/message/internal/map_entry.h',
'third_party/upb/upb/message/internal/map_sorter.h',
@ -2799,6 +2843,8 @@ Pod::Spec.new do |s|
'third_party/upb/upb/wire/reader.h',
'third_party/upb/upb/wire/types.h',
'third_party/utf8_range/utf8_range.h',
'third_party/utf8_range/utf8_range_neon.inc',
'third_party/utf8_range/utf8_range_sse.inc',
'third_party/xxhash/xxhash.h',
'third_party/zlib/crc32.h',
'third_party/zlib/deflate.h',
@ -2823,25 +2869,6 @@ Pod::Spec.new do |s|
'include/grpcpp/impl/codegen/proto_utils.h'
end
s.subspec 'Cronet-Interface' do |ss|
ss.header_mappings_dir = 'include/grpcpp'
ss.public_header_files = "include/grpcpp/security/cronet_credentials.h",
"include/grpcpp/security/cronet_credentials_impl.h"
ss.source_files = "include/grpcpp/security/cronet_credentials.h",
"include/grpcpp/security/cronet_credentials_impl.h"
end
s.subspec 'Cronet-Implementation' do |ss|
ss.header_mappings_dir = '.'
ss.dependency "#{s.name}/Cronet-Interface", version
ss.dependency "#{s.name}/Implementation", version
ss.dependency "#{s.name}/Privacy", version
ss.dependency 'gRPC-Core/Cronet-Implementation', version
ss.source_files = "src/cpp/client/cronet_credentials.cc"
end
# patch include of openssl to openssl_grpc
s.prepare_command = <<-END_OF_COMMAND
set -e

View File

@ -21,7 +21,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-Core'
version = '1.70.0-dev'
version = '1.73.1'
s.version = version
s.summary = 'Core cross-platform gRPC library, written in C'
s.homepage = 'https://grpc.io'
@ -38,8 +38,8 @@ Pod::Spec.new do |s|
# which was released in Cocoapods v1.2.0.
s.cocoapods_version = '>= 1.2.0'
s.ios.deployment_target = '11.0'
s.osx.deployment_target = '10.14'
s.ios.deployment_target = '15.0'
s.osx.deployment_target = '11.0'
s.tvos.deployment_target = '13.0'
s.watchos.deployment_target = '6.0'
s.visionos.deployment_target = '1.0'
@ -47,7 +47,7 @@ Pod::Spec.new do |s|
s.requires_arc = false
name = 'grpc'
abseil_version = '~> 1.20240722.0'
abseil_version = '~> 1.20250127.1'
# When creating a dynamic framework, name it grpc.framework instead of gRPC-Core.framework.
# This lets users write their includes like `#include <grpc/grpc.h>` as opposed to `#include
@ -127,6 +127,7 @@ Pod::Spec.new do |s|
'include/grpc/event_engine/extensible.h',
'include/grpc/event_engine/internal/memory_allocator_impl.h',
'include/grpc/event_engine/internal/slice_cast.h',
'include/grpc/event_engine/internal/write_event.h',
'include/grpc/event_engine/memory_allocator.h',
'include/grpc/event_engine/memory_request.h',
'include/grpc/event_engine/port.h',
@ -200,7 +201,7 @@ Pod::Spec.new do |s|
ss.libraries = 'z'
ss.dependency "#{s.name}/Interface", version
ss.dependency "#{s.name}/Privacy", version
ss.dependency 'BoringSSL-GRPC', '0.0.38'
ss.dependency 'BoringSSL-GRPC', '0.0.41'
ss.dependency 'abseil/algorithm/container', abseil_version
ss.dependency 'abseil/base/base', abseil_version
ss.dependency 'abseil/base/config', abseil_version
@ -208,6 +209,7 @@ Pod::Spec.new do |s|
ss.dependency 'abseil/base/log_severity', abseil_version
ss.dependency 'abseil/base/no_destructor', abseil_version
ss.dependency 'abseil/cleanup/cleanup', abseil_version
ss.dependency 'abseil/container/btree', abseil_version
ss.dependency 'abseil/container/flat_hash_map', abseil_version
ss.dependency 'abseil/container/flat_hash_set', abseil_version
ss.dependency 'abseil/container/inlined_vector', abseil_version
@ -235,18 +237,51 @@ Pod::Spec.new do |s|
ss.dependency 'abseil/time/time', abseil_version
ss.dependency 'abseil/types/optional', abseil_version
ss.dependency 'abseil/types/span', abseil_version
ss.dependency 'abseil/types/variant', abseil_version
ss.dependency 'abseil/utility/utility', abseil_version
ss.compiler_flags = '-DBORINGSSL_PREFIX=GRPC -Wno-unreachable-code -Wno-shorten-64-to-32'
ss.source_files = 'src/core/call/request_buffer.cc',
ss.source_files = 'src/core/call/call_arena_allocator.cc',
'src/core/call/call_arena_allocator.h',
'src/core/call/call_destination.h',
'src/core/call/call_filters.cc',
'src/core/call/call_filters.h',
'src/core/call/call_finalization.h',
'src/core/call/call_spine.cc',
'src/core/call/call_spine.h',
'src/core/call/call_state.cc',
'src/core/call/call_state.h',
'src/core/call/client_call.cc',
'src/core/call/client_call.h',
'src/core/call/custom_metadata.h',
'src/core/call/interception_chain.cc',
'src/core/call/interception_chain.h',
'src/core/call/message.cc',
'src/core/call/message.h',
'src/core/call/metadata.cc',
'src/core/call/metadata.h',
'src/core/call/metadata_batch.cc',
'src/core/call/metadata_batch.h',
'src/core/call/metadata_compression_traits.h',
'src/core/call/metadata_info.cc',
'src/core/call/metadata_info.h',
'src/core/call/parsed_metadata.cc',
'src/core/call/parsed_metadata.h',
'src/core/call/request_buffer.cc',
'src/core/call/request_buffer.h',
'src/core/call/security_context.cc',
'src/core/call/security_context.h',
'src/core/call/server_call.cc',
'src/core/call/server_call.h',
'src/core/call/simple_slice_based_metadata.h',
'src/core/call/status_util.cc',
'src/core/call/status_util.h',
'src/core/channelz/channel_trace.cc',
'src/core/channelz/channel_trace.h',
'src/core/channelz/channelz.cc',
'src/core/channelz/channelz.h',
'src/core/channelz/channelz_registry.cc',
'src/core/channelz/channelz_registry.h',
'src/core/channelz/ztrace_collector.h',
'src/core/client_channel/backup_poller.cc',
'src/core/client_channel/backup_poller.h',
'src/core/client_channel/client_channel.cc',
@ -298,6 +333,108 @@ Pod::Spec.new do |s|
'src/core/config/core_configuration.h',
'src/core/config/load_config.cc',
'src/core/config/load_config.h',
'src/core/credentials/call/call_credentials.h',
'src/core/credentials/call/call_creds_util.cc',
'src/core/credentials/call/call_creds_util.h',
'src/core/credentials/call/composite/composite_call_credentials.cc',
'src/core/credentials/call/composite/composite_call_credentials.h',
'src/core/credentials/call/external/aws_external_account_credentials.cc',
'src/core/credentials/call/external/aws_external_account_credentials.h',
'src/core/credentials/call/external/aws_request_signer.cc',
'src/core/credentials/call/external/aws_request_signer.h',
'src/core/credentials/call/external/external_account_credentials.cc',
'src/core/credentials/call/external/external_account_credentials.h',
'src/core/credentials/call/external/file_external_account_credentials.cc',
'src/core/credentials/call/external/file_external_account_credentials.h',
'src/core/credentials/call/external/url_external_account_credentials.cc',
'src/core/credentials/call/external/url_external_account_credentials.h',
'src/core/credentials/call/gcp_service_account_identity/gcp_service_account_identity_credentials.cc',
'src/core/credentials/call/gcp_service_account_identity/gcp_service_account_identity_credentials.h',
'src/core/credentials/call/iam/iam_credentials.cc',
'src/core/credentials/call/iam/iam_credentials.h',
'src/core/credentials/call/json_util.cc',
'src/core/credentials/call/json_util.h',
'src/core/credentials/call/jwt/json_token.cc',
'src/core/credentials/call/jwt/json_token.h',
'src/core/credentials/call/jwt/jwt_credentials.cc',
'src/core/credentials/call/jwt/jwt_credentials.h',
'src/core/credentials/call/jwt/jwt_verifier.cc',
'src/core/credentials/call/jwt/jwt_verifier.h',
'src/core/credentials/call/oauth2/oauth2_credentials.cc',
'src/core/credentials/call/oauth2/oauth2_credentials.h',
'src/core/credentials/call/plugin/plugin_credentials.cc',
'src/core/credentials/call/plugin/plugin_credentials.h',
'src/core/credentials/call/token_fetcher/token_fetcher_credentials.cc',
'src/core/credentials/call/token_fetcher/token_fetcher_credentials.h',
'src/core/credentials/transport/alts/alts_credentials.cc',
'src/core/credentials/transport/alts/alts_credentials.h',
'src/core/credentials/transport/alts/alts_security_connector.cc',
'src/core/credentials/transport/alts/alts_security_connector.h',
'src/core/credentials/transport/alts/check_gcp_environment.cc',
'src/core/credentials/transport/alts/check_gcp_environment.h',
'src/core/credentials/transport/alts/check_gcp_environment_linux.cc',
'src/core/credentials/transport/alts/check_gcp_environment_no_op.cc',
'src/core/credentials/transport/alts/check_gcp_environment_windows.cc',
'src/core/credentials/transport/alts/grpc_alts_credentials_client_options.cc',
'src/core/credentials/transport/alts/grpc_alts_credentials_options.cc',
'src/core/credentials/transport/alts/grpc_alts_credentials_options.h',
'src/core/credentials/transport/alts/grpc_alts_credentials_server_options.cc',
'src/core/credentials/transport/channel_creds_registry.h',
'src/core/credentials/transport/channel_creds_registry_init.cc',
'src/core/credentials/transport/composite/composite_channel_credentials.cc',
'src/core/credentials/transport/composite/composite_channel_credentials.h',
'src/core/credentials/transport/fake/fake_credentials.cc',
'src/core/credentials/transport/fake/fake_credentials.h',
'src/core/credentials/transport/fake/fake_security_connector.cc',
'src/core/credentials/transport/fake/fake_security_connector.h',
'src/core/credentials/transport/google_default/credentials_generic.cc',
'src/core/credentials/transport/google_default/google_default_credentials.cc',
'src/core/credentials/transport/google_default/google_default_credentials.h',
'src/core/credentials/transport/insecure/insecure_credentials.cc',
'src/core/credentials/transport/insecure/insecure_credentials.h',
'src/core/credentials/transport/insecure/insecure_security_connector.cc',
'src/core/credentials/transport/insecure/insecure_security_connector.h',
'src/core/credentials/transport/local/local_credentials.cc',
'src/core/credentials/transport/local/local_credentials.h',
'src/core/credentials/transport/local/local_security_connector.cc',
'src/core/credentials/transport/local/local_security_connector.h',
'src/core/credentials/transport/security_connector.cc',
'src/core/credentials/transport/security_connector.h',
'src/core/credentials/transport/ssl/ssl_credentials.cc',
'src/core/credentials/transport/ssl/ssl_credentials.h',
'src/core/credentials/transport/ssl/ssl_security_connector.cc',
'src/core/credentials/transport/ssl/ssl_security_connector.h',
'src/core/credentials/transport/tls/certificate_provider_factory.h',
'src/core/credentials/transport/tls/certificate_provider_registry.cc',
'src/core/credentials/transport/tls/certificate_provider_registry.h',
'src/core/credentials/transport/tls/grpc_tls_certificate_distributor.cc',
'src/core/credentials/transport/tls/grpc_tls_certificate_distributor.h',
'src/core/credentials/transport/tls/grpc_tls_certificate_match.cc',
'src/core/credentials/transport/tls/grpc_tls_certificate_provider.cc',
'src/core/credentials/transport/tls/grpc_tls_certificate_provider.h',
'src/core/credentials/transport/tls/grpc_tls_certificate_verifier.cc',
'src/core/credentials/transport/tls/grpc_tls_certificate_verifier.h',
'src/core/credentials/transport/tls/grpc_tls_credentials_options.cc',
'src/core/credentials/transport/tls/grpc_tls_credentials_options.h',
'src/core/credentials/transport/tls/grpc_tls_crl_provider.cc',
'src/core/credentials/transport/tls/grpc_tls_crl_provider.h',
'src/core/credentials/transport/tls/load_system_roots.h',
'src/core/credentials/transport/tls/load_system_roots_fallback.cc',
'src/core/credentials/transport/tls/load_system_roots_supported.cc',
'src/core/credentials/transport/tls/load_system_roots_supported.h',
'src/core/credentials/transport/tls/load_system_roots_windows.cc',
'src/core/credentials/transport/tls/ssl_utils.cc',
'src/core/credentials/transport/tls/ssl_utils.h',
'src/core/credentials/transport/tls/tls_credentials.cc',
'src/core/credentials/transport/tls/tls_credentials.h',
'src/core/credentials/transport/tls/tls_security_connector.cc',
'src/core/credentials/transport/tls/tls_security_connector.h',
'src/core/credentials/transport/tls/tls_utils.cc',
'src/core/credentials/transport/tls/tls_utils.h',
'src/core/credentials/transport/transport_credentials.cc',
'src/core/credentials/transport/transport_credentials.h',
'src/core/credentials/transport/xds/xds_credentials.cc',
'src/core/credentials/transport/xds/xds_credentials.h',
'src/core/ext/filters/backend_metrics/backend_metric_filter.cc',
'src/core/ext/filters/backend_metrics/backend_metric_filter.h',
'src/core/ext/filters/backend_metrics/backend_metric_provider.h',
@ -335,6 +472,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/stateful_session/stateful_session_service_config_parser.h',
'src/core/ext/transport/chttp2/alpn/alpn.cc',
'src/core/ext/transport/chttp2/alpn/alpn.h',
'src/core/ext/transport/chttp2/chttp2_plugin.cc',
'src/core/ext/transport/chttp2/client/chttp2_connector.cc',
'src/core/ext/transport/chttp2/client/chttp2_connector.h',
'src/core/ext/transport/chttp2/server/chttp2_server.cc',
@ -347,7 +485,6 @@ Pod::Spec.new do |s|
'src/core/ext/transport/chttp2/transport/call_tracer_wrapper.h',
'src/core/ext/transport/chttp2/transport/chttp2_transport.cc',
'src/core/ext/transport/chttp2/transport/chttp2_transport.h',
'src/core/ext/transport/chttp2/transport/context_list_entry.h',
'src/core/ext/transport/chttp2/transport/decode_huff.cc',
'src/core/ext/transport/chttp2/transport/decode_huff.h',
'src/core/ext/transport/chttp2/transport/flow_control.cc',
@ -381,9 +518,12 @@ Pod::Spec.new do |s|
'src/core/ext/transport/chttp2/transport/hpack_parser_table.h',
'src/core/ext/transport/chttp2/transport/http2_settings.cc',
'src/core/ext/transport/chttp2/transport/http2_settings.h',
'src/core/ext/transport/chttp2/transport/http2_status.h',
'src/core/ext/transport/chttp2/transport/http2_ztrace_collector.h',
'src/core/ext/transport/chttp2/transport/huffsyms.cc',
'src/core/ext/transport/chttp2/transport/huffsyms.h',
'src/core/ext/transport/chttp2/transport/internal.h',
'src/core/ext/transport/chttp2/transport/internal_channel_arg_names.h',
'src/core/ext/transport/chttp2/transport/legacy_frame.h',
'src/core/ext/transport/chttp2/transport/parsing.cc',
'src/core/ext/transport/chttp2/transport/ping_abuse_policy.cc',
@ -679,6 +819,9 @@ Pod::Spec.new do |s|
'src/core/ext/upb-gen/envoy/type/http/v3/path_transformation.upb.h',
'src/core/ext/upb-gen/envoy/type/http/v3/path_transformation.upb_minitable.c',
'src/core/ext/upb-gen/envoy/type/http/v3/path_transformation.upb_minitable.h',
'src/core/ext/upb-gen/envoy/type/matcher/v3/address.upb.h',
'src/core/ext/upb-gen/envoy/type/matcher/v3/address.upb_minitable.c',
'src/core/ext/upb-gen/envoy/type/matcher/v3/address.upb_minitable.h',
'src/core/ext/upb-gen/envoy/type/matcher/v3/filter_state.upb.h',
'src/core/ext/upb-gen/envoy/type/matcher/v3/filter_state.upb_minitable.c',
'src/core/ext/upb-gen/envoy/type/matcher/v3/filter_state.upb_minitable.h',
@ -1075,6 +1218,8 @@ Pod::Spec.new do |s|
'src/core/ext/upbdefs-gen/envoy/type/http/v3/cookie.upbdefs.h',
'src/core/ext/upbdefs-gen/envoy/type/http/v3/path_transformation.upbdefs.c',
'src/core/ext/upbdefs-gen/envoy/type/http/v3/path_transformation.upbdefs.h',
'src/core/ext/upbdefs-gen/envoy/type/matcher/v3/address.upbdefs.c',
'src/core/ext/upbdefs-gen/envoy/type/matcher/v3/address.upbdefs.h',
'src/core/ext/upbdefs-gen/envoy/type/matcher/v3/filter_state.upbdefs.c',
'src/core/ext/upbdefs-gen/envoy/type/matcher/v3/filter_state.upbdefs.h',
'src/core/ext/upbdefs-gen/envoy/type/matcher/v3/http_inputs.upbdefs.c',
@ -1207,6 +1352,9 @@ Pod::Spec.new do |s|
'src/core/ext/upbdefs-gen/xds/type/v3/range.upbdefs.h',
'src/core/ext/upbdefs-gen/xds/type/v3/typed_struct.upbdefs.c',
'src/core/ext/upbdefs-gen/xds/type/v3/typed_struct.upbdefs.h',
'src/core/filter/auth/auth_filters.h',
'src/core/filter/auth/client_auth_filter.cc',
'src/core/filter/auth/server_auth_filter.cc',
'src/core/filter/blackboard.cc',
'src/core/filter/blackboard.h',
'src/core/filter/filter_args.h',
@ -1226,6 +1374,7 @@ Pod::Spec.new do |s|
'src/core/handshaker/proxy_mapper.h',
'src/core/handshaker/proxy_mapper_registry.cc',
'src/core/handshaker/proxy_mapper_registry.h',
'src/core/handshaker/security/legacy_secure_endpoint.cc',
'src/core/handshaker/security/secure_endpoint.cc',
'src/core/handshaker/security/secure_endpoint.h',
'src/core/handshaker/security/security_handshaker.cc',
@ -1236,7 +1385,6 @@ Pod::Spec.new do |s|
'src/core/lib/address_utils/parse_address.h',
'src/core/lib/address_utils/sockaddr_utils.cc',
'src/core/lib/address_utils/sockaddr_utils.h',
'src/core/lib/channel/call_finalization.h',
'src/core/lib/channel/channel_args.cc',
'src/core/lib/channel/channel_args.h',
'src/core/lib/channel/channel_args_preconditioning.cc',
@ -1252,8 +1400,6 @@ Pod::Spec.new do |s|
'src/core/lib/channel/connected_channel.h',
'src/core/lib/channel/promise_based_filter.cc',
'src/core/lib/channel/promise_based_filter.h',
'src/core/lib/channel/status_util.cc',
'src/core/lib/channel/status_util.h',
'src/core/lib/compression/compression.cc',
'src/core/lib/compression/compression_internal.cc',
'src/core/lib/compression/compression_internal.h',
@ -1282,9 +1428,13 @@ Pod::Spec.new do |s|
'src/core/lib/event_engine/default_event_engine_factory.h',
'src/core/lib/event_engine/event_engine.cc',
'src/core/lib/event_engine/event_engine_context.h',
'src/core/lib/event_engine/extensions/blocking_dns.h',
'src/core/lib/event_engine/extensions/can_track_errors.h',
'src/core/lib/event_engine/extensions/channelz.h',
'src/core/lib/event_engine/extensions/chaotic_good_extension.h',
'src/core/lib/event_engine/extensions/iomgr_compatible.h',
'src/core/lib/event_engine/extensions/supports_fd.h',
'src/core/lib/event_engine/extensions/supports_win_sockets.h',
'src/core/lib/event_engine/extensions/tcp_trace.h',
'src/core/lib/event_engine/forkable.cc',
'src/core/lib/event_engine/forkable.h',
@ -1317,6 +1467,7 @@ Pod::Spec.new do |s|
'src/core/lib/event_engine/posix_engine/posix_engine_listener.h',
'src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.cc',
'src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.h',
'src/core/lib/event_engine/posix_engine/set_socket_dualstack.cc',
'src/core/lib/event_engine/posix_engine/tcp_socket_utils.cc',
'src/core/lib/event_engine/posix_engine/tcp_socket_utils.h',
'src/core/lib/event_engine/posix_engine/timer.cc',
@ -1419,8 +1570,6 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/event_engine_shims/tcp_client.h',
'src/core/lib/iomgr/exec_ctx.cc',
'src/core/lib/iomgr/exec_ctx.h',
'src/core/lib/iomgr/executor.cc',
'src/core/lib/iomgr/executor.h',
'src/core/lib/iomgr/fork_posix.cc',
'src/core/lib/iomgr/fork_windows.cc',
'src/core/lib/iomgr/internal_errqueue.cc',
@ -1577,110 +1726,6 @@ Pod::Spec.new do |s|
'src/core/lib/security/authorization/rbac_policy.h',
'src/core/lib/security/authorization/stdout_logger.cc',
'src/core/lib/security/authorization/stdout_logger.h',
'src/core/lib/security/certificate_provider/certificate_provider_factory.h',
'src/core/lib/security/certificate_provider/certificate_provider_registry.cc',
'src/core/lib/security/certificate_provider/certificate_provider_registry.h',
'src/core/lib/security/context/security_context.cc',
'src/core/lib/security/context/security_context.h',
'src/core/lib/security/credentials/alts/alts_credentials.cc',
'src/core/lib/security/credentials/alts/alts_credentials.h',
'src/core/lib/security/credentials/alts/check_gcp_environment.cc',
'src/core/lib/security/credentials/alts/check_gcp_environment.h',
'src/core/lib/security/credentials/alts/check_gcp_environment_linux.cc',
'src/core/lib/security/credentials/alts/check_gcp_environment_no_op.cc',
'src/core/lib/security/credentials/alts/check_gcp_environment_windows.cc',
'src/core/lib/security/credentials/alts/grpc_alts_credentials_client_options.cc',
'src/core/lib/security/credentials/alts/grpc_alts_credentials_options.cc',
'src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h',
'src/core/lib/security/credentials/alts/grpc_alts_credentials_server_options.cc',
'src/core/lib/security/credentials/call_creds_util.cc',
'src/core/lib/security/credentials/call_creds_util.h',
'src/core/lib/security/credentials/channel_creds_registry.h',
'src/core/lib/security/credentials/channel_creds_registry_init.cc',
'src/core/lib/security/credentials/composite/composite_credentials.cc',
'src/core/lib/security/credentials/composite/composite_credentials.h',
'src/core/lib/security/credentials/credentials.cc',
'src/core/lib/security/credentials/credentials.h',
'src/core/lib/security/credentials/external/aws_external_account_credentials.cc',
'src/core/lib/security/credentials/external/aws_external_account_credentials.h',
'src/core/lib/security/credentials/external/aws_request_signer.cc',
'src/core/lib/security/credentials/external/aws_request_signer.h',
'src/core/lib/security/credentials/external/external_account_credentials.cc',
'src/core/lib/security/credentials/external/external_account_credentials.h',
'src/core/lib/security/credentials/external/file_external_account_credentials.cc',
'src/core/lib/security/credentials/external/file_external_account_credentials.h',
'src/core/lib/security/credentials/external/url_external_account_credentials.cc',
'src/core/lib/security/credentials/external/url_external_account_credentials.h',
'src/core/lib/security/credentials/fake/fake_credentials.cc',
'src/core/lib/security/credentials/fake/fake_credentials.h',
'src/core/lib/security/credentials/gcp_service_account_identity/gcp_service_account_identity_credentials.cc',
'src/core/lib/security/credentials/gcp_service_account_identity/gcp_service_account_identity_credentials.h',
'src/core/lib/security/credentials/google_default/credentials_generic.cc',
'src/core/lib/security/credentials/google_default/google_default_credentials.cc',
'src/core/lib/security/credentials/google_default/google_default_credentials.h',
'src/core/lib/security/credentials/iam/iam_credentials.cc',
'src/core/lib/security/credentials/iam/iam_credentials.h',
'src/core/lib/security/credentials/insecure/insecure_credentials.cc',
'src/core/lib/security/credentials/insecure/insecure_credentials.h',
'src/core/lib/security/credentials/jwt/json_token.cc',
'src/core/lib/security/credentials/jwt/json_token.h',
'src/core/lib/security/credentials/jwt/jwt_credentials.cc',
'src/core/lib/security/credentials/jwt/jwt_credentials.h',
'src/core/lib/security/credentials/jwt/jwt_verifier.cc',
'src/core/lib/security/credentials/jwt/jwt_verifier.h',
'src/core/lib/security/credentials/local/local_credentials.cc',
'src/core/lib/security/credentials/local/local_credentials.h',
'src/core/lib/security/credentials/oauth2/oauth2_credentials.cc',
'src/core/lib/security/credentials/oauth2/oauth2_credentials.h',
'src/core/lib/security/credentials/plugin/plugin_credentials.cc',
'src/core/lib/security/credentials/plugin/plugin_credentials.h',
'src/core/lib/security/credentials/ssl/ssl_credentials.cc',
'src/core/lib/security/credentials/ssl/ssl_credentials.h',
'src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.cc',
'src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.h',
'src/core/lib/security/credentials/tls/grpc_tls_certificate_match.cc',
'src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc',
'src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h',
'src/core/lib/security/credentials/tls/grpc_tls_certificate_verifier.cc',
'src/core/lib/security/credentials/tls/grpc_tls_certificate_verifier.h',
'src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc',
'src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h',
'src/core/lib/security/credentials/tls/grpc_tls_crl_provider.cc',
'src/core/lib/security/credentials/tls/grpc_tls_crl_provider.h',
'src/core/lib/security/credentials/tls/tls_credentials.cc',
'src/core/lib/security/credentials/tls/tls_credentials.h',
'src/core/lib/security/credentials/tls/tls_utils.cc',
'src/core/lib/security/credentials/tls/tls_utils.h',
'src/core/lib/security/credentials/token_fetcher/token_fetcher_credentials.cc',
'src/core/lib/security/credentials/token_fetcher/token_fetcher_credentials.h',
'src/core/lib/security/credentials/xds/xds_credentials.cc',
'src/core/lib/security/credentials/xds/xds_credentials.h',
'src/core/lib/security/security_connector/alts/alts_security_connector.cc',
'src/core/lib/security/security_connector/alts/alts_security_connector.h',
'src/core/lib/security/security_connector/fake/fake_security_connector.cc',
'src/core/lib/security/security_connector/fake/fake_security_connector.h',
'src/core/lib/security/security_connector/insecure/insecure_security_connector.cc',
'src/core/lib/security/security_connector/insecure/insecure_security_connector.h',
'src/core/lib/security/security_connector/load_system_roots.h',
'src/core/lib/security/security_connector/load_system_roots_fallback.cc',
'src/core/lib/security/security_connector/load_system_roots_supported.cc',
'src/core/lib/security/security_connector/load_system_roots_supported.h',
'src/core/lib/security/security_connector/load_system_roots_windows.cc',
'src/core/lib/security/security_connector/local/local_security_connector.cc',
'src/core/lib/security/security_connector/local/local_security_connector.h',
'src/core/lib/security/security_connector/security_connector.cc',
'src/core/lib/security/security_connector/security_connector.h',
'src/core/lib/security/security_connector/ssl/ssl_security_connector.cc',
'src/core/lib/security/security_connector/ssl/ssl_security_connector.h',
'src/core/lib/security/security_connector/ssl_utils.cc',
'src/core/lib/security/security_connector/ssl_utils.h',
'src/core/lib/security/security_connector/tls/tls_security_connector.cc',
'src/core/lib/security/security_connector/tls/tls_security_connector.h',
'src/core/lib/security/transport/auth_filters.h',
'src/core/lib/security/transport/client_auth_filter.cc',
'src/core/lib/security/transport/server_auth_filter.cc',
'src/core/lib/security/util/json_util.cc',
'src/core/lib/security/util/json_util.h',
'src/core/lib/slice/percent_encoding.cc',
'src/core/lib/slice/percent_encoding.h',
'src/core/lib/slice/slice.cc',
@ -1708,8 +1753,6 @@ Pod::Spec.new do |s|
'src/core/lib/surface/channel_init.h',
'src/core/lib/surface/channel_stack_type.cc',
'src/core/lib/surface/channel_stack_type.h',
'src/core/lib/surface/client_call.cc',
'src/core/lib/surface/client_call.h',
'src/core/lib/surface/completion_queue.cc',
'src/core/lib/surface/completion_queue.h',
'src/core/lib/surface/completion_queue_factory.cc',
@ -1729,44 +1772,17 @@ Pod::Spec.new do |s|
'src/core/lib/surface/legacy_channel.cc',
'src/core/lib/surface/legacy_channel.h',
'src/core/lib/surface/metadata_array.cc',
'src/core/lib/surface/server_call.cc',
'src/core/lib/surface/server_call.h',
'src/core/lib/surface/validate_metadata.cc',
'src/core/lib/surface/validate_metadata.h',
'src/core/lib/surface/version.cc',
'src/core/lib/transport/bdp_estimator.cc',
'src/core/lib/transport/bdp_estimator.h',
'src/core/lib/transport/call_arena_allocator.cc',
'src/core/lib/transport/call_arena_allocator.h',
'src/core/lib/transport/call_destination.h',
'src/core/lib/transport/call_filters.cc',
'src/core/lib/transport/call_filters.h',
'src/core/lib/transport/call_final_info.cc',
'src/core/lib/transport/call_final_info.h',
'src/core/lib/transport/call_spine.cc',
'src/core/lib/transport/call_spine.h',
'src/core/lib/transport/call_state.cc',
'src/core/lib/transport/call_state.h',
'src/core/lib/transport/connectivity_state.cc',
'src/core/lib/transport/connectivity_state.h',
'src/core/lib/transport/custom_metadata.h',
'src/core/lib/transport/error_utils.cc',
'src/core/lib/transport/error_utils.h',
'src/core/lib/transport/http2_errors.h',
'src/core/lib/transport/interception_chain.cc',
'src/core/lib/transport/interception_chain.h',
'src/core/lib/transport/message.cc',
'src/core/lib/transport/message.h',
'src/core/lib/transport/metadata.cc',
'src/core/lib/transport/metadata.h',
'src/core/lib/transport/metadata_batch.cc',
'src/core/lib/transport/metadata_batch.h',
'src/core/lib/transport/metadata_compression_traits.h',
'src/core/lib/transport/metadata_info.cc',
'src/core/lib/transport/metadata_info.h',
'src/core/lib/transport/parsed_metadata.cc',
'src/core/lib/transport/parsed_metadata.h',
'src/core/lib/transport/simple_slice_based_metadata.h',
'src/core/lib/transport/status_conversion.cc',
'src/core/lib/transport/status_conversion.h',
'src/core/lib/transport/timeout_encoding.cc',
@ -1869,6 +1885,7 @@ Pod::Spec.new do |s|
'src/core/resolver/xds/xds_dependency_manager.h',
'src/core/resolver/xds/xds_resolver.cc',
'src/core/resolver/xds/xds_resolver_attributes.h',
'src/core/server/add_port.cc',
'src/core/server/server.cc',
'src/core/server/server.h',
'src/core/server/server_call_tracer_filter.cc',
@ -1889,6 +1906,9 @@ Pod::Spec.new do |s|
'src/core/service_config/service_config_parser.h',
'src/core/telemetry/call_tracer.cc',
'src/core/telemetry/call_tracer.h',
'src/core/telemetry/context_list_entry.h',
'src/core/telemetry/default_tcp_tracer.cc',
'src/core/telemetry/default_tcp_tracer.h',
'src/core/telemetry/histogram_view.cc',
'src/core/telemetry/histogram_view.h',
'src/core/telemetry/metrics.cc',
@ -1897,7 +1917,13 @@ Pod::Spec.new do |s|
'src/core/telemetry/stats.h',
'src/core/telemetry/stats_data.cc',
'src/core/telemetry/stats_data.h',
'src/core/telemetry/tcp_tracer.cc',
'src/core/telemetry/tcp_tracer.h',
'src/core/transport/auth_context.cc',
'src/core/transport/auth_context.h',
'src/core/transport/endpoint_transport.h',
'src/core/transport/endpoint_transport_client_channel_factory.cc',
'src/core/transport/endpoint_transport_client_channel_factory.h',
'src/core/tsi/alts/crypt/aes_gcm.cc',
'src/core/tsi/alts/crypt/gsec.cc',
'src/core/tsi/alts/crypt/gsec.h',
@ -1963,6 +1989,7 @@ Pod::Spec.new do |s|
'src/core/util/backoff.cc',
'src/core/util/backoff.h',
'src/core/util/bitset.h',
'src/core/util/check_class_size.h',
'src/core/util/chunked_vector.h',
'src/core/util/construct_destruct.h',
'src/core/util/cpp_impl_of.h',
@ -1981,6 +2008,7 @@ Pod::Spec.new do |s|
'src/core/util/examine_stack.h',
'src/core/util/fork.cc',
'src/core/util/fork.h',
'src/core/util/function_signature.h',
'src/core/util/gcp_metadata_query.cc',
'src/core/util/gcp_metadata_query.h',
'src/core/util/gethostname.h',
@ -2055,6 +2083,8 @@ Pod::Spec.new do |s|
'src/core/util/ref_counted_string.cc',
'src/core/util/ref_counted_string.h',
'src/core/util/ring_buffer.h',
'src/core/util/shared_bit_gen.cc',
'src/core/util/shared_bit_gen.h',
'src/core/util/single_set_ptr.h',
'src/core/util/sorted_pack.h',
'src/core/util/spinlock.h',
@ -2092,6 +2122,7 @@ Pod::Spec.new do |s|
'src/core/util/uuid_v4.h',
'src/core/util/validation_errors.cc',
'src/core/util/validation_errors.h',
'src/core/util/wait_for_single_owner.h',
'src/core/util/windows/cpu.cc',
'src/core/util/windows/directory_reader.cc',
'src/core/util/windows/env.cc',
@ -2162,6 +2193,7 @@ Pod::Spec.new do |s|
'src/core/xds/grpc/xds_routing.h',
'src/core/xds/grpc/xds_server_grpc.cc',
'src/core/xds/grpc/xds_server_grpc.h',
'src/core/xds/grpc/xds_server_grpc_interface.h',
'src/core/xds/grpc/xds_transport_grpc.cc',
'src/core/xds/grpc/xds_transport_grpc.h',
'src/core/xds/xds_client/lrs_client.cc',
@ -2269,10 +2301,10 @@ Pod::Spec.new do |s|
'third_party/upb/upb/message/copy.h',
'third_party/upb/upb/message/internal/accessors.h',
'third_party/upb/upb/message/internal/array.h',
'third_party/upb/upb/message/internal/compare_unknown.c',
'third_party/upb/upb/message/internal/compare_unknown.h',
'third_party/upb/upb/message/internal/extension.c',
'third_party/upb/upb/message/internal/extension.h',
'third_party/upb/upb/message/internal/iterator.c',
'third_party/upb/upb/message/internal/iterator.h',
'third_party/upb/upb/message/internal/map.h',
'third_party/upb/upb/message/internal/map_entry.h',
'third_party/upb/upb/message/internal/map_sorter.h',
@ -2398,6 +2430,8 @@ Pod::Spec.new do |s|
'third_party/upb/upb/wire/types.h',
'third_party/utf8_range/utf8_range.c',
'third_party/utf8_range/utf8_range.h',
'third_party/utf8_range/utf8_range_neon.inc',
'third_party/utf8_range/utf8_range_sse.inc',
'third_party/xxhash/xxhash.h',
'third_party/zlib/adler32.c',
'third_party/zlib/compress.c',
@ -2421,10 +2455,30 @@ Pod::Spec.new do |s|
'third_party/zlib/zlib.h',
'third_party/zlib/zutil.c',
'third_party/zlib/zutil.h'
ss.private_header_files = 'src/core/call/request_buffer.h',
ss.private_header_files = 'src/core/call/call_arena_allocator.h',
'src/core/call/call_destination.h',
'src/core/call/call_filters.h',
'src/core/call/call_finalization.h',
'src/core/call/call_spine.h',
'src/core/call/call_state.h',
'src/core/call/client_call.h',
'src/core/call/custom_metadata.h',
'src/core/call/interception_chain.h',
'src/core/call/message.h',
'src/core/call/metadata.h',
'src/core/call/metadata_batch.h',
'src/core/call/metadata_compression_traits.h',
'src/core/call/metadata_info.h',
'src/core/call/parsed_metadata.h',
'src/core/call/request_buffer.h',
'src/core/call/security_context.h',
'src/core/call/server_call.h',
'src/core/call/simple_slice_based_metadata.h',
'src/core/call/status_util.h',
'src/core/channelz/channel_trace.h',
'src/core/channelz/channelz.h',
'src/core/channelz/channelz_registry.h',
'src/core/channelz/ztrace_collector.h',
'src/core/client_channel/backup_poller.h',
'src/core/client_channel/client_channel.h',
'src/core/client_channel/client_channel_args.h',
@ -2452,6 +2506,54 @@ Pod::Spec.new do |s|
'src/core/config/config_vars.h',
'src/core/config/core_configuration.h',
'src/core/config/load_config.h',
'src/core/credentials/call/call_credentials.h',
'src/core/credentials/call/call_creds_util.h',
'src/core/credentials/call/composite/composite_call_credentials.h',
'src/core/credentials/call/external/aws_external_account_credentials.h',
'src/core/credentials/call/external/aws_request_signer.h',
'src/core/credentials/call/external/external_account_credentials.h',
'src/core/credentials/call/external/file_external_account_credentials.h',
'src/core/credentials/call/external/url_external_account_credentials.h',
'src/core/credentials/call/gcp_service_account_identity/gcp_service_account_identity_credentials.h',
'src/core/credentials/call/iam/iam_credentials.h',
'src/core/credentials/call/json_util.h',
'src/core/credentials/call/jwt/json_token.h',
'src/core/credentials/call/jwt/jwt_credentials.h',
'src/core/credentials/call/jwt/jwt_verifier.h',
'src/core/credentials/call/oauth2/oauth2_credentials.h',
'src/core/credentials/call/plugin/plugin_credentials.h',
'src/core/credentials/call/token_fetcher/token_fetcher_credentials.h',
'src/core/credentials/transport/alts/alts_credentials.h',
'src/core/credentials/transport/alts/alts_security_connector.h',
'src/core/credentials/transport/alts/check_gcp_environment.h',
'src/core/credentials/transport/alts/grpc_alts_credentials_options.h',
'src/core/credentials/transport/channel_creds_registry.h',
'src/core/credentials/transport/composite/composite_channel_credentials.h',
'src/core/credentials/transport/fake/fake_credentials.h',
'src/core/credentials/transport/fake/fake_security_connector.h',
'src/core/credentials/transport/google_default/google_default_credentials.h',
'src/core/credentials/transport/insecure/insecure_credentials.h',
'src/core/credentials/transport/insecure/insecure_security_connector.h',
'src/core/credentials/transport/local/local_credentials.h',
'src/core/credentials/transport/local/local_security_connector.h',
'src/core/credentials/transport/security_connector.h',
'src/core/credentials/transport/ssl/ssl_credentials.h',
'src/core/credentials/transport/ssl/ssl_security_connector.h',
'src/core/credentials/transport/tls/certificate_provider_factory.h',
'src/core/credentials/transport/tls/certificate_provider_registry.h',
'src/core/credentials/transport/tls/grpc_tls_certificate_distributor.h',
'src/core/credentials/transport/tls/grpc_tls_certificate_provider.h',
'src/core/credentials/transport/tls/grpc_tls_certificate_verifier.h',
'src/core/credentials/transport/tls/grpc_tls_credentials_options.h',
'src/core/credentials/transport/tls/grpc_tls_crl_provider.h',
'src/core/credentials/transport/tls/load_system_roots.h',
'src/core/credentials/transport/tls/load_system_roots_supported.h',
'src/core/credentials/transport/tls/ssl_utils.h',
'src/core/credentials/transport/tls/tls_credentials.h',
'src/core/credentials/transport/tls/tls_security_connector.h',
'src/core/credentials/transport/tls/tls_utils.h',
'src/core/credentials/transport/transport_credentials.h',
'src/core/credentials/transport/xds/xds_credentials.h',
'src/core/ext/filters/backend_metrics/backend_metric_filter.h',
'src/core/ext/filters/backend_metrics/backend_metric_provider.h',
'src/core/ext/filters/channel_idle/idle_filter_state.h',
@ -2476,7 +2578,6 @@ Pod::Spec.new do |s|
'src/core/ext/transport/chttp2/transport/bin_encoder.h',
'src/core/ext/transport/chttp2/transport/call_tracer_wrapper.h',
'src/core/ext/transport/chttp2/transport/chttp2_transport.h',
'src/core/ext/transport/chttp2/transport/context_list_entry.h',
'src/core/ext/transport/chttp2/transport/decode_huff.h',
'src/core/ext/transport/chttp2/transport/flow_control.h',
'src/core/ext/transport/chttp2/transport/frame.h',
@ -2494,8 +2595,11 @@ Pod::Spec.new do |s|
'src/core/ext/transport/chttp2/transport/hpack_parser.h',
'src/core/ext/transport/chttp2/transport/hpack_parser_table.h',
'src/core/ext/transport/chttp2/transport/http2_settings.h',
'src/core/ext/transport/chttp2/transport/http2_status.h',
'src/core/ext/transport/chttp2/transport/http2_ztrace_collector.h',
'src/core/ext/transport/chttp2/transport/huffsyms.h',
'src/core/ext/transport/chttp2/transport/internal.h',
'src/core/ext/transport/chttp2/transport/internal_channel_arg_names.h',
'src/core/ext/transport/chttp2/transport/legacy_frame.h',
'src/core/ext/transport/chttp2/transport/ping_abuse_policy.h',
'src/core/ext/transport/chttp2/transport/ping_callbacks.h',
@ -2689,6 +2793,8 @@ Pod::Spec.new do |s|
'src/core/ext/upb-gen/envoy/type/http/v3/cookie.upb_minitable.h',
'src/core/ext/upb-gen/envoy/type/http/v3/path_transformation.upb.h',
'src/core/ext/upb-gen/envoy/type/http/v3/path_transformation.upb_minitable.h',
'src/core/ext/upb-gen/envoy/type/matcher/v3/address.upb.h',
'src/core/ext/upb-gen/envoy/type/matcher/v3/address.upb_minitable.h',
'src/core/ext/upb-gen/envoy/type/matcher/v3/filter_state.upb.h',
'src/core/ext/upb-gen/envoy/type/matcher/v3/filter_state.upb_minitable.h',
'src/core/ext/upb-gen/envoy/type/matcher/v3/http_inputs.upb.h',
@ -2924,6 +3030,7 @@ Pod::Spec.new do |s|
'src/core/ext/upbdefs-gen/envoy/service/status/v3/csds.upbdefs.h',
'src/core/ext/upbdefs-gen/envoy/type/http/v3/cookie.upbdefs.h',
'src/core/ext/upbdefs-gen/envoy/type/http/v3/path_transformation.upbdefs.h',
'src/core/ext/upbdefs-gen/envoy/type/matcher/v3/address.upbdefs.h',
'src/core/ext/upbdefs-gen/envoy/type/matcher/v3/filter_state.upbdefs.h',
'src/core/ext/upbdefs-gen/envoy/type/matcher/v3/http_inputs.upbdefs.h',
'src/core/ext/upbdefs-gen/envoy/type/matcher/v3/metadata.upbdefs.h',
@ -2990,6 +3097,7 @@ Pod::Spec.new do |s|
'src/core/ext/upbdefs-gen/xds/type/v3/cel.upbdefs.h',
'src/core/ext/upbdefs-gen/xds/type/v3/range.upbdefs.h',
'src/core/ext/upbdefs-gen/xds/type/v3/typed_struct.upbdefs.h',
'src/core/filter/auth/auth_filters.h',
'src/core/filter/blackboard.h',
'src/core/filter/filter_args.h',
'src/core/handshaker/endpoint_info/endpoint_info_handshaker.h',
@ -3006,7 +3114,6 @@ Pod::Spec.new do |s|
'src/core/handshaker/tcp_connect/tcp_connect_handshaker.h',
'src/core/lib/address_utils/parse_address.h',
'src/core/lib/address_utils/sockaddr_utils.h',
'src/core/lib/channel/call_finalization.h',
'src/core/lib/channel/channel_args.h',
'src/core/lib/channel/channel_args_preconditioning.h',
'src/core/lib/channel/channel_fwd.h',
@ -3015,7 +3122,6 @@ Pod::Spec.new do |s|
'src/core/lib/channel/channel_stack_builder_impl.h',
'src/core/lib/channel/connected_channel.h',
'src/core/lib/channel/promise_based_filter.h',
'src/core/lib/channel/status_util.h',
'src/core/lib/compression/compression_internal.h',
'src/core/lib/compression/message_compress.h',
'src/core/lib/debug/trace.h',
@ -3031,9 +3137,13 @@ Pod::Spec.new do |s|
'src/core/lib/event_engine/default_event_engine.h',
'src/core/lib/event_engine/default_event_engine_factory.h',
'src/core/lib/event_engine/event_engine_context.h',
'src/core/lib/event_engine/extensions/blocking_dns.h',
'src/core/lib/event_engine/extensions/can_track_errors.h',
'src/core/lib/event_engine/extensions/channelz.h',
'src/core/lib/event_engine/extensions/chaotic_good_extension.h',
'src/core/lib/event_engine/extensions/iomgr_compatible.h',
'src/core/lib/event_engine/extensions/supports_fd.h',
'src/core/lib/event_engine/extensions/supports_win_sockets.h',
'src/core/lib/event_engine/extensions/tcp_trace.h',
'src/core/lib/event_engine/forkable.h',
'src/core/lib/event_engine/grpc_polled_fd.h',
@ -3107,7 +3217,6 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/event_engine_shims/endpoint.h',
'src/core/lib/iomgr/event_engine_shims/tcp_client.h',
'src/core/lib/iomgr/exec_ctx.h',
'src/core/lib/iomgr/executor.h',
'src/core/lib/iomgr/internal_errqueue.h',
'src/core/lib/iomgr/iocp_windows.h',
'src/core/lib/iomgr/iomgr.h',
@ -3196,54 +3305,6 @@ Pod::Spec.new do |s|
'src/core/lib/security/authorization/matchers.h',
'src/core/lib/security/authorization/rbac_policy.h',
'src/core/lib/security/authorization/stdout_logger.h',
'src/core/lib/security/certificate_provider/certificate_provider_factory.h',
'src/core/lib/security/certificate_provider/certificate_provider_registry.h',
'src/core/lib/security/context/security_context.h',
'src/core/lib/security/credentials/alts/alts_credentials.h',
'src/core/lib/security/credentials/alts/check_gcp_environment.h',
'src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h',
'src/core/lib/security/credentials/call_creds_util.h',
'src/core/lib/security/credentials/channel_creds_registry.h',
'src/core/lib/security/credentials/composite/composite_credentials.h',
'src/core/lib/security/credentials/credentials.h',
'src/core/lib/security/credentials/external/aws_external_account_credentials.h',
'src/core/lib/security/credentials/external/aws_request_signer.h',
'src/core/lib/security/credentials/external/external_account_credentials.h',
'src/core/lib/security/credentials/external/file_external_account_credentials.h',
'src/core/lib/security/credentials/external/url_external_account_credentials.h',
'src/core/lib/security/credentials/fake/fake_credentials.h',
'src/core/lib/security/credentials/gcp_service_account_identity/gcp_service_account_identity_credentials.h',
'src/core/lib/security/credentials/google_default/google_default_credentials.h',
'src/core/lib/security/credentials/iam/iam_credentials.h',
'src/core/lib/security/credentials/insecure/insecure_credentials.h',
'src/core/lib/security/credentials/jwt/json_token.h',
'src/core/lib/security/credentials/jwt/jwt_credentials.h',
'src/core/lib/security/credentials/jwt/jwt_verifier.h',
'src/core/lib/security/credentials/local/local_credentials.h',
'src/core/lib/security/credentials/oauth2/oauth2_credentials.h',
'src/core/lib/security/credentials/plugin/plugin_credentials.h',
'src/core/lib/security/credentials/ssl/ssl_credentials.h',
'src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.h',
'src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h',
'src/core/lib/security/credentials/tls/grpc_tls_certificate_verifier.h',
'src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h',
'src/core/lib/security/credentials/tls/grpc_tls_crl_provider.h',
'src/core/lib/security/credentials/tls/tls_credentials.h',
'src/core/lib/security/credentials/tls/tls_utils.h',
'src/core/lib/security/credentials/token_fetcher/token_fetcher_credentials.h',
'src/core/lib/security/credentials/xds/xds_credentials.h',
'src/core/lib/security/security_connector/alts/alts_security_connector.h',
'src/core/lib/security/security_connector/fake/fake_security_connector.h',
'src/core/lib/security/security_connector/insecure/insecure_security_connector.h',
'src/core/lib/security/security_connector/load_system_roots.h',
'src/core/lib/security/security_connector/load_system_roots_supported.h',
'src/core/lib/security/security_connector/local/local_security_connector.h',
'src/core/lib/security/security_connector/security_connector.h',
'src/core/lib/security/security_connector/ssl/ssl_security_connector.h',
'src/core/lib/security/security_connector/ssl_utils.h',
'src/core/lib/security/security_connector/tls/tls_security_connector.h',
'src/core/lib/security/transport/auth_filters.h',
'src/core/lib/security/util/json_util.h',
'src/core/lib/slice/percent_encoding.h',
'src/core/lib/slice/slice.h',
'src/core/lib/slice/slice_buffer.h',
@ -3257,7 +3318,6 @@ Pod::Spec.new do |s|
'src/core/lib/surface/channel_create.h',
'src/core/lib/surface/channel_init.h',
'src/core/lib/surface/channel_stack_type.h',
'src/core/lib/surface/client_call.h',
'src/core/lib/surface/completion_queue.h',
'src/core/lib/surface/completion_queue_factory.h',
'src/core/lib/surface/connection_context.h',
@ -3267,27 +3327,11 @@ Pod::Spec.new do |s|
'src/core/lib/surface/init_internally.h',
'src/core/lib/surface/lame_client.h',
'src/core/lib/surface/legacy_channel.h',
'src/core/lib/surface/server_call.h',
'src/core/lib/surface/validate_metadata.h',
'src/core/lib/transport/bdp_estimator.h',
'src/core/lib/transport/call_arena_allocator.h',
'src/core/lib/transport/call_destination.h',
'src/core/lib/transport/call_filters.h',
'src/core/lib/transport/call_final_info.h',
'src/core/lib/transport/call_spine.h',
'src/core/lib/transport/call_state.h',
'src/core/lib/transport/connectivity_state.h',
'src/core/lib/transport/custom_metadata.h',
'src/core/lib/transport/error_utils.h',
'src/core/lib/transport/http2_errors.h',
'src/core/lib/transport/interception_chain.h',
'src/core/lib/transport/message.h',
'src/core/lib/transport/metadata.h',
'src/core/lib/transport/metadata_batch.h',
'src/core/lib/transport/metadata_compression_traits.h',
'src/core/lib/transport/metadata_info.h',
'src/core/lib/transport/parsed_metadata.h',
'src/core/lib/transport/simple_slice_based_metadata.h',
'src/core/lib/transport/status_conversion.h',
'src/core/lib/transport/timeout_encoding.h',
'src/core/lib/transport/transport.h',
@ -3348,11 +3392,16 @@ Pod::Spec.new do |s|
'src/core/service_config/service_config_impl.h',
'src/core/service_config/service_config_parser.h',
'src/core/telemetry/call_tracer.h',
'src/core/telemetry/context_list_entry.h',
'src/core/telemetry/default_tcp_tracer.h',
'src/core/telemetry/histogram_view.h',
'src/core/telemetry/metrics.h',
'src/core/telemetry/stats.h',
'src/core/telemetry/stats_data.h',
'src/core/telemetry/tcp_tracer.h',
'src/core/transport/auth_context.h',
'src/core/transport/endpoint_transport.h',
'src/core/transport/endpoint_transport_client_channel_factory.h',
'src/core/tsi/alts/crypt/gsec.h',
'src/core/tsi/alts/frame_protector/alts_counter.h',
'src/core/tsi/alts/frame_protector/alts_crypter.h',
@ -3387,6 +3436,7 @@ Pod::Spec.new do |s|
'src/core/util/avl.h',
'src/core/util/backoff.h',
'src/core/util/bitset.h',
'src/core/util/check_class_size.h',
'src/core/util/chunked_vector.h',
'src/core/util/construct_destruct.h',
'src/core/util/cpp_impl_of.h',
@ -3400,6 +3450,7 @@ Pod::Spec.new do |s|
'src/core/util/event_log.h',
'src/core/util/examine_stack.h',
'src/core/util/fork.h',
'src/core/util/function_signature.h',
'src/core/util/gcp_metadata_query.h',
'src/core/util/gethostname.h',
'src/core/util/glob.h',
@ -3436,6 +3487,7 @@ Pod::Spec.new do |s|
'src/core/util/ref_counted_ptr.h',
'src/core/util/ref_counted_string.h',
'src/core/util/ring_buffer.h',
'src/core/util/shared_bit_gen.h',
'src/core/util/single_set_ptr.h',
'src/core/util/sorted_pack.h',
'src/core/util/spinlock.h',
@ -3460,6 +3512,7 @@ Pod::Spec.new do |s|
'src/core/util/useful.h',
'src/core/util/uuid_v4.h',
'src/core/util/validation_errors.h',
'src/core/util/wait_for_single_owner.h',
'src/core/util/work_serializer.h',
'src/core/util/xxhash_inline.h',
'src/core/xds/grpc/certificate_provider_store.h',
@ -3491,6 +3544,7 @@ Pod::Spec.new do |s|
'src/core/xds/grpc/xds_route_config_parser.h',
'src/core/xds/grpc/xds_routing.h',
'src/core/xds/grpc/xds_server_grpc.h',
'src/core/xds/grpc/xds_server_grpc_interface.h',
'src/core/xds/grpc/xds_transport_grpc.h',
'src/core/xds/xds_client/lrs_client.h',
'src/core/xds/xds_client/xds_api.h',
@ -3553,8 +3607,8 @@ Pod::Spec.new do |s|
'third_party/upb/upb/message/copy.h',
'third_party/upb/upb/message/internal/accessors.h',
'third_party/upb/upb/message/internal/array.h',
'third_party/upb/upb/message/internal/compare_unknown.h',
'third_party/upb/upb/message/internal/extension.h',
'third_party/upb/upb/message/internal/iterator.h',
'third_party/upb/upb/message/internal/map.h',
'third_party/upb/upb/message/internal/map_entry.h',
'third_party/upb/upb/message/internal/map_sorter.h',
@ -3642,6 +3696,8 @@ Pod::Spec.new do |s|
'third_party/upb/upb/wire/reader.h',
'third_party/upb/upb/wire/types.h',
'third_party/utf8_range/utf8_range.h',
'third_party/utf8_range/utf8_range_neon.inc',
'third_party/utf8_range/utf8_range_sse.inc',
'third_party/xxhash/xxhash.h',
'third_party/zlib/crc32.h',
'third_party/zlib/deflate.h',
@ -3661,28 +3717,6 @@ Pod::Spec.new do |s|
ss.dependency "#{s.name}/Implementation", version
end
s.subspec 'Cronet-Interface' do |ss|
ss.header_mappings_dir = 'include/grpc'
ss.source_files = 'include/grpc/grpc_cronet.h'
end
s.subspec 'Cronet-Implementation' do |ss|
ss.header_mappings_dir = '.'
ss.dependency "#{s.name}/Interface", version
ss.dependency "#{s.name}/Implementation", version
ss.dependency "#{s.name}/Privacy", version
ss.dependency "#{s.name}/Cronet-Interface", version
ss.source_files = 'src/core/ext/transport/cronet/client/secure/cronet_channel_create.cc',
'src/core/ext/transport/cronet/client/secure/cronet_channel_create.h',
'src/core/ext/transport/cronet/transport/cronet_status.cc',
'src/core/ext/transport/cronet/transport/cronet_status.h',
'src/core/ext/transport/cronet/transport/cronet_transport.cc',
'src/core/ext/transport/cronet/transport/cronet_transport.h',
'third_party/objective_c/Cronet/bidirectional_stream_c.h'
end
# patch include of openssl to openssl_grpc
s.prepare_command = <<-END_OF_COMMAND
set -e

View File

@ -21,7 +21,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-ProtoRPC'
version = '1.70.0-dev'
version = '1.73.1'
s.version = version
s.summary = 'RPC library for Protocol Buffers, based on gRPC'
s.homepage = 'https://grpc.io'
@ -33,8 +33,8 @@ Pod::Spec.new do |s|
:tag => "v#{version}",
}
s.ios.deployment_target = '11.0'
s.osx.deployment_target = '10.14'
s.ios.deployment_target = '15.0'
s.osx.deployment_target = '11.0'
s.tvos.deployment_target = '13.0'
s.watchos.deployment_target = '6.0'
s.visionos.deployment_target = '1.0'
@ -55,7 +55,7 @@ Pod::Spec.new do |s|
ss.header_mappings_dir = "src/objective-c/ProtoRPC"
ss.dependency "#{s.name}/Legacy-Header", version
ss.dependency 'gRPC/Interface', version
ss.dependency 'Protobuf', '~> 3.0'
ss.dependency 'Protobuf', '~> 4.0'
ss.source_files = "src/objective-c/ProtoRPC/ProtoMethod.{h,m}",
"src/objective-c/ProtoRPC/ProtoRPC.{h,m}",
@ -68,7 +68,7 @@ Pod::Spec.new do |s|
ss.dependency "#{s.name}/Legacy-Header", version
ss.dependency 'gRPC/GRPCCore', version
ss.dependency 'gRPC-RxLibrary', version
ss.dependency 'Protobuf', '~> 3.0'
ss.dependency 'Protobuf', '~> 4.0'
ss.source_files = "src/objective-c/ProtoRPC/ProtoRPCLegacy.m",
"src/objective-c/ProtoRPC/ProtoServiceLegacy.m"

View File

@ -21,7 +21,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-RxLibrary'
version = '1.70.0-dev'
version = '1.73.1'
s.version = version
s.summary = 'Reactive Extensions library for iOS/OSX.'
s.homepage = 'https://grpc.io'
@ -33,8 +33,8 @@ Pod::Spec.new do |s|
:tag => "v#{version}",
}
s.ios.deployment_target = '11.0'
s.osx.deployment_target = '10.14'
s.ios.deployment_target = '15.0'
s.osx.deployment_target = '11.0'
s.tvos.deployment_target = '13.0'
s.watchos.deployment_target = '6.0'
s.visionos.deployment_target = '1.0'

View File

@ -20,7 +20,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC'
version = '1.70.0-dev'
version = '1.73.1'
s.version = version
s.summary = 'gRPC client library for iOS/OSX'
s.homepage = 'https://grpc.io'
@ -45,8 +45,8 @@ Pod::Spec.new do |s|
'CLANG_CXX_LANGUAGE_STANDARD' => 'c++17',
}
s.ios.deployment_target = '11.0'
s.osx.deployment_target = '10.14'
s.ios.deployment_target = '15.0'
s.osx.deployment_target = '11.0'
s.tvos.deployment_target = '13.0'
s.watchos.deployment_target = '6.0'
s.visionos.deployment_target = '1.0'
@ -64,7 +64,6 @@ Pod::Spec.new do |s|
ss.public_header_files = "src/objective-c/GRPCClient/GRPCCall+ChannelArg.h",
"src/objective-c/GRPCClient/GRPCCall+ChannelCredentials.h",
"src/objective-c/GRPCClient/GRPCCall+Cronet.h",
"src/objective-c/GRPCClient/GRPCCall+OAuth2.h",
"src/objective-c/GRPCClient/GRPCCall+Tests.h",
"src/objective-c/GRPCClient/GRPCCallLegacy.h",
@ -72,7 +71,6 @@ Pod::Spec.new do |s|
ss.source_files = "src/objective-c/GRPCClient/GRPCCall+ChannelArg.h",
"src/objective-c/GRPCClient/GRPCCall+ChannelCredentials.h",
"src/objective-c/GRPCClient/GRPCCall+Cronet.h",
"src/objective-c/GRPCClient/GRPCCall+OAuth2.h",
"src/objective-c/GRPCClient/GRPCCall+Tests.h",
"src/objective-c/GRPCClient/GRPCCallLegacy.h",
@ -80,8 +78,8 @@ Pod::Spec.new do |s|
"src/objective-c/GRPCClient/GRPCTypes.mm"
ss.dependency "gRPC-RxLibrary/Interface", version
ss.dependency "#{s.name}/Privacy", version
s.ios.deployment_target = '11.0'
s.osx.deployment_target = '10.14'
s.ios.deployment_target = '15.0'
s.osx.deployment_target = '11.0'
s.tvos.deployment_target = '13.0'
s.watchos.deployment_target = '6.0'
s.visionos.deployment_target = '1.0'
@ -116,8 +114,8 @@ Pod::Spec.new do |s|
ss.dependency "#{s.name}/Interface-Legacy", version
ss.dependency "#{s.name}/Privacy", version
s.ios.deployment_target = '11.0'
s.osx.deployment_target = '10.14'
s.ios.deployment_target = '15.0'
s.osx.deployment_target = '11.0'
s.tvos.deployment_target = '13.0'
s.watchos.deployment_target = '6.0'
s.visionos.deployment_target = '1.0'
@ -127,7 +125,6 @@ Pod::Spec.new do |s|
ss.header_mappings_dir = 'src/objective-c/GRPCClient'
ss.public_header_files = 'src/objective-c/GRPCClient/GRPCCall+ChannelCredentials.h',
'src/objective-c/GRPCClient/GRPCCall+Cronet.h',
'src/objective-c/GRPCClient/GRPCCall+OAuth2.h',
'src/objective-c/GRPCClient/GRPCCall+Tests.h',
'src/objective-c/GRPCClient/GRPCCall+ChannelArg.h'
@ -137,8 +134,6 @@ Pod::Spec.new do |s|
'src/objective-c/GRPCClient/GRPCCall+ChannelArg.mm',
'src/objective-c/GRPCClient/GRPCCall+ChannelCredentials.h',
'src/objective-c/GRPCClient/GRPCCall+ChannelCredentials.mm',
'src/objective-c/GRPCClient/GRPCCall+Cronet.h',
'src/objective-c/GRPCClient/GRPCCall+Cronet.mm',
'src/objective-c/GRPCClient/GRPCCall+OAuth2.h',
'src/objective-c/GRPCClient/GRPCCall+OAuth2.mm',
'src/objective-c/GRPCClient/GRPCCall+Tests.h',
@ -154,33 +149,19 @@ Pod::Spec.new do |s|
ss.dependency 'gRPC-Core', version
ss.dependency 'gRPC-RxLibrary', version
s.ios.deployment_target = '11.0'
s.osx.deployment_target = '10.14'
s.ios.deployment_target = '15.0'
s.osx.deployment_target = '11.0'
s.tvos.deployment_target = '13.0'
s.watchos.deployment_target = '6.0'
s.visionos.deployment_target = '1.0'
end
s.subspec 'GRPCCoreCronet' do |ss|
ss.header_mappings_dir = 'src/objective-c/GRPCClient'
ss.source_files = 'src/objective-c/GRPCClient/GRPCCall+Cronet.h',
'src/objective-c/GRPCClient/GRPCCall+Cronet.mm',
'src/objective-c/GRPCClient/private/GRPCCore/GRPCCoreCronet/*.{h,mm}'
ss.dependency "#{s.name}/GRPCCore", version
ss.dependency "#{s.name}/Privacy", version
ss.dependency 'gRPC-Core/Cronet-Implementation', version
ss.dependency 'CronetFramework'
ss.ios.deployment_target = '11.0'
end
# CFStream is now default. Leaving this subspec only for compatibility purpose.
s.subspec 'CFStream' do |ss|
ss.dependency "#{s.name}/GRPCCore", version
s.ios.deployment_target = '11.0'
s.osx.deployment_target = '10.14'
s.ios.deployment_target = '15.0'
s.osx.deployment_target = '11.0'
s.tvos.deployment_target = '13.0'
s.watchos.deployment_target = '6.0'
s.visionos.deployment_target = '1.0'
@ -192,8 +173,8 @@ Pod::Spec.new do |s|
ss.source_files = 'src/objective-c/GRPCClient/internal_testing/*.{h,mm}'
ss.header_mappings_dir = 'src/objective-c/GRPCClient'
s.ios.deployment_target = '11.0'
s.osx.deployment_target = '10.14'
s.ios.deployment_target = '15.0'
s.osx.deployment_target = '11.0'
s.tvos.deployment_target = '13.0'
s.watchos.deployment_target = '6.0'
s.visionos.deployment_target = '1.0'

View File

@ -16,10 +16,10 @@
#include <grpc/support/port_platform.h>
#include <optional>
#include <string>
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
namespace grpc_event_engine {
namespace experimental {
@ -32,11 +32,11 @@ class EndpointConfig {
public:
virtual ~EndpointConfig() = default;
// If the key points to an integer config, an integer value gets returned.
// Otherwise it returns an absl::nullopt_t
virtual absl::optional<int> GetInt(absl::string_view key) const = 0;
// Otherwise it returns an std::nullopt_t
virtual std::optional<int> GetInt(absl::string_view key) const = 0;
// If the key points to an string config, an string value gets returned.
// Otherwise it returns an absl::nullopt_t
virtual absl::optional<absl::string_view> GetString(
// Otherwise it returns an std::nullopt_t
virtual std::optional<absl::string_view> GetString(
absl::string_view key) const = 0;
// If the key points to an void* config, a void* pointer value gets returned.
// Otherwise it returns nullptr

View File

@ -16,11 +16,14 @@
#include <grpc/event_engine/endpoint_config.h>
#include <grpc/event_engine/extensible.h>
#include <grpc/event_engine/internal/write_event.h>
#include <grpc/event_engine/memory_allocator.h>
#include <grpc/event_engine/port.h>
#include <grpc/event_engine/slice_buffer.h>
#include <grpc/support/port_platform.h>
#include <bitset>
#include <initializer_list>
#include <vector>
#include "absl/functional/any_invocable.h"
@ -28,6 +31,7 @@
#include "absl/status/statusor.h"
// TODO(vigneshbabu): Define the Endpoint::Write metrics collection system
// TODO(hork): remove all references to the factory methods.
namespace grpc_event_engine {
namespace experimental {
@ -179,13 +183,26 @@ class EventEngine : public std::enable_shared_from_this<EventEngine>,
/// EventEngine Endpoint Read API call.
///
/// Passed as argument to an Endpoint \a Read
struct ReadArgs {
class ReadArgs final {
public:
ReadArgs() = default;
ReadArgs(const ReadArgs&) = delete;
ReadArgs& operator=(const ReadArgs&) = delete;
ReadArgs(ReadArgs&&) = default;
ReadArgs& operator=(ReadArgs&&) = default;
// A suggestion to the endpoint implementation to read at-least the
// specified number of bytes over the network connection before marking
// the endpoint read operation as complete. gRPC may use this argument
// to minimize the number of endpoint read API calls over the lifetime
// of a connection.
int64_t read_hint_bytes;
void set_read_hint_bytes(int64_t read_hint_bytes) {
read_hint_bytes_ = read_hint_bytes;
}
int64_t read_hint_bytes() const { return read_hint_bytes_; }
private:
int64_t read_hint_bytes_ = 1;
};
/// Reads data from the Endpoint.
///
@ -211,20 +228,110 @@ class EventEngine : public std::enable_shared_from_this<EventEngine>,
/// statuses to \a on_read. For example, callbacks might expect to receive
/// CANCELLED on endpoint shutdown.
virtual bool Read(absl::AnyInvocable<void(absl::Status)> on_read,
SliceBuffer* buffer, const ReadArgs* args) = 0;
SliceBuffer* buffer, ReadArgs args) = 0;
//// The set of write events that can be reported by an Endpoint.
using WriteEvent = ::grpc_event_engine::experimental::internal::WriteEvent;
/// An output WriteMetric consists of a key and a value.
/// The space of keys can be queried from the endpoint via the
/// \a AllWriteMetrics, \a GetMetricName and \a GetMetricKey APIs.
/// The value is an int64_t that is implementation-defined. Check with the
/// endpoint implementation documentation for the semantics of each metric.
struct WriteMetric {
size_t key;
int64_t value;
};
using WriteEventCallback = absl::AnyInvocable<void(
WriteEvent, absl::Time, std::vector<WriteMetric>) const>;
// A bitmask of the events that the caller is interested in.
// Each bit corresponds to an entry in WriteEvent.
using WriteEventSet = std::bitset<static_cast<int>(WriteEvent::kCount)>;
// A sink to receive write events.
// The requested metrics are the keys of the metrics that the caller is
// interested in. The on_event callback will be called on each event
// requested.
class WriteEventSink final {
public:
WriteEventSink(absl::Span<const size_t> requested_metrics,
std::initializer_list<WriteEvent> requested_events,
WriteEventCallback on_event)
: requested_metrics_(requested_metrics),
on_event_(std::move(on_event)) {
for (auto event : requested_events) {
requested_events_mask_.set(static_cast<int>(event));
}
}
absl::Span<const size_t> requested_metrics() const {
return requested_metrics_;
}
bool requested_event(WriteEvent event) const {
return requested_events_mask_.test(static_cast<int>(event));
}
WriteEventSet requested_events_mask() const {
return requested_events_mask_;
}
WriteEventCallback TakeEventCallback() { return std::move(on_event_); }
private:
absl::Span<const size_t> requested_metrics_;
WriteEventSet requested_events_mask_;
// The callback to be called on each event.
WriteEventCallback on_event_;
};
/// A struct representing optional arguments that may be provided to an
/// EventEngine Endpoint Write API call.
///
/// Passed as argument to an Endpoint \a Write
struct WriteArgs {
class WriteArgs final {
public:
WriteArgs() = default;
WriteArgs(const WriteArgs&) = delete;
WriteArgs& operator=(const WriteArgs&) = delete;
WriteArgs(WriteArgs&&) = default;
WriteArgs& operator=(WriteArgs&&) = default;
// A sink to receive write events.
std::optional<WriteEventSink> TakeMetricsSink() {
auto sink = std::move(metrics_sink_);
metrics_sink_.reset();
return sink;
}
bool has_metrics_sink() const { return metrics_sink_.has_value(); }
void set_metrics_sink(WriteEventSink sink) {
metrics_sink_ = std::move(sink);
}
// Represents private information that may be passed by gRPC for
// select endpoints expected to be used only within google.
void* google_specific = nullptr;
// TODO(ctiller): Remove this method once all callers are migrated to
// metrics sink.
void* GetDeprecatedAndDiscouragedGoogleSpecificPointer() {
return google_specific_;
}
void SetDeprecatedAndDiscouragedGoogleSpecificPointer(void* pointer) {
google_specific_ = pointer;
}
// A suggestion to the endpoint implementation to group data to be written
// into frames of the specified max_frame_size. gRPC may use this
// argument to dynamically control the max sizes of frames sent to a
// receiver in response to high receiver memory pressure.
int64_t max_frame_size;
int64_t max_frame_size() const { return max_frame_size_; }
void set_max_frame_size(int64_t max_frame_size) {
max_frame_size_ = max_frame_size;
}
private:
std::optional<WriteEventSink> metrics_sink_;
void* google_specific_ = nullptr;
int64_t max_frame_size_ = 1024 * 1024;
};
/// Writes data out on the connection.
///
@ -247,11 +354,22 @@ class EventEngine : public std::enable_shared_from_this<EventEngine>,
/// statuses to \a on_writable. For example, callbacks might expect to
/// receive CANCELLED on endpoint shutdown.
virtual bool Write(absl::AnyInvocable<void(absl::Status)> on_writable,
SliceBuffer* data, const WriteArgs* args) = 0;
SliceBuffer* data, WriteArgs args) = 0;
/// Returns an address in the format described in DNSResolver. The returned
/// values are expected to remain valid for the life of the Endpoint.
virtual const ResolvedAddress& GetPeerAddress() const = 0;
virtual const ResolvedAddress& GetLocalAddress() const = 0;
/// Returns the list of write metrics that the endpoint supports.
/// The keys are used to identify the metrics in the GetMetricName and
/// GetMetricKey APIs. The current value of the metric can be queried by
/// adding a WriteEventSink to the WriteArgs of a Write call.
virtual std::vector<size_t> AllWriteMetrics() = 0;
/// Returns the name of the write metric with the given key.
/// If the key is not found, returns std::nullopt.
virtual std::optional<absl::string_view> GetMetricName(size_t key) = 0;
/// Returns the key of the write metric with the given name.
/// If the name is not found, returns std::nullopt.
virtual std::optional<size_t> GetMetricKey(absl::string_view name) = 0;
};
/// Called when a new connection is established.
@ -333,7 +451,7 @@ class EventEngine : public std::enable_shared_from_this<EventEngine>,
/// when the object is destroyed and all pending callbacks will be called
/// shortly. If cancellation races with request completion, implementations
/// may choose to either cancel or satisfy the request.
class DNSResolver {
class DNSResolver : public Extensible {
public:
/// Optional configuration for DNSResolvers.
struct ResolverOptions {
@ -471,7 +589,7 @@ class EventEngine : public std::enable_shared_from_this<EventEngine>,
virtual bool Cancel(TaskHandle handle) = 0;
};
/// Replace gRPC's default EventEngine factory.
/// [DEPRECATED] Replace gRPC's default EventEngine factory.
///
/// Applications may call \a SetEventEngineFactory at any time to replace the
/// default factory used within gRPC. EventEngines will be created when
@ -480,18 +598,56 @@ class EventEngine : public std::enable_shared_from_this<EventEngine>,
/// To be certain that none of the gRPC-provided built-in EventEngines are
/// created, applications must set a custom EventEngine factory method *before*
/// grpc is initialized.
// TODO(hork): delete once all known users have migrated away
void SetEventEngineFactory(
absl::AnyInvocable<std::unique_ptr<EventEngine>()> factory);
absl::AnyInvocable<std::shared_ptr<EventEngine>()> factory);
/// Reset gRPC's EventEngine factory to the built-in default.
/// [DEPRECATED] Reset gRPC's EventEngine factory to the built-in default.
///
/// Applications that have called \a SetEventEngineFactory can remove their
/// custom factory using this method. The built-in EventEngine factories will be
/// used going forward. This has no affect on any EventEngines that were created
/// using the previous factories.
//
// TODO(hork): delete once all known users have migrated away
void EventEngineFactoryReset();
/// Create an EventEngine using the default factory.
std::unique_ptr<EventEngine> CreateEventEngine();
/// Create a new EventEngine instance.
std::shared_ptr<EventEngine> CreateEventEngine();
/// Set the default EventEngine instance, which will be used throughout gRPC
///
/// gRPC will hold a ref to this engine until either
/// \a ShutdownDefaultEventEngine() is called or \a SetDefaultEventEngine() is
/// called again with a different value. Passing a value of nullptr will cause
/// gRPC to drop the ref it was holding without setting it to a new one.
///
/// Earlier calls to \a GetDefaultEventEngine will still hold a ref to the
/// previous default engine instance, if any.
void SetDefaultEventEngine(std::shared_ptr<EventEngine> engine);
/// Returns the default EventEngine instance.
///
/// Note that if SetDefaultEventEngine() has not been called, then the default
/// EventEngine may be created and destroyed as needed, meaning that multiple
/// calls to GetDefaultEventEngine() over a process's lifetime may return
/// different instances. Callers are expected to call GetDefaultEventEngine()
/// once and hold the returned reference for as long as they need the
/// EventEngine instance.
std::shared_ptr<EventEngine> GetDefaultEventEngine();
/// Resets gRPC to use one of the default internal EventEngines for all *new*
/// \a GetDefaultEventEngine requests and blocks until all refs on the active
/// default engine have been released (destroying that engine).
///
/// If you called \a SetDefaultEventEngine, you must call either
/// \a ShutdownDefaultEventEngine or \a SetDefaultEventEngine(nullptr) at the
/// end of your program. If you don't, the engine will never be destroyed.
///
/// If you want to reset the default engine to one of gRPC's internal versions
/// without waiting for all references to be released on the current default
/// engine, call \a SetDefaultEventEngine(nullptr) instead.
void ShutdownDefaultEventEngine();
bool operator==(const EventEngine::TaskHandle& lhs,
const EventEngine::TaskHandle& rhs);

View File

@ -0,0 +1,34 @@
// Copyright 2022 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef GRPC_EVENT_ENGINE_INTERNAL_WRITE_EVENT_H
#define GRPC_EVENT_ENGINE_INTERNAL_WRITE_EVENT_H
namespace grpc_event_engine::experimental::internal {
// Use of this enum via this name is internal to gRPC.
// API users should get this enumeration via the
// EventEngine::Endpoint::WriteEvent.
enum class WriteEvent {
kSendMsg,
kScheduled,
kSent,
kAcked,
kClosed,
kCount // Must be last.
};
} // namespace grpc_event_engine::experimental::internal
#endif // GRPC_EVENT_ENGINE_INTERNAL_WRITE_EVENT_H

View File

@ -55,11 +55,11 @@ class MemoryRequest {
template <typename Sink>
friend void AbslStringify(Sink& s, const MemoryRequest& r) {
if (r.min_ == r.max_) {
s.Append(r.min_);
s.Append(std::to_string(r.min_));
} else {
s.Append(r.min_);
s.Append(std::to_string(r.min_));
s.Append("..");
s.Append(r.max_);
s.Append(std::to_string(r.max_));
}
}

View File

@ -1,37 +0,0 @@
/*
*
* Copyright 2016 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef GRPC_GRPC_CRONET_H
#define GRPC_GRPC_CRONET_H
#include <grpc/grpc.h>
#include <grpc/support/port_platform.h>
#ifdef __cplusplus
extern "C" {
#endif
GRPCAPI grpc_channel* grpc_cronet_secure_channel_create(
void* engine, const char* target, const grpc_channel_args* args,
void* reserved);
#ifdef __cplusplus
}
#endif
#endif /* GRPC_GRPC_CRONET_H */

View File

@ -31,13 +31,15 @@
#define GRPC_ARG_SERVER_CALL_METRIC_RECORDING \
"grpc.server_call_metric_recording"
/** Request that optional features default to off (regardless of what they
usually default to) - to enable tight control over what gets enabled */
usually default to) - to enable tight control over what gets enabled
Boolean valued. Defaults to false. */
#define GRPC_ARG_MINIMAL_STACK "grpc.minimal_stack"
/** Maximum number of concurrent incoming streams to allow on a http2
connection. Int valued. */
connection. Int valued. Deafult to -1(indicating no explicit limit).*/
#define GRPC_ARG_MAX_CONCURRENT_STREAMS "grpc.max_concurrent_streams"
/** Maximum message length that the channel can receive. Int valued, bytes.
-1 means unlimited. */
-1 means unlimited. Defaults to 4MB(4*1024*1024 bytes). -1 means unlimited.
*/
#define GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH "grpc.max_receive_message_length"
/** \deprecated For backward compatibility.
* Use GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH instead. */
@ -47,27 +49,31 @@
#define GRPC_ARG_MAX_SEND_MESSAGE_LENGTH "grpc.max_send_message_length"
/** Maximum time that a channel may have no outstanding rpcs, after which the
* server will close the connection. Int valued, milliseconds. INT_MAX means
* unlimited. */
* unlimited. Defaults to INT_MAX. */
#define GRPC_ARG_MAX_CONNECTION_IDLE_MS "grpc.max_connection_idle_ms"
/** Maximum time that a channel may exist. Int valued, milliseconds.
* INT_MAX means unlimited. */
/** Maximum amount of time in milliseconds that a connection may exist before it
* will be gracefully shut down. Refer
* https://github.com/grpc/proposal/blob/master/A9-server-side-conn-mgt.md for
* more details. Int valued, defaults to INT_MAX (disabled). */
#define GRPC_ARG_MAX_CONNECTION_AGE_MS "grpc.max_connection_age_ms"
/** Grace period after the channel reaches its max age. Int valued,
milliseconds. INT_MAX means unlimited. */
/** Grace period in milliseconds after connection reaches its max age for
* outstanding RPCs to complete. Int valued, defaults to INT_MAX (disabled). */
#define GRPC_ARG_MAX_CONNECTION_AGE_GRACE_MS "grpc.max_connection_age_grace_ms"
/** Timeout after the last RPC finishes on the client channel at which the
* channel goes back into IDLE state. Int valued, milliseconds. INT_MAX means
* unlimited. The default value is 30 minutes and the min value is 1 second. */
#define GRPC_ARG_CLIENT_IDLE_TIMEOUT_MS "grpc.client_idle_timeout_ms"
/** Enable/disable support for per-message compression. Defaults to 1, unless
GRPC_ARG_MINIMAL_STACK is enabled, in which case it defaults to 0. */
/** Enable/disable support for per-message compression. Boolean valued. Defaults
to true, unless GRPC_ARG_MINIMAL_STACK is enabled, in which case it defaults
to false. */
#define GRPC_ARG_ENABLE_PER_MESSAGE_COMPRESSION "grpc.per_message_compression"
/** Experimental Arg. Enable/disable support for per-message decompression.
Defaults to 1. If disabled, decompression will not be performed and the
application will see the compressed message in the byte buffer. */
#define GRPC_ARG_ENABLE_PER_MESSAGE_DECOMPRESSION \
"grpc.per_message_decompression"
/** Initial stream ID for http2 transports. Int valued. */
/** Initial stream ID for http2 transports. Int valued. Defaults to -1
indicating use of default http2 setting initial stream ID (1). */
#define GRPC_ARG_HTTP2_INITIAL_SEQUENCE_NUMBER \
"grpc.http2.initial_sequence_number"
/** Amount to read ahead on individual streams. Defaults to 64kb, larger
@ -75,17 +81,22 @@
NOTE: at some point we'd like to auto-tune this, and this parameter
will become a no-op. Int valued, bytes. */
#define GRPC_ARG_HTTP2_STREAM_LOOKAHEAD_BYTES "grpc.http2.lookahead_bytes"
/** How much memory to use for hpack decoding. Int valued, bytes. */
/** How much memory to use for hpack decoding. Int valued, bytes. Defaults to -1
indicating use of default http2 setting(4096 bytes). */
#define GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_DECODER \
"grpc.http2.hpack_table_size.decoder"
/** How much memory to use for hpack encoding. Int valued, bytes. */
/** How much memory to use for hpack encoding. Int valued, bytes. Defaults to -1
indicating use of default http2 setting(4096 bytes). */
#define GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_ENCODER \
"grpc.http2.hpack_table_size.encoder"
/** How big a frame are we willing to receive via HTTP2.
Min 16384, max 16777215. Larger values give lower CPU usage for large
messages, but more head of line blocking for small messages. */
messages, but more head of line blocking for small messages. Defaults to
-1(indicating no explicit max frame size), so it will take standard http/2
specified max frame size to 16 KB. */
#define GRPC_ARG_HTTP2_MAX_FRAME_SIZE "grpc.http2.max_frame_size"
/** Should BDP probing be performed? */
/** Should BDP probing be performed?
Boolean valued. Defaults to true(enabled). */
#define GRPC_ARG_HTTP2_BDP_PROBE "grpc.http2.bdp_probe"
/** (DEPRECATED) Does not have any effect.
Earlier, this arg configured the minimum time between successive ping frames
@ -109,21 +120,24 @@
before the request is cancelled */
#define GRPC_ARG_SERVER_MAX_UNREQUESTED_TIME_IN_SERVER_SECONDS \
"grpc.server_max_unrequested_time_in_server"
/** Channel arg to override the http2 :scheme header */
/** Channel arg to override the http2 :scheme header. String valued. */
#define GRPC_ARG_HTTP2_SCHEME "grpc.http2_scheme"
/** How many pings can the client send before needing to send a data/header
frame? (0 indicates that an infinite number of pings can be sent without
sending a data frame or header frame).
If experiment "max_pings_wo_data_throttle" is enabled, instead of pings being
completely blocked, they are throttled. */
completely blocked, they are throttled.
* Integer valued. Defaults to 2. */
#define GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA \
"grpc.http2.max_pings_without_data"
/** How many misbehaving pings the server can bear before sending goaway and
closing the transport? (0 indicates that the server can bear an infinite
number of misbehaving pings) */
number of misbehaving pings)
* Integer valued. Defaults to 2. */
#define GRPC_ARG_HTTP2_MAX_PING_STRIKES "grpc.http2.max_ping_strikes"
/** How much data are we willing to queue up per stream if
GRPC_WRITE_BUFFER_HINT is set? This is an upper bound */
GRPC_WRITE_BUFFER_HINT is set? This is an upper bound
* Integer valued, bytes. Defaults to 65535 bytes. */
#define GRPC_ARG_HTTP2_WRITE_BUFFER_SIZE "grpc.http2.write_buffer_size"
/** Should we allow receipt of true-binary data on http2 connections?
Defaults to on (1) */
@ -136,33 +150,44 @@
#define GRPC_ARG_EXPERIMENTAL_HTTP2_PREFERRED_CRYPTO_FRAME_SIZE \
"grpc.experimental.http2.enable_preferred_frame_size"
/** After a duration of this time the client/server pings its peer to see if the
transport is still alive. Int valued, milliseconds. */
transport is still alive. Int valued, milliseconds. Defaults to 7200000 (2
hours). */
#define GRPC_ARG_KEEPALIVE_TIME_MS "grpc.keepalive_time_ms"
/** After waiting for a duration of this time, if the keepalive ping sender does
not receive the ping ack, it will close the transport. Int valued,
milliseconds. */
milliseconds. Defaults to 20000 (20 seonds). */
#define GRPC_ARG_KEEPALIVE_TIMEOUT_MS "grpc.keepalive_timeout_ms"
/** Is it permissible to send keepalive pings from the client without any
outstanding streams. Int valued, 0(false)/1(true). */
outstanding streams. Int valued, 0(false)/1(true). Defaults to 0. */
#define GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS \
"grpc.keepalive_permit_without_calls"
/** Default authority to pass if none specified on call construction. A string.
* */
#define GRPC_ARG_DEFAULT_AUTHORITY "grpc.default_authority"
/** Primary user agent: goes at the start of the user-agent metadata
sent on each request. A string. */
sent on each request. A string. Defaults to empty string(""). */
#define GRPC_ARG_PRIMARY_USER_AGENT_STRING "grpc.primary_user_agent"
/** Secondary user agent: goes at the end of the user-agent metadata
sent on each request. A string. */
#define GRPC_ARG_SECONDARY_USER_AGENT_STRING "grpc.secondary_user_agent"
/** The minimum time between subsequent connection attempts, in ms */
/** The minimum time between subsequent connection attempts, in ms. Refer to
* MIN_CONNECT_TIMEOUT from
* https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md. Defaults
* to 20 seconds. */
#define GRPC_ARG_MIN_RECONNECT_BACKOFF_MS "grpc.min_reconnect_backoff_ms"
/** The maximum time between subsequent connection attempts, in ms */
/** The maximum time between subsequent connection attempts, in ms. Refer to
* MAX_BACKOFF from
* https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md. Defaults
* to 120 seconds. */
#define GRPC_ARG_MAX_RECONNECT_BACKOFF_MS "grpc.max_reconnect_backoff_ms"
/** The time between the first and second connection attempts, in ms */
/** The time between the first and second connection attempts, in ms. Refer to
* INITIAL_BACKOFF from
* https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md. Defaults
* to 1 second. */
#define GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS \
"grpc.initial_reconnect_backoff_ms"
/** Minimum amount of time between DNS resolutions, in ms */
/** Minimum amount of time between DNS resolutions, in ms. Defaults to 30
* seconds. */
#define GRPC_ARG_DNS_MIN_TIME_BETWEEN_RESOLUTIONS_MS \
"grpc.dns_min_time_between_resolutions_ms"
/** The timeout used on servers for finishing handshaking on an incoming
@ -178,10 +203,10 @@
#define GRPC_SSL_TARGET_NAME_OVERRIDE_ARG "grpc.ssl_target_name_override"
/** If non-zero, a pointer to a session cache (a pointer of type
grpc_ssl_session_cache*). (use grpc_ssl_session_cache_arg_vtable() to fetch
an appropriate pointer arg vtable) */
an appropriate pointer arg vtable). */
#define GRPC_SSL_SESSION_CACHE_ARG "grpc.ssl_session_cache"
/** If non-zero, it will determine the maximum frame size used by TSI's frame
* protector.
* protector. Defaults to zero.
*/
#define GRPC_ARG_TSI_MAX_FRAME_SIZE "grpc.tsi.max_frame_size"
/** Maximum metadata size (soft limit), in bytes. Note this limit applies to the
@ -200,17 +225,20 @@
#define GRPC_ARG_ALLOW_REUSEPORT "grpc.so_reuseport"
/** If non-zero, a pointer to a buffer pool (a pointer of type
* grpc_resource_quota*). (use grpc_resource_quota_arg_vtable() to fetch an
* appropriate pointer arg vtable) */
* appropriate pointer arg vtable). */
#define GRPC_ARG_RESOURCE_QUOTA "grpc.resource_quota"
/** If non-zero, expand wildcard addresses to a list of local addresses. */
/** If non-zero, expand wildcard addresses to a list of local addresses. Boolean
* valued. */
#define GRPC_ARG_EXPAND_WILDCARD_ADDRS "grpc.expand_wildcard_addrs"
/** Service config data in JSON form.
This value will be ignored if the name resolver returns a service config. */
This value will be ignored if the name resolver returns a service config. A
string value. */
#define GRPC_ARG_SERVICE_CONFIG "grpc.service_config"
/** Disable looking up the service config via the name resolver. */
/** Disable looking up the service config via the name resolver. Boolean valued.
* Defaults to true. */
#define GRPC_ARG_SERVICE_CONFIG_DISABLE_RESOLUTION \
"grpc.service_config_disable_resolution"
/** LB policy name. */
/** LB policy name. A string value.*/
#define GRPC_ARG_LB_POLICY_NAME "grpc.lb_policy_name"
/** Cap for ring size in the ring_hash LB policy. The min and max ring size
values set in the LB policy config will be capped to this value.
@ -223,24 +251,23 @@
/** The maximum amount of memory used by trace events per channel trace node.
* Once the maximum is reached, subsequent events will evict the oldest events
* from the buffer. The unit for this knob is bytes. Setting it to zero causes
* channel tracing to be disabled. */
* channel tracing to be disabled. Defaults to (1024 * 4) bytes. */
#define GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE \
"grpc.max_channel_trace_event_memory_per_node"
/** If non-zero, gRPC library will track stats and information at at per channel
* level. Disabling channelz naturally disables channel tracing. The default
* is for channelz to be enabled. */
#define GRPC_ARG_ENABLE_CHANNELZ "grpc.enable_channelz"
/** If non-zero, Cronet transport will coalesce packets to fewer frames
* when possible. */
#define GRPC_ARG_USE_CRONET_PACKET_COALESCING \
"grpc.use_cronet_packet_coalescing"
/** Channel arg (integer) setting how large a slice to try and read from the
wire each time recvmsg (or equivalent) is called **/
wire each time recvmsg (or equivalent). Range varied from 1
to (32 * 1024 * 1024) bytes. Defaults to 8192 bytes. **/
#define GRPC_ARG_TCP_READ_CHUNK_SIZE "grpc.experimental.tcp_read_chunk_size"
/** Note this is not a "channel arg" key. This is the default slice size to use
* when trying to read from the wire if the GRPC_ARG_TCP_READ_CHUNK_SIZE
* channel arg is unspecified. */
#define GRPC_TCP_DEFAULT_READ_SLICE_SIZE 8192
/** Minimum read chunk size defaults to 256 bytes. Range varies from 1 to (32 *
* 1024 * 1024) bytes. */
#define GRPC_ARG_TCP_MIN_READ_CHUNK_SIZE \
"grpc.experimental.tcp_min_read_chunk_size"
#define GRPC_ARG_TCP_MAX_READ_CHUNK_SIZE \
@ -259,10 +286,12 @@
issued by the tcp_write(). By default, this is set to 4. */
#define GRPC_ARG_TCP_TX_ZEROCOPY_MAX_SIMULT_SENDS \
"grpc.experimental.tcp_tx_zerocopy_max_simultaneous_sends"
/* Overrides the TCP socket receive buffer size, SO_RCVBUF. */
/* Overrides the TCP socket receive buffer size, SO_RCVBUF.
Default value is -1(kReadBufferSizeUnset) indicating that the system will
decide the buffer size. Range varies from 0 to INT_MAX. */
#define GRPC_ARG_TCP_RECEIVE_BUFFER_SIZE "grpc.tcp_receive_buffer_size"
/* Timeout in milliseconds to use for calls to the grpclb load balancer.
If 0 or unset, the balancer calls will have no deadline. */
If 0 or unset, the balancer calls will have no deadline. Defaults to 0 ms. */
#define GRPC_ARG_GRPCLB_CALL_TIMEOUT_MS "grpc.grpclb_call_timeout_ms"
/* Specifies the xDS bootstrap config as a JSON string.
FOR TESTING PURPOSES ONLY -- DO NOT USE IN PRODUCTION.
@ -277,7 +306,7 @@
"grpc.TEST_ONLY_DO_NOT_USE_IN_PROD.xds_bootstrap_config"
/* Timeout in milliseconds to wait for the serverlist from the grpclb load
balancer before using fallback backend addresses from the resolver.
If 0, enter fallback mode immediately. Default value is 10000. */
If 0, enter fallback mode immediately. Default value is 10000ms. */
#define GRPC_ARG_GRPCLB_FALLBACK_TIMEOUT_MS "grpc.grpclb_fallback_timeout_ms"
/* Experimental Arg. Channel args to be used for the control-plane channel
* created to the grpclb load balancers. This is a pointer arg whose value is a
@ -290,9 +319,6 @@
over to the next priority. Default value is 10 seconds. */
#define GRPC_ARG_PRIORITY_FAILOVER_TIMEOUT_MS \
"grpc.priority_failover_timeout_ms"
/** If non-zero, grpc server's cronet compression workaround will be enabled */
#define GRPC_ARG_WORKAROUND_CRONET_COMPRESSION \
"grpc.workaround.cronet_compression"
/** String defining the optimization target for a channel.
Can be: "latency" - attempt to minimize latency at the cost of throughput
"blend" - try to balance latency and throughput
@ -325,13 +351,15 @@
/** Channel arg that carries the bridged objective c object for custom metrics
* logging filter. */
#define GRPC_ARG_MOBILE_LOG_CONTEXT "grpc.mobile_log_context"
/** If non-zero, client authority filter is disabled for the channel */
/** If non-zero, client authority filter is disabled for the channel.
* Boolean valued. Defaults to false. */
#define GRPC_ARG_DISABLE_CLIENT_AUTHORITY_FILTER \
"grpc.disable_client_authority_filter"
/** If set to zero, disables use of http proxies. Enabled by default. */
#define GRPC_ARG_ENABLE_HTTP_PROXY "grpc.enable_http_proxy"
/** Channel arg to set http proxy per channel. If set, the channel arg
* value will be preferred over the environment variable settings. */
* value will be preferred over the environment variable settings. String
* value. */
#define GRPC_ARG_HTTP_PROXY "grpc.http_proxy"
/** Specifies an HTTP proxy to use for individual addresses.
* The proxy must be specified as an IP address, not a DNS name.
@ -347,7 +375,7 @@
agent is surfaced by default. */
#define GRPC_ARG_SURFACE_USER_AGENT "grpc.surface_user_agent"
/** If set, inhibits health checking (which may be enabled via the
* service config.) */
* service config.). Boolean valued. Defaults to false. */
#define GRPC_ARG_INHIBIT_HEALTH_CHECKING "grpc.inhibit_health_checking"
/** If enabled, the channel's DNS resolver queries for SRV records.
* This is useful only when using the "grpclb" load balancing policy,
@ -356,17 +384,17 @@
* https://github.com/grpc/proposal/blob/master/A24-lb-policy-config.md
* https://github.com/grpc/proposal/blob/master/A26-grpclb-selection.md
* Note that this works only with the "ares" DNS resolver; it isn't supported
* by the "native" DNS resolver. */
* by the "native" DNS resolver. Boolean valued. Defaults to false. */
#define GRPC_ARG_DNS_ENABLE_SRV_QUERIES "grpc.dns_enable_srv_queries"
/** If set, determines an upper bound on the number of milliseconds that the
* c-ares based DNS resolver will wait on queries before cancelling them.
* The default value is 120,000. Setting this to "0" will disable the
* The default value is 120,000ms. Setting this to "0" will disable the
* overall timeout entirely. Note that this doesn't include internal c-ares
* timeouts/backoff/retry logic, and so the actual DNS resolution may time out
* sooner than the value specified here. */
#define GRPC_ARG_DNS_ARES_QUERY_TIMEOUT_MS "grpc.dns_ares_query_timeout"
/** If set, uses a local subchannel pool within the channel. Otherwise, uses the
* global subchannel pool. */
* global subchannel pool. Boolean valued. Defaults to false. */
#define GRPC_ARG_USE_LOCAL_SUBCHANNEL_POOL "grpc.use_local_subchannel_pool"
/** gRPC Objective-C channel pooling domain string. */
#define GRPC_ARG_CHANNEL_POOL_DOMAIN "grpc.channel_pooling_domain"

View File

@ -41,8 +41,9 @@ extern "C" {
* Its value is an int from the \a grpc_compression_algorithm enum. */
#define GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM \
"grpc.default_compression_algorithm"
/** Default compression level for the channel.
* Its value is an int from the \a grpc_compression_level enum. */
/** Set the default compression level for the channel.
* Valid values are defined by the enum type grpc_compression_level, defaults to
* GRPC_COMPRESS_LEVEL_NONE. */
#define GRPC_COMPRESSION_CHANNEL_DEFAULT_LEVEL "grpc.default_compression_level"
/** Compression algorithms supported by the channel.
* Its value is a bitset (an int). Bits correspond to algorithms in \a

View File

@ -73,7 +73,7 @@ struct grpc_slice {
} data;
};
#define GRPC_SLICE_BUFFER_INLINE_ELEMENTS 6
#define GRPC_SLICE_BUFFER_INLINE_ELEMENTS 3
/** Represents an expandable array of slices, to be interpreted as a
single item. */

View File

@ -146,7 +146,7 @@ typedef enum {
GRPC_STATUS_DATA_LOSS = 15,
/** Force users to include a default branch: */
GRPC_STATUS__DO_NOT_USE = -1
GRPC_STATUS__DO_NOT_USE = 0x7fffffffu,
} grpc_status_code;
#ifdef __cplusplus

View File

@ -22,11 +22,12 @@
#include <map>
#include <string>
#include <type_traits>
#include <utility>
#include <variant>
#include <vector>
#include "absl/strings/str_cat.h"
#include "absl/types/variant.h"
namespace grpc_core {
namespace experimental {
@ -72,27 +73,8 @@ class Json {
json.value_ = NumberValue{std::move(str)};
return json;
}
static Json FromNumber(int32_t value) {
Json json;
json.value_ = NumberValue{absl::StrCat(value)};
return json;
}
static Json FromNumber(uint32_t value) {
Json json;
json.value_ = NumberValue{absl::StrCat(value)};
return json;
}
static Json FromNumber(int64_t value) {
Json json;
json.value_ = NumberValue{absl::StrCat(value)};
return json;
}
static Json FromNumber(uint64_t value) {
Json json;
json.value_ = NumberValue{absl::StrCat(value)};
return json;
}
static Json FromNumber(double value) {
template <typename T>
static std::enable_if_t<std::is_arithmetic_v<T>, Json> FromNumber(T value) {
Json json;
json.value_ = NumberValue{absl::StrCat(value)};
return json;
@ -147,46 +129,46 @@ class Json {
// Moveable.
Json(Json&& other) noexcept : value_(std::move(other.value_)) {
other.value_ = absl::monostate();
other.value_ = std::monostate();
}
Json& operator=(Json&& other) noexcept {
value_ = std::move(other.value_);
other.value_ = absl::monostate();
other.value_ = std::monostate();
return *this;
}
// Returns the JSON type.
Type type() const {
struct ValueFunctor {
Json::Type operator()(const absl::monostate&) { return Type::kNull; }
Json::Type operator()(const std::monostate&) { return Type::kNull; }
Json::Type operator()(bool) { return Type::kBoolean; }
Json::Type operator()(const NumberValue&) { return Type::kNumber; }
Json::Type operator()(const std::string&) { return Type::kString; }
Json::Type operator()(const Object&) { return Type::kObject; }
Json::Type operator()(const Array&) { return Type::kArray; }
};
return absl::visit(ValueFunctor(), value_);
return std::visit(ValueFunctor(), value_);
}
// Payload accessor for kBoolean.
// Must not be called for other types.
bool boolean() const { return absl::get<bool>(value_); }
bool boolean() const { return std::get<bool>(value_); }
// Payload accessor for kNumber or kString.
// Must not be called for other types.
const std::string& string() const {
const NumberValue* num = absl::get_if<NumberValue>(&value_);
const NumberValue* num = std::get_if<NumberValue>(&value_);
if (num != nullptr) return num->value;
return absl::get<std::string>(value_);
return std::get<std::string>(value_);
}
// Payload accessor for kObject.
// Must not be called for other types.
const Object& object() const { return absl::get<Object>(value_); }
const Object& object() const { return std::get<Object>(value_); }
// Payload accessor for kArray.
// Must not be called for other types.
const Array& array() const { return absl::get<Array>(value_); }
const Array& array() const { return std::get<Array>(value_); }
bool operator==(const Json& other) const { return value_ == other.value_; }
bool operator!=(const Json& other) const { return !(*this == other); }
@ -199,12 +181,12 @@ class Json {
return value == other.value;
}
};
using Value = absl::variant<absl::monostate, // kNull
bool, // kBoolean
NumberValue, // kNumber
std::string, // kString
Object, // kObject
Array>; // kArray
using Value = std::variant<std::monostate, // kNull
bool, // kBoolean
NumberValue, // kNumber
std::string, // kString
Object, // kObject
Array>; // kArray
explicit Json(Value value) : value_(std::move(value)) {}

View File

@ -26,17 +26,20 @@
#define GRPC_DEPRECATED(reason)
#endif // __cplusplus >= 201402L
#ifndef GPR_DISABLE_ABSEIL_SYNC
/*
* Defines GPR_ABSEIL_SYNC to use synchronization features from Abseil
*
* You can opt for gRPC's native synchronization by enabling
* GPR_DISABLE_ABSEIL_SYNC. However, this flag is temporary and will be
* removed once the Abseil synchronization is stabilized.
* If you encounter any issues with this feature, please report them
* by filing a bug at https://github.com/grpc/grpc.
*/
#ifndef GPR_ABSEIL_SYNC
#if defined(__APPLE__)
// This is disabled on Apple platforms because macos/grpc_basictests_c_cpp
// fails with this. https://github.com/grpc/grpc/issues/23661
#else
#define GPR_ABSEIL_SYNC 1
#endif
#endif // GPR_ABSEIL_SYNC
#endif // GPR_DISABLE_ABSEIL_SYNC
/* Get windows.h included everywhere (we need it) */
#if defined(_WIN64) || defined(WIN64) || defined(_WIN32) || defined(WIN32)

View File

@ -23,9 +23,6 @@
* explanation and detailed descriptions of workarounds, see
* /doc/workarounds.md
*/
typedef enum {
GRPC_WORKAROUND_ID_CRONET_COMPRESSION = 0,
GRPC_MAX_WORKAROUND_ID
} grpc_workaround_list;
typedef enum { GRPC_MAX_WORKAROUND_ID } grpc_workaround_list;
#endif /* GRPC_SUPPORT_WORKAROUND_LIST_H */

View File

@ -36,12 +36,12 @@
#include <grpc/support/atm.h>
#include <grpc/support/time.h>
#include <grpcpp/impl/codegen/rpc_service_method.h>
#include <grpcpp/impl/codegen/status.h>
#include <grpcpp/impl/codegen/sync.h>
#include <grpcpp/impl/codegen/time.h>
#include <grpcpp/impl/completion_queue_tag.h>
#include <grpcpp/impl/grpc_library.h>
#include <grpcpp/impl/sync.h>
#include <grpcpp/support/status.h>
#include <list>

View File

@ -26,7 +26,6 @@
#include <string>
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
namespace grpc {
namespace experimental {

View File

@ -116,8 +116,8 @@ class CallbackUnaryHandler : public grpc::internal::MethodHandler {
// A callback that only contains a call to MaybeDone can be run as an
// inline callback regardless of whether or not OnDone is inlineable
// because if the actual OnDone callback needs to be scheduled, MaybeDone
// is responsible for dispatching to an executor thread if needed. Thus,
// when setting up the finish_tag_, we can set its own callback to
// is responsible for dispatching to an EventEngine thread if needed.
// Thus, when setting up the finish_tag_, we can set its own callback to
// inlineable.
finish_tag_.Set(
call_.call(),
@ -152,9 +152,9 @@ class CallbackUnaryHandler : public grpc::internal::MethodHandler {
this->Ref();
// The callback for this function should not be marked inline because it
// is directly invoking a user-controlled reaction
// (OnSendInitialMetadataDone). Thus it must be dispatched to an executor
// thread. However, any OnDone needed after that can be inlined because it
// is already running on an executor thread.
// (OnSendInitialMetadataDone). Thus it must be dispatched to an
// EventEngine thread. However, any OnDone needed after that can be
// inlined because it is already running on an EventEngine thread.
meta_tag_.Set(
call_.call(),
[this](bool ok) {
@ -340,7 +340,7 @@ class CallbackClientStreamingHandler : public grpc::internal::MethodHandler {
this->Ref();
// The callback for this function should not be inlined because it invokes
// a user-controlled reaction, but any resulting OnDone can be inlined in
// the executor to which this callback is dispatched.
// the EventEngine thread to which this callback is dispatched.
meta_tag_.Set(
call_.call(),
[this](bool ok) {
@ -380,7 +380,7 @@ class CallbackClientStreamingHandler : public grpc::internal::MethodHandler {
reactor_.store(reactor, std::memory_order_relaxed);
// The callback for this function should not be inlined because it invokes
// a user-controlled reaction, but any resulting OnDone can be inlined in
// the executor to which this callback is dispatched.
// the EventEngine thread to which this callback is dispatched.
read_tag_.Set(
call_.call(),
[this, reactor](bool ok) {
@ -544,7 +544,7 @@ class CallbackServerStreamingHandler : public grpc::internal::MethodHandler {
this->Ref();
// The callback for this function should not be inlined because it invokes
// a user-controlled reaction, but any resulting OnDone can be inlined in
// the executor to which this callback is dispatched.
// the EventEngine thread to which this callback is dispatched.
meta_tag_.Set(
call_.call(),
[this](bool ok) {
@ -607,7 +607,7 @@ class CallbackServerStreamingHandler : public grpc::internal::MethodHandler {
reactor_.store(reactor, std::memory_order_relaxed);
// The callback for this function should not be inlined because it invokes
// a user-controlled reaction, but any resulting OnDone can be inlined in
// the executor to which this callback is dispatched.
// the EventEngine thread to which this callback is dispatched.
write_tag_.Set(
call_.call(),
[this, reactor](bool ok) {
@ -756,7 +756,7 @@ class CallbackBidiHandler : public grpc::internal::MethodHandler {
this->Ref();
// The callback for this function should not be inlined because it invokes
// a user-controlled reaction, but any resulting OnDone can be inlined in
// the executor to which this callback is dispatched.
// the EventEngine thread to which this callback is dispatched.
meta_tag_.Set(
call_.call(),
[this](bool ok) {
@ -821,7 +821,7 @@ class CallbackBidiHandler : public grpc::internal::MethodHandler {
reactor_.store(reactor, std::memory_order_relaxed);
// The callbacks for these functions should not be inlined because they
// invoke user-controlled reactions, but any resulting OnDones can be
// inlined in the executor to which a callback is dispatched.
// inlined in the EventEngine thread to which a callback is dispatched.
write_tag_.Set(
call_.call(),
[this, reactor](bool ok) {

View File

@ -0,0 +1,137 @@
/*
*
* Copyright 2025 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Protect Code from unwanted/inconvienet macros
* you must follow this pattern when #including port_def.inc in a header file:
*
* #include "other_header.h"
* #include "message.h"
* etc.
*
* #include "port_def.inc" // MUST be last header included
*
* Definitions for this header.
*
* #include "port_undef.inc" //At end of file
*
* This is a textual header with no include guard, because we want to
* detect/prohibit anytime it is #included twice without a corresponding
* #undef.
*/
#ifdef GRPC_PORT_
#error "port_def.inc included multiple times"
#endif
#define GRPC_PORT_
// Windows declares several inconvenient macro names. We #undef them and then
// restore them in port_undef.inc.
#ifdef _WIN32
#pragma push_macro("CompareString")
#undef CompareString
#pragma push_macro("CREATE_NEW")
#undef CREATE_NEW
#pragma push_macro("DELETE")
#undef DELETE
#pragma push_macro("DOUBLE_CLICK")
#undef DOUBLE_CLICK
#pragma push_macro("ERROR")
#undef ERROR
#pragma push_macro("ERROR_BUSY")
#undef ERROR_BUSY
#pragma push_macro("ERROR_INSTALL_FAILED")
#undef ERROR_INSTALL_FAILED
#pragma push_macro("ERROR_NOT_FOUND")
#undef ERROR_NOT_FOUND
#pragma push_macro("ERROR_RETRY")
#undef ERROR_RETRY
#pragma push_macro("ERROR_TIMEOUT")
#undef ERROR_TIMEOUT
#pragma push_macro("GetClassName")
#undef GetClassName
#pragma push_macro("GetCurrentTime")
#undef GetCurrentTime
#pragma push_macro("GetMessage")
#undef GetMessage
#pragma push_macro("GetObject")
#undef GetObject
#pragma push_macro("IGNORE")
#undef IGNORE
#pragma push_macro("IN")
#undef IN
#pragma push_macro("INPUT_KEYBOARD")
#undef INPUT_KEYBOARD
#pragma push_macro("NO_ERROR")
#undef NO_ERROR
#pragma push_macro("OUT")
#undef OUT
#pragma push_macro("OPTIONAL")
#undef OPTIONAL
#pragma push_macro("min")
#undef min
#pragma push_macro("max")
#undef max
#pragma push_macro("NEAR")
#undef NEAR
#pragma push_macro("NO_DATA")
#undef NO_DATA
#pragma push_macro("REASON_UNKNOWN")
#undef REASON_UNKNOWN
#pragma push_macro("SERVICE_DISABLED")
#undef SERVICE_DISABLED
#pragma push_macro("SERVICE_STOP")
#undef SERVICE_STOP
#pragma push_macro("SEVERITY_ERROR")
#undef SEVERITY_ERROR
#pragma push_macro("STATUS_PENDING")
#undef STATUS_PENDING
#pragma push_macro("STRICT")
#undef STRICT
#pragma push_macro("timezone")
#undef timezone
#pragma push_macro("TRUE")
#undef TRUE
#pragma push_macro("FALSE")
#undef FALSE
#pragma push_macro("UNICODE")
#undef UNICODE
#endif // _WIN32
#ifdef __APPLE__
// Inconvenient macro names from /usr/include/mach/boolean.h in some macOS SDKs.
#pragma push_macro("TRUE")
#undef TRUE
#pragma push_macro("FALSE")
#undef FALSE
// Inconvenient macro names from usr/include/sys/syslimits.h in some macOS SDKs.
#pragma push_macro("UID_MAX")
#undef UID_MAX
#pragma push_macro("GID_MAX")
#undef GID_MAX
// TYPE_BOOL is defined in the MacOS's ConditionalMacros.h.
#pragma push_macro("TYPE_BOOL")
#undef TYPE_BOOL
#endif // __APPLE__
#if defined(ANDROID) || defined(__ANDROID__)
// Inconvenient macro names from usr/include/limits.h in some Android NDKs.
#pragma push_macro("UID_MAX")
#undef UID_MAX
#pragma push_macro("GID_MAX")
#undef GID_MAX
#endif // defined(ANDROID) || defined(__ANDROID__)

View File

@ -0,0 +1,75 @@
/*
*
* Copyright 2025 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* #undefs all macros defined in port_def.inc. See comments in port_def.inc
* for more info.
*/
#ifndef GRPC_PORT_
#error "port_undef.inc must be included after port_def.inc"
#endif
#undef GRPC_PORT_
#ifdef _WIN32
#pragma pop_macro("CompareString")
#pragma pop_macro("CREATE_NEW")
#pragma pop_macro("DELETE")
#pragma pop_macro("DOUBLE_CLICK")
#pragma pop_macro("ERROR")
#pragma pop_macro("ERROR_BUSY")
#pragma pop_macro("ERROR_INSTALL_FAILED")
#pragma pop_macro("ERROR_NOT_FOUND")
#pragma pop_macro("ERROR_RETRY")
#pragma pop_macro("ERROR_TIMEOUT")
#pragma pop_macro("GetClassName")
#pragma pop_macro("GetCurrentTime")
#pragma pop_macro("GetMessage")
#pragma pop_macro("GetObject")
#pragma pop_macro("IGNORE")
#pragma pop_macro("IN")
#pragma pop_macro("INPUT_KEYBOARD")
#pragma pop_macro("NO_ERROR")
#pragma pop_macro("OUT")
#pragma pop_macro("OPTIONAL")
#pragma pop_macro("min")
#pragma pop_macro("max")
#pragma pop_macro("NEAR")
#pragma pop_macro("NO_DATA")
#pragma pop_macro("REASON_UNKNOWN")
#pragma pop_macro("SERVICE_DISABLED")
#pragma pop_macro("SERVICE_STOP")
#pragma pop_macro("SEVERITY_ERROR")
#pragma pop_macro("STRICT")
#pragma pop_macro("STATUS_PENDING")
#pragma pop_macro("timezone")
#pragma pop_macro("TRUE")
#pragma pop_macro("FALSE")
#pragma pop_macro("UNICODE")
#endif
#ifdef __APPLE__
#pragma pop_macro("TRUE")
#pragma pop_macro("FALSE")
#pragma pop_macro("UID_MAX")
#pragma pop_macro("GID_MAX")
#pragma pop_macro("TYPE_BOOL")
#endif // __APPLE__
#if defined(ANDROID) || defined(__ANDROID__)
#pragma pop_macro("UID_MAX")
#pragma pop_macro("GID_MAX")
#endif // defined(ANDROID) || defined(__ANDROID__)

View File

@ -17,7 +17,7 @@
#include <grpc/grpc_security.h>
#include <grpc/status.h>
#include <grpcpp/impl/codegen/status.h>
#include <grpcpp/support/status.h>
#include <memory>

View File

@ -501,9 +501,9 @@ class ServerContextBase {
void OnCancel() override {}
void OnDone() override {}
// Override InternalInlineable for this class since its reactions are
// trivial and thus do not need to be run from the executor (triggering a
// thread hop). This should only be used by internal reactors (thus the
// name) and not by user application code.
// trivial and thus do not need to be run from the EventEngine (potentially
// triggering a thread hop). This should only be used by internal reactors
// (thus the name) and not by user application code.
bool InternalInlineable() override { return true; }
};

View File

@ -84,8 +84,10 @@ class ChannelArguments {
void SetMaxSendMessageSize(int size);
/// Set LB policy name.
/// Note that if the name resolver returns only balancer addresses, the
/// grpclb LB policy will be used, regardless of what is specified here.
/// Note that this API implicitly provides an empty config for the
/// specified LB policy, so it cannot be used for any policy with
/// required configuration parameters. For those cases, set the LB
/// policy via the service config instead.
void SetLoadBalancingPolicyName(const std::string& lb_policy_name);
/// Set service config in JSON form.

View File

@ -636,8 +636,8 @@ class ClientCallbackReaderWriterImpl
// like StartCall or RemoveHold. If this is the last operation or hold on this
// object, it will invoke the OnDone reaction. If MaybeFinish was called from
// a reaction, it can call OnDone directly. If not, it would need to schedule
// OnDone onto an executor thread to avoid the possibility of deadlocking with
// any locks in the user code that invoked it.
// OnDone onto an EventEngine thread to avoid the possibility of deadlocking
// with any locks in the user code that invoked it.
void MaybeFinish(bool from_reaction) {
if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub(
1, std::memory_order_acq_rel) == 1)) {

View File

@ -56,7 +56,7 @@ class ServerReactor {
virtual void OnCancel() = 0;
// The following is not API. It is for internal use only and specifies whether
// all reactions of this Reactor can be run without an extra executor
// all reactions of this Reactor can be run without extra EventEngine
// scheduling. This should only be used for internally-defined reactors with
// trivial reactions.
virtual bool InternalInlineable() { return false; }
@ -90,7 +90,7 @@ class ServerCallbackCall {
// advance (used for the ServerContext CompletionOp), and one for where we
// know the inlineability of the OnDone reaction. You should set the inline
// flag to true if either the Reactor is InternalInlineable() or if this
// callback is already being forced to run dispatched to an executor
// callback is already being forced to run dispatched to an EventEngine thread
// (typically because it contains additional work than just the MaybeDone).
void MaybeDone() {
@ -141,12 +141,12 @@ class ServerCallbackCall {
// ever invoked on a fully-Unref'fed ServerCallbackCall.
virtual void CallOnDone() = 0;
// If the OnDone reaction is inlineable, execute it inline. Otherwise send it
// to an executor.
// If the OnDone reaction is inlineable, execute it inline. Otherwise run it
// async on EventEngine.
void ScheduleOnDone(bool inline_ondone);
// If the OnCancel reaction is inlineable, execute it inline. Otherwise send
// it to an executor.
// If the OnCancel reaction is inlineable, execute it inline. Otherwise run it
// async on EventEngine.
void CallOnCancel(ServerReactor* reactor);
// Implement the cancellation constraint counter. Return true if OnCancel
@ -477,10 +477,10 @@ class ServerBidiReactor : public internal::ServerReactor {
}
grpc::internal::Mutex stream_mu_;
// TODO(vjpai): Make stream_or_backlog_ into a std::variant or absl::variant
// once C++17 or ABSL is supported since stream and backlog are
// mutually exclusive in this class. Do likewise with the
// remaining reactor classes and their backlogs as well.
// TODO(vjpai): Make stream_or_backlog_ into an std::variant once C++17 or
// ABSL is supported since stream and backlog are mutually exclusive in this
// class. Do likewise with the remaining reactor classes and their backlogs
// as well.
std::atomic<ServerCallbackReaderWriter<Request, Response>*> stream_{nullptr};
struct PreBindBacklog {
bool send_initial_metadata_wanted = false;

View File

@ -19,9 +19,9 @@
#define GRPCPP_VERSION_INFO_H
#define GRPC_CPP_VERSION_MAJOR 1
#define GRPC_CPP_VERSION_MINOR 70
#define GRPC_CPP_VERSION_PATCH 0
#define GRPC_CPP_VERSION_TAG "dev"
#define GRPC_CPP_VERSION_STRING "1.70.0-dev"
#define GRPC_CPP_VERSION_MINOR 73
#define GRPC_CPP_VERSION_PATCH 1
#define GRPC_CPP_VERSION_TAG ""
#define GRPC_CPP_VERSION_STRING "1.73.1"
#endif // GRPCPP_VERSION_INFO_H
#endif // GRPCPP_VERSION_INFO_H

View File

@ -9,7 +9,7 @@ GRPC_IOS_BUILD_FLAGS="
CODE_SIGNING_ALLOWED=NO
ONLY_ACTIVE_ARCH=NO
ARCHS=arm64
IPHONEOS_DEPLOYMENT_TARGET=12.0
IPHONEOS_DEPLOYMENT_TARGET=15.0
"
# Xcodebuild destination for iOS

View File

@ -28,10 +28,14 @@ targets = (
'grpc_authorization_provider',
'gpr',
'upb_base_lib',
'upb_hash_lib',
'upb_lex_lib',
'upb_mem_lib',
'upb_message_lib',
'upb_mini_descriptor_lib',
'upb_mini_table_lib',
'upb_json_lib',
'upb_reflection_lib',
'upb_textformat_lib',
'upb_wire_lib',
'utf8_range_lib',
@ -53,17 +57,6 @@ extra_files = (
'src/objective-c/!ProtoCompiler-gRPCPlugin.podspec',
'src/objective-c/!ProtoCompiler.podspec',
'src/objective-c/BoringSSL-GRPC.podspec',
# cronet files
'include/grpc/grpc_cronet.h',
'src/core/ext/transport/cronet/client/secure/cronet_channel_create.cc',
'src/core/ext/transport/cronet/client/secure/cronet_channel_create.h',
'src/core/ext/transport/cronet/transport/cronet_status.cc',
'src/core/ext/transport/cronet/transport/cronet_status.h',
'src/core/ext/transport/cronet/transport/cronet_transport.cc',
'src/core/ext/transport/cronet/transport/cronet_transport.h',
'third_party/objective_c/Cronet/bidirectional_stream_c.h',
'include/grpcpp/security/cronet_credentials.h',
'src/cpp/client/cronet_credentials.cc',
# podspec files
'gRPC-C++.podspec',
'gRPC-Core.podspec',

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/core/lib/transport/call_arena_allocator.h"
#include "src/core/call/call_arena_allocator.h"
#include <grpc/support/port_platform.h>

View File

@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef GRPC_SRC_CORE_LIB_TRANSPORT_CALL_ARENA_ALLOCATOR_H
#define GRPC_SRC_CORE_LIB_TRANSPORT_CALL_ARENA_ALLOCATOR_H
#ifndef GRPC_SRC_CORE_CALL_CALL_ARENA_ALLOCATOR_H
#define GRPC_SRC_CORE_CALL_CALL_ARENA_ALLOCATOR_H
#include <grpc/support/port_platform.h>
#include <stddef.h>
@ -88,4 +88,4 @@ class CallArenaAllocator final : public ArenaFactory {
} // namespace grpc_core
#endif // GRPC_SRC_CORE_LIB_TRANSPORT_CALL_ARENA_ALLOCATOR_H
#endif // GRPC_SRC_CORE_CALL_CALL_ARENA_ALLOCATOR_H

View File

@ -12,12 +12,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef GRPC_SRC_CORE_LIB_TRANSPORT_CALL_DESTINATION_H
#define GRPC_SRC_CORE_LIB_TRANSPORT_CALL_DESTINATION_H
#ifndef GRPC_SRC_CORE_CALL_CALL_DESTINATION_H
#define GRPC_SRC_CORE_CALL_CALL_DESTINATION_H
#include <grpc/support/port_platform.h>
#include "src/core/lib/transport/call_spine.h"
#include "src/core/call/call_spine.h"
#include "src/core/util/orphanable.h"
namespace grpc_core {
@ -73,4 +73,4 @@ auto MakeCallDestinationFromHandlerFunction(HC handle_call) {
} // namespace grpc_core
#endif // GRPC_SRC_CORE_LIB_TRANSPORT_CALL_DESTINATION_H
#endif // GRPC_SRC_CORE_CALL_CALL_DESTINATION_H

View File

@ -12,13 +12,13 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/core/lib/transport/call_filters.h"
#include "src/core/call/call_filters.h"
#include <grpc/support/port_platform.h>
#include "absl/log/check.h"
#include "absl/log/log.h"
#include "src/core/lib/transport/metadata.h"
#include "src/core/call/metadata.h"
#include "src/core/util/crash.h"
namespace grpc_core {

View File

@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef GRPC_SRC_CORE_LIB_TRANSPORT_CALL_FILTERS_H
#define GRPC_SRC_CORE_LIB_TRANSPORT_CALL_FILTERS_H
#ifndef GRPC_SRC_CORE_CALL_CALL_FILTERS_H
#define GRPC_SRC_CORE_CALL_CALL_FILTERS_H
#include <grpc/support/port_platform.h>
@ -24,6 +24,9 @@
#include <type_traits>
#include "absl/log/check.h"
#include "src/core/call/call_state.h"
#include "src/core/call/message.h"
#include "src/core/call/metadata.h"
#include "src/core/lib/promise/for_each.h"
#include "src/core/lib/promise/if.h"
#include "src/core/lib/promise/latch.h"
@ -33,9 +36,6 @@
#include "src/core/lib/promise/status_flag.h"
#include "src/core/lib/promise/try_seq.h"
#include "src/core/lib/transport/call_final_info.h"
#include "src/core/lib/transport/call_state.h"
#include "src/core/lib/transport/message.h"
#include "src/core/lib/transport/metadata.h"
#include "src/core/util/dump_args.h"
#include "src/core/util/ref_counted.h"
#include "src/core/util/ref_counted_ptr.h"
@ -58,7 +58,7 @@
//
// The type of these members matters, and is selectable by the class
// author. For $INTERCEPTOR_NAME in the above list:
// - static const NoInterceptor $INTERCEPTOR_NAME:
// - static inline const NoInterceptor $INTERCEPTOR_NAME:
// defines that this filter does not intercept this event.
// there is zero runtime cost added to handling that event by this filter.
// - void $INTERCEPTOR_NAME($VALUE_TYPE&):
@ -91,7 +91,7 @@
//
// Finally, OnFinalize is added to intecept call finalization.
// It must have one of the signatures:
// - static const NoInterceptor OnFinalize:
// - static inline const NoInterceptor OnFinalize:
// the filter does not intercept call finalization.
// - void OnFinalize(const grpc_call_final_info*):
// the filter intercepts call finalization.
@ -111,13 +111,8 @@ namespace grpc_core {
// Tag type to indicate no interception.
// This is used to indicate that a filter does not intercept a particular
// event.
// In C++14 we declare these as (for example):
// static const NoInterceptor OnClientInitialMetadata;
// and out-of-line provide the definition:
// const MyFilter::Call::NoInterceptor
// MyFilter::Call::OnClientInitialMetadata;
// In C++17 and later we can use inline variables instead:
// inline static const NoInterceptor OnClientInitialMetadata;
// We declare these as (for example):
// inline static inline const NoInterceptor OnClientInitialMetadata;
struct NoInterceptor {};
namespace filters_detail {
@ -191,6 +186,12 @@ class NextMessage {
DCHECK(has_value());
return *message_;
}
const Message& value() const {
DCHECK_NE(message_, taken());
DCHECK(ok());
DCHECK(has_value());
return *message_;
}
MessageHandle TakeValue() {
DCHECK_NE(message_, taken());
DCHECK(ok());
@ -205,6 +206,19 @@ class NextMessage {
call_state_ = nullptr;
}
template <typename Sink>
friend void AbslStringify(Sink& sink, const NextMessage& msg) {
if (!msg.ok()) {
sink.Append("<failure>");
return;
}
if (!msg.has_value()) {
sink.Append("<end-of-stream>");
return;
}
AbslStringify(sink, msg.value());
}
private:
static Message* end_of_stream() { return nullptr; }
static Message* error() { return reinterpret_cast<Message*>(1); }
@ -545,6 +559,31 @@ struct AddOpImpl<
}
};
// void $INTERCEPTOR_NAME(const $VALUE_TYPE&, FilterType*)
template <typename FilterType, typename T,
void (FilterType::Call::*impl)(const typename T::element_type&,
FilterType*)>
struct AddOpImpl<FilterType, T,
void (FilterType::Call::*)(const typename T::element_type&,
FilterType*),
impl> {
static void Add(FilterType* channel_data, size_t call_offset, Layout<T>& to) {
to.Add(0, 0,
Operator<T>{
channel_data,
call_offset,
[](void*, void* call_data, void* channel_data,
T value) -> Poll<ResultOr<T>> {
(static_cast<typename FilterType::Call*>(call_data)->*impl)(
*value, static_cast<FilterType*>(channel_data));
return ResultOr<T>{std::move(value), nullptr};
},
nullptr,
nullptr,
});
}
};
// $VALUE_HANDLE $INTERCEPTOR_NAME($VALUE_HANDLE, FilterType*)
template <typename FilterType, typename T,
T (FilterType::Call::*impl)(T, FilterType*)>
@ -932,6 +971,30 @@ struct AddOpImpl<FilterType, T, R (FilterType::Call::*)(T, FilterType*), impl,
absl::enable_if_t<std::is_same<absl::StatusOr<T>,
PromiseResult<R>>::value>> {
static void Add(FilterType* channel_data, size_t call_offset, Layout<T>& to) {
#if defined(__GNUC__) && __GNUC__ == 9
// Workaround for a bug in GNU C++ 9 compilers that fail to compile this
// class.
class Promise {
public:
Promise(T value, typename FilterType::Call* call_data,
FilterType* channel_data)
: impl_(std::make_unique<R>(
(call_data->*impl)(std::move(value), channel_data))) {}
Poll<ResultOr<T>> PollOnce() {
auto p = (*impl_)();
auto* r = p.value_if_ready();
if (r == nullptr) return Pending{};
this->~Promise();
if (r->ok()) return ResultOr<T>{std::move(**r), nullptr};
return ResultOr<T>{nullptr,
CancelledServerMetadataFromStatus(r->status())};
}
private:
std::unique_ptr<R> impl_;
};
#else
class Promise {
public:
Promise(T value, typename FilterType::Call* call_data,
@ -951,6 +1014,7 @@ struct AddOpImpl<FilterType, T, R (FilterType::Call::*)(T, FilterType*), impl,
private:
GPR_NO_UNIQUE_ADDRESS R impl_;
};
#endif
to.Add(sizeof(Promise), alignof(Promise),
Operator<T>{
channel_data,
@ -1252,7 +1316,7 @@ template <typename T>
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION inline OperationExecutor<
T>::~OperationExecutor() {
if (promise_data_ != nullptr) {
ops_->early_destroy(promise_data_);
if (ops_ != end_ops_) ops_->early_destroy(promise_data_);
gpr_free_aligned(promise_data_);
}
}
@ -1285,7 +1349,10 @@ OperationExecutor<T>::InitStep(T input, void* call_data) {
ops_->promise_init(promise_data_, Offset(call_data, ops_->call_offset),
ops_->channel_data, std::move(input));
if (auto* r = p.value_if_ready()) {
if (r->ok == nullptr) return std::move(*r);
if (r->ok == nullptr) {
ops_ = end_ops_;
return std::move(*r);
}
input = std::move(r->ok);
++ops_;
continue;
@ -1323,12 +1390,12 @@ class ServerTrailingMetadataInterceptor {
public:
class Call {
public:
static const NoInterceptor OnClientInitialMetadata;
static const NoInterceptor OnServerInitialMetadata;
static const NoInterceptor OnClientToServerMessage;
static const NoInterceptor OnClientToServerHalfClose;
static const NoInterceptor OnServerToClientMessage;
static const NoInterceptor OnFinalize;
static const inline NoInterceptor OnClientInitialMetadata;
static const inline NoInterceptor OnServerInitialMetadata;
static const inline NoInterceptor OnClientToServerMessage;
static const inline NoInterceptor OnClientToServerHalfClose;
static const inline NoInterceptor OnServerToClientMessage;
static const inline NoInterceptor OnFinalize;
void OnServerTrailingMetadata(ServerMetadata& md,
ServerTrailingMetadataInterceptor* filter) {
filter->fn_(md);
@ -1340,23 +1407,6 @@ class ServerTrailingMetadataInterceptor {
private:
GPR_NO_UNIQUE_ADDRESS Fn fn_;
};
template <typename Fn>
const NoInterceptor
ServerTrailingMetadataInterceptor<Fn>::Call::OnClientInitialMetadata;
template <typename Fn>
const NoInterceptor
ServerTrailingMetadataInterceptor<Fn>::Call::OnServerInitialMetadata;
template <typename Fn>
const NoInterceptor
ServerTrailingMetadataInterceptor<Fn>::Call::OnClientToServerMessage;
template <typename Fn>
const NoInterceptor
ServerTrailingMetadataInterceptor<Fn>::Call::OnClientToServerHalfClose;
template <typename Fn>
const NoInterceptor
ServerTrailingMetadataInterceptor<Fn>::Call::OnServerToClientMessage;
template <typename Fn>
const NoInterceptor ServerTrailingMetadataInterceptor<Fn>::Call::OnFinalize;
template <typename Fn>
class ClientInitialMetadataInterceptor {
@ -1367,12 +1417,12 @@ class ClientInitialMetadataInterceptor {
ClientInitialMetadataInterceptor* filter) {
return filter->fn_(md);
}
static const NoInterceptor OnServerInitialMetadata;
static const NoInterceptor OnClientToServerMessage;
static const NoInterceptor OnClientToServerHalfClose;
static const NoInterceptor OnServerToClientMessage;
static const NoInterceptor OnServerTrailingMetadata;
static const NoInterceptor OnFinalize;
static const inline NoInterceptor OnServerInitialMetadata;
static const inline NoInterceptor OnClientToServerMessage;
static const inline NoInterceptor OnClientToServerHalfClose;
static const inline NoInterceptor OnServerToClientMessage;
static const inline NoInterceptor OnServerTrailingMetadata;
static const inline NoInterceptor OnFinalize;
};
explicit ClientInitialMetadataInterceptor(Fn fn) : fn_(std::move(fn)) {}
@ -1380,24 +1430,37 @@ class ClientInitialMetadataInterceptor {
private:
GPR_NO_UNIQUE_ADDRESS Fn fn_;
};
template <typename Fn>
const NoInterceptor
ClientInitialMetadataInterceptor<Fn>::Call::OnServerInitialMetadata;
template <typename Fn>
const NoInterceptor
ClientInitialMetadataInterceptor<Fn>::Call::OnClientToServerMessage;
template <typename Fn>
const NoInterceptor
ClientInitialMetadataInterceptor<Fn>::Call::OnClientToServerHalfClose;
template <typename Fn>
const NoInterceptor
ClientInitialMetadataInterceptor<Fn>::Call::OnServerToClientMessage;
template <typename Fn>
const NoInterceptor
ClientInitialMetadataInterceptor<Fn>::Call::OnServerTrailingMetadata;
template <typename Fn>
const NoInterceptor ClientInitialMetadataInterceptor<Fn>::Call::OnFinalize;
// Determine if an interceptor needs to access the channel via one of its
// arguments.
template <typename T>
constexpr bool MethodHasChannelAccess = false;
template <typename T, typename R, typename A>
constexpr bool MethodHasChannelAccess<R (T::*)(A)> = false;
template <typename T, typename R>
constexpr bool MethodHasChannelAccess<R (T::*)()> = false;
template <typename T, typename R, typename A, typename C>
constexpr bool MethodHasChannelAccess<R (T::*)(A, C)> = true;
template <typename... Ts>
constexpr bool AnyMethodHasChannelAccess = (MethodHasChannelAccess<Ts> || ...);
// Composite for a given channel type to determine if any of its interceptors
// fall into this category: later code should use this.
template <typename Derived>
inline constexpr bool CallHasChannelAccess() {
return AnyMethodHasChannelAccess<
decltype(&Derived::Call::OnClientInitialMetadata),
decltype(&Derived::Call::OnClientToServerMessage),
decltype(&Derived::Call::OnServerInitialMetadata),
decltype(&Derived::Call::OnServerToClientMessage),
decltype(&Derived::Call::OnServerTrailingMetadata),
decltype(&Derived::Call::OnFinalize)>;
}
} // namespace filters_detail
namespace for_each_detail {
@ -1607,7 +1670,9 @@ class CallFilters {
}
return FinishStep(executor_.Start(
&(stack_current_->stack->data_.*layout),
std::move(filters_->*input_location), filters_->call_data_));
std::move(filters_->*input_location),
filters_detail::Offset(filters_->call_data_,
stack_current_->call_data_offset)));
} else {
return FinishStep(executor_.Step(filters_->call_data_));
}
@ -1624,9 +1689,10 @@ class CallFilters {
(filters_->call_state_.*on_done)();
return ValueOrFailure<Output>{std::move(r->ok)};
}
return FinishStep(
executor_.Start(&(stack_current_->stack->data_.*layout),
std::move(r->ok), filters_->call_data_));
return FinishStep(executor_.Start(
&(stack_current_->stack->data_.*layout), std::move(r->ok),
filters_detail::Offset(filters_->call_data_,
stack_current_->call_data_offset)));
}
(filters_->call_state_.*on_done)();
filters_->PushServerTrailingMetadata(std::move(r->error));
@ -1664,7 +1730,9 @@ class CallFilters {
}
return FinishStep(executor_.Start(
&(stack_current_->stack->data_.*layout),
std::move(filters_->*input_location), filters_->call_data_));
std::move(filters_->*input_location),
filters_detail::Offset(filters_->call_data_,
stack_current_->call_data_offset)));
} else {
return FinishStep(executor_.Step(filters_->call_data_));
}
@ -1679,9 +1747,10 @@ class CallFilters {
if (stack_current_ == stack_end_) {
return NextMsg{std::move(r->ok), &filters_->call_state_};
}
return FinishStep(
executor_.Start(&(stack_current_->stack->data_.*layout),
std::move(r->ok), filters_->call_data_));
return FinishStep(executor_.Start(
&(stack_current_->stack->data_.*layout), std::move(r->ok),
filters_detail::Offset(filters_->call_data_,
stack_current_->call_data_offset)));
}
(filters_->call_state_.*on_done)();
filters_->PushServerTrailingMetadata(std::move(r->error));
@ -1725,20 +1794,20 @@ class CallFilters {
[this]() {
return Map(
MetadataExecutor<
absl::optional<ServerMetadataHandle>,
std::optional<ServerMetadataHandle>,
ServerMetadataHandle,
&CallFilters::push_server_initial_metadata_,
&filters_detail::StackData::server_initial_metadata,
&CallState::FinishPullServerInitialMetadata,
StacksVector::const_reverse_iterator>(
this, stacks_.crbegin(), stacks_.crend()),
[](ValueOrFailure<absl::optional<ServerMetadataHandle>> r) {
[](ValueOrFailure<std::optional<ServerMetadataHandle>> r) {
if (r.ok()) return std::move(*r);
return absl::optional<ServerMetadataHandle>{};
return std::optional<ServerMetadataHandle>{};
});
},
[]() {
return Immediate(absl::optional<ServerMetadataHandle>{});
return Immediate(std::optional<ServerMetadataHandle>{});
});
});
}
@ -1904,4 +1973,4 @@ static_assert(
} // namespace grpc_core
#endif // GRPC_SRC_CORE_LIB_TRANSPORT_CALL_FILTERS_H
#endif // GRPC_SRC_CORE_CALL_CALL_FILTERS_H

View File

@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef GRPC_SRC_CORE_LIB_CHANNEL_CALL_FINALIZATION_H
#define GRPC_SRC_CORE_LIB_CHANNEL_CALL_FINALIZATION_H
#ifndef GRPC_SRC_CORE_CALL_CALL_FINALIZATION_H
#define GRPC_SRC_CORE_CALL_CALL_FINALIZATION_H
#include <grpc/support/port_platform.h>
@ -85,4 +85,4 @@ struct ContextType<CallFinalization> {};
} // namespace grpc_core
#endif // GRPC_SRC_CORE_LIB_CHANNEL_CALL_FINALIZATION_H
#endif // GRPC_SRC_CORE_CALL_CALL_FINALIZATION_H

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/core/lib/transport/call_spine.h"
#include "src/core/call/call_spine.h"
#include <grpc/support/port_platform.h>
@ -28,46 +28,44 @@ void ForwardCall(CallHandler call_handler, CallInitiator call_initiator,
on_server_trailing_metadata_from_initiator) {
call_handler.AddChildCall(call_initiator);
// Read messages from handler into initiator.
call_handler.SpawnInfallible("read_messages", [call_handler,
call_initiator]() mutable {
return Seq(ForEach(MessagesFrom(call_handler),
[call_initiator](MessageHandle msg) mutable {
// Need to spawn a job into the initiator's activity to
// push the message in.
return call_initiator.SpawnPushMessage(std::move(msg));
}),
[call_initiator](StatusFlag result) mutable {
if (result.ok()) {
call_initiator.SpawnFinishSends();
}
});
});
call_handler.SpawnInfallible(
"read_messages", [call_handler, call_initiator]() mutable {
return Seq(
ForEach(MessagesFrom(call_handler),
[call_initiator](MessageHandle msg) mutable {
// Need to spawn a job into the initiator's activity to
// push the message in.
call_initiator.SpawnPushMessage(std::move(msg));
return Success{};
}),
[call_initiator]() mutable { call_initiator.SpawnFinishSends(); });
});
call_initiator.SpawnInfallible(
"read_the_things",
[call_initiator, call_handler,
on_server_trailing_metadata_from_initiator =
std::move(on_server_trailing_metadata_from_initiator)]() mutable {
return Seq(
call_initiator.CancelIfFails(
TrySeq(call_initiator.PullServerInitialMetadata(),
[call_handler, call_initiator](
absl::optional<ServerMetadataHandle> md) mutable {
const bool has_md = md.has_value();
return If(
has_md,
[&call_handler, &call_initiator,
md = std::move(md)]() mutable {
call_handler.SpawnPushServerInitialMetadata(
std::move(*md));
return ForEach(
MessagesFrom(call_initiator),
[call_handler](MessageHandle msg) mutable {
return call_handler.SpawnPushMessage(
std::move(msg));
});
},
[]() -> StatusFlag { return Success{}; });
})),
call_initiator.CancelIfFails(TrySeq(
call_initiator.PullServerInitialMetadata(),
[call_handler, call_initiator](
std::optional<ServerMetadataHandle> md) mutable {
const bool has_md = md.has_value();
return If(
has_md,
[&call_handler, &call_initiator,
md = std::move(md)]() mutable {
call_handler.SpawnPushServerInitialMetadata(
std::move(*md));
return ForEach(
MessagesFrom(call_initiator),
[call_handler](MessageHandle msg) mutable {
call_handler.SpawnPushMessage(std::move(msg));
return Success{};
});
},
[]() -> StatusFlag { return Success{}; });
})),
call_initiator.PullServerTrailingMetadata(),
[call_handler,
on_server_trailing_metadata_from_initiator =

View File

@ -12,12 +12,16 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef GRPC_SRC_CORE_LIB_TRANSPORT_CALL_SPINE_H
#define GRPC_SRC_CORE_LIB_TRANSPORT_CALL_SPINE_H
#ifndef GRPC_SRC_CORE_CALL_CALL_SPINE_H
#define GRPC_SRC_CORE_CALL_CALL_SPINE_H
#include <grpc/support/port_platform.h>
#include "absl/log/check.h"
#include "src/core/call/call_arena_allocator.h"
#include "src/core/call/call_filters.h"
#include "src/core/call/message.h"
#include "src/core/call/metadata.h"
#include "src/core/lib/promise/detail/status.h"
#include "src/core/lib/promise/if.h"
#include "src/core/lib/promise/latch.h"
@ -27,10 +31,6 @@
#include "src/core/lib/promise/promise.h"
#include "src/core/lib/promise/status_flag.h"
#include "src/core/lib/promise/try_seq.h"
#include "src/core/lib/transport/call_arena_allocator.h"
#include "src/core/lib/transport/call_filters.h"
#include "src/core/lib/transport/message.h"
#include "src/core/lib/transport/metadata.h"
#include "src/core/util/dual_ref_counted.h"
namespace grpc_core {
@ -106,7 +106,8 @@ class CallSpine final : public Party {
void PushServerTrailingMetadata(ServerMetadataHandle md) {
GRPC_TRACE_LOG(call_state, INFO)
<< "[call_state] PushServerTrailingMetadata: " << md->DebugString();
<< "[call_state] PushServerTrailingMetadata: " << this << " "
<< md->DebugString();
call_filters().PushServerTrailingMetadata(std::move(md));
}
@ -134,15 +135,17 @@ class CallSpine final : public Party {
DCHECK(GetContext<Activity>() == this);
using P = promise_detail::PromiseLike<Promise>;
using ResultType = typename P::Result;
return Map(std::move(promise), [this](ResultType r) {
CancelIfFailed(r);
return r;
});
return Map(std::move(promise),
[self = RefAsSubclass<CallSpine>()](ResultType r) {
self->CancelIfFailed(r);
});
}
template <typename StatusType>
void CancelIfFailed(const StatusType& r) {
if (!IsStatusOk(r)) {
GRPC_TRACE_LOG(call_state, INFO)
<< "[call_state] spine " << this << " fails: " << r;
Cancel();
}
}
@ -200,27 +203,33 @@ class CallSpine final : public Party {
// Spawned operations: these are callable from /outside/ the call; they spawn
// an operation into the call and execute that operation.
//
// Server -> client operations are serialized in the order they are spawned.
// Client -> server operations are serialized in the order they are spawned.
//
// It's required that at most one thread call a server->client operation at a
// time, and likewise for client->server operations. There is no requirement
// that there be synchronization between the two directionalities.
//
// No ordering is given between the `Spawn` and the basic operations.
void SpawnPushServerInitialMetadata(ServerMetadataHandle md) {
SpawnInfallible(
"push-server-initial-metadata",
server_to_client_serializer()->Spawn(
[md = std::move(md), self = RefAsSubclass<CallSpine>()]() mutable {
self->CancelIfFailed(self->PushServerInitialMetadata(std::move(md)));
});
}
auto SpawnPushServerToClientMessage(MessageHandle msg) {
return SpawnWaitable(
"push-message",
void SpawnPushServerToClientMessage(MessageHandle msg) {
server_to_client_serializer()->Spawn(
[msg = std::move(msg), self = RefAsSubclass<CallSpine>()]() mutable {
return self->CancelIfFails(
self->PushServerToClientMessage(std::move(msg)));
});
}
auto SpawnPushClientToServerMessage(MessageHandle msg) {
return SpawnWaitable(
"push-message",
void SpawnPushClientToServerMessage(MessageHandle msg) {
client_to_server_serializer()->Spawn(
[msg = std::move(msg), self = RefAsSubclass<CallSpine>()]() mutable {
return self->CancelIfFails(
self->PushClientToServerMessage(std::move(msg)));
@ -228,19 +237,28 @@ class CallSpine final : public Party {
}
void SpawnFinishSends() {
SpawnInfallible("finish-sends", [self = RefAsSubclass<CallSpine>()]() {
client_to_server_serializer()->Spawn([self = RefAsSubclass<CallSpine>()]() {
self->FinishSends();
return Empty{};
});
}
void SpawnPushServerTrailingMetadata(ServerMetadataHandle md) {
SpawnInfallible(
"push-server-trailing-metadata",
[md = std::move(md), self = RefAsSubclass<CallSpine>()]() mutable {
self->PushServerTrailingMetadata(std::move(md));
return Empty{};
});
if (md->get(GrpcCallWasCancelled()).value_or(false)) {
// Cancellation doesn't serialize with the rest of ops
SpawnInfallible(
"push-server-trailing-metadata",
[md = std::move(md), self = RefAsSubclass<CallSpine>()]() mutable {
self->PushServerTrailingMetadata(std::move(md));
return Empty{};
});
} else {
server_to_client_serializer()->Spawn(
[md = std::move(md), self = RefAsSubclass<CallSpine>()]() mutable {
self->PushServerTrailingMetadata(std::move(md));
return Empty{};
});
}
}
void SpawnCancel() {
@ -274,11 +292,27 @@ class CallSpine final : public Party {
: Party(std::move(arena)),
call_filters_(std::move(client_initial_metadata)) {}
SpawnSerializer* client_to_server_serializer() {
if (client_to_server_serializer_ == nullptr) {
client_to_server_serializer_ = MakeSpawnSerializer();
}
return client_to_server_serializer_;
}
SpawnSerializer* server_to_client_serializer() {
if (server_to_client_serializer_ == nullptr) {
server_to_client_serializer_ = MakeSpawnSerializer();
}
return server_to_client_serializer_;
}
// Call filters/pipes part of the spine
CallFilters call_filters_;
absl::AnyInvocable<void(bool)> on_done_{nullptr};
// Call spines that should be cancelled if this spine is cancelled
absl::InlinedVector<RefCountedPtr<CallSpine>, 3> child_calls_;
SpawnSerializer* client_to_server_serializer_ = nullptr;
SpawnSerializer* server_to_client_serializer_ = nullptr;
};
class CallHandler;
@ -289,36 +323,56 @@ class CallInitiator {
CallInitiator() = default;
explicit CallInitiator(RefCountedPtr<CallSpine> spine)
: spine_(std::move(spine)) {}
: spine_(std::move(spine)) {
DCHECK_NE(spine_.get(), nullptr);
}
// Wrap a promise so that if it returns failure it automatically cancels
// the rest of the call.
// The resulting (returned) promise will resolve to Empty.
template <typename Promise>
auto CancelIfFails(Promise promise) {
DCHECK_NE(spine_.get(), nullptr);
return spine_->CancelIfFails(std::move(promise));
}
auto PullServerInitialMetadata() {
DCHECK_NE(spine_.get(), nullptr);
return spine_->PullServerInitialMetadata();
}
auto PushMessage(MessageHandle message) {
DCHECK_NE(spine_.get(), nullptr);
return spine_->PushClientToServerMessage(std::move(message));
}
auto SpawnPushMessage(MessageHandle message) {
return spine_->SpawnPushClientToServerMessage(std::move(message));
void SpawnPushMessage(MessageHandle message) {
DCHECK_NE(spine_.get(), nullptr);
spine_->SpawnPushClientToServerMessage(std::move(message));
}
void FinishSends() { spine_->FinishSends(); }
void FinishSends() {
DCHECK_NE(spine_.get(), nullptr);
spine_->FinishSends();
}
void SpawnFinishSends() { spine_->SpawnFinishSends(); }
void SpawnFinishSends() {
DCHECK_NE(spine_.get(), nullptr);
spine_->SpawnFinishSends();
}
auto PullMessage() { return spine_->PullServerToClientMessage(); }
auto PullMessage() {
DCHECK_NE(spine_.get(), nullptr);
return spine_->PullServerToClientMessage();
}
auto PullServerTrailingMetadata() {
DCHECK_NE(spine_.get(), nullptr);
return spine_->PullServerTrailingMetadata();
}
void Cancel(absl::Status error) {
DCHECK_NE(spine_.get(), nullptr);
CHECK(!error.ok());
auto status = ServerMetadataFromStatus(error);
status->Set(GrpcCallWasCancelled(), true);
@ -326,47 +380,72 @@ class CallInitiator {
}
void SpawnCancel(absl::Status error) {
DCHECK_NE(spine_.get(), nullptr);
CHECK(!error.ok());
auto status = ServerMetadataFromStatus(error);
status->Set(GrpcCallWasCancelled(), true);
spine_->SpawnPushServerTrailingMetadata(std::move(status));
}
void Cancel() { spine_->Cancel(); }
void Cancel() {
DCHECK_NE(spine_.get(), nullptr);
spine_->Cancel();
}
void SpawnCancel() { spine_->SpawnCancel(); }
void SpawnCancel() {
DCHECK_NE(spine_.get(), nullptr);
spine_->SpawnCancel();
}
GRPC_MUST_USE_RESULT bool OnDone(absl::AnyInvocable<void(bool)> fn) {
DCHECK_NE(spine_.get(), nullptr);
return spine_->OnDone(std::move(fn));
}
template <typename Promise>
auto UntilCallCompletes(Promise promise) {
DCHECK_NE(spine_.get(), nullptr);
return spine_->UntilCallCompletes(std::move(promise));
}
template <typename PromiseFactory>
void SpawnGuarded(absl::string_view name, PromiseFactory promise_factory) {
DCHECK_NE(spine_.get(), nullptr);
spine_->SpawnGuarded(name, std::move(promise_factory));
}
template <typename PromiseFactory>
void SpawnGuardedUntilCallCompletes(absl::string_view name,
PromiseFactory promise_factory) {
DCHECK_NE(spine_.get(), nullptr);
spine_->SpawnGuardedUntilCallCompletes(name, std::move(promise_factory));
}
template <typename PromiseFactory>
void SpawnInfallible(absl::string_view name, PromiseFactory promise_factory) {
DCHECK_NE(spine_.get(), nullptr);
spine_->SpawnInfallible(name, std::move(promise_factory));
}
template <typename PromiseFactory>
auto SpawnWaitable(absl::string_view name, PromiseFactory promise_factory) {
DCHECK_NE(spine_.get(), nullptr);
return spine_->SpawnWaitable(name, std::move(promise_factory));
}
bool WasCancelledPushed() const {
DCHECK_NE(spine_.get(), nullptr);
return spine_->call_filters().WasCancelledPushed();
}
Arena* arena() { return spine_->arena(); }
Party* party() { return spine_.get(); }
Arena* arena() {
DCHECK_NE(spine_.get(), nullptr);
return spine_->arena();
}
Party* party() {
DCHECK_NE(spine_.get(), nullptr);
return spine_.get();
}
private:
friend class CallHandler;
@ -404,6 +483,9 @@ class CallHandler {
return spine_->OnDone(std::move(fn));
}
// Wrap a promise so that if it returns failure it automatically cancels
// the rest of the call.
// The resulting (returned) promise will resolve to Empty.
template <typename Promise>
auto CancelIfFails(Promise promise) {
return spine_->CancelIfFails(std::move(promise));
@ -413,8 +495,8 @@ class CallHandler {
return spine_->PushServerToClientMessage(std::move(message));
}
auto SpawnPushMessage(MessageHandle message) {
return spine_->SpawnPushServerToClientMessage(std::move(message));
void SpawnPushMessage(MessageHandle message) {
spine_->SpawnPushServerToClientMessage(std::move(message));
}
auto PullMessage() { return spine_->PullClientToServerMessage(); }
@ -425,6 +507,11 @@ class CallHandler {
return spine_->call_filters().WasCancelledPushed();
}
template <typename Promise>
auto UntilCallCompletes(Promise promise) {
return spine_->UntilCallCompletes(std::move(promise));
}
template <typename PromiseFactory>
void SpawnGuarded(absl::string_view name, PromiseFactory promise_factory,
DebugLocation whence = {}) {
@ -556,4 +643,4 @@ void ForwardCall(
} // namespace grpc_core
#endif // GRPC_SRC_CORE_LIB_TRANSPORT_CALL_SPINE_H
#endif // GRPC_SRC_CORE_CALL_CALL_SPINE_H

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/core/lib/transport/call_state.h"
#include "src/core/call/call_state.h"
namespace grpc_core {

View File

@ -12,12 +12,13 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef GRPC_SRC_CORE_LIB_TRANSPORT_CALL_STATE_H
#define GRPC_SRC_CORE_LIB_TRANSPORT_CALL_STATE_H
#ifndef GRPC_SRC_CORE_CALL_CALL_STATE_H
#define GRPC_SRC_CORE_CALL_CALL_STATE_H
#include <grpc/support/port_platform.h>
#include "absl/types/optional.h"
#include <optional>
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/promise/activity.h"
#include "src/core/lib/promise/poll.h"
@ -487,7 +488,7 @@ CallState::PollPullClientToServerMessageAvailable() {
case ClientToServerPullState::kIdle:
client_to_server_pull_state_ = ClientToServerPullState::kReading;
client_to_server_pull_waiter_.Wake();
ABSL_FALLTHROUGH_INTENDED;
[[fallthrough]];
case ClientToServerPullState::kReading:
break;
case ClientToServerPullState::kProcessingClientToServerMessage:
@ -879,7 +880,7 @@ CallState::PollPullServerToClientMessageAvailable() {
return server_to_client_pull_waiter_.pending();
case ServerToClientPullState::kStarted:
server_to_client_pull_state_ = ServerToClientPullState::kStartedReading;
ABSL_FALLTHROUGH_INTENDED;
[[fallthrough]];
case ServerToClientPullState::kStartedReading:
if (server_to_client_push_state_ ==
ServerToClientPushState::kTrailersOnly) {
@ -889,7 +890,7 @@ CallState::PollPullServerToClientMessageAvailable() {
case ServerToClientPullState::kIdle:
server_to_client_pull_state_ = ServerToClientPullState::kReading;
server_to_client_pull_waiter_.Wake();
ABSL_FALLTHROUGH_INTENDED;
[[fallthrough]];
case ServerToClientPullState::kReading:
break;
case ServerToClientPullState::kProcessingServerToClientMessage:
@ -1038,7 +1039,7 @@ CallState::PollServerTrailingMetadataAvailable() {
ServerTrailingMetadataState::kNotPushed) {
break; // Ready for processing
}
ABSL_FALLTHROUGH_INTENDED;
[[fallthrough]];
case ServerToClientPushState::kPushedMessageWithoutInitialMetadata:
case ServerToClientPushState::kPushedServerInitialMetadata:
case ServerToClientPushState::
@ -1102,12 +1103,11 @@ CallState::PollWasCancelled() {
<< GRPC_DUMP_ARGS(this, server_trailing_metadata_state_);
switch (server_trailing_metadata_state_) {
case ServerTrailingMetadataState::kNotPushed:
case ServerTrailingMetadataState::kPushed:
case ServerTrailingMetadataState::kPushedCancel: {
return server_trailing_metadata_waiter_.pending();
}
case ServerTrailingMetadataState::kPushed:
case ServerTrailingMetadataState::kPulled:
return false;
case ServerTrailingMetadataState::kPushedCancel:
case ServerTrailingMetadataState::kPulledCancel:
return true;
}
@ -1151,4 +1151,4 @@ CallState::PollServerTrailingMetadataWasPushed() {
} // namespace grpc_core
#endif // GRPC_SRC_CORE_LIB_TRANSPORT_CALL_STATE_H
#endif // GRPC_SRC_CORE_CALL_CALL_STATE_H

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/core/lib/surface/client_call.h"
#include "src/core/call/client_call.h"
#include <grpc/byte_buffer.h>
#include <grpc/compression.h>
@ -42,6 +42,7 @@
#include "absl/log/check.h"
#include "absl/status/status.h"
#include "absl/strings/string_view.h"
#include "src/core/call/metadata.h"
#include "src/core/lib/event_engine/event_engine_context.h"
#include "src/core/lib/promise/all_ok.h"
#include "src/core/lib/promise/status_flag.h"
@ -49,7 +50,6 @@
#include "src/core/lib/resource_quota/arena.h"
#include "src/core/lib/slice/slice_buffer.h"
#include "src/core/lib/surface/completion_queue.h"
#include "src/core/lib/transport/metadata.h"
#include "src/core/telemetry/stats.h"
#include "src/core/telemetry/stats_data.h"
#include "src/core/util/bitset.h"
@ -100,7 +100,7 @@ grpc_call_error ValidateClientBatch(const grpc_op* ops, size_t nops) {
} // namespace
ClientCall::ClientCall(grpc_call*, uint32_t, grpc_completion_queue* cq,
Slice path, absl::optional<Slice> authority,
Slice path, std::optional<Slice> authority,
bool registered_method, Timestamp deadline,
grpc_compression_options compression_options,
RefCountedPtr<Arena> arena,
@ -318,7 +318,7 @@ void ClientCall::CommitBatch(const grpc_op* ops, size_t nops, void* notify_tag,
return Map(
started_call_initiator_.PullServerInitialMetadata(),
[this,
array](ValueOrFailure<absl::optional<ServerMetadataHandle>> md) {
array](ValueOrFailure<std::optional<ServerMetadataHandle>> md) {
ServerMetadataHandle metadata;
if (!md.ok() || !md->has_value()) {
is_trailers_only_ = true;
@ -335,9 +335,16 @@ void ClientCall::CommitBatch(const grpc_op* ops, size_t nops, void* notify_tag,
});
};
});
auto primary_ops = AllOk<StatusFlag>(
TrySeq(std::move(send_message), std::move(send_close_from_client)),
TrySeq(std::move(recv_initial_metadata), std::move(recv_message)));
// We capture 'this' in the op handlers, but the call may be destroyed before
// the party owned by CallInitiator/CallHandler is destroyed -- meaning that
// op callbacks may happen after call destruction if we don't hold a ref.
// We do that via an implicitly captured one in a Map() here so that we don't
// need a ref held per batch operation -- they have the same lifetime always.
auto primary_ops = Map(
AllOk<StatusFlag>(
TrySeq(std::move(send_message), std::move(send_close_from_client)),
TrySeq(std::move(recv_initial_metadata), std::move(recv_message))),
[self = WeakRef()](StatusFlag x) { return x; });
Party::WakeupHold wakeup_hold;
if (const grpc_op* op = op_index.op(GRPC_OP_SEND_INITIAL_METADATA)) {
wakeup_hold = StartCall(*op);
@ -397,12 +404,14 @@ void ClientCall::OnReceivedStatus(ServerMetadataHandle server_trailing_metadata,
const auto status = server_trailing_metadata->get(GrpcStatusMetadata())
.value_or(GRPC_STATUS_UNKNOWN);
*out_status = status;
Slice message_slice;
if (Slice* message =
server_trailing_metadata->get_pointer(GrpcMessageMetadata())) {
message_slice = message->Ref();
if (!IsErrorFlattenEnabled() || status != GRPC_STATUS_OK) {
Slice message_slice;
if (Slice* message =
server_trailing_metadata->get_pointer(GrpcMessageMetadata())) {
message_slice = message->Ref();
}
*out_status_details = message_slice.TakeCSlice();
}
*out_status_details = message_slice.TakeCSlice();
if (out_error_string != nullptr) {
if (status != GRPC_STATUS_OK) {
*out_error_string =
@ -431,7 +440,7 @@ char* ClientCall::GetPeer() {
grpc_call* MakeClientCall(grpc_call* parent_call, uint32_t propagation_mask,
grpc_completion_queue* cq, Slice path,
absl::optional<Slice> authority,
std::optional<Slice> authority,
bool registered_method, Timestamp deadline,
grpc_compression_options compression_options,
RefCountedPtr<Arena> arena,

View File

@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef GRPC_SRC_CORE_LIB_SURFACE_CLIENT_CALL_H
#define GRPC_SRC_CORE_LIB_SURFACE_CLIENT_CALL_H
#ifndef GRPC_SRC_CORE_CALL_CLIENT_CALL_H
#define GRPC_SRC_CORE_CALL_CLIENT_CALL_H
#include <grpc/byte_buffer.h>
#include <grpc/compression.h>
@ -40,11 +40,11 @@
#include "absl/status/status.h"
#include "absl/strings/str_format.h"
#include "absl/strings/string_view.h"
#include "src/core/call/metadata.h"
#include "src/core/lib/promise/status_flag.h"
#include "src/core/lib/resource_quota/arena.h"
#include "src/core/lib/surface/call.h"
#include "src/core/lib/surface/call_utils.h"
#include "src/core/lib/transport/metadata.h"
#include "src/core/util/crash.h"
#include "src/core/util/ref_counted.h"
#include "src/core/util/ref_counted_ptr.h"
@ -59,7 +59,7 @@ class ClientCall final
public:
ClientCall(grpc_call* parent_call, uint32_t propagation_mask,
grpc_completion_queue* cq, Slice path,
absl::optional<Slice> authority, bool registered_method,
std::optional<Slice> authority, bool registered_method,
Timestamp deadline, grpc_compression_options compression_options,
RefCountedPtr<Arena> arena,
RefCountedPtr<UnstartedCallDestination> destination);
@ -181,7 +181,7 @@ class ClientCall final
grpc_call* MakeClientCall(grpc_call* parent_call, uint32_t propagation_mask,
grpc_completion_queue* cq, Slice path,
absl::optional<Slice> authority,
std::optional<Slice> authority,
bool registered_method, Timestamp deadline,
grpc_compression_options compression_options,
RefCountedPtr<Arena> arena,
@ -189,4 +189,4 @@ grpc_call* MakeClientCall(grpc_call* parent_call, uint32_t propagation_mask,
} // namespace grpc_core
#endif // GRPC_SRC_CORE_LIB_SURFACE_CLIENT_CALL_H
#endif // GRPC_SRC_CORE_CALL_CLIENT_CALL_H

View File

@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef GRPC_SRC_CORE_LIB_TRANSPORT_CUSTOM_METADATA_H
#define GRPC_SRC_CORE_LIB_TRANSPORT_CUSTOM_METADATA_H
#ifndef GRPC_SRC_CORE_CALL_CUSTOM_METADATA_H
#define GRPC_SRC_CORE_CALL_CUSTOM_METADATA_H
// This file defines two macros: GRPC_CUSTOM_CLIENT_METADATA and
// GRPC_CUSTOM_SERVER_METADATA.
@ -27,4 +27,4 @@
#define GRPC_CUSTOM_CLIENT_METADATA
#define GRPC_CUSTOM_SERVER_METADATA
#endif // GRPC_SRC_CORE_LIB_TRANSPORT_CUSTOM_METADATA_H
#endif // GRPC_SRC_CORE_CALL_CUSTOM_METADATA_H

View File

@ -12,17 +12,17 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/core/lib/transport/interception_chain.h"
#include "src/core/call/interception_chain.h"
#include <grpc/support/port_platform.h>
#include <cstddef>
#include "src/core/call/call_destination.h"
#include "src/core/call/call_filters.h"
#include "src/core/call/call_spine.h"
#include "src/core/call/metadata.h"
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/transport/call_destination.h"
#include "src/core/lib/transport/call_filters.h"
#include "src/core/lib/transport/call_spine.h"
#include "src/core/lib/transport/metadata.h"
#include "src/core/util/match.h"
namespace grpc_core {

View File

@ -12,18 +12,18 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef GRPC_SRC_CORE_LIB_TRANSPORT_INTERCEPTION_CHAIN_H
#define GRPC_SRC_CORE_LIB_TRANSPORT_INTERCEPTION_CHAIN_H
#ifndef GRPC_SRC_CORE_CALL_INTERCEPTION_CHAIN_H
#define GRPC_SRC_CORE_CALL_INTERCEPTION_CHAIN_H
#include <grpc/support/port_platform.h>
#include <memory>
#include <vector>
#include "src/core/lib/transport/call_destination.h"
#include "src/core/lib/transport/call_filters.h"
#include "src/core/lib/transport/call_spine.h"
#include "src/core/lib/transport/metadata.h"
#include "src/core/call/call_destination.h"
#include "src/core/call/call_filters.h"
#include "src/core/call/call_spine.h"
#include "src/core/call/metadata.h"
#include "src/core/util/ref_counted.h"
namespace grpc_core {
@ -159,9 +159,8 @@ class InterceptionChainBuilder final {
// the future, and building is a builder responsibility.
// Instead, we declare a relatively closed set of destinations here, and
// hide the adaptors inside the builder at build time.
using FinalDestination =
absl::variant<RefCountedPtr<UnstartedCallDestination>,
RefCountedPtr<CallDestination>>;
using FinalDestination = std::variant<RefCountedPtr<UnstartedCallDestination>,
RefCountedPtr<CallDestination>>;
explicit InterceptionChainBuilder(ChannelArgs args,
const Blackboard* old_blackboard = nullptr,
@ -201,14 +200,30 @@ class InterceptionChainBuilder final {
// Add a filter that just mutates client initial metadata.
template <typename F>
void AddOnClientInitialMetadata(F f) {
InterceptionChainBuilder& AddOnClientInitialMetadata(F f) {
stack_builder().AddOnClientInitialMetadata(std::move(f));
return *this;
}
// Add a filter that just mutates server trailing metadata.
template <typename F>
void AddOnServerTrailingMetadata(F f) {
InterceptionChainBuilder& AddOnServerTrailingMetadata(F f) {
stack_builder().AddOnServerTrailingMetadata(std::move(f));
return *this;
}
// Immediately: Call AddOnServerTrailingMetadata
// Then, or every interceptor added to the filter from this point on:
// Perform an AddOnServerTrailingMetadata() immediately after
// the interceptor was added - but only if other filters or interceptors
// are added below it.
template <typename F>
InterceptionChainBuilder& AddOnServerTrailingMetadataForEachInterceptor(F f) {
AddOnServerTrailingMetadata(f);
on_new_interception_tail_.emplace_back([f](InterceptionChainBuilder* b) {
b->AddOnServerTrailingMetadata(f);
});
return *this;
}
void Fail(absl::Status status) {
@ -224,7 +239,10 @@ class InterceptionChainBuilder final {
private:
CallFilters::StackBuilder& stack_builder() {
if (!stack_builder_.has_value()) stack_builder_.emplace();
if (!stack_builder_.has_value()) {
stack_builder_.emplace();
for (auto& f : on_new_interception_tail_) f(this);
}
return *stack_builder_;
}
@ -248,8 +266,10 @@ class InterceptionChainBuilder final {
void AddInterceptor(absl::StatusOr<RefCountedPtr<Interceptor>> interceptor);
ChannelArgs args_;
absl::optional<CallFilters::StackBuilder> stack_builder_;
std::optional<CallFilters::StackBuilder> stack_builder_;
RefCountedPtr<Interceptor> top_interceptor_;
std::vector<absl::AnyInvocable<void(InterceptionChainBuilder*)>>
on_new_interception_tail_;
absl::Status status_;
std::map<size_t, size_t> filter_type_counts_;
static std::atomic<size_t> next_filter_id_;
@ -259,4 +279,4 @@ class InterceptionChainBuilder final {
} // namespace grpc_core
#endif // GRPC_SRC_CORE_LIB_TRANSPORT_INTERCEPTION_CHAIN_H
#endif // GRPC_SRC_CORE_CALL_INTERCEPTION_CHAIN_H

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/core/lib/transport/message.h"
#include "src/core/call/message.h"
#include <grpc/impl/grpc_types.h>
#include <grpc/support/port_platform.h>

View File

@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef GRPC_SRC_CORE_LIB_TRANSPORT_MESSAGE_H
#define GRPC_SRC_CORE_LIB_TRANSPORT_MESSAGE_H
#ifndef GRPC_SRC_CORE_CALL_MESSAGE_H
#define GRPC_SRC_CORE_CALL_MESSAGE_H
#include <grpc/support/port_platform.h>
@ -47,6 +47,10 @@ class Message {
SliceBuffer* payload() { return &payload_; }
const SliceBuffer* payload() const { return &payload_; }
Arena::PoolPtr<Message> Clone() const {
return Arena::MakePooled<Message>(payload_.Copy(), flags_);
}
std::string DebugString() const;
template <typename Sink>
@ -63,4 +67,4 @@ using MessageHandle = Arena::PoolPtr<Message>;
} // namespace grpc_core
#endif // GRPC_SRC_CORE_LIB_TRANSPORT_MESSAGE_H
#endif // GRPC_SRC_CORE_CALL_MESSAGE_H

View File

@ -12,12 +12,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/core/lib/transport/metadata.h"
#include "src/core/call/metadata.h"
#include <grpc/support/port_platform.h>
#include "src/core/call/metadata_batch.h"
#include "src/core/lib/transport/error_utils.h"
#include "src/core/lib/transport/metadata_batch.h"
namespace grpc_core {

View File

@ -12,12 +12,13 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef GRPC_SRC_CORE_LIB_TRANSPORT_METADATA_H
#define GRPC_SRC_CORE_LIB_TRANSPORT_METADATA_H
#ifndef GRPC_SRC_CORE_CALL_METADATA_H
#define GRPC_SRC_CORE_CALL_METADATA_H
#include <grpc/support/port_platform.h>
#include "src/core/lib/transport/metadata_batch.h"
#include "src/core/call/metadata_batch.h"
#include "src/core/lib/promise/try_seq.h"
namespace grpc_core {
@ -31,6 +32,110 @@ using ServerMetadataHandle = Arena::PoolPtr<ServerMetadata>;
using ClientMetadata = grpc_metadata_batch;
using ClientMetadataHandle = Arena::PoolPtr<ClientMetadata>;
template <typename T>
class ServerMetadataOrHandle {
public:
using ValueType = Arena::PoolPtr<T>;
static ServerMetadataOrHandle Ok(ValueType value) {
return ServerMetadataOrHandle{nullptr, std::move(value)};
}
static ServerMetadataOrHandle Failure(ServerMetadataHandle server_metadata) {
return ServerMetadataOrHandle{std::move(server_metadata), nullptr};
}
bool ok() const { return server_metadata_ == nullptr; }
ServerMetadataHandle& metadata() {
CHECK(!ok());
return server_metadata_;
}
ValueType& operator*() {
CHECK(ok());
return value_;
}
const ServerMetadataHandle& metadata() const {
CHECK(!ok());
return server_metadata_;
}
const ValueType& operator*() const {
CHECK(ok());
return value_;
}
ServerMetadataHandle TakeMetadata() && {
CHECK(!ok());
return std::move(server_metadata_);
}
ValueType TakeValue() && {
CHECK(ok());
return std::move(value_);
}
private:
ServerMetadataOrHandle(ServerMetadataHandle server_metadata, ValueType value)
: server_metadata_(std::move(server_metadata)),
value_(std::move(value)) {}
ServerMetadataHandle server_metadata_;
ValueType value_;
};
template <typename T>
struct FailureStatusCastImpl<ServerMetadataOrHandle<T>, ServerMetadataHandle> {
static ServerMetadataOrHandle<T> Cast(ServerMetadataHandle t) {
return ServerMetadataOrHandle<T>::Failure(std::move(t));
}
};
template <typename T>
struct FailureStatusCastImpl<ServerMetadataOrHandle<T>, ServerMetadataHandle&> {
static ServerMetadataOrHandle<T> Cast(ServerMetadataHandle& t) {
return ServerMetadataOrHandle<T>::Failure(std::move(t));
}
};
template <>
struct FailureStatusCastImpl<ServerMetadataHandle, ServerMetadataHandle&> {
static ServerMetadataHandle Cast(ServerMetadataHandle& t) {
return std::move(t);
}
};
template <typename T>
inline bool IsStatusOk(const ServerMetadataOrHandle<T>& x) {
return x.ok();
}
namespace promise_detail {
template <typename T>
struct AllowGenericTrySeqTraits<ServerMetadataOrHandle<T>> {
static constexpr bool value = false;
};
template <typename T>
struct TrySeqTraitsWithSfinae<ServerMetadataOrHandle<T>> {
using UnwrappedType = Arena::PoolPtr<T>;
using WrappedType = ServerMetadataOrHandle<T>;
template <typename Next>
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static auto CallFactory(
Next* next, ServerMetadataOrHandle<T>&& status) {
return next->Make(std::move(*status));
}
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static bool IsOk(
const ServerMetadataOrHandle<T>& status) {
return status.ok();
}
static std::string ErrorString(const ServerMetadataOrHandle<T>& status) {
return status.metadata()->DebugString();
}
template <typename R>
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static R ReturnValue(
ServerMetadataOrHandle<T>&& status) {
return FailureStatusCast<R>(status.metadata());
}
};
} // namespace promise_detail
// TODO(ctiller): separate when we have different types for client/server
// metadata.
template <typename Sink>
@ -110,4 +215,4 @@ struct StatusCastImpl<
} // namespace grpc_core
#endif // GRPC_SRC_CORE_LIB_TRANSPORT_METADATA_H
#endif // GRPC_SRC_CORE_CALL_METADATA_H

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/core/lib/transport/metadata_batch.h"
#include "src/core/call/metadata_batch.h"
#include <grpc/support/port_platform.h>
#include <string.h>
@ -114,9 +114,9 @@ void UnknownMap::Remove(absl::string_view key) {
unknown_.end());
}
absl::optional<absl::string_view> UnknownMap::GetStringValue(
std::optional<absl::string_view> UnknownMap::GetStringValue(
absl::string_view key, std::string* backing) const {
absl::optional<absl::string_view> out;
std::optional<absl::string_view> out;
for (const auto& p : unknown_) {
if (p.first.as_string_view() == key) {
if (!out.has_value()) {

View File

@ -16,8 +16,8 @@
//
//
#ifndef GRPC_SRC_CORE_LIB_TRANSPORT_METADATA_BATCH_H
#define GRPC_SRC_CORE_LIB_TRANSPORT_METADATA_BATCH_H
#ifndef GRPC_SRC_CORE_CALL_METADATA_BATCH_H
#define GRPC_SRC_CORE_CALL_METADATA_BATCH_H
#include <grpc/impl/compression_types.h>
#include <grpc/status.h>
@ -25,6 +25,7 @@
#include <stdlib.h>
#include <cstdint>
#include <optional>
#include <string>
#include <type_traits>
#include <utility>
@ -35,15 +36,14 @@
#include "absl/meta/type_traits.h"
#include "absl/strings/numbers.h"
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "src/core/call/custom_metadata.h"
#include "src/core/call/metadata_compression_traits.h"
#include "src/core/call/parsed_metadata.h"
#include "src/core/call/simple_slice_based_metadata.h"
#include "src/core/lib/compression/compression_internal.h"
#include "src/core/lib/experiments/experiments.h"
#include "src/core/lib/promise/poll.h"
#include "src/core/lib/slice/slice.h"
#include "src/core/lib/transport/custom_metadata.h"
#include "src/core/lib/transport/metadata_compression_traits.h"
#include "src/core/lib/transport/parsed_metadata.h"
#include "src/core/lib/transport/simple_slice_based_metadata.h"
#include "src/core/util/chunked_vector.h"
#include "src/core/util/if_list.h"
#include "src/core/util/packed_table.h"
@ -369,12 +369,73 @@ struct SimpleIntBasedMetadata : public SimpleIntBasedMetadataBase<Int> {
};
// grpc-status metadata trait.
struct GrpcStatusMetadata
: public SimpleIntBasedMetadata<grpc_status_code, GRPC_STATUS_UNKNOWN> {
struct GrpcStatusMetadata {
using ValueType = grpc_status_code;
using MementoType = grpc_status_code;
static ValueType MementoToValue(MementoType value) { return value; }
static Slice Encode(ValueType x) { return Slice::FromInt64(x); }
static std::string DisplayValue(ValueType x) {
switch (x) {
case GRPC_STATUS_OK:
return "OK";
case GRPC_STATUS_CANCELLED:
return "CANCELLED";
case GRPC_STATUS_UNKNOWN:
return "UNKNOWN";
case GRPC_STATUS_INVALID_ARGUMENT:
return "INVALID_ARGUMENT";
case GRPC_STATUS_DEADLINE_EXCEEDED:
return "DEADLINE_EXCEEDED";
case GRPC_STATUS_NOT_FOUND:
return "NOT_FOUND";
case GRPC_STATUS_ALREADY_EXISTS:
return "ALREADY_EXISTS";
case GRPC_STATUS_PERMISSION_DENIED:
return "PERMISSION_DENIED";
case GRPC_STATUS_RESOURCE_EXHAUSTED:
return "RESOURCE_EXHAUSTED";
case GRPC_STATUS_FAILED_PRECONDITION:
return "FAILED_PRECONDITION";
case GRPC_STATUS_ABORTED:
return "ABORTED";
case GRPC_STATUS_OUT_OF_RANGE:
return "OUT_OF_RANGE";
case GRPC_STATUS_UNIMPLEMENTED:
return "UNIMPLEMENTED";
case GRPC_STATUS_INTERNAL:
return "INTERNAL";
case GRPC_STATUS_UNAVAILABLE:
return "UNAVAILABLE";
case GRPC_STATUS_DATA_LOSS:
return "DATA_LOSS";
case GRPC_STATUS_UNAUTHENTICATED:
return "UNAUTHENTICATED";
default:
return absl::StrCat("UNKNOWN(", static_cast<int>(x), ")");
}
}
static auto DisplayMemento(MementoType x) { return DisplayValue(x); }
static constexpr bool kRepeatable = false;
static constexpr bool kTransferOnTrailersOnly = false;
using CompressionTraits = SmallIntegralValuesCompressor<16>;
static absl::string_view key() { return "grpc-status"; }
static grpc_status_code ParseMemento(Slice value, bool,
MetadataParseErrorFn on_error) {
int64_t wire_value;
if (!absl::SimpleAtoi(value.as_string_view(), &wire_value)) {
on_error("not an integer", value);
return GRPC_STATUS_UNKNOWN;
}
if (wire_value < 0) {
on_error("negative value", value);
return GRPC_STATUS_UNKNOWN;
}
if (wire_value >= GRPC_STATUS__DO_NOT_USE) {
on_error("out of range", value);
return GRPC_STATUS_UNKNOWN;
}
return static_cast<grpc_status_code>(wire_value);
}
};
// grpc-previous-rpc-attempts metadata trait.
@ -772,10 +833,10 @@ class GetStringValueHelper {
GPR_ATTRIBUTE_NOINLINE absl::enable_if_t<
Trait::kRepeatable == false &&
std::is_same<Slice, typename Trait::ValueType>::value,
absl::optional<absl::string_view>>
std::optional<absl::string_view>>
Found(Trait) {
const auto* value = container_->get_pointer(Trait());
if (value == nullptr) return absl::nullopt;
if (value == nullptr) return std::nullopt;
return value->as_string_view();
}
@ -783,10 +844,10 @@ class GetStringValueHelper {
GPR_ATTRIBUTE_NOINLINE absl::enable_if_t<
Trait::kRepeatable == true &&
!std::is_same<Slice, typename Trait::ValueType>::value,
absl::optional<absl::string_view>>
std::optional<absl::string_view>>
Found(Trait) {
const auto* value = container_->get_pointer(Trait());
if (value == nullptr) return absl::nullopt;
if (value == nullptr) return std::nullopt;
backing_->clear();
for (const auto& v : *value) {
if (!backing_->empty()) backing_->push_back(',');
@ -800,15 +861,15 @@ class GetStringValueHelper {
GPR_ATTRIBUTE_NOINLINE absl::enable_if_t<
Trait::kRepeatable == false &&
!std::is_same<Slice, typename Trait::ValueType>::value,
absl::optional<absl::string_view>>
std::optional<absl::string_view>>
Found(Trait) {
const auto* value = container_->get_pointer(Trait());
if (value == nullptr) return absl::nullopt;
if (value == nullptr) return std::nullopt;
*backing_ = std::string(Trait::Encode(*value).as_string_view());
return *backing_;
}
GPR_ATTRIBUTE_NOINLINE absl::optional<absl::string_view> NotFound(
GPR_ATTRIBUTE_NOINLINE std::optional<absl::string_view> NotFound(
absl::string_view key) {
return container_->unknown_.GetStringValue(key, backing_);
}
@ -1113,8 +1174,8 @@ class UnknownMap {
void Append(absl::string_view key, Slice value);
void Remove(absl::string_view key);
absl::optional<absl::string_view> GetStringValue(absl::string_view key,
std::string* backing) const;
std::optional<absl::string_view> GetStringValue(absl::string_view key,
std::string* backing) const;
BackingType::const_iterator begin() const { return unknown_.cbegin(); }
BackingType::const_iterator end() const { return unknown_.cend(); }
@ -1405,9 +1466,9 @@ class MetadataMap {
// Returns nullopt if the metadata is not present.
// Causes a compilation error if Which is not an element of Traits.
template <typename Which>
absl::optional<typename Which::ValueType> get(Which) const {
std::optional<typename Which::ValueType> get(Which) const {
if (auto* p = table_.template get<Value<Which>>()) return p->value;
return absl::nullopt;
return std::nullopt;
}
// Set the value of some known metadata.
@ -1438,8 +1499,8 @@ class MetadataMap {
void Remove(const char* key) { Remove(absl::string_view(key)); }
// Retrieve some metadata by name
absl::optional<absl::string_view> GetStringValue(absl::string_view name,
std::string* buffer) const {
std::optional<absl::string_view> GetStringValue(absl::string_view name,
std::string* buffer) const {
metadata_detail::GetStringValueHelper<Derived> helper(
static_cast<const Derived*>(this), buffer);
return metadata_detail::NameLookup<Traits...>::Lookup(name, &helper);
@ -1452,10 +1513,10 @@ class MetadataMap {
// m.Remove(T());
template <typename Which>
absl::enable_if_t<Which::kRepeatable == false,
absl::optional<typename Which::ValueType>>
std::optional<typename Which::ValueType>>
Take(Which which) {
if (auto* p = get_pointer(which)) {
absl::optional<typename Which::ValueType> value(std::move(*p));
std::optional<typename Which::ValueType> value(std::move(*p));
Remove(which);
return value;
}
@ -1604,4 +1665,4 @@ struct grpc_metadata_batch : public grpc_metadata_batch_base {
using grpc_metadata_batch_base::grpc_metadata_batch_base;
};
#endif // GRPC_SRC_CORE_LIB_TRANSPORT_METADATA_BATCH_H
#endif // GRPC_SRC_CORE_CALL_METADATA_BATCH_H

View File

@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef GRPC_SRC_CORE_LIB_TRANSPORT_METADATA_COMPRESSION_TRAITS_H
#define GRPC_SRC_CORE_LIB_TRANSPORT_METADATA_COMPRESSION_TRAITS_H
#ifndef GRPC_SRC_CORE_CALL_METADATA_COMPRESSION_TRAITS_H
#define GRPC_SRC_CORE_CALL_METADATA_COMPRESSION_TRAITS_H
#include <grpc/support/port_platform.h>
#include <stddef.h>
@ -63,4 +63,4 @@ struct HttpStatusCompressor {};
} // namespace grpc_core
#endif // GRPC_SRC_CORE_LIB_TRANSPORT_METADATA_COMPRESSION_TRAITS_H
#endif // GRPC_SRC_CORE_CALL_METADATA_COMPRESSION_TRAITS_H

View File

@ -12,17 +12,28 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/core/lib/transport/metadata_info.h"
#include "src/core/call/metadata_info.h"
#include <grpc/support/port_platform.h>
#include <cstddef>
#include <string>
#include "absl/strings/str_cat.h"
#include "src/core/lib/slice/slice.h"
namespace grpc_core {
class MetadataSizesAnnotation::MetadataSizeEncoder {
public:
explicit MetadataSizeEncoder(std::string& summary) : summary_(summary) {}
explicit MetadataSizeEncoder(std::string& summary, uint64_t soft_limit,
uint64_t hard_limit)
: summary_(summary) {
header_ = absl::StrCat("gRPC metadata soft_limit:", soft_limit,
",hard_limit:", hard_limit, ",");
absl::StrAppend(&summary_, header_);
entry_length_ = header_.length();
}
void Encode(const Slice& key, const Slice& value) {
AddToSummary(key.as_string_view(), value.size());
@ -36,18 +47,25 @@ class MetadataSizesAnnotation::MetadataSizeEncoder {
private:
void AddToSummary(absl::string_view key,
size_t value_length) GPR_ATTRIBUTE_NOINLINE {
absl::StrAppend(&summary_, key, ":",
hpack_constants::SizeForEntry(key.size(), value_length),
",");
std::string metadata_str = absl::StrCat(
key, ":", hpack_constants::SizeForEntry(key.size(), value_length), ",");
if ((entry_length_ + metadata_str.length()) < 200) {
// Limit each annotation to 200 bytes.
entry_length_ += metadata_str.length();
absl::StrAppend(&summary_, metadata_str);
} else {
absl::StrAppend(&summary_, ";", header_, metadata_str);
entry_length_ = header_.length() + metadata_str.length();
}
}
std::string& summary_;
std::string header_;
size_t entry_length_ = 0;
};
std::string MetadataSizesAnnotation::ToString() const {
std::string metadata_annotation =
absl::StrCat("gRPC metadata soft_limit:", soft_limit_,
",hard_limit:", hard_limit_, ",");
MetadataSizeEncoder encoder(metadata_annotation);
std::string metadata_annotation;
MetadataSizeEncoder encoder(metadata_annotation, soft_limit_, hard_limit_);
metadata_buffer_->Encode(&encoder);
return metadata_annotation;
}

View File

@ -12,14 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef GRPC_SRC_CORE_LIB_TRANSPORT_METADATA_INFO_H
#define GRPC_SRC_CORE_LIB_TRANSPORT_METADATA_INFO_H
#ifndef GRPC_SRC_CORE_CALL_METADATA_INFO_H
#define GRPC_SRC_CORE_CALL_METADATA_INFO_H
#include <grpc/support/port_platform.h>
#include "src/core/call/metadata_batch.h"
#include "src/core/ext/transport/chttp2/transport/hpack_constants.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/transport/metadata_batch.h"
#include "src/core/telemetry/call_tracer.h"
namespace grpc_core {
@ -82,4 +82,4 @@ class MetadataSizesAnnotation
} // namespace grpc_core
#endif // GRPC_SRC_CORE_LIB_TRANSPORT_METADATA_INFO_H
#endif // GRPC_SRC_CORE_CALL_METADATA_INFO_H

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/core/lib/transport/parsed_metadata.h"
#include "src/core/call/parsed_metadata.h"
#include <grpc/support/port_platform.h>

View File

@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef GRPC_SRC_CORE_LIB_TRANSPORT_PARSED_METADATA_H
#define GRPC_SRC_CORE_LIB_TRANSPORT_PARSED_METADATA_H
#ifndef GRPC_SRC_CORE_CALL_PARSED_METADATA_H
#define GRPC_SRC_CORE_CALL_PARSED_METADATA_H
#include <grpc/slice.h>
#include <grpc/support/port_platform.h>
@ -426,4 +426,4 @@ ParsedMetadata<MetadataContainer>::KeyValueVTable(absl::string_view key) {
} // namespace grpc_core
#endif // GRPC_SRC_CORE_LIB_TRANSPORT_PARSED_METADATA_H
#endif // GRPC_SRC_CORE_CALL_PARSED_METADATA_H

View File

@ -15,9 +15,9 @@
#include "src/core/call/request_buffer.h"
#include <cstdint>
#include <optional>
#include "absl/strings/str_cat.h"
#include "absl/types/optional.h"
#include "src/core/util/match.h"
namespace grpc_core {
@ -29,8 +29,8 @@ RequestBuffer::RequestBuffer() : state_(absl::in_place_type_t<Buffering>()) {}
ValueOrFailure<size_t> RequestBuffer::PushClientInitialMetadata(
ClientMetadataHandle md) {
MutexLock lock(&mu_);
if (absl::get_if<Cancelled>(&state_)) return Failure{};
auto& buffering = absl::get<Buffering>(state_);
if (std::get_if<Cancelled>(&state_)) return Failure{};
auto& buffering = std::get<Buffering>(state_);
CHECK_EQ(buffering.initial_metadata.get(), nullptr);
buffering.initial_metadata = std::move(md);
buffering.buffered += buffering.initial_metadata->TransportSize();
@ -41,15 +41,15 @@ ValueOrFailure<size_t> RequestBuffer::PushClientInitialMetadata(
Poll<ValueOrFailure<size_t>> RequestBuffer::PollPushMessage(
MessageHandle& message) {
MutexLock lock(&mu_);
if (absl::get_if<Cancelled>(&state_)) return Failure{};
if (std::get_if<Cancelled>(&state_)) return Failure{};
size_t buffered = 0;
if (auto* buffering = absl::get_if<Buffering>(&state_)) {
if (auto* buffering = std::get_if<Buffering>(&state_)) {
if (winner_ != nullptr) return PendingPush();
buffering->buffered += message->payload()->Length();
buffered = buffering->buffered;
buffering->messages.push_back(std::move(message));
} else {
auto& streaming = absl::get<Streaming>(state_);
auto& streaming = std::get<Streaming>(state_);
CHECK_EQ(streaming.end_of_stream, false);
if (streaming.message != nullptr) {
return PendingPush();
@ -62,13 +62,13 @@ Poll<ValueOrFailure<size_t>> RequestBuffer::PollPushMessage(
StatusFlag RequestBuffer::FinishSends() {
MutexLock lock(&mu_);
if (absl::get_if<Cancelled>(&state_)) return Failure{};
if (auto* buffering = absl::get_if<Buffering>(&state_)) {
if (std::get_if<Cancelled>(&state_)) return Failure{};
if (auto* buffering = std::get_if<Buffering>(&state_)) {
Buffered buffered(std::move(buffering->initial_metadata),
std::move(buffering->messages));
state_.emplace<Buffered>(std::move(buffered));
} else {
auto& streaming = absl::get<Streaming>(state_);
auto& streaming = std::get<Streaming>(state_);
CHECK_EQ(streaming.end_of_stream, false);
streaming.end_of_stream = true;
}
@ -78,7 +78,7 @@ StatusFlag RequestBuffer::FinishSends() {
void RequestBuffer::Cancel(absl::Status error) {
MutexLock lock(&mu_);
if (absl::holds_alternative<Cancelled>(state_)) return;
if (std::holds_alternative<Cancelled>(state_)) return;
state_.emplace<Cancelled>(std::move(error));
WakeupAsyncAllPullers();
}
@ -87,13 +87,13 @@ void RequestBuffer::Commit(Reader* winner) {
MutexLock lock(&mu_);
CHECK_EQ(winner_, nullptr);
winner_ = winner;
if (auto* buffering = absl::get_if<Buffering>(&state_)) {
if (auto* buffering = std::get_if<Buffering>(&state_)) {
if (buffering->initial_metadata != nullptr &&
winner->message_index_ == buffering->messages.size() &&
winner->pulled_client_initial_metadata_) {
state_.emplace<Streaming>();
}
} else if (auto* buffered = absl::get_if<Buffered>(&state_)) {
} else if (auto* buffered = std::get_if<Buffered>(&state_)) {
CHECK_NE(buffered->initial_metadata.get(), nullptr);
if (winner->message_index_ == buffered->messages.size()) {
state_.emplace<Streaming>().end_of_stream = true;
@ -116,7 +116,7 @@ RequestBuffer::Reader::PollPullClientInitialMetadata() {
error_ = absl::CancelledError("Another call was chosen");
return Failure{};
}
if (auto* buffering = absl::get_if<Buffering>(&buffer_->state_)) {
if (auto* buffering = std::get_if<Buffering>(&buffer_->state_)) {
if (buffering->initial_metadata.get() == nullptr) {
return buffer_->PendingPull(this);
}
@ -125,22 +125,22 @@ RequestBuffer::Reader::PollPullClientInitialMetadata() {
buffer_->MaybeSwitchToStreaming();
return std::move(result);
}
if (auto* buffered = absl::get_if<Buffered>(&buffer_->state_)) {
if (auto* buffered = std::get_if<Buffered>(&buffer_->state_)) {
pulled_client_initial_metadata_ = true;
return ClaimObject(buffered->initial_metadata);
}
error_ = absl::get<Cancelled>(buffer_->state_).error;
error_ = std::get<Cancelled>(buffer_->state_).error;
return Failure{};
}
Poll<ValueOrFailure<absl::optional<MessageHandle>>>
Poll<ValueOrFailure<std::optional<MessageHandle>>>
RequestBuffer::Reader::PollPullMessage() {
ReleasableMutexLock lock(&buffer_->mu_);
if (buffer_->winner_ != nullptr && buffer_->winner_ != this) {
error_ = absl::CancelledError("Another call was chosen");
return Failure{};
}
if (auto* buffering = absl::get_if<Buffering>(&buffer_->state_)) {
if (auto* buffering = std::get_if<Buffering>(&buffer_->state_)) {
if (message_index_ == buffering->messages.size()) {
return buffer_->PendingPull(this);
}
@ -150,15 +150,15 @@ RequestBuffer::Reader::PollPullMessage() {
buffer_->MaybeSwitchToStreaming();
return std::move(result);
}
if (auto* buffered = absl::get_if<Buffered>(&buffer_->state_)) {
if (message_index_ == buffered->messages.size()) return absl::nullopt;
if (auto* buffered = std::get_if<Buffered>(&buffer_->state_)) {
if (message_index_ == buffered->messages.size()) return std::nullopt;
const auto idx = message_index_;
++message_index_;
return ClaimObject(buffered->messages[idx]);
}
if (auto* streaming = absl::get_if<Streaming>(&buffer_->state_)) {
if (auto* streaming = std::get_if<Streaming>(&buffer_->state_)) {
if (streaming->message == nullptr) {
if (streaming->end_of_stream) return absl::nullopt;
if (streaming->end_of_stream) return std::nullopt;
return buffer_->PendingPull(this);
}
auto msg = std::move(streaming->message);
@ -167,7 +167,7 @@ RequestBuffer::Reader::PollPullMessage() {
waker.Wakeup();
return std::move(msg);
}
error_ = absl::get<Cancelled>(buffer_->state_).error;
error_ = std::get<Cancelled>(buffer_->state_).error;
return Failure{};
}

View File

@ -17,9 +17,9 @@
#include <utility>
#include "src/core/lib/transport/call_spine.h"
#include "src/core/lib/transport/message.h"
#include "src/core/lib/transport/metadata.h"
#include "src/core/call/call_spine.h"
#include "src/core/call/message.h"
#include "src/core/call/metadata.h"
namespace grpc_core {
@ -51,7 +51,7 @@ class RequestBuffer {
return [this]() { return PollPullClientInitialMetadata(); };
}
// Pull a message. Returns a promise that resolves to a
// ValueOrFailure<absl::optional<MessageHandle>>.
// ValueOrFailure<std::optional<MessageHandle>>.
GRPC_MUST_USE_RESULT auto PullMessage() {
return [this]() { return PollPullMessage(); };
}
@ -62,7 +62,7 @@ class RequestBuffer {
friend class RequestBuffer;
Poll<ValueOrFailure<ClientMetadataHandle>> PollPullClientInitialMetadata();
Poll<ValueOrFailure<absl::optional<MessageHandle>>> PollPullMessage();
Poll<ValueOrFailure<std::optional<MessageHandle>>> PollPullMessage();
template <typename T>
T ClaimObject(T& object) ABSL_EXCLUSIVE_LOCKS_REQUIRED(buffer_->mu_) {
@ -143,7 +143,7 @@ class RequestBuffer {
explicit Cancelled(absl::Status error) : error(std::move(error)) {}
absl::Status error;
};
using State = absl::variant<Buffering, Buffered, Streaming, Cancelled>;
using State = std::variant<Buffering, Buffered, Streaming, Cancelled>;
Poll<ValueOrFailure<size_t>> PollPushMessage(MessageHandle& message);
Pending PendingPull(Reader* reader) ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_) {
@ -155,7 +155,7 @@ class RequestBuffer {
return Pending{};
}
void MaybeSwitchToStreaming() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_) {
auto& buffering = absl::get<Buffering>(state_);
auto& buffering = std::get<Buffering>(state_);
if (winner_ == nullptr) return;
if (winner_->message_index_ < buffering.messages.size()) return;
state_.emplace<Streaming>();

View File

@ -0,0 +1,125 @@
//
// Copyright 2015 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "src/core/call/security_context.h"
#include <grpc/credentials.h>
#include <grpc/grpc_security.h>
#include <grpc/support/alloc.h>
#include <grpc/support/port_platform.h>
#include <grpc/support/string_util.h>
#include <string.h>
#include <algorithm>
#include "absl/log/check.h"
#include "absl/log/log.h"
#include "src/core/credentials/call/call_credentials.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/resource_quota/arena.h"
#include "src/core/lib/surface/call.h"
#include "src/core/util/ref_counted_ptr.h"
// --- grpc_call ---
grpc_call_error grpc_call_set_credentials(grpc_call* call,
grpc_call_credentials* creds) {
grpc_core::ExecCtx exec_ctx;
grpc_client_security_context* ctx = nullptr;
GRPC_TRACE_LOG(api, INFO) << "grpc_call_set_credentials(call=" << call
<< ", creds=" << creds << ")";
if (!grpc_call_is_client(call)) {
LOG(ERROR) << "Method is client-side only.";
return GRPC_CALL_ERROR_NOT_ON_SERVER;
}
auto* arena = grpc_call_get_arena(call);
ctx = grpc_core::DownCast<grpc_client_security_context*>(
arena->GetContext<grpc_core::SecurityContext>());
if (ctx == nullptr) {
ctx = grpc_client_security_context_create(arena, creds);
arena->SetContext<grpc_core::SecurityContext>(ctx);
} else {
ctx->creds = creds != nullptr ? creds->Ref() : nullptr;
}
return GRPC_CALL_OK;
}
grpc_auth_context* grpc_call_auth_context(grpc_call* call) {
auto* sec_ctx =
grpc_call_get_arena(call)->GetContext<grpc_core::SecurityContext>();
GRPC_TRACE_LOG(api, INFO) << "grpc_call_auth_context(call=" << call << ")";
if (sec_ctx == nullptr) return nullptr;
if (grpc_call_is_client(call)) {
auto* sc = grpc_core::DownCast<grpc_client_security_context*>(sec_ctx);
if (sc->auth_context == nullptr) {
return nullptr;
} else {
return sc->auth_context
->Ref(DEBUG_LOCATION, "grpc_call_auth_context client")
.release();
}
} else {
auto* sc = grpc_core::DownCast<grpc_server_security_context*>(sec_ctx);
if (sc->auth_context == nullptr) {
return nullptr;
} else {
return sc->auth_context
->Ref(DEBUG_LOCATION, "grpc_call_auth_context server")
.release();
}
}
}
// --- grpc_client_security_context ---
grpc_client_security_context::~grpc_client_security_context() {
auth_context.reset(DEBUG_LOCATION, "client_security_context");
if (extension.instance != nullptr && extension.destroy != nullptr) {
extension.destroy(extension.instance);
}
}
grpc_client_security_context* grpc_client_security_context_create(
grpc_core::Arena* arena, grpc_call_credentials* creds) {
return arena->New<grpc_client_security_context>(
creds != nullptr ? creds->Ref() : nullptr);
}
void grpc_client_security_context_destroy(void* ctx) {
grpc_client_security_context* c =
static_cast<grpc_client_security_context*>(ctx);
c->~grpc_client_security_context();
}
// --- grpc_server_security_context ---
grpc_server_security_context::~grpc_server_security_context() {
auth_context.reset(DEBUG_LOCATION, "server_security_context");
if (extension.instance != nullptr && extension.destroy != nullptr) {
extension.destroy(extension.instance);
}
}
grpc_server_security_context* grpc_server_security_context_create(
grpc_core::Arena* arena) {
return arena->New<grpc_server_security_context>();
}
void grpc_server_security_context_destroy(void* ctx) {
grpc_server_security_context* c =
static_cast<grpc_server_security_context*>(ctx);
c->~grpc_server_security_context();
}

View File

@ -0,0 +1,114 @@
//
// Copyright 2015 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef GRPC_SRC_CORE_CALL_SECURITY_CONTEXT_H
#define GRPC_SRC_CORE_CALL_SECURITY_CONTEXT_H
#include <grpc/credentials.h>
#include <grpc/grpc.h>
#include <grpc/grpc_security.h>
#include <grpc/support/alloc.h>
#include <grpc/support/port_platform.h>
#include <stddef.h>
#include <memory>
#include <utility>
#include "absl/strings/string_view.h"
#include "src/core/credentials/call/call_credentials.h" // IWYU pragma: keep
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/resource_quota/arena.h"
#include "src/core/lib/surface/connection_context.h"
#include "src/core/transport/auth_context.h"
#include "src/core/util/debug_location.h"
#include "src/core/util/orphanable.h"
#include "src/core/util/ref_counted.h"
#include "src/core/util/ref_counted_ptr.h"
#include "src/core/util/useful.h"
// --- grpc_security_context_extension ---
// Extension to the security context that may be set in a filter and accessed
// later by a higher level method on a grpc_call object.
struct grpc_security_context_extension {
void* instance = nullptr;
void (*destroy)(void*) = nullptr;
};
namespace grpc_core {
// TODO(roth): Consider renaming to something like CallSecurityContext
// to reflect the fact that it stores call-level security properties.
class SecurityContext {
public:
virtual ~SecurityContext() = default;
};
} // namespace grpc_core
// --- grpc_client_security_context ---
// Internal client-side security context.
struct grpc_client_security_context final : public grpc_core::SecurityContext {
explicit grpc_client_security_context(
grpc_core::RefCountedPtr<grpc_call_credentials> creds)
: creds(std::move(creds)) {}
~grpc_client_security_context() override;
grpc_core::RefCountedPtr<grpc_call_credentials> creds;
grpc_core::RefCountedPtr<grpc_auth_context> auth_context;
grpc_security_context_extension extension;
};
grpc_client_security_context* grpc_client_security_context_create(
grpc_core::Arena* arena, grpc_call_credentials* creds);
void grpc_client_security_context_destroy(void* ctx);
// --- grpc_server_security_context ---
// Internal server-side security context.
struct grpc_server_security_context final : public grpc_core::SecurityContext {
grpc_server_security_context() = default;
~grpc_server_security_context() override;
grpc_core::RefCountedPtr<grpc_auth_context> auth_context;
grpc_security_context_extension extension;
};
grpc_server_security_context* grpc_server_security_context_create(
grpc_core::Arena* arena);
void grpc_server_security_context_destroy(void* ctx);
namespace grpc_core {
template <>
struct ArenaContextType<SecurityContext> {
static void Destroy(SecurityContext* p) { p->~SecurityContext(); }
};
template <>
struct ContextSubclass<grpc_client_security_context> {
using Base = SecurityContext;
};
template <>
struct ContextSubclass<grpc_server_security_context> {
using Base = SecurityContext;
};
} // namespace grpc_core
#endif // GRPC_SRC_CORE_CALL_SECURITY_CONTEXT_H

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/core/lib/surface/server_call.h"
#include "src/core/call/server_call.h"
#include <grpc/byte_buffer.h>
#include <grpc/compression.h>
@ -32,12 +32,15 @@
#include <stdlib.h>
#include <string.h>
#include <atomic>
#include <memory>
#include <string>
#include <utility>
#include "absl/log/check.h"
#include "absl/strings/string_view.h"
#include "src/core/call/metadata.h"
#include "src/core/call/metadata_batch.h"
#include "src/core/lib/promise/all_ok.h"
#include "src/core/lib/promise/map.h"
#include "src/core/lib/promise/poll.h"
@ -46,8 +49,6 @@
#include "src/core/lib/resource_quota/arena.h"
#include "src/core/lib/slice/slice_buffer.h"
#include "src/core/lib/surface/completion_queue.h"
#include "src/core/lib/transport/metadata.h"
#include "src/core/lib/transport/metadata_batch.h"
#include "src/core/server/server_interface.h"
#include "src/core/util/bitset.h"
#include "src/core/util/latent_see.h"
@ -169,16 +170,28 @@ void ServerCall::CommitBatch(const grpc_op* ops, size_t nops, void* notify_tag,
metadata->Set(GrpcMessageMetadata(), Slice(grpc_slice_copy(*details)));
}
CHECK(metadata != nullptr);
return [this, metadata = std::move(metadata)]() mutable {
bool wait_for_initial_metadata_scheduled =
sent_server_initial_metadata_batch_.load(std::memory_order_relaxed);
return [this, metadata = std::move(metadata),
wait_for_initial_metadata_scheduled]() mutable {
CHECK(metadata != nullptr);
return [this, metadata = std::move(metadata)]() mutable -> Poll<Success> {
CHECK(metadata != nullptr);
call_handler_.PushServerTrailingMetadata(std::move(metadata));
return Success{};
};
// If there was a send initial metadata batch sent prior to this one, then
// make sure it's been scheduled first - otherwise we may accidentally
// treat this as trailers only.
return Seq(
If(
wait_for_initial_metadata_scheduled,
[this]() { return server_initial_metadata_scheduled_.Wait(); },
[]() { return Empty{}; }),
[this, metadata = std::move(metadata)]() mutable -> Poll<Success> {
CHECK(metadata != nullptr);
call_handler_.PushServerTrailingMetadata(std::move(metadata));
return Success{};
});
};
};
// Handle send trailing metadata only
if (op_index.has_op(GRPC_OP_SEND_INITIAL_METADATA) &&
op_index.has_op(GRPC_OP_SEND_STATUS_FROM_SERVER) &&
!op_index.has_op(GRPC_OP_SEND_MESSAGE) &&
@ -189,6 +202,7 @@ void ServerCall::CommitBatch(const grpc_op* ops, size_t nops, void* notify_tag,
commit_with_send_ops(OpHandler<GRPC_OP_SEND_STATUS_FROM_SERVER>(
make_send_trailing_metadata(trailing_metadata)));
} else {
// Non-send-trailing-metadata path
auto send_initial_metadata =
op_index.OpHandler<GRPC_OP_SEND_INITIAL_METADATA>(
[this](const grpc_op& op) {
@ -196,9 +210,12 @@ void ServerCall::CommitBatch(const grpc_op* ops, size_t nops, void* notify_tag,
PrepareOutgoingInitialMetadata(op, *metadata);
CToMetadata(op.data.send_initial_metadata.metadata,
op.data.send_initial_metadata.count, metadata.get());
sent_server_initial_metadata_batch_.store(
true, std::memory_order_relaxed);
GRPC_TRACE_LOG(call, INFO)
<< DebugTag() << "[call] Send initial metadata";
return [this, metadata = std::move(metadata)]() mutable {
server_initial_metadata_scheduled_.Set();
return call_handler_.PushServerInitialMetadata(
std::move(metadata));
};

View File

@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef GRPC_SRC_CORE_LIB_SURFACE_SERVER_CALL_H
#define GRPC_SRC_CORE_LIB_SURFACE_SERVER_CALL_H
#ifndef GRPC_SRC_CORE_CALL_SERVER_CALL_H
#define GRPC_SRC_CORE_CALL_SERVER_CALL_H
#include <grpc/byte_buffer.h>
#include <grpc/compression.h>
@ -43,12 +43,12 @@
#include "absl/status/status.h"
#include "absl/strings/str_format.h"
#include "absl/strings/string_view.h"
#include "src/core/call/metadata.h"
#include "src/core/call/metadata_batch.h"
#include "src/core/lib/promise/poll.h"
#include "src/core/lib/resource_quota/arena.h"
#include "src/core/lib/surface/call.h"
#include "src/core/lib/surface/call_utils.h"
#include "src/core/lib/transport/metadata.h"
#include "src/core/lib/transport/metadata_batch.h"
#include "src/core/server/server_interface.h"
#include "src/core/telemetry/stats.h"
#include "src/core/telemetry/stats_data.h"
@ -150,6 +150,8 @@ class ServerCall final : public Call, public DualRefCounted<ServerCall> {
std::string DebugTag() { return absl::StrFormat("SERVER_CALL[%p]: ", this); }
CallHandler call_handler_;
std::atomic<bool> sent_server_initial_metadata_batch_{false};
Latch<void> server_initial_metadata_scheduled_;
MessageReceiver message_receiver_;
ClientMetadataHandle client_initial_metadata_stored_;
grpc_completion_queue* const cq_;
@ -164,4 +166,4 @@ grpc_call* MakeServerCall(CallHandler call_handler,
} // namespace grpc_core
#endif // GRPC_SRC_CORE_LIB_SURFACE_SERVER_CALL_H
#endif // GRPC_SRC_CORE_CALL_SERVER_CALL_H

View File

@ -12,14 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef GRPC_SRC_CORE_LIB_TRANSPORT_SIMPLE_SLICE_BASED_METADATA_H
#define GRPC_SRC_CORE_LIB_TRANSPORT_SIMPLE_SLICE_BASED_METADATA_H
#ifndef GRPC_SRC_CORE_CALL_SIMPLE_SLICE_BASED_METADATA_H
#define GRPC_SRC_CORE_CALL_SIMPLE_SLICE_BASED_METADATA_H
#include <grpc/support/port_platform.h>
#include "absl/strings/string_view.h"
#include "src/core/call/parsed_metadata.h"
#include "src/core/lib/slice/slice.h"
#include "src/core/lib/transport/parsed_metadata.h"
namespace grpc_core {
@ -50,4 +50,4 @@ struct SimpleSliceBasedMetadata {
} // namespace grpc_core
#endif // GRPC_SRC_CORE_LIB_TRANSPORT_SIMPLE_SLICE_BASED_METADATA_H
#endif // GRPC_SRC_CORE_CALL_SIMPLE_SLICE_BASED_METADATA_H

View File

@ -16,7 +16,7 @@
//
//
#include "src/core/lib/channel/status_util.h"
#include "src/core/call/status_util.h"
#include <grpc/support/port_platform.h>
#include <string.h>

View File

@ -16,8 +16,8 @@
//
//
#ifndef GRPC_SRC_CORE_LIB_CHANNEL_STATUS_UTIL_H
#define GRPC_SRC_CORE_LIB_CHANNEL_STATUS_UTIL_H
#ifndef GRPC_SRC_CORE_CALL_STATUS_UTIL_H
#define GRPC_SRC_CORE_CALL_STATUS_UTIL_H
#include <grpc/status.h>
#include <grpc/support/port_platform.h>
@ -77,4 +77,4 @@ absl::Status MaybeRewriteIllegalStatusCode(absl::Status status,
} // namespace grpc_core
#endif // GRPC_SRC_CORE_LIB_CHANNEL_STATUS_UTIL_H
#endif // GRPC_SRC_CORE_CALL_STATUS_UTIL_H

View File

@ -29,7 +29,9 @@
#include "src/core/channelz/channelz.h"
#include "src/core/lib/slice/slice.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/util/ref_counted_ptr.h"
#include "src/core/util/string.h"
#include "src/core/util/sync.h"
#include "src/core/util/time.h"
namespace grpc_core {
@ -52,41 +54,8 @@ ChannelTrace::TraceEvent::TraceEvent(Severity severity, const grpc_slice& data)
ChannelTrace::TraceEvent::~TraceEvent() { CSliceUnref(data_); }
namespace {
const char* SeverityString(ChannelTrace::Severity severity) {
switch (severity) {
case ChannelTrace::Severity::Info:
return "CT_INFO";
case ChannelTrace::Severity::Warning:
return "CT_WARNING";
case ChannelTrace::Severity::Error:
return "CT_ERROR";
default:
GPR_UNREACHABLE_CODE(return "CT_UNKNOWN");
}
}
} // anonymous namespace
Json ChannelTrace::TraceEvent::RenderTraceEvent() const {
char* description = grpc_slice_to_c_string(data_);
Json::Object object = {
{"description", Json::FromString(description)},
{"severity", Json::FromString(SeverityString(severity_))},
{"timestamp", Json::FromString(gpr_format_timespec(timestamp_))},
};
gpr_free(description);
if (referenced_entity_ != nullptr) {
const bool is_channel =
(referenced_entity_->type() == BaseNode::EntityType::kTopLevelChannel ||
referenced_entity_->type() == BaseNode::EntityType::kInternalChannel);
object[is_channel ? "channelRef" : "subchannelRef"] = Json::FromObject({
{(is_channel ? "channelId" : "subchannelId"),
Json::FromString(absl::StrCat(referenced_entity_->uuid()))},
});
}
return Json::FromObject(std::move(object));
RefCountedPtr<BaseNode> ChannelTrace::TraceEvent::referenced_entity() const {
return referenced_entity_;
}
//
@ -115,9 +84,8 @@ void ChannelTrace::AddTraceEventHelper(TraceEvent* new_trace_event) {
// first event case
if (head_trace_ == nullptr) {
head_trace_ = tail_trace_ = new_trace_event;
}
// regular event add case
else {
} else {
// regular event add case
tail_trace_->set_next(new_trace_event);
tail_trace_ = tail_trace_->next();
}
@ -151,6 +119,25 @@ void ChannelTrace::AddTraceEventWithReference(
new TraceEvent(severity, data, std::move(referenced_entity)));
}
std::string ChannelTrace::TraceEvent::description() const {
char* description = grpc_slice_to_c_string(data_);
std::string s(description);
gpr_free(description);
return s;
}
void ChannelTrace::ForEachTraceEventLocked(
absl::FunctionRef<void(gpr_timespec, Severity, std::string,
RefCountedPtr<BaseNode>)>
callback) const {
TraceEvent* it = head_trace_;
while (it != nullptr) {
callback(it->timestamp(), it->severity(), it->description(),
it->referenced_entity());
it = it->next();
}
}
Json ChannelTrace::RenderJson() const {
// Tracing is disabled if max_event_memory_ == 0.
if (max_event_memory_ == 0) {
@ -166,15 +153,36 @@ Json ChannelTrace::RenderJson() const {
Json::FromString(absl::StrCat(num_events_logged_));
}
// Only add in the event list if it is non-empty.
if (head_trace_ != nullptr) {
Json::Array array;
for (TraceEvent* it = head_trace_; it != nullptr; it = it->next()) {
array.emplace_back(it->RenderTraceEvent());
Json::Array array;
ForEachTraceEventLocked([&array](gpr_timespec timestamp, Severity severity,
std::string description,
RefCountedPtr<BaseNode> referenced_entity) {
Json::Object object = {
{"description", Json::FromString(description)},
{"severity", Json::FromString(SeverityString(severity))},
{"timestamp", Json::FromString(gpr_format_timespec(timestamp))},
};
if (referenced_entity != nullptr) {
const bool is_channel =
(referenced_entity->type() ==
BaseNode::EntityType::kTopLevelChannel ||
referenced_entity->type() == BaseNode::EntityType::kInternalChannel);
object[is_channel ? "channelRef" : "subchannelRef"] = Json::FromObject({
{(is_channel ? "channelId" : "subchannelId"),
Json::FromString(absl::StrCat(referenced_entity->uuid()))},
});
}
array.emplace_back(Json::FromObject(std::move(object)));
});
if (!array.empty()) {
object["events"] = Json::FromArray(std::move(array));
}
return Json::FromObject(std::move(object));
}
std::string ChannelTrace::creation_timestamp() const {
return gpr_format_timespec(time_created_);
}
} // namespace channelz
} // namespace grpc_core

View File

@ -24,6 +24,7 @@
#include <grpc/support/time.h>
#include <stddef.h>
#include <stdint.h>
#include <sys/types.h>
#include "absl/base/thread_annotations.h"
#include "src/core/util/json/json.h"
@ -54,6 +55,19 @@ class ChannelTrace {
Error
};
static const char* SeverityString(ChannelTrace::Severity severity) {
switch (severity) {
case ChannelTrace::Severity::Info:
return "CT_INFO";
case ChannelTrace::Severity::Warning:
return "CT_WARNING";
case ChannelTrace::Severity::Error:
return "CT_ERROR";
default:
GPR_UNREACHABLE_CODE(return "CT_UNKNOWN");
}
}
// Adds a new trace event to the tracing object
//
// NOTE: each ChannelTrace tracks the memory used by its list of trace
@ -82,6 +96,19 @@ class ChannelTrace {
// object may incorporate the json before rendering.
Json RenderJson() const;
void ForEachTraceEvent(
absl::FunctionRef<void(gpr_timespec, Severity, std::string,
RefCountedPtr<BaseNode>)>
callback) const {
MutexLock lock(&mu_);
ForEachTraceEventLocked(callback);
}
std::string creation_timestamp() const;
uint64_t num_events_logged() const {
MutexLock lock(&mu_);
return num_events_logged_;
}
private:
friend size_t testing::GetSizeofTraceEvent(void);
@ -99,15 +126,15 @@ class ChannelTrace {
~TraceEvent();
// Renders the data inside of this TraceEvent into a json object. This is
// used by the ChannelTrace, when it is rendering itself.
Json RenderTraceEvent() const;
// set and get for the next_ pointer.
TraceEvent* next() const { return next_; }
void set_next(TraceEvent* next) { next_ = next; }
size_t memory_usage() const { return memory_usage_; }
gpr_timespec timestamp() const { return timestamp_; }
Severity severity() const { return severity_; }
std::string description() const;
RefCountedPtr<BaseNode> referenced_entity() const;
private:
const gpr_timespec timestamp_;
@ -121,6 +148,10 @@ class ChannelTrace {
// Internal helper to add and link in a trace event
void AddTraceEventHelper(TraceEvent* new_trace_event);
void ForEachTraceEventLocked(
absl::FunctionRef<void(gpr_timespec, Severity, std::string,
RefCountedPtr<BaseNode>)>) const
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_);
const size_t max_event_memory_;
const gpr_timespec time_created_;

View File

@ -25,6 +25,10 @@
#include <algorithm>
#include <atomic>
#include <cstdint>
#include <initializer_list>
#include <limits>
#include <string>
#include <tuple>
#include "absl/log/check.h"
#include "absl/status/statusor.h"
@ -39,12 +43,123 @@
#include "src/core/lib/transport/connectivity_state.h"
#include "src/core/util/json/json_writer.h"
#include "src/core/util/string.h"
#include "src/core/util/time.h"
#include "src/core/util/uri.h"
#include "src/core/util/useful.h"
namespace grpc_core {
namespace channelz {
//
// DataSink
//
namespace {
class ChildObjectCollector {
public:
void Add(RefCountedPtr<BaseNode> node) {
child_objects_[node->type()].insert(node->uuid());
}
void Add(std::vector<RefCountedPtr<BaseNode>> nodes) {
for (auto& node : nodes) Add(std::move(node));
}
// Calls AddAdditionalInfo to export the collected child objects.
void Finalize(DataSink& sink) {
if (child_objects_.empty()) return;
Json::Object subobjects;
for (const auto& [type, child_objects] : child_objects_) {
std::string key;
switch (type) {
case BaseNode::EntityType::kTopLevelChannel:
case BaseNode::EntityType::kSubchannel:
case BaseNode::EntityType::kListenSocket:
case BaseNode::EntityType::kServer:
case BaseNode::EntityType::kInternalChannel: {
LOG(ERROR)
<< "Nodes of type " << BaseNode::EntityTypeString(type)
<< " not supported for child object collection in DataSink";
continue;
}
case BaseNode::EntityType::kSocket:
key = "subSockets";
break;
case BaseNode::EntityType::kCall:
key = "calls";
break;
}
Json::Array uuids;
uuids.reserve(child_objects.size());
for (int64_t uuid : child_objects) {
uuids.push_back(Json::FromNumber(uuid));
}
subobjects[key] = Json::FromArray(std::move(uuids));
}
sink.AddAdditionalInfo("childObjects", std::move(subobjects));
}
private:
std::map<BaseNode::EntityType, std::set<int64_t>> child_objects_;
};
class JsonDataSink final : public DataSink {
public:
explicit JsonDataSink(Json::Object& output) : output_(output) {
CHECK(output_.find("additionalInfo") == output_.end());
}
~JsonDataSink() {
collector_.Finalize(*this);
if (additional_info_ != nullptr) {
output_["additionalInfo"] =
Json::FromObject(std::move(*additional_info_));
}
}
void AddAdditionalInfo(absl::string_view name,
Json::Object additional_info) override {
if (additional_info_ == nullptr) {
additional_info_ = std::make_unique<Json::Object>();
}
additional_info_->emplace(name,
Json::FromObject(std::move(additional_info)));
}
void AddChildObjects(
std::vector<RefCountedPtr<BaseNode>> child_objects) override {
collector_.Add(std::move(child_objects));
}
private:
Json::Object& output_;
std::unique_ptr<Json::Object> additional_info_;
ChildObjectCollector collector_;
};
class ExplicitJsonDataSink final : public DataSink {
public:
void AddAdditionalInfo(absl::string_view name,
Json::Object additional_info) override {
additional_info_.emplace(name,
Json::FromObject(std::move(additional_info)));
}
void AddChildObjects(
std::vector<RefCountedPtr<BaseNode>> child_objects) override {
collector_.Add(std::move(child_objects));
}
Json::Object Finalize() {
collector_.Finalize(*this);
return std::move(additional_info_);
}
private:
Json::Object additional_info_;
ChildObjectCollector collector_;
};
} // namespace
//
// BaseNode
//
@ -55,13 +170,95 @@ BaseNode::BaseNode(EntityType type, std::string name)
ChannelzRegistry::Register(this);
}
BaseNode::~BaseNode() { ChannelzRegistry::Unregister(uuid_); }
void BaseNode::Orphaned() { ChannelzRegistry::Unregister(this); }
intptr_t BaseNode::UuidSlow() { return ChannelzRegistry::NumberNode(this); }
std::string BaseNode::RenderJsonString() {
Json json = RenderJson();
return JsonDump(json);
}
void BaseNode::PopulateJsonFromDataSources(Json::Object& json) {
JsonDataSink sink(json);
MutexLock lock(&data_sources_mu_);
for (DataSource* data_source : data_sources_) {
data_source->AddData(sink);
}
}
Json::Object BaseNode::AdditionalInfo() {
ExplicitJsonDataSink sink;
MutexLock lock(&data_sources_mu_);
for (DataSource* data_source : data_sources_) {
data_source->AddData(sink);
}
return sink.Finalize();
}
void BaseNode::RunZTrace(
absl::string_view name, Timestamp deadline,
std::map<std::string, std::string> args,
std::shared_ptr<grpc_event_engine::experimental::EventEngine> event_engine,
absl::AnyInvocable<void(Json)> callback) {
// Limit deadline to help contain potential resource exhaustion due to
// tracing.
deadline = std::min(deadline, Timestamp::Now() + Duration::Minutes(10));
auto fail = [&callback, event_engine](absl::Status status) {
event_engine->Run(
[callback = std::move(callback), status = std::move(status)]() mutable {
Json::Object object;
object["status"] = Json::FromString(status.ToString());
callback(Json::FromObject(std::move(object)));
});
};
std::unique_ptr<ZTrace> ztrace;
{
MutexLock lock(&data_sources_mu_);
for (auto* data_source : data_sources_) {
if (auto found_ztrace = data_source->GetZTrace(name);
found_ztrace != nullptr) {
if (ztrace == nullptr) {
ztrace = std::move(found_ztrace);
} else {
fail(absl::InternalError(
absl::StrCat("Ambiguous ztrace handler: ", name)));
return;
}
}
}
}
if (ztrace == nullptr) {
fail(absl::NotFoundError(absl::StrCat("ztrace not found: ", name)));
return;
}
ztrace->Run(deadline, std::move(args), event_engine, std::move(callback));
}
//
// DataSource
//
DataSource::DataSource(RefCountedPtr<BaseNode> node) : node_(std::move(node)) {
if (node_ == nullptr) return;
MutexLock lock(&node_->data_sources_mu_);
node_->data_sources_.push_back(this);
}
DataSource::~DataSource() {
DCHECK(node_ == nullptr) << "DataSource must be ResetDataSource()'d in the "
"most derived class before destruction";
}
void DataSource::ResetDataSource() {
RefCountedPtr<BaseNode> node = std::move(node_);
if (node == nullptr) return;
MutexLock lock(&node->data_sources_mu_);
node->data_sources_.erase(
std::remove(node->data_sources_.begin(), node->data_sources_.end(), this),
node->data_sources_.end());
}
//
// CallCountingHelper
//
@ -80,24 +277,21 @@ void CallCountingHelper::RecordCallSucceeded() {
calls_succeeded_.fetch_add(1, std::memory_order_relaxed);
}
void CallCountingHelper::PopulateCallCounts(Json::Object* json) {
auto calls_started = calls_started_.load(std::memory_order_relaxed);
auto calls_succeeded = calls_succeeded_.load(std::memory_order_relaxed);
auto calls_failed = calls_failed_.load(std::memory_order_relaxed);
auto last_call_started_cycle =
last_call_started_cycle_.load(std::memory_order_relaxed);
//
// CallCounts
//
void CallCounts::PopulateJson(Json::Object& json) const {
if (calls_started != 0) {
(*json)["callsStarted"] = Json::FromString(absl::StrCat(calls_started));
gpr_timespec ts = gpr_convert_clock_type(
gpr_cycle_counter_to_time(last_call_started_cycle), GPR_CLOCK_REALTIME);
(*json)["lastCallStartedTimestamp"] =
Json::FromString(gpr_format_timespec(ts));
json["callsStarted"] = Json::FromString(absl::StrCat(calls_started));
json["lastCallStartedTimestamp"] =
Json::FromString(last_call_started_timestamp());
}
if (calls_succeeded != 0) {
(*json)["callsSucceeded"] = Json::FromString(absl::StrCat(calls_succeeded));
json["callsSucceeded"] = Json::FromString(absl::StrCat(calls_succeeded));
}
if (calls_failed != 0) {
(*json)["callsFailed"] = Json::FromString(absl::StrCat(calls_failed));
json["callsFailed"] = Json::FromString(absl::StrCat(calls_failed));
}
}
@ -121,33 +315,20 @@ void PerCpuCallCountingHelper::RecordCallSucceeded() {
std::memory_order_relaxed);
}
void PerCpuCallCountingHelper::PopulateCallCounts(Json::Object* json) {
int64_t calls_started = 0;
int64_t calls_succeeded = 0;
int64_t calls_failed = 0;
gpr_cycle_counter last_call_started_cycle = 0;
CallCounts PerCpuCallCountingHelper::GetCallCounts() const {
CallCounts call_counts;
for (const auto& cpu : per_cpu_data_) {
calls_started += cpu.calls_started.load(std::memory_order_relaxed);
calls_succeeded += cpu.calls_succeeded.load(std::memory_order_relaxed);
calls_failed += cpu.calls_failed.load(std::memory_order_relaxed);
last_call_started_cycle =
std::max(last_call_started_cycle,
call_counts.calls_started +=
cpu.calls_started.load(std::memory_order_relaxed);
call_counts.calls_succeeded +=
cpu.calls_succeeded.load(std::memory_order_relaxed);
call_counts.calls_failed +=
cpu.calls_failed.load(std::memory_order_relaxed);
call_counts.last_call_started_cycle =
std::max(call_counts.last_call_started_cycle,
cpu.last_call_started_cycle.load(std::memory_order_relaxed));
}
if (calls_started != 0) {
(*json)["callsStarted"] = Json::FromString(absl::StrCat(calls_started));
gpr_timespec ts = gpr_convert_clock_type(
gpr_cycle_counter_to_time(last_call_started_cycle), GPR_CLOCK_REALTIME);
(*json)["lastCallStartedTimestamp"] =
Json::FromString(gpr_format_timespec(ts));
}
if (calls_succeeded != 0) {
(*json)["callsSucceeded"] = Json::FromString(absl::StrCat(calls_succeeded));
}
if (calls_failed != 0) {
(*json)["callsFailed"] = Json::FromString(absl::StrCat(calls_failed));
}
return call_counts;
}
//
@ -179,18 +360,48 @@ const char* ChannelNode::GetChannelConnectivityStateChangeString(
GPR_UNREACHABLE_CODE(return "UNKNOWN");
}
Json ChannelNode::RenderJson() {
Json::Object data = {
{"target", Json::FromString(target_)},
};
namespace {
std::set<intptr_t> ChildIdSet(const BaseNode* parent,
BaseNode::EntityType type) {
std::set<intptr_t> ids;
auto [children, _] = ChannelzRegistry::GetChildrenOfType(
0, parent, type, std::numeric_limits<size_t>::max());
for (const auto& node : children) {
ids.insert(node->uuid());
}
return ids;
}
} // namespace
std::set<intptr_t> ChannelNode::child_channels() const {
return ChildIdSet(this, BaseNode::EntityType::kInternalChannel);
}
std::set<intptr_t> ChannelNode::child_subchannels() const {
return ChildIdSet(this, BaseNode::EntityType::kSubchannel);
}
std::optional<std::string> ChannelNode::connectivity_state() {
// Connectivity state.
// If low-order bit is on, then the field is set.
int state_field = connectivity_state_.load(std::memory_order_relaxed);
if ((state_field & 1) != 0) {
grpc_connectivity_state state =
static_cast<grpc_connectivity_state>(state_field >> 1);
return ConnectivityStateName(state);
}
return std::nullopt;
}
Json ChannelNode::RenderJson() {
Json::Object data = {
{"target", Json::FromString(target_)},
};
if (auto cs = connectivity_state(); cs.has_value()) {
data["state"] = Json::FromObject({
{"state", Json::FromString(ConnectivityStateName(state))},
{"state", Json::FromString(cs.value())},
});
}
// Fill in the channel trace if applicable.
@ -199,7 +410,7 @@ Json ChannelNode::RenderJson() {
data["trace"] = std::move(trace_json);
}
// Ask CallCountingHelper to populate call count data.
call_counter_.PopulateCallCounts(&data);
call_counter_.GetCallCounts().PopulateJson(data);
// Construct outer object.
Json::Object json = {
{"ref", Json::FromObject({
@ -210,23 +421,25 @@ Json ChannelNode::RenderJson() {
// Template method. Child classes may override this to add their specific
// functionality.
PopulateChildRefs(&json);
PopulateJsonFromDataSources(json);
return Json::FromObject(std::move(json));
}
void ChannelNode::PopulateChildRefs(Json::Object* json) {
MutexLock lock(&child_mu_);
if (!child_subchannels_.empty()) {
auto child_subchannels = this->child_subchannels();
auto child_channels = this->child_channels();
if (!child_subchannels.empty()) {
Json::Array array;
for (intptr_t subchannel_uuid : child_subchannels_) {
for (intptr_t subchannel_uuid : child_subchannels) {
array.emplace_back(Json::FromObject({
{"subchannelId", Json::FromString(absl::StrCat(subchannel_uuid))},
}));
}
(*json)["subchannelRef"] = Json::FromArray(std::move(array));
}
if (!child_channels_.empty()) {
if (!child_channels.empty()) {
Json::Array array;
for (intptr_t channel_uuid : child_channels_) {
for (intptr_t channel_uuid : child_channels) {
array.emplace_back(Json::FromObject({
{"channelId", Json::FromString(absl::StrCat(channel_uuid))},
}));
@ -241,26 +454,6 @@ void ChannelNode::SetConnectivityState(grpc_connectivity_state state) {
connectivity_state_.store(state_field, std::memory_order_relaxed);
}
void ChannelNode::AddChildChannel(intptr_t child_uuid) {
MutexLock lock(&child_mu_);
child_channels_.insert(child_uuid);
}
void ChannelNode::RemoveChildChannel(intptr_t child_uuid) {
MutexLock lock(&child_mu_);
child_channels_.erase(child_uuid);
}
void ChannelNode::AddChildSubchannel(intptr_t child_uuid) {
MutexLock lock(&child_mu_);
child_subchannels_.insert(child_uuid);
}
void ChannelNode::RemoveChildSubchannel(intptr_t child_uuid) {
MutexLock lock(&child_mu_);
child_subchannels_.erase(child_uuid);
}
//
// SubchannelNode
//
@ -282,13 +475,17 @@ void SubchannelNode::SetChildSocket(RefCountedPtr<SocketNode> socket) {
child_socket_ = std::move(socket);
}
Json SubchannelNode::RenderJson() {
// Create and fill the data child.
std::string SubchannelNode::connectivity_state() const {
grpc_connectivity_state state =
connectivity_state_.load(std::memory_order_relaxed);
return ConnectivityStateName(state);
}
Json SubchannelNode::RenderJson() {
// Create and fill the data child.
Json::Object data = {
{"state", Json::FromObject({
{"state", Json::FromString(ConnectivityStateName(state))},
{"state", Json::FromString(connectivity_state())},
})},
{"target", Json::FromString(target_)},
};
@ -298,7 +495,7 @@ Json SubchannelNode::RenderJson() {
data["trace"] = std::move(trace_json);
}
// Ask CallCountingHelper to populate call count data.
call_counter_.PopulateCallCounts(&data);
call_counter_.GetCallCounts().PopulateJson(data);
// Construct top-level object.
Json::Object object{
{"ref", Json::FromObject({
@ -320,7 +517,8 @@ Json SubchannelNode::RenderJson() {
}),
});
}
return Json::FromObject(object);
PopulateJsonFromDataSources(object);
return Json::FromObject(std::move(object));
}
//
@ -332,51 +530,25 @@ ServerNode::ServerNode(size_t channel_tracer_max_nodes)
ServerNode::~ServerNode() {}
void ServerNode::AddChildSocket(RefCountedPtr<SocketNode> node) {
MutexLock lock(&child_mu_);
child_sockets_.insert(std::make_pair(node->uuid(), std::move(node)));
}
void ServerNode::RemoveChildSocket(intptr_t child_uuid) {
MutexLock lock(&child_mu_);
child_sockets_.erase(child_uuid);
}
void ServerNode::AddChildListenSocket(RefCountedPtr<ListenSocketNode> node) {
MutexLock lock(&child_mu_);
child_listen_sockets_.insert(std::make_pair(node->uuid(), std::move(node)));
}
void ServerNode::RemoveChildListenSocket(intptr_t child_uuid) {
MutexLock lock(&child_mu_);
child_listen_sockets_.erase(child_uuid);
}
std::string ServerNode::RenderServerSockets(intptr_t start_socket_id,
intptr_t max_results) {
CHECK_GE(start_socket_id, 0);
CHECK_GE(max_results, 0);
// If user does not set max_results, we choose 500.
size_t pagination_limit = max_results == 0 ? 500 : max_results;
if (max_results == 0) max_results = 500;
Json::Object object;
{
MutexLock lock(&child_mu_);
size_t sockets_rendered = 0;
// Create list of socket refs.
Json::Array array;
auto it = child_sockets_.lower_bound(start_socket_id);
for (; it != child_sockets_.end() && sockets_rendered < pagination_limit;
++it, ++sockets_rendered) {
array.emplace_back(Json::FromObject({
{"socketId", Json::FromString(absl::StrCat(it->first))},
{"name", Json::FromString(it->second->name())},
}));
}
object["socketRef"] = Json::FromArray(std::move(array));
if (it == child_sockets_.end()) {
object["end"] = Json::FromBool(true);
}
auto [children, end] = ChannelzRegistry::GetChildrenOfType(
start_socket_id, this, BaseNode::EntityType::kSocket, max_results);
// Create list of socket refs.
Json::Array array;
for (const auto& child : children) {
array.emplace_back(Json::FromObject({
{"socketId", Json::FromString(absl::StrCat(child->uuid()))},
{"name", Json::FromString(child->name())},
}));
}
object["socketRef"] = Json::FromArray(std::move(array));
if (end) object["end"] = Json::FromBool(true);
return JsonDump(Json::FromObject(std::move(object)));
}
@ -388,7 +560,7 @@ Json ServerNode::RenderJson() {
data["trace"] = std::move(trace_json);
}
// Ask CallCountingHelper to populate call count data.
call_counter_.PopulateCallCounts(&data);
call_counter_.GetCallCounts().PopulateJson(data);
// Construct top-level object.
Json::Object object = {
{"ref", Json::FromObject({
@ -397,22 +569,47 @@ Json ServerNode::RenderJson() {
{"data", Json::FromObject(std::move(data))},
};
// Render listen sockets.
{
MutexLock lock(&child_mu_);
if (!child_listen_sockets_.empty()) {
Json::Array array;
for (const auto& it : child_listen_sockets_) {
array.emplace_back(Json::FromObject({
{"socketId", Json::FromString(absl::StrCat(it.first))},
{"name", Json::FromString(it.second->name())},
}));
}
object["listenSocket"] = Json::FromArray(std::move(array));
auto [children, _] = ChannelzRegistry::GetChildrenOfType(
0, this, BaseNode::EntityType::kListenSocket,
std::numeric_limits<size_t>::max());
if (!children.empty()) {
Json::Array array;
for (const auto& child : children) {
array.emplace_back(Json::FromObject({
{"socketId", Json::FromString(absl::StrCat(child->uuid()))},
{"name", Json::FromString(child->name())},
}));
}
object["listenSocket"] = Json::FromArray(std::move(array));
}
PopulateJsonFromDataSources(object);
return Json::FromObject(std::move(object));
}
std::map<intptr_t, RefCountedPtr<ListenSocketNode>>
ServerNode::child_listen_sockets() const {
std::map<intptr_t, RefCountedPtr<ListenSocketNode>> result;
auto [children, _] = ChannelzRegistry::GetChildrenOfType(
0, this, BaseNode::EntityType::kListenSocket,
std::numeric_limits<size_t>::max());
for (const auto& child : children) {
result[child->uuid()] = child->RefAsSubclass<ListenSocketNode>();
}
return result;
}
std::map<intptr_t, RefCountedPtr<SocketNode>> ServerNode::child_sockets()
const {
std::map<intptr_t, RefCountedPtr<SocketNode>> result;
auto [children, _] = ChannelzRegistry::GetChildrenOfType(
0, this, BaseNode::EntityType::kSocket,
std::numeric_limits<size_t>::max());
for (const auto& child : children) {
result[child->uuid()] = child->RefAsSubclass<SocketNode>();
}
return result;
}
//
// SocketNode::Security::Tls
//
@ -644,6 +841,7 @@ Json SocketNode::RenderJson() {
}
PopulateSocketAddressJson(&object, "remote", remote_.c_str());
PopulateSocketAddressJson(&object, "local", local_.c_str());
PopulateJsonFromDataSources(object);
return Json::FromObject(std::move(object));
}
@ -652,7 +850,7 @@ Json SocketNode::RenderJson() {
//
ListenSocketNode::ListenSocketNode(std::string local_addr, std::string name)
: BaseNode(EntityType::kSocket, std::move(name)),
: BaseNode(EntityType::kListenSocket, std::move(name)),
local_addr_(std::move(local_addr)) {}
Json ListenSocketNode::RenderJson() {
@ -663,6 +861,21 @@ Json ListenSocketNode::RenderJson() {
})},
};
PopulateSocketAddressJson(&object, "local", local_addr_.c_str());
PopulateJsonFromDataSources(object);
return Json::FromObject(std::move(object));
}
//
// CallNode
//
Json CallNode::RenderJson() {
Json::Object object = {
{"ref", Json::FromObject({
{"callId", Json::FromString(absl::StrCat(uuid()))},
})},
};
PopulateJsonFromDataSources(object);
return Json::FromObject(std::move(object));
}

View File

@ -27,25 +27,37 @@
#include <atomic>
#include <cstdint>
#include <initializer_list>
#include <map>
#include <optional>
#include <set>
#include <string>
#include <utility>
#include "absl/base/thread_annotations.h"
#include "absl/container/flat_hash_set.h"
#include "absl/container/inlined_vector.h"
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "src/core/channelz/channel_trace.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/util/dual_ref_counted.h"
#include "src/core/util/json/json.h"
#include "src/core/util/per_cpu.h"
#include "src/core/util/ref_counted.h"
#include "src/core/util/ref_counted_ptr.h"
#include "src/core/util/string.h"
#include "src/core/util/sync.h"
#include "src/core/util/time.h"
#include "src/core/util/time_precise.h"
#include "src/core/util/useful.h"
// Channel arg key for channelz node.
#define GRPC_ARG_CHANNELZ_CHANNEL_NODE "grpc.internal.channelz_channel_node"
#define GRPC_ARG_CHANNELZ_CHANNEL_NODE \
"grpc.internal.no_subchannel.channelz_channel_node"
// Channel arg key for the containing base node
#define GRPC_ARG_CHANNELZ_CONTAINING_BASE_NODE \
"grpc.internal.no_subchannel.channelz_containing_base_node"
// Channel arg key for indicating an internal channel.
#define GRPC_ARG_CHANNELZ_IS_INTERNAL_CHANNEL \
@ -67,6 +79,8 @@ namespace channelz {
class SocketNode;
class ListenSocketNode;
class DataSource;
class ZTrace;
namespace testing {
class CallCountingHelperPeer;
@ -74,7 +88,7 @@ class SubchannelNodePeer;
} // namespace testing
// base class for all channelz entities
class BaseNode : public RefCounted<BaseNode> {
class BaseNode : public DualRefCounted<BaseNode> {
public:
// There are only four high level channelz entities. However, to support
// GetTopChannelsRequest, we split the Channel entity into two different
@ -84,14 +98,58 @@ class BaseNode : public RefCounted<BaseNode> {
kInternalChannel,
kSubchannel,
kServer,
kListenSocket,
kSocket,
kCall,
};
static absl::string_view EntityTypeString(EntityType type) {
switch (type) {
case EntityType::kTopLevelChannel:
return "top_level_channel";
case EntityType::kInternalChannel:
return "internal_channel";
case EntityType::kSubchannel:
return "subchannel";
case EntityType::kServer:
return "server";
case EntityType::kListenSocket:
return "listen_socket";
case EntityType::kSocket:
return "socket";
case EntityType::kCall:
return "call";
}
return "unknown";
}
protected:
BaseNode(EntityType type, std::string name);
public:
~BaseNode() override;
void Orphaned() override;
bool HasParent(const BaseNode* parent) const {
MutexLock lock(&parent_mu_);
return parents_.find(parent) != parents_.end();
}
void AddParent(BaseNode* parent) {
MutexLock lock(&parent_mu_);
parents_.insert(parent->WeakRef());
}
void RemoveParent(BaseNode* parent) {
MutexLock lock(&parent_mu_);
parents_.erase(parent);
}
static absl::string_view ChannelArgName() {
return GRPC_ARG_CHANNELZ_CONTAINING_BASE_NODE;
}
static int ChannelArgsCompare(const BaseNode* a, const BaseNode* b) {
return QsortCompare(a, b);
}
// All children must implement this function.
virtual Json RenderJson() = 0;
@ -101,15 +159,107 @@ class BaseNode : public RefCounted<BaseNode> {
std::string RenderJsonString();
EntityType type() const { return type_; }
intptr_t uuid() const { return uuid_; }
intptr_t uuid() {
const intptr_t id = uuid_.load(std::memory_order_relaxed);
if (id > 0) return id;
return UuidSlow();
}
const std::string& name() const { return name_; }
void RunZTrace(absl::string_view name, Timestamp deadline,
std::map<std::string, std::string> args,
std::shared_ptr<grpc_event_engine::experimental::EventEngine>
event_engine,
absl::AnyInvocable<void(Json output)> callback);
Json::Object AdditionalInfo();
protected:
void PopulateJsonFromDataSources(Json::Object& json);
private:
// to allow the ChannelzRegistry to set uuid_ under its lock.
friend class ChannelzRegistry;
// allow data source to register/unregister itself
friend class DataSource;
using ParentSet = absl::flat_hash_set<WeakRefCountedPtr<BaseNode>,
WeakRefCountedPtrHash<BaseNode>,
WeakRefCountedPtrEq<BaseNode>>;
intptr_t UuidSlow();
const EntityType type_;
intptr_t uuid_;
uint64_t orphaned_index_ = 0; // updated by registry
std::atomic<intptr_t> uuid_;
std::string name_;
Mutex data_sources_mu_;
absl::InlinedVector<DataSource*, 3> data_sources_
ABSL_GUARDED_BY(data_sources_mu_);
BaseNode* prev_; // updated by registry
BaseNode* next_; // updated by registry
mutable Mutex parent_mu_;
ParentSet parents_ ABSL_GUARDED_BY(parent_mu_);
};
class ZTrace {
public:
virtual ~ZTrace() = default;
virtual void Run(Timestamp deadline, std::map<std::string, std::string> args,
std::shared_ptr<grpc_event_engine::experimental::EventEngine>
event_engine,
absl::AnyInvocable<void(Json)>) = 0;
};
class DataSink {
public:
virtual void AddAdditionalInfo(absl::string_view name,
Json::Object additional_info) = 0;
virtual void AddChildObjects(
std::vector<RefCountedPtr<BaseNode>> children) = 0;
protected:
~DataSink() = default;
};
class DataSource {
public:
explicit DataSource(RefCountedPtr<BaseNode> node);
// Add any relevant json fragments to the output.
// This method must not cause the DataSource to be deleted, or else there will
// be a deadlock.
virtual void AddData(DataSink&) {}
// If this data source exports some ztrace, return it here.
virtual std::unique_ptr<ZTrace> GetZTrace(absl::string_view /*name*/) {
return nullptr;
}
protected:
~DataSource();
RefCountedPtr<BaseNode> channelz_node() { return node_; }
// This method must be called in the most derived class's destructor.
// It removes this data source from the node's list of data sources.
// If it is not called, then the AddData() function pointer may be invalid
// when the node is queried.
void ResetDataSource();
private:
RefCountedPtr<BaseNode> node_;
};
struct CallCounts {
int64_t calls_started = 0;
int64_t calls_succeeded = 0;
int64_t calls_failed = 0;
gpr_cycle_counter last_call_started_cycle = 0;
std::string last_call_started_timestamp() const {
return gpr_format_timespec(
gpr_cycle_counter_to_time(last_call_started_cycle));
}
void PopulateJson(Json::Object& json) const;
};
// This class is a helper class for channelz entities that deal with Channels,
@ -124,8 +274,14 @@ class CallCountingHelper final {
void RecordCallFailed();
void RecordCallSucceeded();
// Common rendering of the call count data and last_call_started_timestamp.
void PopulateCallCounts(Json::Object* json);
CallCounts GetCallCounts() const {
return {
calls_started_.load(std::memory_order_relaxed),
calls_succeeded_.load(std::memory_order_relaxed),
calls_failed_.load(std::memory_order_relaxed),
last_call_started_cycle_.load(std::memory_order_relaxed),
};
}
private:
// testing peer friend.
@ -143,8 +299,7 @@ class PerCpuCallCountingHelper final {
void RecordCallFailed();
void RecordCallSucceeded();
// Common rendering of the call count data and last_call_started_timestamp.
void PopulateCallCounts(Json::Object* json);
CallCounts GetCallCounts() const;
private:
// testing peer friend.
@ -152,31 +307,12 @@ class PerCpuCallCountingHelper final {
// We want to ensure that this per-cpu data structure lands on different
// cachelines per cpu.
// With C++17 we can do so explicitly with an `alignas` specifier.
// Prior versions we can at best approximate it by padding the structure.
// It'll probably work out ok, but it's not guaranteed across allocators.
// (in the bad case where this gets split across cachelines we'll just have
// two cpus fighting over the same cacheline with a slight performance
// degregation).
// TODO(ctiller): When we move to C++17 delete the duplicate definition.
#if __cplusplus >= 201703L
struct alignas(GPR_CACHELINE_SIZE) PerCpuData {
std::atomic<int64_t> calls_started{0};
std::atomic<int64_t> calls_succeeded{0};
std::atomic<int64_t> calls_failed{0};
std::atomic<gpr_cycle_counter> last_call_started_cycle{0};
};
#else
struct PerCpuDataHeader {
std::atomic<int64_t> calls_started{0};
std::atomic<int64_t> calls_succeeded{0};
std::atomic<int64_t> calls_failed{0};
std::atomic<gpr_cycle_counter> last_call_started_cycle{0};
};
struct PerCpuData : public PerCpuDataHeader {
uint8_t padding[GPR_CACHELINE_SIZE - sizeof(PerCpuDataHeader)];
};
#endif
PerCpu<PerCpuData> per_cpu_data_{PerCpuOptions().SetCpusPerShard(4)};
};
@ -186,6 +322,11 @@ class ChannelNode final : public BaseNode {
ChannelNode(std::string target, size_t channel_tracer_max_nodes,
bool is_internal_channel);
void Orphaned() override {
channel_args_ = ChannelArgs();
BaseNode::Orphaned();
}
static absl::string_view ChannelArgName() {
return GRPC_ARG_CHANNELZ_CHANNEL_NODE;
}
@ -209,21 +350,22 @@ class ChannelNode final : public BaseNode {
trace_.AddTraceEventWithReference(severity, data,
std::move(referenced_channel));
}
void SetChannelArgs(const ChannelArgs& channel_args) {
channel_args_ = channel_args;
}
void RecordCallStarted() { call_counter_.RecordCallStarted(); }
void RecordCallFailed() { call_counter_.RecordCallFailed(); }
void RecordCallSucceeded() { call_counter_.RecordCallSucceeded(); }
void SetConnectivityState(grpc_connectivity_state state);
// TODO(roth): take in a RefCountedPtr to the child channel so we can retrieve
// the human-readable name.
void AddChildChannel(intptr_t child_uuid);
void RemoveChildChannel(intptr_t child_uuid);
// TODO(roth): take in a RefCountedPtr to the child subchannel so we can
// retrieve the human-readable name.
void AddChildSubchannel(intptr_t child_uuid);
void RemoveChildSubchannel(intptr_t child_uuid);
const std::string& target() const { return target_; }
std::optional<std::string> connectivity_state();
CallCounts GetCallCounts() const { return call_counter_.GetCallCounts(); }
std::set<intptr_t> child_channels() const;
std::set<intptr_t> child_subchannels() const;
const ChannelTrace& trace() const { return trace_; }
const ChannelArgs& channel_args() const { return channel_args_; }
private:
void PopulateChildRefs(Json::Object* json);
@ -231,14 +373,13 @@ class ChannelNode final : public BaseNode {
std::string target_;
CallCountingHelper call_counter_;
ChannelTrace trace_;
// TODO(ctiller): keeping channel args here can create odd circular references
// that are hard to reason about. Consider moving this to a DataSource.
ChannelArgs channel_args_;
// Least significant bit indicates whether the value is set. Remaining
// bits are a grpc_connectivity_state value.
std::atomic<int> connectivity_state_{0};
Mutex child_mu_; // Guards sets below.
std::set<intptr_t> child_channels_;
std::set<intptr_t> child_subchannels_;
};
// Handles channelz bookkeeping for subchannels
@ -247,6 +388,11 @@ class SubchannelNode final : public BaseNode {
SubchannelNode(std::string target_address, size_t channel_tracer_max_nodes);
~SubchannelNode() override;
void Orphaned() override {
channel_args_ = ChannelArgs();
BaseNode::Orphaned();
}
// Sets the subchannel's connectivity state without health checking.
void UpdateConnectivityState(grpc_connectivity_state state);
@ -261,6 +407,9 @@ class SubchannelNode final : public BaseNode {
void AddTraceEvent(ChannelTrace::Severity severity, const grpc_slice& data) {
trace_.AddTraceEvent(severity, data);
}
void SetChannelArgs(const ChannelArgs& channel_args) {
channel_args_ = channel_args;
}
void AddTraceEventWithReference(ChannelTrace::Severity severity,
const grpc_slice& data,
RefCountedPtr<BaseNode> referenced_channel) {
@ -271,16 +420,29 @@ class SubchannelNode final : public BaseNode {
void RecordCallFailed() { call_counter_.RecordCallFailed(); }
void RecordCallSucceeded() { call_counter_.RecordCallSucceeded(); }
const std::string& target() const { return target_; }
std::string connectivity_state() const;
CallCounts GetCallCounts() const { return call_counter_.GetCallCounts(); }
RefCountedPtr<SocketNode> child_socket() const {
MutexLock lock(&socket_mu_);
return child_socket_;
}
const ChannelTrace& trace() const { return trace_; }
const ChannelArgs& channel_args() const { return channel_args_; }
private:
// Allows the channel trace test to access trace_.
friend class testing::SubchannelNodePeer;
std::atomic<grpc_connectivity_state> connectivity_state_{GRPC_CHANNEL_IDLE};
Mutex socket_mu_;
mutable Mutex socket_mu_;
RefCountedPtr<SocketNode> child_socket_ ABSL_GUARDED_BY(socket_mu_);
std::string target_;
CallCountingHelper call_counter_;
ChannelTrace trace_;
// TODO(ctiller): keeping channel args here can create odd circular references
// that are hard to reason about. Consider moving this to a DataSource.
ChannelArgs channel_args_;
};
// Handles channelz bookkeeping for servers
@ -290,19 +452,16 @@ class ServerNode final : public BaseNode {
~ServerNode() override;
void Orphaned() override {
channel_args_ = ChannelArgs();
BaseNode::Orphaned();
}
Json RenderJson() override;
std::string RenderServerSockets(intptr_t start_socket_id,
intptr_t max_results);
void AddChildSocket(RefCountedPtr<SocketNode> node);
void RemoveChildSocket(intptr_t child_uuid);
void AddChildListenSocket(RefCountedPtr<ListenSocketNode> node);
void RemoveChildListenSocket(intptr_t child_uuid);
// proxy methods to composed classes.
void AddTraceEvent(ChannelTrace::Severity severity, const grpc_slice& data) {
trace_.AddTraceEvent(severity, data);
@ -313,16 +472,28 @@ class ServerNode final : public BaseNode {
trace_.AddTraceEventWithReference(severity, data,
std::move(referenced_channel));
}
void SetChannelArgs(const ChannelArgs& channel_args) {
channel_args_ = channel_args;
}
void RecordCallStarted() { call_counter_.RecordCallStarted(); }
void RecordCallFailed() { call_counter_.RecordCallFailed(); }
void RecordCallSucceeded() { call_counter_.RecordCallSucceeded(); }
CallCounts GetCallCounts() const { return call_counter_.GetCallCounts(); }
std::map<intptr_t, RefCountedPtr<ListenSocketNode>> child_listen_sockets()
const;
std::map<intptr_t, RefCountedPtr<SocketNode>> child_sockets() const;
const ChannelTrace& trace() const { return trace_; }
const ChannelArgs& channel_args() const { return channel_args_; }
private:
PerCpuCallCountingHelper call_counter_;
ChannelTrace trace_;
Mutex child_mu_; // Guards child maps below.
std::map<intptr_t, RefCountedPtr<SocketNode>> child_sockets_;
std::map<intptr_t, RefCountedPtr<ListenSocketNode>> child_listen_sockets_;
// TODO(ctiller): keeping channel args here can create odd circular references
// that are hard to reason about. Consider moving this to a DataSource.
ChannelArgs channel_args_;
};
#define GRPC_ARG_CHANNELZ_SECURITY "grpc.internal.channelz_security"
@ -346,8 +517,8 @@ class SocketNode final : public BaseNode {
};
enum class ModelType { kUnset = 0, kTls = 1, kOther = 2 };
ModelType type = ModelType::kUnset;
absl::optional<Tls> tls;
absl::optional<Json> other;
std::optional<Tls> tls;
std::optional<Json> other;
Json RenderJson();
@ -387,7 +558,51 @@ class SocketNode final : public BaseNode {
const std::string& remote() { return remote_; }
int64_t streams_started() const {
return streams_started_.load(std::memory_order_relaxed);
}
int64_t streams_succeeded() const {
return streams_succeeded_.load(std::memory_order_relaxed);
}
int64_t streams_failed() const {
return streams_failed_.load(std::memory_order_relaxed);
}
int64_t messages_sent() const {
return messages_sent_.load(std::memory_order_relaxed);
}
int64_t messages_received() const {
return messages_received_.load(std::memory_order_relaxed);
}
int64_t keepalives_sent() const {
return keepalives_sent_.load(std::memory_order_relaxed);
}
auto last_local_stream_created_timestamp() const {
return CycleCounterToTimestamp(
last_local_stream_created_cycle_.load(std::memory_order_relaxed));
}
auto last_remote_stream_created_timestamp() const {
return CycleCounterToTimestamp(
last_remote_stream_created_cycle_.load(std::memory_order_relaxed));
}
auto last_message_sent_timestamp() const {
return CycleCounterToTimestamp(
last_message_sent_cycle_.load(std::memory_order_relaxed));
}
auto last_message_received_timestamp() const {
return CycleCounterToTimestamp(
last_message_received_cycle_.load(std::memory_order_relaxed));
}
const std::string& local() const { return local_; }
const std::string& remote() const { return remote_; }
RefCountedPtr<Security> security() const { return security_; }
private:
std::optional<std::string> CycleCounterToTimestamp(
gpr_cycle_counter cycle_counter) const {
return gpr_format_timespec(gpr_cycle_counter_to_time(cycle_counter));
}
std::atomic<int64_t> streams_started_{0};
std::atomic<int64_t> streams_succeeded_{0};
std::atomic<int64_t> streams_failed_{0};
@ -415,6 +630,14 @@ class ListenSocketNode final : public BaseNode {
std::string local_addr_;
};
class CallNode final : public BaseNode {
public:
explicit CallNode(std::string name)
: BaseNode(EntityType::kCall, std::move(name)) {}
Json RenderJson() override;
};
} // namespace channelz
} // namespace grpc_core

View File

@ -24,179 +24,379 @@
#include <grpc/support/string_util.h>
#include <algorithm>
#include <atomic>
#include <cstdint>
#include <cstring>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>
#include "absl/log/check.h"
#include "absl/log/log.h"
#include "src/core/channelz/channelz.h"
#include "src/core/config/config_vars.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/util/json/json.h"
#include "src/core/util/json/json_reader.h"
#include "src/core/util/json/json_writer.h"
#include "src/core/util/shared_bit_gen.h"
#include "src/core/util/sync.h"
namespace grpc_core {
namespace channelz {
namespace {
template <typename T>
std::string RenderArray(std::tuple<T, bool> values_and_end,
const std::string& key) {
auto& [values, end] = values_and_end;
Json::Object object;
if (!values.empty()) {
// Create list of channels.
Json::Array array;
for (size_t i = 0; i < values.size(); ++i) {
array.emplace_back(values[i]->RenderJson());
}
object[key] = Json::FromArray(std::move(array));
}
if (end) {
object["end"] = Json::FromBool(true);
}
return JsonDump(Json::FromObject(std::move(object)));
}
const int kPaginationLimit = 100;
Json RemoveAdditionalInfo(const Json& json) {
switch (json.type()) {
case Json::Type::kArray: {
Json::Array out;
for (const auto& node : json.array()) {
out.emplace_back(RemoveAdditionalInfo(node));
}
return Json::FromArray(std::move(out));
} break;
case Json::Type::kObject: {
Json::Object out;
for (const auto& [key, value] : json.object()) {
if (key == "additionalInfo") continue;
out[key] = RemoveAdditionalInfo(value);
}
return Json::FromObject(std::move(out));
} break;
default:
return json;
}
}
} // anonymous namespace
// TODO(ctiller): Temporary hack to remove fields that are objectionable to the
// protobuf parser (because we've not published them in protobuf yet).
char* ApplyHacks(const std::string& json_str) {
return gpr_strdup(StripAdditionalInfoFromJson(json_str).c_str());
}
} // namespace
std::string StripAdditionalInfoFromJson(absl::string_view json_str) {
auto json = JsonParse(json_str);
if (!json.ok()) return gpr_strdup(std::string(json_str).c_str());
return JsonDump(RemoveAdditionalInfo(*json));
}
ChannelzRegistry* ChannelzRegistry::Default() {
static ChannelzRegistry* singleton = new ChannelzRegistry();
return singleton;
}
void ChannelzRegistry::InternalRegister(BaseNode* node) {
MutexLock lock(&mu_);
node->uuid_ = ++uuid_generator_;
node_map_[node->uuid_] = node;
}
void ChannelzRegistry::InternalUnregister(intptr_t uuid) {
CHECK_GE(uuid, 1);
MutexLock lock(&mu_);
CHECK(uuid <= uuid_generator_);
node_map_.erase(uuid);
}
RefCountedPtr<BaseNode> ChannelzRegistry::InternalGet(intptr_t uuid) {
MutexLock lock(&mu_);
if (uuid < 1 || uuid > uuid_generator_) {
return nullptr;
}
auto it = node_map_.find(uuid);
if (it == node_map_.end()) return nullptr;
// Found node. Return only if its refcount is not zero (i.e., when we
// know that there is no other thread about to destroy it).
BaseNode* node = it->second;
return node->RefIfNonZero();
}
std::string ChannelzRegistry::InternalGetTopChannels(
intptr_t start_channel_id) {
std::vector<RefCountedPtr<BaseNode>> top_level_channels;
RefCountedPtr<BaseNode> node_after_pagination_limit;
{
MutexLock lock(&mu_);
for (auto it = node_map_.lower_bound(start_channel_id);
it != node_map_.end(); ++it) {
BaseNode* node = it->second;
RefCountedPtr<BaseNode> node_ref;
if (node->type() == BaseNode::EntityType::kTopLevelChannel &&
(node_ref = node->RefIfNonZero()) != nullptr) {
// Check if we are over pagination limit to determine if we need to set
// the "end" element. If we don't go through this block, we know that
// when the loop terminates, we have <= to kPaginationLimit.
// Note that because we have already increased this node's
// refcount, we need to decrease it, but we can't unref while
// holding the lock, because this may lead to a deadlock.
if (top_level_channels.size() == kPaginationLimit) {
node_after_pagination_limit = std::move(node_ref);
break;
}
top_level_channels.emplace_back(std::move(node_ref));
}
}
}
Json::Object object;
if (!top_level_channels.empty()) {
// Create list of channels.
Json::Array array;
for (size_t i = 0; i < top_level_channels.size(); ++i) {
array.emplace_back(top_level_channels[i]->RenderJson());
}
object["channel"] = Json::FromArray(std::move(array));
}
if (node_after_pagination_limit == nullptr) {
object["end"] = Json::FromBool(true);
}
return JsonDump(Json::FromObject(std::move(object)));
}
std::string ChannelzRegistry::InternalGetServers(intptr_t start_server_id) {
std::vector<RefCountedPtr<BaseNode>> servers;
RefCountedPtr<BaseNode> node_after_pagination_limit;
{
MutexLock lock(&mu_);
for (auto it = node_map_.lower_bound(start_server_id);
it != node_map_.end(); ++it) {
BaseNode* node = it->second;
RefCountedPtr<BaseNode> node_ref;
if (node->type() == BaseNode::EntityType::kServer &&
(node_ref = node->RefIfNonZero()) != nullptr) {
// Check if we are over pagination limit to determine if we need to set
// the "end" element. If we don't go through this block, we know that
// when the loop terminates, we have <= to kPaginationLimit.
// Note that because we have already increased this node's
// refcount, we need to decrease it, but we can't unref while
// holding the lock, because this may lead to a deadlock.
if (servers.size() == kPaginationLimit) {
node_after_pagination_limit = std::move(node_ref);
break;
}
servers.emplace_back(std::move(node_ref));
}
}
}
Json::Object object;
if (!servers.empty()) {
// Create list of servers.
Json::Array array;
for (size_t i = 0; i < servers.size(); ++i) {
array.emplace_back(servers[i]->RenderJson());
}
object["server"] = Json::FromArray(std::move(array));
}
if (node_after_pagination_limit == nullptr) {
object["end"] = Json::FromBool(true);
}
return JsonDump(Json::FromObject(std::move(object)));
std::vector<WeakRefCountedPtr<BaseNode>>
ChannelzRegistry::InternalGetAllEntities() {
return std::get<0>(QueryNodes(
0, [](const BaseNode*) { return true; },
std::numeric_limits<size_t>::max()));
}
void ChannelzRegistry::InternalLogAllEntities() {
std::vector<RefCountedPtr<BaseNode>> nodes;
{
MutexLock lock(&mu_);
for (auto& p : node_map_) {
RefCountedPtr<BaseNode> node = p.second->RefIfNonZero();
if (node != nullptr) {
nodes.emplace_back(std::move(node));
for (const auto& p : InternalGetAllEntities()) {
std::string json = p->RenderJsonString();
LOG(INFO) << json;
}
}
std::string ChannelzRegistry::GetTopChannelsJson(intptr_t start_channel_id) {
return RenderArray(GetTopChannels(start_channel_id), "channel");
}
std::string ChannelzRegistry::GetServersJson(intptr_t start_server_id) {
return RenderArray(GetServers(start_server_id), "server");
}
void ChannelzRegistry::InternalRegister(BaseNode* node) {
DCHECK_EQ(node->uuid_, -1);
const size_t node_shard_index = NodeShardIndex(node);
NodeShard& node_shard = node_shards_[node_shard_index];
MutexLock lock(&node_shard.mu);
node_shard.nursery.AddToHead(node);
}
void ChannelzRegistry::InternalUnregister(BaseNode* node) {
const size_t node_shard_index = NodeShardIndex(node);
NodeShard& node_shard = node_shards_[node_shard_index];
node_shard.mu.Lock();
CHECK_EQ(node->orphaned_index_, 0u);
intptr_t uuid = node->uuid_.load(std::memory_order_relaxed);
NodeList& remove_list = uuid == -1 ? node_shard.nursery : node_shard.numbered;
remove_list.Remove(node);
if (max_orphaned_per_shard_ == 0) {
// We are not tracking orphaned nodes... remove from the index
// if necessary, then exit out.
node_shard.mu.Unlock();
if (uuid != -1) {
MutexLock lock(&index_mu_);
index_.erase(uuid);
}
return;
}
NodeList& add_list =
uuid != -1 ? node_shard.orphaned_numbered : node_shard.orphaned;
// Ref counting: once a node becomes orphaned we add a single weak ref to it.
// We hold that ref until it gets garbage collected later.
node->WeakRef().release();
node->orphaned_index_ = node_shard.next_orphan_index;
CHECK_GT(node->orphaned_index_, 0u);
++node_shard.next_orphan_index;
add_list.AddToHead(node);
if (node_shard.TotalOrphaned() <= max_orphaned_per_shard_) {
// Below recycling thresholds: just exit out
node_shard.mu.Unlock();
return;
}
CHECK_EQ(node_shard.TotalOrphaned(), max_orphaned_per_shard_ + 1);
NodeList* gc_list;
// choose the oldest node to evict, regardless of numbered or not
if (node_shard.orphaned.tail == nullptr) {
CHECK_NE(node_shard.orphaned_numbered.tail, nullptr);
gc_list = &node_shard.orphaned_numbered;
} else if (node_shard.orphaned_numbered.tail == nullptr) {
gc_list = &node_shard.orphaned;
} else if (node_shard.orphaned.tail->orphaned_index_ <
node_shard.orphaned_numbered.tail->orphaned_index_) {
gc_list = &node_shard.orphaned;
} else {
gc_list = &node_shard.orphaned_numbered;
}
auto* n = gc_list->tail;
CHECK_GT(n->orphaned_index_, 0u);
gc_list->Remove(n);
// Note: we capture the reference to n previously added here, and release
// it when this smart pointer is destroyed, outside of any locks.
WeakRefCountedPtr<BaseNode> gcd_node(n);
node_shard.mu.Unlock();
if (gc_list == &node_shard.orphaned_numbered) {
MutexLock lock(&index_mu_);
intptr_t uuid = n->uuid_.load(std::memory_order_relaxed);
index_.erase(uuid);
}
}
void ChannelzRegistry::LoadConfig() {
const auto max_orphaned = ConfigVars::Get().ChannelzMaxOrphanedNodes();
if (max_orphaned == 0) {
max_orphaned_per_shard_ = 0;
} else {
max_orphaned_per_shard_ = std::max<int>(max_orphaned / kNodeShards, 1);
}
}
std::tuple<std::vector<WeakRefCountedPtr<BaseNode>>, bool>
ChannelzRegistry::QueryNodes(
intptr_t start_node, absl::FunctionRef<bool(const BaseNode*)> discriminator,
size_t max_results) {
// Mitigate drain hotspotting by randomizing the drain order each query.
std::vector<size_t> nursery_visitation_order;
for (size_t i = 0; i < kNodeShards; ++i) {
nursery_visitation_order.push_back(i);
}
absl::c_shuffle(nursery_visitation_order, SharedBitGen());
// In the iteration below, even once we have max_results nodes, we need
// to find the next node in order to know if we've hit the end. If we get
// through the loop without returning, then we return end=true. But if we
// find a node to add after we already have max_results nodes, then we
// return with end=false before exiting the loop. However, in the latter
// case, we will have already increased the ref count of the next node,
// so we need to unref it, but we can't do that while holding the lock.
// So instead, we store it in node_after_end, which will be unreffed
// after releasing the lock.
WeakRefCountedPtr<BaseNode> node_after_end;
std::vector<WeakRefCountedPtr<BaseNode>> result;
MutexLock index_lock(&index_mu_);
for (auto it = index_.lower_bound(start_node); it != index_.end(); ++it) {
BaseNode* node = it->second;
if (!discriminator(node)) continue;
auto node_ref = node->WeakRefIfNonZero();
if (node_ref == nullptr) continue;
if (result.size() == max_results) {
node_after_end = std::move(node_ref);
return std::tuple(std::move(result), false);
}
result.emplace_back(std::move(node_ref));
}
for (auto nursery_index : nursery_visitation_order) {
NodeShard& node_shard = node_shards_[nursery_index];
MutexLock shard_lock(&node_shard.mu);
for (auto [nursery, numbered] :
{std::pair(&node_shard.nursery, &node_shard.numbered),
std::pair(&node_shard.orphaned, &node_shard.orphaned_numbered)}) {
if (nursery->head == nullptr) continue;
BaseNode* n = nursery->head;
while (n != nullptr) {
if (!discriminator(n)) {
n = n->next_;
continue;
}
auto node_ref = n->WeakRefIfNonZero();
if (node_ref == nullptr) {
n = n->next_;
continue;
}
BaseNode* next = n->next_;
nursery->Remove(n);
numbered->AddToHead(n);
n->uuid_ = uuid_generator_;
++uuid_generator_;
index_.emplace(n->uuid_, n);
if (n->uuid_ >= start_node) {
if (result.size() == max_results) {
node_after_end = std::move(node_ref);
return std::tuple(std::move(result), false);
}
result.emplace_back(std::move(node_ref));
}
n = next;
}
}
}
for (size_t i = 0; i < nodes.size(); ++i) {
std::string json = nodes[i]->RenderJsonString();
LOG(INFO) << json;
CHECK(node_after_end == nullptr);
return std::tuple(std::move(result), true);
}
WeakRefCountedPtr<BaseNode> ChannelzRegistry::InternalGet(intptr_t uuid) {
MutexLock index_lock(&index_mu_);
auto it = index_.find(uuid);
if (it == index_.end()) return nullptr;
BaseNode* node = it->second;
return node->WeakRefIfNonZero();
}
intptr_t ChannelzRegistry::InternalNumberNode(BaseNode* node) {
// node must be strongly owned still
node->AssertStronglyOwned();
const size_t node_shard_index = NodeShardIndex(node);
NodeShard& node_shard = node_shards_[node_shard_index];
MutexLock index_lock(&index_mu_);
MutexLock lock(&node_shard.mu);
intptr_t uuid = node->uuid_.load(std::memory_order_relaxed);
if (uuid != -1) return uuid;
uuid = uuid_generator_;
++uuid_generator_;
node->uuid_ = uuid;
if (node->orphaned_index_ > 0) {
node_shard.orphaned.Remove(node);
node_shard.orphaned_numbered.AddToHead(node);
} else {
node_shard.nursery.Remove(node);
node_shard.numbered.AddToHead(node);
}
index_.emplace(uuid, node);
return uuid;
}
bool ChannelzRegistry::NodeList::Holds(BaseNode* node) const {
BaseNode* n = head;
while (n != nullptr) {
if (n == node) return true;
n = n->next_;
}
return false;
}
void ChannelzRegistry::NodeList::AddToHead(BaseNode* node) {
DCHECK(!Holds(node));
++count;
if (head != nullptr) head->prev_ = node;
node->next_ = head;
node->prev_ = nullptr;
head = node;
if (tail == nullptr) tail = node;
DCHECK(Holds(node));
}
void ChannelzRegistry::NodeList::Remove(BaseNode* node) {
DCHECK(Holds(node));
DCHECK_GT(count, 0u);
--count;
if (node->prev_ == nullptr) {
head = node->next_;
if (head == nullptr) {
DCHECK_EQ(count, 0u);
tail = nullptr;
DCHECK(!Holds(node));
return;
}
} else {
node->prev_->next_ = node->next_;
}
if (node->next_ == nullptr) {
tail = node->prev_;
} else {
node->next_->prev_ = node->prev_;
}
DCHECK(!Holds(node));
}
void ChannelzRegistry::TestOnlyReset() {
auto* p = Default();
p->uuid_generator_ = 1;
p->LoadConfig();
std::vector<WeakRefCountedPtr<BaseNode>> free_nodes;
for (size_t i = 0; i < kNodeShards; i++) {
MutexLock lock(&p->node_shards_[i].mu);
CHECK(p->node_shards_[i].nursery.head == nullptr);
CHECK(p->node_shards_[i].numbered.head == nullptr);
while (p->node_shards_[i].orphaned.head != nullptr) {
free_nodes.emplace_back(p->node_shards_[i].orphaned.head);
p->node_shards_[i].orphaned.Remove(p->node_shards_[i].orphaned.head);
}
while (p->node_shards_[i].orphaned_numbered.head != nullptr) {
free_nodes.emplace_back(p->node_shards_[i].orphaned_numbered.head);
p->node_shards_[i].orphaned_numbered.Remove(
p->node_shards_[i].orphaned_numbered.head);
}
}
std::vector<NodeShard> replace_node_shards(kNodeShards);
replace_node_shards.swap(p->node_shards_);
MutexLock lock(&p->index_mu_);
p->index_.clear();
}
} // namespace channelz
} // namespace grpc_core
char* grpc_channelz_get_top_channels(intptr_t start_channel_id) {
grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
grpc_core::ExecCtx exec_ctx;
return gpr_strdup(
grpc_core::channelz::ChannelzRegistry::GetTopChannels(start_channel_id)
return grpc_core::channelz::ApplyHacks(
grpc_core::channelz::ChannelzRegistry::GetTopChannelsJson(
start_channel_id)
.c_str());
}
char* grpc_channelz_get_servers(intptr_t start_server_id) {
grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
grpc_core::ExecCtx exec_ctx;
return gpr_strdup(
grpc_core::channelz::ChannelzRegistry::GetServers(start_server_id)
return grpc_core::channelz::ApplyHacks(
grpc_core::channelz::ChannelzRegistry::GetServersJson(start_server_id)
.c_str());
}
char* grpc_channelz_get_server(intptr_t server_id) {
grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
grpc_core::ExecCtx exec_ctx;
grpc_core::RefCountedPtr<grpc_core::channelz::BaseNode> server_node =
grpc_core::WeakRefCountedPtr<grpc_core::channelz::BaseNode> server_node =
grpc_core::channelz::ChannelzRegistry::Get(server_id);
if (server_node == nullptr ||
server_node->type() !=
@ -206,16 +406,15 @@ char* grpc_channelz_get_server(intptr_t server_id) {
grpc_core::Json json = grpc_core::Json::FromObject({
{"server", server_node->RenderJson()},
});
return gpr_strdup(grpc_core::JsonDump(json).c_str());
return grpc_core::channelz::ApplyHacks(grpc_core::JsonDump(json).c_str());
}
char* grpc_channelz_get_server_sockets(intptr_t server_id,
intptr_t start_socket_id,
intptr_t max_results) {
grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
grpc_core::ExecCtx exec_ctx;
// Validate inputs before handing them of to the renderer.
grpc_core::RefCountedPtr<grpc_core::channelz::BaseNode> base_node =
grpc_core::WeakRefCountedPtr<grpc_core::channelz::BaseNode> base_node =
grpc_core::channelz::ChannelzRegistry::Get(server_id);
if (base_node == nullptr ||
base_node->type() != grpc_core::channelz::BaseNode::EntityType::kServer ||
@ -226,14 +425,13 @@ char* grpc_channelz_get_server_sockets(intptr_t server_id,
// actually a server node.
grpc_core::channelz::ServerNode* server_node =
static_cast<grpc_core::channelz::ServerNode*>(base_node.get());
return gpr_strdup(
return grpc_core::channelz::ApplyHacks(
server_node->RenderServerSockets(start_socket_id, max_results).c_str());
}
char* grpc_channelz_get_channel(intptr_t channel_id) {
grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
grpc_core::ExecCtx exec_ctx;
grpc_core::RefCountedPtr<grpc_core::channelz::BaseNode> channel_node =
grpc_core::WeakRefCountedPtr<grpc_core::channelz::BaseNode> channel_node =
grpc_core::channelz::ChannelzRegistry::Get(channel_id);
if (channel_node == nullptr ||
(channel_node->type() !=
@ -245,13 +443,12 @@ char* grpc_channelz_get_channel(intptr_t channel_id) {
grpc_core::Json json = grpc_core::Json::FromObject({
{"channel", channel_node->RenderJson()},
});
return gpr_strdup(grpc_core::JsonDump(json).c_str());
return grpc_core::channelz::ApplyHacks(grpc_core::JsonDump(json).c_str());
}
char* grpc_channelz_get_subchannel(intptr_t subchannel_id) {
grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
grpc_core::ExecCtx exec_ctx;
grpc_core::RefCountedPtr<grpc_core::channelz::BaseNode> subchannel_node =
grpc_core::WeakRefCountedPtr<grpc_core::channelz::BaseNode> subchannel_node =
grpc_core::channelz::ChannelzRegistry::Get(subchannel_id);
if (subchannel_node == nullptr ||
subchannel_node->type() !=
@ -261,21 +458,22 @@ char* grpc_channelz_get_subchannel(intptr_t subchannel_id) {
grpc_core::Json json = grpc_core::Json::FromObject({
{"subchannel", subchannel_node->RenderJson()},
});
return gpr_strdup(grpc_core::JsonDump(json).c_str());
return grpc_core::channelz::ApplyHacks(grpc_core::JsonDump(json).c_str());
}
char* grpc_channelz_get_socket(intptr_t socket_id) {
grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
grpc_core::ExecCtx exec_ctx;
grpc_core::RefCountedPtr<grpc_core::channelz::BaseNode> socket_node =
grpc_core::WeakRefCountedPtr<grpc_core::channelz::BaseNode> socket_node =
grpc_core::channelz::ChannelzRegistry::Get(socket_id);
if (socket_node == nullptr ||
socket_node->type() !=
grpc_core::channelz::BaseNode::EntityType::kSocket) {
(socket_node->type() !=
grpc_core::channelz::BaseNode::EntityType::kSocket &&
socket_node->type() !=
grpc_core::channelz::BaseNode::EntityType::kListenSocket)) {
return nullptr;
}
grpc_core::Json json = grpc_core::Json::FromObject({
{"socket", socket_node->RenderJson()},
});
return gpr_strdup(grpc_core::JsonDump(json).c_str());
return grpc_core::channelz::ApplyHacks(grpc_core::JsonDump(json).c_str());
}

View File

@ -25,8 +25,10 @@
#include <map>
#include <string>
#include "absl/base/thread_annotations.h"
#include "absl/container/btree_map.h"
#include "absl/functional/function_ref.h"
#include "src/core/channelz/channelz.h"
#include "src/core/util/json/json_writer.h"
#include "src/core/util/ref_counted_ptr.h"
#include "src/core/util/sync.h"
@ -40,36 +42,134 @@ class ChannelzRegistry final {
static void Register(BaseNode* node) {
return Default()->InternalRegister(node);
}
static void Unregister(intptr_t uuid) { Default()->InternalUnregister(uuid); }
static RefCountedPtr<BaseNode> Get(intptr_t uuid) {
static void Unregister(BaseNode* node) {
Default()->InternalUnregister(node);
}
static WeakRefCountedPtr<BaseNode> Get(intptr_t uuid) {
return Default()->InternalGet(uuid);
}
static intptr_t NumberNode(BaseNode* node) {
return Default()->InternalNumberNode(node);
}
static WeakRefCountedPtr<SubchannelNode> GetSubchannel(intptr_t uuid) {
return Default()
->InternalGetTyped<SubchannelNode, BaseNode::EntityType::kSubchannel>(
uuid);
}
static WeakRefCountedPtr<ChannelNode> GetChannel(intptr_t uuid) {
auto node = Default()->InternalGet(uuid);
if (node == nullptr) return nullptr;
if (node->type() == BaseNode::EntityType::kTopLevelChannel) {
return node->WeakRefAsSubclass<ChannelNode>();
}
if (node->type() == BaseNode::EntityType::kInternalChannel) {
return node->WeakRefAsSubclass<ChannelNode>();
}
return nullptr;
}
static WeakRefCountedPtr<ServerNode> GetServer(intptr_t uuid) {
return Default()
->InternalGetTyped<ServerNode, BaseNode::EntityType::kServer>(uuid);
}
static WeakRefCountedPtr<SocketNode> GetSocket(intptr_t uuid) {
return Default()
->InternalGetTyped<SocketNode, BaseNode::EntityType::kSocket>(uuid);
}
// Returns the allocated JSON string that represents the proto
// GetTopChannelsResponse as per channelz.proto.
static std::string GetTopChannels(intptr_t start_channel_id) {
return Default()->InternalGetTopChannels(start_channel_id);
static auto GetTopChannels(intptr_t start_channel_id) {
return Default()
->InternalGetObjects<ChannelNode,
BaseNode::EntityType::kTopLevelChannel>(
start_channel_id);
}
static std::string GetTopChannelsJson(intptr_t start_channel_id);
static std::string GetServersJson(intptr_t start_server_id);
// Returns the allocated JSON string that represents the proto
// GetServersResponse as per channelz.proto.
static std::string GetServers(intptr_t start_server_id) {
return Default()->InternalGetServers(start_server_id);
static auto GetServers(intptr_t start_server_id) {
return Default()
->InternalGetObjects<ServerNode, BaseNode::EntityType::kServer>(
start_server_id);
}
static std::tuple<std::vector<WeakRefCountedPtr<BaseNode>>, bool>
GetChildrenOfType(intptr_t start_node, const BaseNode* parent,
BaseNode::EntityType type, size_t max_results) {
return Default()->InternalGetChildrenOfType(start_node, parent, type,
max_results);
}
// Test only helper function to dump the JSON representation to std out.
// This can aid in debugging channelz code.
static void LogAllEntities() { Default()->InternalLogAllEntities(); }
// Test only helper function to reset to initial state.
static void TestOnlyReset() {
auto* p = Default();
MutexLock lock(&p->mu_);
p->node_map_.clear();
p->uuid_generator_ = 0;
static std::vector<WeakRefCountedPtr<BaseNode>> GetAllEntities() {
return Default()->InternalGetAllEntities();
}
// Test only helper function to reset to initial state.
static void TestOnlyReset();
private:
ChannelzRegistry() { LoadConfig(); }
void LoadConfig();
// Takes a callable F: (WeakRefCountedPtr<BaseNode>) -> bool, and returns
// a (BaseNode*) -> bool that filters unreffed objects and returns true.
// The ref must be unreffed outside the NodeMapInterface iteration.
template <typename F>
static auto CollectReferences(F fn) {
return [fn = std::move(fn)](BaseNode* n) {
auto node = n->RefIfNonZero();
if (node == nullptr) return true;
return fn(std::move(node));
};
}
struct NodeList {
BaseNode* head = nullptr;
BaseNode* tail = nullptr;
size_t count = 0;
bool Holds(BaseNode* node) const;
void AddToHead(BaseNode* node);
void Remove(BaseNode* node);
};
// Nodes traverse through up to four lists, depending on
// whether they have a uuid (this is becoming numbered),
// and whether they have been orphaned or not.
// The lists help us find un-numbered nodes when needed for
// queries, and the oldest orphaned node when needed for
// garbage collection.
// Nodes are organized into shards based on their pointer
// address. A shard tracks the four lists of nodes
// independently - we strive to have no cross-talk between
// shards as these are very global objects.
struct alignas(GPR_CACHELINE_SIZE) NodeShard {
Mutex mu;
// Nursery nodes have no uuid and are not orphaned.
NodeList nursery ABSL_GUARDED_BY(mu);
// Numbered nodes have been assigned a uuid, and are not orphaned.
NodeList numbered ABSL_GUARDED_BY(mu);
// Orphaned nodes have no uuid, but have been orphaned.
NodeList orphaned ABSL_GUARDED_BY(mu);
// Finally, orphaned numbered nodes are orphaned, and have been assigned a
// uuid.
NodeList orphaned_numbered ABSL_GUARDED_BY(mu);
uint64_t next_orphan_index ABSL_GUARDED_BY(mu) = 1;
size_t TotalOrphaned() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu) {
return orphaned.count + orphaned_numbered.count;
}
};
// Returned the singleton instance of ChannelzRegistry;
static ChannelzRegistry* Default();
@ -78,23 +178,81 @@ class ChannelzRegistry final {
// globally unregisters the object that is associated to uuid. Also does
// sanity check that an object doesn't try to unregister the wrong type.
void InternalUnregister(intptr_t uuid);
void InternalUnregister(BaseNode* node);
intptr_t InternalNumberNode(BaseNode* node);
// if object with uuid has previously been registered as the correct type,
// returns the void* associated with that uuid. Else returns nullptr.
RefCountedPtr<BaseNode> InternalGet(intptr_t uuid);
WeakRefCountedPtr<BaseNode> InternalGet(intptr_t uuid);
std::string InternalGetTopChannels(intptr_t start_channel_id);
std::string InternalGetServers(intptr_t start_server_id);
// Generic query over nodes.
// This function takes care of all the gnarly locking, and allows high level
// code to request a start node and maximum number of results (for pagination
// purposes).
// `discriminator` allows callers to choose which nodes will be returned - if
// it returns true, the node is included in the result.
// `discriminator` *MUST NOT* ref the node, nor call into ChannelzRegistry via
// any code path (locks are held during the call).
std::tuple<std::vector<WeakRefCountedPtr<BaseNode>>, bool> QueryNodes(
intptr_t start_node,
absl::FunctionRef<bool(const BaseNode*)> discriminator,
size_t max_results);
std::tuple<std::vector<WeakRefCountedPtr<BaseNode>>, bool>
InternalGetChildrenOfType(intptr_t start_node, const BaseNode* parent,
BaseNode::EntityType type, size_t max_results) {
return QueryNodes(
start_node,
[type, parent](const BaseNode* n) {
return n->type() == type && n->HasParent(parent);
},
max_results);
}
template <typename T, BaseNode::EntityType entity_type>
WeakRefCountedPtr<T> InternalGetTyped(intptr_t uuid) {
WeakRefCountedPtr<BaseNode> node = InternalGet(uuid);
if (node == nullptr || node->type() != entity_type) {
return nullptr;
}
return node->WeakRefAsSubclass<T>();
}
template <typename T, BaseNode::EntityType entity_type>
std::tuple<std::vector<WeakRefCountedPtr<T>>, bool> InternalGetObjects(
intptr_t start_id) {
const int kPaginationLimit = 100;
std::vector<WeakRefCountedPtr<T>> top_level_channels;
const auto [nodes, end] = QueryNodes(
start_id,
[](const BaseNode* node) { return node->type() == entity_type; },
kPaginationLimit);
for (const auto& p : nodes) {
top_level_channels.emplace_back(p->template WeakRefAsSubclass<T>());
}
return std::tuple(std::move(top_level_channels), end);
}
void InternalLogAllEntities();
std::vector<WeakRefCountedPtr<BaseNode>> InternalGetAllEntities();
// protects members
Mutex mu_;
std::map<intptr_t, BaseNode*> node_map_ ABSL_GUARDED_BY(mu_);
intptr_t uuid_generator_ ABSL_GUARDED_BY(mu_) = 0;
static constexpr size_t kNodeShards = 63;
size_t NodeShardIndex(BaseNode* node) {
return absl::HashOf(node) % kNodeShards;
}
int64_t uuid_generator_{1};
std::vector<NodeShard> node_shards_{kNodeShards};
Mutex index_mu_;
absl::btree_map<intptr_t, BaseNode*> index_ ABSL_GUARDED_BY(index_mu_);
size_t max_orphaned_per_shard_;
};
// `additionalInfo` section is not yet in the protobuf format, so we
// provide a utility to strip it for compatibility.
std::string StripAdditionalInfoFromJson(absl::string_view json);
} // namespace channelz
} // namespace grpc_core

View File

@ -0,0 +1,315 @@
// Copyright 2025 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef GRPC_SRC_CORE_CHANNELZ_ZTRACE_COLLECTOR_H
#define GRPC_SRC_CORE_CHANNELZ_ZTRACE_COLLECTOR_H
#include <grpc/support/time.h>
#include <memory>
#include <tuple>
#include <vector>
#include "absl/container/flat_hash_set.h"
#include "src/core/channelz/channelz.h"
#include "src/core/lib/debug/trace.h"
#include "src/core/util/json/json_writer.h"
#include "src/core/util/single_set_ptr.h"
#include "src/core/util/string.h"
#include "src/core/util/sync.h"
#include "src/core/util/time.h"
#ifdef GRPC_NO_ZTRACE
namespace grpc_core::channelz {
namespace ztrace_collector_detail {
class ZTraceImpl final : public ZTrace {
public:
explicit ZTraceImpl() {}
void Run(Timestamp deadline, std::map<std::string, std::string> args,
std::shared_ptr<grpc_event_engine::experimental::EventEngine>
event_engine,
absl::AnyInvocable<void(Json)> callback) override {
event_engine->Run([callback = std::move(callback)]() mutable {
callback(Json::FromBool(false));
});
}
};
class StubImpl {
public:
template <typename T>
void Append(const T&) {}
std::unique_ptr<ZTrace> MakeZTrace() {
return std::make_unique<ZTraceImpl>();
}
};
} // namespace ztrace_collector_detail
template <typename...>
class ZTraceCollector : public ztrace_collector_detail::StubImpl {};
} // namespace grpc_core::channelz
#else
namespace grpc_core::channelz {
namespace ztrace_collector_detail {
template <typename T>
using Collection = std::deque<std::pair<gpr_cycle_counter, T> >;
template <typename T>
void AppendResults(const Collection<T>& data, Json::Array& results) {
for (const auto& value : data) {
Json::Object object;
object["timestamp"] =
Json::FromString(gpr_format_timespec(gpr_convert_clock_type(
gpr_cycle_counter_to_time(value.first), GPR_CLOCK_REALTIME)));
value.second.RenderJson(object);
results.emplace_back(Json::FromObject(std::move(object)));
}
}
template <typename Needle, typename... Haystack>
constexpr bool kIsElement = false;
template <typename Needle, typename... Haystack>
constexpr bool kIsElement<Needle, Needle, Haystack...> = true;
template <typename Needle, typename H, typename... Haystack>
constexpr bool kIsElement<Needle, H, Haystack...> =
kIsElement<Needle, Haystack...>;
} // namespace ztrace_collector_detail
inline std::optional<int64_t> IntFromArgs(
const std::map<std::string, std::string>& args, const std::string& name) {
auto it = args.find(name);
if (it == args.end()) return std::nullopt;
int64_t out;
if (!absl::SimpleAtoi(it->second, &out)) return std::nullopt;
return out;
}
// Generic collector infrastructure for ztrace queries.
// Abstracts away most of the ztrace requirements in an efficient manner,
// allowing system authors to concentrate on emitting useful data.
// If no trace is performed, overhead is one pointer and one relaxed atomic read
// per trace event.
//
// Two kinds of objects are required:
// 1. A `Config`
// - This type should be constructible with a std::map<std::string,
// std::string>
// and provides overall query configuration - the map can be used to pull
// predicates from the calling system.
// - Needs a `bool Finishes(T)` method for each Data type (see 2).
// This allows the config to terminate a query in the event of reaching
// some configured predicate.
// 2. N `Data` types
// - One for each kind of data captured in the trace
// - Allows avoiding e.g. variant<> data types; these are inefficient
// in this context because they force every recorded entry to use the
// same number of bytes whilst pending.
template <typename Config, typename... Data>
class ZTraceCollector {
public:
template <typename X>
void Append(X producer_or_value) {
GRPC_TRACE_LOG(ztrace, INFO) << "ZTRACE[" << this << "]: " << [&]() {
Json::Object obj;
if constexpr (ztrace_collector_detail::kIsElement<X, Data...>) {
producer_or_value.RenderJson(obj);
} else {
producer_or_value().RenderJson(obj);
}
return JsonDump(Json::FromObject(std::move(obj)));
}();
if (!impl_.is_set()) return;
if constexpr (ztrace_collector_detail::kIsElement<X, Data...>) {
AppendValue(std::move(producer_or_value));
} else {
AppendValue(producer_or_value());
}
}
std::unique_ptr<ZTrace> MakeZTrace() {
return std::make_unique<ZTraceImpl>(impl_.GetOrCreate());
}
private:
template <typename T>
using Collection = ztrace_collector_detail::Collection<T>;
struct Instance : public RefCounted<Instance> {
Instance(std::map<std::string, std::string> args,
std::shared_ptr<grpc_event_engine::experimental::EventEngine>
event_engine,
absl::AnyInvocable<void(Json)> done)
: memory_cap_(IntFromArgs(args, "memory_cap").value_or(1024 * 1024)),
config(args),
event_engine(std::move(event_engine)),
done(std::move(done)) {}
using Collections = std::tuple<Collection<Data>...>;
struct RemoveMostRecentState {
void (*enact)(Instance*) = nullptr;
gpr_cycle_counter most_recent =
std::numeric_limits<gpr_cycle_counter>::max();
};
template <typename T>
void Append(std::pair<gpr_cycle_counter, T> value) {
memory_used_ += value.second.MemoryUsage();
while (memory_used_ > memory_cap_) RemoveMostRecent();
std::get<Collection<T> >(data).push_back(std::move(value));
}
void RemoveMostRecent() {
RemoveMostRecentState state;
(UpdateRemoveMostRecentState<Data>(&state), ...);
CHECK(state.enact != nullptr);
state.enact(this);
++items_removed_;
}
template <typename T>
void UpdateRemoveMostRecentState(RemoveMostRecentState* state) {
auto& collection = std::get<Collection<T> >(data);
if (collection.empty()) return;
if (state->enact == nullptr ||
collection.front().first < state->most_recent) {
state->enact = +[](Instance* instance) {
auto& collection = std::get<Collection<T> >(instance->data);
const size_t ent_usage = collection.front().second.MemoryUsage();
CHECK_GE(instance->memory_used_, ent_usage);
instance->memory_used_ -= ent_usage;
collection.pop_front();
};
state->most_recent = collection.front().first;
}
}
void Finish(absl::Status status) {
event_engine->Run([data = std::move(data), done = std::move(done),
status = std::move(status), memory_used = memory_used_,
items_removed = items_removed_]() mutable {
Json::Array entries;
(ztrace_collector_detail::AppendResults(
std::get<Collection<Data> >(data), entries),
...);
Json::Object result;
result["entries"] = Json::FromArray(entries);
result["status"] = Json::FromString(status.ToString());
result["memory_used"] =
Json::FromNumber(static_cast<uint64_t>(memory_used));
result["items_removed"] = Json::FromNumber(items_removed);
done(Json::FromObject(std::move(result)));
});
}
size_t memory_used_ = 0;
size_t memory_cap_ = 0;
uint64_t items_removed_ = 0;
Config config;
const Timestamp start_time = Timestamp::Now();
std::shared_ptr<grpc_event_engine::experimental::EventEngine> event_engine;
grpc_event_engine::experimental::EventEngine::TaskHandle task_handle{
grpc_event_engine::experimental::EventEngine::TaskHandle::kInvalid};
Collections data;
absl::AnyInvocable<void(Json)> done;
};
struct Impl : public RefCounted<Impl> {
Mutex mu;
absl::flat_hash_set<RefCountedPtr<Instance> > instances ABSL_GUARDED_BY(mu);
};
class ZTraceImpl final : public ZTrace {
public:
explicit ZTraceImpl(RefCountedPtr<Impl> impl) : impl_(std::move(impl)) {}
void Run(Timestamp deadline, std::map<std::string, std::string> args,
std::shared_ptr<grpc_event_engine::experimental::EventEngine>
event_engine,
absl::AnyInvocable<void(Json)> callback) override {
auto instance = MakeRefCounted<Instance>(std::move(args), event_engine,
std::move(callback));
auto impl = std::move(impl_);
RefCountedPtr<Instance> oldest_instance;
MutexLock lock(&impl->mu);
if (impl->instances.size() > 20) {
// Eject oldest running trace
Timestamp oldest_time = Timestamp::InfFuture();
for (auto& instance : impl->instances) {
if (instance->start_time < oldest_time) {
oldest_time = instance->start_time;
oldest_instance = instance;
}
}
CHECK(oldest_instance != nullptr);
impl->instances.erase(oldest_instance);
oldest_instance->Finish(
absl::ResourceExhaustedError("Too many concurrent ztrace queries"));
}
instance->task_handle = event_engine->RunAfter(
deadline - Timestamp::Now(), [instance, impl]() {
bool finish;
{
MutexLock lock(&impl->mu);
finish = impl->instances.erase(instance);
}
if (finish) instance->Finish(absl::DeadlineExceededError(""));
});
impl->instances.insert(instance);
}
private:
RefCountedPtr<Impl> impl_;
};
template <typename T>
void AppendValue(T&& data) {
auto value = std::pair(gpr_get_cycle_counter(), std::forward<T>(data));
auto* impl = impl_.Get();
{
MutexLock lock(&impl->mu);
switch (impl->instances.size()) {
case 0:
return;
case 1: {
auto& instances = impl->instances;
auto& instance = *instances.begin();
const bool finishes = instance->config.Finishes(value.second);
instance->Append(std::move(value));
if (finishes) {
instance->Finish(absl::OkStatus());
instances.clear();
}
} break;
default: {
std::vector<RefCountedPtr<Instance> > finished;
for (auto& instance : impl->instances) {
const bool finishes = instance->config.Finishes(value.second);
instance->Append(value);
if (finishes) {
finished.push_back(instance);
}
}
for (const auto& instance : finished) {
instance->Finish(absl::OkStatus());
impl->instances.erase(instance);
}
}
}
}
}
SingleSetRefCountedPtr<Impl> impl_;
};
} // namespace grpc_core::channelz
#endif // GRPC_NO_ZTRACE
#endif // GRPC_SRC_CORE_CHANNELZ_ZTRACE_COLLECTOR_H

View File

@ -62,10 +62,15 @@ static grpc_core::Duration g_poll_interval =
static bool g_backup_polling_disabled;
void grpc_client_channel_global_init_backup_polling() {
#ifndef GRPC_DO_NOT_INSTANTIATE_POSIX_POLLER
// Disable backup polling if EventEngine is used everywhere.
g_backup_polling_disabled = grpc_core::IsEventEngineClientEnabled() &&
grpc_core::IsEventEngineListenerEnabled() &&
grpc_core::IsEventEngineDnsEnabled();
#else
// EventEngine polling not supported, keep using the backup poller.
g_backup_polling_disabled = false;
#endif
if (g_backup_polling_disabled) {
return;
}
@ -155,11 +160,21 @@ static void g_poller_init_locked() {
}
}
static bool g_can_poll_in_background() {
#ifndef GRPC_DO_NOT_INSTANTIATE_POSIX_POLLER
return grpc_iomgr_run_in_background();
#else
// No iomgr "event_engines" (not to be confused with the new EventEngine)
// are able to run in backgroung.
return false;
#endif
}
void grpc_client_channel_start_backup_polling(
grpc_pollset_set* interested_parties) {
if (g_backup_polling_disabled ||
g_poll_interval == grpc_core::Duration::Zero() ||
grpc_iomgr_run_in_background()) {
g_can_poll_in_background()) {
return;
}
gpr_mu_lock(&g_poller_mu);
@ -179,7 +194,7 @@ void grpc_client_channel_stop_backup_polling(
grpc_pollset_set* interested_parties) {
if (g_backup_polling_disabled ||
g_poll_interval == grpc_core::Duration::Zero() ||
grpc_iomgr_run_in_background()) {
g_can_poll_in_background()) {
return;
}
grpc_pollset_set_del_pollset(interested_parties, g_poller->pollset);

View File

@ -29,9 +29,11 @@
#include <algorithm>
#include <functional>
#include <new>
#include <optional>
#include <set>
#include <type_traits>
#include <utility>
#include <variant>
#include <vector>
#include "absl/cleanup/cleanup.h"
@ -43,8 +45,10 @@
#include "absl/strings/str_cat.h"
#include "absl/strings/str_join.h"
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "absl/types/variant.h"
#include "src/core/call/call_spine.h"
#include "src/core/call/client_call.h"
#include "src/core/call/metadata_batch.h"
#include "src/core/call/status_util.h"
#include "src/core/client_channel/client_channel_internal.h"
#include "src/core/client_channel/client_channel_service_config.h"
#include "src/core/client_channel/config_selector.h"
@ -55,10 +59,10 @@
#include "src/core/client_channel/subchannel.h"
#include "src/core/client_channel/subchannel_interface_internal.h"
#include "src/core/config/core_configuration.h"
#include "src/core/credentials/transport/transport_credentials.h"
#include "src/core/ext/filters/channel_idle/legacy_channel_idle_filter.h"
#include "src/core/lib/address_utils/sockaddr_utils.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/status_util.h"
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/event_engine/channel_args_endpoint_config.h"
#include "src/core/lib/iomgr/resolved_address.h"
@ -70,16 +74,12 @@
#include "src/core/lib/promise/sleep.h"
#include "src/core/lib/promise/try_seq.h"
#include "src/core/lib/resource_quota/arena.h"
#include "src/core/lib/security/credentials/credentials.h"
#include "src/core/lib/slice/slice.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/surface/call.h"
#include "src/core/lib/surface/channel.h"
#include "src/core/lib/surface/client_call.h"
#include "src/core/lib/surface/completion_queue.h"
#include "src/core/lib/transport/call_spine.h"
#include "src/core/lib/transport/connectivity_state.h"
#include "src/core/lib/transport/metadata_batch.h"
#include "src/core/load_balancing/child_policy_handler.h"
#include "src/core/load_balancing/lb_policy.h"
#include "src/core/load_balancing/lb_policy_registry.h"
@ -228,23 +228,20 @@ class ClientChannel::SubchannelWrapper::WatcherWrapper
subchannel_wrapper_.reset(DEBUG_LOCATION, "WatcherWrapper");
}
void OnConnectivityStateChange(
RefCountedPtr<ConnectivityStateWatcherInterface> self,
grpc_connectivity_state state, const absl::Status& status) override {
void OnConnectivityStateChange(grpc_connectivity_state state,
const absl::Status& status) override {
GRPC_TRACE_LOG(client_channel, INFO)
<< "client_channel=" << subchannel_wrapper_->client_channel_.get()
<< ": connectivity change for subchannel wrapper "
<< subchannel_wrapper_.get() << " subchannel "
<< subchannel_wrapper_->subchannel_.get()
<< "; hopping into work_serializer";
self.release(); // Held by callback.
auto self = RefAsSubclass<WatcherWrapper>();
subchannel_wrapper_->client_channel_->work_serializer_->Run(
[this, state, status]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(
*subchannel_wrapper_->client_channel_->work_serializer_) {
ApplyUpdateInControlPlaneWorkSerializer(state, status);
Unref();
},
DEBUG_LOCATION);
[self, state, status]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(
*self->subchannel_wrapper_->client_channel_->work_serializer_) {
self->ApplyUpdateInControlPlaneWorkSerializer(state, status);
});
}
grpc_pollset_set* interested_parties() override { return nullptr; }
@ -262,8 +259,7 @@ class ClientChannel::SubchannelWrapper::WatcherWrapper
<< subchannel_wrapper_->subchannel_.get()
<< " watcher=" << watcher_.get()
<< " state=" << ConnectivityStateName(state) << " status=" << status;
absl::optional<absl::Cord> keepalive_throttling =
status.GetPayload(kKeepaliveThrottlingKey);
auto keepalive_throttling = status.GetPayload(kKeepaliveThrottlingKey);
if (keepalive_throttling.has_value()) {
int new_keepalive_time = -1;
if (absl::SimpleAtoi(std::string(keepalive_throttling.value()),
@ -326,8 +322,7 @@ ClientChannel::SubchannelWrapper::SubchannelWrapper(
auto it =
client_channel_->subchannel_refcount_map_.find(subchannel_.get());
if (it == client_channel_->subchannel_refcount_map_.end()) {
client_channel_->channelz_node_->AddChildSubchannel(
subchannel_node->uuid());
subchannel_node->AddParent(client_channel_->channelz_node_);
it = client_channel_->subchannel_refcount_map_
.emplace(subchannel_.get(), 0)
.first;
@ -362,14 +357,13 @@ void ClientChannel::SubchannelWrapper::Orphaned() {
CHECK(it != self->client_channel_->subchannel_refcount_map_.end());
--it->second;
if (it->second == 0) {
self->client_channel_->channelz_node_->RemoveChildSubchannel(
subchannel_node->uuid());
subchannel_node->RemoveParent(
self->client_channel_->channelz_node_);
self->client_channel_->subchannel_refcount_map_.erase(it);
}
}
}
},
DEBUG_LOCATION);
});
}
void ClientChannel::SubchannelWrapper::WatchConnectivityState(
@ -498,7 +492,7 @@ class ClientChannel::ClientChannelControlHelper
}
GlobalStatsPluginRegistry::StatsPluginGroup& GetStatsPluginGroup() override {
return client_channel_->stats_plugin_group_;
return *client_channel_->stats_plugin_group_;
}
void AddTraceEvent(TraceSeverity severity, absl::string_view message) override
@ -533,7 +527,11 @@ RefCountedPtr<SubchannelPoolInterface> GetSubchannelPool(
if (args.GetBool(GRPC_ARG_USE_LOCAL_SUBCHANNEL_POOL).value_or(false)) {
return MakeRefCounted<LocalSubchannelPool>();
}
return GlobalSubchannelPool::instance();
if (IsShardGlobalConnectionPoolEnabled()) {
return GlobalSubchannelPool::instance();
} else {
return LegacyGlobalSubchannelPool::instance();
}
}
} // namespace
@ -557,7 +555,7 @@ absl::StatusOr<RefCountedPtr<Channel>> ClientChannel::Create(
}
// Get default service config. If none is specified via the client API,
// we use an empty config.
absl::optional<absl::string_view> service_config_json =
std::optional<absl::string_view> service_config_json =
channel_args.GetString(GRPC_ARG_SERVICE_CONFIG);
if (!service_config_json.has_value()) service_config_json = "{}";
auto default_service_config =
@ -590,9 +588,10 @@ absl::StatusOr<RefCountedPtr<Channel>> ClientChannel::Create(
}
namespace {
std::string GetDefaultAuthorityFromChannelArgs(const ChannelArgs& channel_args,
absl::string_view target) {
absl::optional<std::string> default_authority =
std::optional<std::string> default_authority =
channel_args.GetOwnedString(GRPC_ARG_DEFAULT_AUTHORITY);
if (!default_authority.has_value()) {
return CoreConfiguration::Get().resolver_registry().GetDefaultAuthority(
@ -601,6 +600,18 @@ std::string GetDefaultAuthorityFromChannelArgs(const ChannelArgs& channel_args,
return std::move(*default_authority);
}
}
std::shared_ptr<GlobalStatsPluginRegistry::StatsPluginGroup>
GetStatsPluginGroupFromChannelArgs(const ChannelArgs& channel_args,
absl::string_view target,
absl::string_view default_authority) {
grpc_event_engine::experimental::ChannelArgsEndpointConfig endpoint_config(
channel_args);
experimental::StatsPluginChannelScope scope(target, default_authority,
endpoint_config);
return GlobalStatsPluginRegistry::GetStatsPluginsForChannel(scope);
}
} // namespace
ClientChannel::ClientChannel(
@ -609,15 +620,17 @@ ClientChannel::ClientChannel(
ClientChannelFactory* client_channel_factory,
CallDestinationFactory* call_destination_factory)
: Channel(std::move(target), channel_args),
channel_args_(std::move(channel_args)),
default_authority_(
GetDefaultAuthorityFromChannelArgs(channel_args, this->target())),
stats_plugin_group_(GetStatsPluginGroupFromChannelArgs(
channel_args, this->target(), default_authority_)),
channel_args_(channel_args.SetObject(stats_plugin_group_)),
event_engine_(channel_args_.GetObjectRef<EventEngine>()),
uri_to_resolve_(std::move(uri_to_resolve)),
service_config_parser_index_(
internal::ClientChannelServiceConfigParser::ParserIndex()),
default_service_config_(std::move(default_service_config)),
client_channel_factory_(client_channel_factory),
default_authority_(
GetDefaultAuthorityFromChannelArgs(channel_args_, this->target())),
channelz_node_(channel_args_.GetObject<channelz::ChannelNode>()),
idle_timeout_(GetClientIdleTimeout(channel_args_)),
resolver_data_for_calls_(ResolverDataForCalls{}),
@ -637,13 +650,6 @@ ClientChannel::ClientChannel(
} else {
keepalive_time_ = -1; // unset
}
// Get stats plugins for channel.
grpc_event_engine::experimental::ChannelArgsEndpointConfig endpoint_config(
channel_args_);
experimental::StatsPluginChannelScope scope(
this->target(), default_authority_, endpoint_config);
stats_plugin_group_ =
GlobalStatsPluginRegistry::GetStatsPluginsForChannel(scope);
}
ClientChannel::~ClientChannel() {
@ -661,8 +667,7 @@ void ClientChannel::Orphaned() {
work_serializer_->Run(
[self]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*self->work_serializer_) {
self->DestroyResolverAndLbPolicyLocked();
},
DEBUG_LOCATION);
});
// IncreaseCallCount() introduces a phony call and prevents the idle
// timer from being reset by other threads.
idle_state_.IncreaseCallCount();
@ -682,8 +687,7 @@ grpc_connectivity_state ClientChannel::CheckConnectivityState(
work_serializer_->Run(
[self]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*self->work_serializer_) {
self->TryToConnectLocked();
},
DEBUG_LOCATION);
});
}
return state;
}
@ -698,6 +702,7 @@ class ExternalStateWatcher : public RefCounted<ExternalStateWatcher> {
grpc_connectivity_state last_observed_state,
Timestamp deadline)
: channel_(std::move(channel)), cq_(cq), tag_(tag) {
grpc_cq_begin_op(cq, tag);
MutexLock lock(&mu_);
// Start watch. This inherits the ref from creation.
auto watcher =
@ -708,7 +713,6 @@ class ExternalStateWatcher : public RefCounted<ExternalStateWatcher> {
const Duration timeout = deadline - Timestamp::Now();
timer_handle_ =
channel_->event_engine()->RunAfter(timeout, [self = Ref()]() mutable {
ApplicationCallbackExecCtx callback_exec_ctx;
ExecCtx exec_ctx;
self->MaybeStartCompletion(absl::DeadlineExceededError(
"Timed out waiting for connection state change"));
@ -778,18 +782,14 @@ void ClientChannel::WatchConnectivityState(grpc_connectivity_state state,
}
void ClientChannel::AddConnectivityWatcher(
grpc_connectivity_state,
OrphanablePtr<AsyncConnectivityStateWatcherInterface>) {
Crash("not implemented");
// TODO(ctiller): to make this work, need to change WorkSerializer to use
// absl::AnyInvocable<> instead of std::function<>
// work_serializer_->Run(
// [self = RefAsSubclass<ClientChannel>(), initial_state,
// watcher = std::move(watcher)]()
// ABSL_EXCLUSIVE_LOCKS_REQUIRED(*work_serializer_) {
// self->state_tracker_.AddWatcher(initial_state, std::move(watcher));
// },
// DEBUG_LOCATION);
grpc_connectivity_state initial_state,
OrphanablePtr<AsyncConnectivityStateWatcherInterface> watcher) {
auto self = RefAsSubclass<ClientChannel>();
work_serializer_->Run(
[self, initial_state, watcher = std::move(watcher)]()
ABSL_EXCLUSIVE_LOCKS_REQUIRED(*self->work_serializer_) mutable {
self->state_tracker_.AddWatcher(initial_state, std::move(watcher));
});
}
void ClientChannel::RemoveConnectivityWatcher(
@ -798,8 +798,7 @@ void ClientChannel::RemoveConnectivityWatcher(
work_serializer_->Run(
[self, watcher]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*self->work_serializer_) {
self->state_tracker_.RemoveWatcher(watcher);
},
DEBUG_LOCATION);
});
}
void ClientChannel::GetInfo(const grpc_channel_info* info) {
@ -817,8 +816,7 @@ void ClientChannel::ResetConnectionBackoff() {
work_serializer_->Run(
[self]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*self->work_serializer_) {
if (self->lb_policy_ != nullptr) self->lb_policy_->ResetBackoffLocked();
},
DEBUG_LOCATION);
});
}
namespace {
@ -855,7 +853,7 @@ void ClientChannel::Ping(grpc_completion_queue*, void*) {
grpc_call* ClientChannel::CreateCall(
grpc_call* parent_call, uint32_t propagation_mask,
grpc_completion_queue* cq, grpc_pollset_set* /*pollset_set_alternative*/,
Slice path, absl::optional<Slice> authority, Timestamp deadline, bool) {
Slice path, std::optional<Slice> authority, Timestamp deadline, bool) {
auto arena = call_arena_allocator()->MakeArena();
arena->SetContext<grpc_event_engine::experimental::EventEngine>(
event_engine());
@ -985,7 +983,7 @@ RefCountedPtr<LoadBalancingPolicy::Config> ChooseLbPolicy(
}
// Try the deprecated LB policy name from the service config.
// If not, try the setting from channel args.
absl::optional<absl::string_view> policy_name;
std::optional<absl::string_view> policy_name;
if (!parsed_service_config->parsed_deprecated_lb_policy().empty()) {
policy_name = parsed_service_config->parsed_deprecated_lb_policy();
} else {
@ -1189,7 +1187,7 @@ void ClientChannel::OnResolverErrorLocked(absl::Status status) {
absl::Status ClientChannel::CreateOrUpdateLbPolicyLocked(
RefCountedPtr<LoadBalancingPolicy::Config> lb_policy_config,
const absl::optional<std::string>& health_check_service_name,
const std::optional<std::string>& health_check_service_name,
Resolver::Result result) {
// Construct update.
LoadBalancingPolicy::UpdateArgs update_args;
@ -1321,11 +1319,13 @@ void ClientChannel::UpdateStateLocked(grpc_connectivity_state state,
state_tracker_.SetState(state, status, reason);
if (channelz_node_ != nullptr) {
channelz_node_->SetConnectivityState(state);
channelz_node_->AddTraceEvent(
channelz::ChannelTrace::Severity::Info,
grpc_slice_from_static_string(
channelz::ChannelNode::GetChannelConnectivityStateChangeString(
state)));
std::string trace =
channelz::ChannelNode::GetChannelConnectivityStateChangeString(state);
if (!status.ok() || state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
absl::StrAppend(&trace, " status:", status.ToString());
}
channelz_node_->AddTraceEvent(channelz::ChannelTrace::Severity::Info,
grpc_slice_from_cpp_string(std::move(trace)));
}
}
@ -1368,8 +1368,7 @@ void ClientChannel::StartIdleTimer() {
// might need to check for any calls that are
// queued waiting for a resolver result or an LB
// pick.
},
DEBUG_LOCATION);
});
}
},
std::move(arena)));

View File

@ -22,6 +22,7 @@
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "src/core/call/metadata.h"
#include "src/core/client_channel/client_channel_factory.h"
#include "src/core/client_channel/config_selector.h"
#include "src/core/client_channel/subchannel.h"
@ -29,7 +30,6 @@
#include "src/core/filter/blackboard.h"
#include "src/core/lib/promise/observable.h"
#include "src/core/lib/surface/channel.h"
#include "src/core/lib/transport/metadata.h"
#include "src/core/load_balancing/lb_policy.h"
#include "src/core/resolver/resolver.h"
#include "src/core/service_config/service_config.h"
@ -74,7 +74,7 @@ class ClientChannel : public Channel {
grpc_call* CreateCall(grpc_call* parent_call, uint32_t propagation_mask,
grpc_completion_queue* cq,
grpc_pollset_set* /*pollset_set_alternative*/,
Slice path, absl::optional<Slice> authority,
Slice path, std::optional<Slice> authority,
Timestamp deadline, bool registered_method) override;
void StartCall(UnstartedCallHandler unstarted_handler) override;
@ -139,7 +139,7 @@ class ClientChannel : public Channel {
absl::Status CreateOrUpdateLbPolicyLocked(
RefCountedPtr<LoadBalancingPolicy::Config> lb_policy_config,
const absl::optional<std::string>& health_check_service_name,
const std::optional<std::string>& health_check_service_name,
Resolver::Result result) ABSL_EXCLUSIVE_LOCKS_REQUIRED(*work_serializer_);
OrphanablePtr<LoadBalancingPolicy> CreateLbPolicyLocked(
const ChannelArgs& args) ABSL_EXCLUSIVE_LOCKS_REQUIRED(*work_serializer_);
@ -170,6 +170,9 @@ class ClientChannel : public Channel {
ConfigSelector& config_selector,
ClientMetadata& client_initial_metadata) const;
const std::string default_authority_;
const std::shared_ptr<GlobalStatsPluginRegistry::StatsPluginGroup>
stats_plugin_group_;
const ChannelArgs channel_args_;
const std::shared_ptr<grpc_event_engine::experimental::EventEngine>
event_engine_;
@ -177,9 +180,7 @@ class ClientChannel : public Channel {
const size_t service_config_parser_index_;
const RefCountedPtr<ServiceConfig> default_service_config_;
ClientChannelFactory* const client_channel_factory_;
const std::string default_authority_;
channelz::ChannelNode* const channelz_node_;
GlobalStatsPluginRegistry::StatsPluginGroup stats_plugin_group_;
//
// Idleness state.

View File

@ -30,9 +30,11 @@
#include <algorithm>
#include <functional>
#include <new>
#include <optional>
#include <set>
#include <type_traits>
#include <utility>
#include <variant>
#include <vector>
#include "absl/cleanup/cleanup.h"
@ -45,8 +47,8 @@
#include "absl/strings/str_cat.h"
#include "absl/strings/str_join.h"
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "absl/types/variant.h"
#include "src/core/call/metadata_batch.h"
#include "src/core/call/status_util.h"
#include "src/core/channelz/channel_trace.h"
#include "src/core/client_channel/backup_poller.h"
#include "src/core/client_channel/client_channel_internal.h"
@ -60,11 +62,11 @@
#include "src/core/client_channel/subchannel.h"
#include "src/core/client_channel/subchannel_interface_internal.h"
#include "src/core/config/core_configuration.h"
#include "src/core/credentials/transport/transport_credentials.h"
#include "src/core/handshaker/proxy_mapper_registry.h"
#include "src/core/lib/address_utils/sockaddr_utils.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/channel/status_util.h"
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/experiments/experiments.h"
#include "src/core/lib/iomgr/exec_ctx.h"
@ -79,13 +81,11 @@
#include "src/core/lib/promise/poll.h"
#include "src/core/lib/promise/promise.h"
#include "src/core/lib/promise/try_seq.h"
#include "src/core/lib/security/credentials/credentials.h"
#include "src/core/lib/slice/slice.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/surface/call.h"
#include "src/core/lib/transport/connectivity_state.h"
#include "src/core/lib/transport/error_utils.h"
#include "src/core/lib/transport/metadata_batch.h"
#include "src/core/load_balancing/backend_metric_parser.h"
#include "src/core/load_balancing/child_policy_handler.h"
#include "src/core/load_balancing/lb_policy_registry.h"
@ -139,14 +139,14 @@ class ClientChannelFilter::CallData {
// Checks whether a resolver result is available. The following
// outcomes are possible:
// - No resolver result is available yet. The call will be queued and
// absl::nullopt will be returned. Later, when a resolver result
// std::nullopt will be returned. Later, when a resolver result
// becomes available, RetryCheckResolutionLocked() will be called.
// - The resolver has returned a transient failure. If the call is
// not wait_for_ready, a non-OK status will be returned. (If the
// call *is* wait_for_ready, it will be queued instead.)
// - There is a valid resolver result. The service config will be
// stored in the call context and an OK status will be returned.
absl::optional<absl::Status> CheckResolution(bool was_queued);
std::optional<absl::Status> CheckResolution(bool was_queued);
private:
// Accessors for data stored in the subclass.
@ -268,7 +268,6 @@ class ClientChannelFilter::FilterBasedCallData final
static void RecvTrailingMetadataReadyForConfigSelectorCommitCallback(
void* arg, grpc_error_handle error);
grpc_slice path_; // Request path.
gpr_cycle_counter call_start_time_;
Timestamp deadline_;
@ -398,7 +397,6 @@ class DynamicTerminationFilter::CallData final {
auto* chand = static_cast<DynamicTerminationFilter*>(elem->channel_data);
ClientChannelFilter* client_channel = chand->chand_;
grpc_call_element_args args = {calld->owning_call_, nullptr,
calld->path_,
/*start_time=*/0, calld->deadline_,
calld->arena_, calld->call_combiner_};
auto* service_config_call_data = GetServiceConfigCallData(calld->arena_);
@ -413,15 +411,11 @@ class DynamicTerminationFilter::CallData final {
private:
explicit CallData(const grpc_call_element_args& args)
: path_(CSliceRef(args.path)),
deadline_(args.deadline),
: deadline_(args.deadline),
arena_(args.arena),
owning_call_(args.call_stack),
call_combiner_(args.call_combiner) {}
~CallData() { CSliceUnref(path_); }
grpc_slice path_; // Request path.
Timestamp deadline_;
Arena* arena_;
grpc_call_stack* owning_call_;
@ -507,7 +501,7 @@ class ClientChannelFilter::SubchannelWrapper final
if (subchannel_node != nullptr) {
auto it = chand_->subchannel_refcount_map_.find(subchannel_.get());
if (it == chand_->subchannel_refcount_map_.end()) {
chand_->channelz_node_->AddChildSubchannel(subchannel_node->uuid());
subchannel_node->AddParent(chand_->channelz_node_);
it = chand_->subchannel_refcount_map_.emplace(subchannel_.get(), 0)
.first;
}
@ -521,7 +515,16 @@ class ClientChannelFilter::SubchannelWrapper final
GRPC_TRACE_LOG(client_channel, INFO)
<< "chand=" << chand_ << ": destroying subchannel wrapper " << this
<< "for subchannel " << subchannel_.get();
if (!IsWorkSerializerDispatchEnabled()) {
GRPC_CHANNEL_STACK_UNREF(chand_->owning_stack_, "SubchannelWrapper");
}
void Orphaned() override {
// Make sure we clean up the channel's subchannel maps inside the
// WorkSerializer.
// Ref held by callback.
WeakRef(DEBUG_LOCATION, "subchannel map cleanup").release();
chand_->work_serializer_->Run([this]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(
*chand_->work_serializer_) {
chand_->subchannel_wrappers_.erase(this);
if (chand_->channelz_node_ != nullptr) {
auto* subchannel_node = subchannel_->channelz_node();
@ -530,42 +533,13 @@ class ClientChannelFilter::SubchannelWrapper final
CHECK(it != chand_->subchannel_refcount_map_.end());
--it->second;
if (it->second == 0) {
chand_->channelz_node_->RemoveChildSubchannel(
subchannel_node->uuid());
subchannel_node->RemoveParent(chand_->channelz_node_);
chand_->subchannel_refcount_map_.erase(it);
}
}
}
}
GRPC_CHANNEL_STACK_UNREF(chand_->owning_stack_, "SubchannelWrapper");
}
void Orphaned() override {
if (!IsWorkSerializerDispatchEnabled()) return;
// Make sure we clean up the channel's subchannel maps inside the
// WorkSerializer.
// Ref held by callback.
WeakRef(DEBUG_LOCATION, "subchannel map cleanup").release();
chand_->work_serializer_->Run(
[this]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*chand_->work_serializer_) {
chand_->subchannel_wrappers_.erase(this);
if (chand_->channelz_node_ != nullptr) {
auto* subchannel_node = subchannel_->channelz_node();
if (subchannel_node != nullptr) {
auto it =
chand_->subchannel_refcount_map_.find(subchannel_.get());
CHECK(it != chand_->subchannel_refcount_map_.end());
--it->second;
if (it->second == 0) {
chand_->channelz_node_->RemoveChildSubchannel(
subchannel_node->uuid());
chand_->subchannel_refcount_map_.erase(it);
}
}
}
WeakUnref(DEBUG_LOCATION, "subchannel map cleanup");
},
DEBUG_LOCATION);
WeakUnref(DEBUG_LOCATION, "subchannel map cleanup");
});
}
void WatchConnectivityState(
@ -639,35 +613,22 @@ class ClientChannelFilter::SubchannelWrapper final
: watcher_(std::move(watcher)), parent_(std::move(parent)) {}
~WatcherWrapper() override {
if (!IsWorkSerializerDispatchEnabled()) {
auto* parent = parent_.release(); // ref owned by lambda
parent->chand_->work_serializer_->Run(
[parent]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(
*parent_->chand_->work_serializer_) {
parent->Unref(DEBUG_LOCATION, "WatcherWrapper");
},
DEBUG_LOCATION);
return;
}
parent_.reset(DEBUG_LOCATION, "WatcherWrapper");
}
void OnConnectivityStateChange(
RefCountedPtr<ConnectivityStateWatcherInterface> self,
grpc_connectivity_state state, const absl::Status& status) override {
void OnConnectivityStateChange(grpc_connectivity_state state,
const absl::Status& status) override {
GRPC_TRACE_LOG(client_channel, INFO)
<< "chand=" << parent_->chand_
<< ": connectivity change for subchannel wrapper " << parent_.get()
<< " subchannel " << parent_->subchannel_.get()
<< "hopping into work_serializer";
self.release(); // Held by callback.
auto self = RefAsSubclass<WatcherWrapper>();
parent_->chand_->work_serializer_->Run(
[this, state, status]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(
*parent_->chand_->work_serializer_) {
ApplyUpdateInControlPlaneWorkSerializer(state, status);
Unref();
},
DEBUG_LOCATION);
[self, state, status]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(
*self->parent_->chand_->work_serializer_) {
self->ApplyUpdateInControlPlaneWorkSerializer(state, status);
});
}
grpc_pollset_set* interested_parties() override {
@ -685,8 +646,7 @@ class ClientChannelFilter::SubchannelWrapper final
<< parent_.get() << " subchannel " << parent_->subchannel_.get()
<< " watcher=" << watcher_.get()
<< " state=" << ConnectivityStateName(state) << " status=" << status;
absl::optional<absl::Cord> keepalive_throttling =
status.GetPayload(kKeepaliveThrottlingKey);
auto keepalive_throttling = status.GetPayload(kKeepaliveThrottlingKey);
if (keepalive_throttling.has_value()) {
int new_keepalive_time = -1;
if (absl::SimpleAtoi(std::string(keepalive_throttling.value()),
@ -787,8 +747,7 @@ ClientChannelFilter::ExternalConnectivityWatcher::ExternalConnectivityWatcher(
[this]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*chand_->work_serializer_) {
// The ref is passed to AddWatcherLocked().
AddWatcherLocked();
},
DEBUG_LOCATION);
});
}
ClientChannelFilter::ExternalConnectivityWatcher::
@ -841,8 +800,7 @@ void ClientChannelFilter::ExternalConnectivityWatcher::Notify(
[this]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*chand_->work_serializer_) {
RemoveWatcherLocked();
Unref(DEBUG_LOCATION, "RemoveWatcherLocked()");
},
DEBUG_LOCATION);
});
}
}
@ -861,8 +819,7 @@ void ClientChannelFilter::ExternalConnectivityWatcher::Cancel() {
[this]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*chand_->work_serializer_) {
RemoveWatcherLocked();
Unref(DEBUG_LOCATION, "RemoveWatcherLocked()");
},
DEBUG_LOCATION);
});
}
void ClientChannelFilter::ExternalConnectivityWatcher::AddWatcherLocked() {
@ -892,8 +849,7 @@ class ClientChannelFilter::ConnectivityWatcherAdder final {
chand_->work_serializer_->Run(
[this]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*chand_->work_serializer_) {
AddWatcherLocked();
},
DEBUG_LOCATION);
});
}
private:
@ -922,8 +878,7 @@ class ClientChannelFilter::ConnectivityWatcherRemover final {
chand_->work_serializer_->Run(
[this]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*chand_->work_serializer_) {
RemoveWatcherLocked();
},
DEBUG_LOCATION);
});
}
private:
@ -1022,7 +977,7 @@ class ClientChannelFilter::ClientChannelControlHelper final
}
GlobalStatsPluginRegistry::StatsPluginGroup& GetStatsPluginGroup() override {
return *chand_->owning_stack_->stats_plugin_group;
return **chand_->owning_stack_->stats_plugin_group;
}
void AddTraceEvent(TraceSeverity severity, absl::string_view message) override
@ -1071,7 +1026,11 @@ RefCountedPtr<SubchannelPoolInterface> GetSubchannelPool(
if (args.GetBool(GRPC_ARG_USE_LOCAL_SUBCHANNEL_POOL).value_or(false)) {
return MakeRefCounted<LocalSubchannelPool>();
}
return GlobalSubchannelPool::instance();
if (IsShardGlobalConnectionPoolEnabled()) {
return GlobalSubchannelPool::instance();
} else {
return LegacyGlobalSubchannelPool::instance();
}
}
} // namespace
@ -1102,7 +1061,7 @@ ClientChannelFilter::ClientChannelFilter(grpc_channel_element_args* args,
}
// Get default service config. If none is specified via the client API,
// we use an empty config.
absl::optional<absl::string_view> service_config_json =
std::optional<absl::string_view> service_config_json =
channel_args_.GetString(GRPC_ARG_SERVICE_CONFIG);
if (!service_config_json.has_value()) service_config_json = "{}";
*error = absl::OkStatus();
@ -1114,7 +1073,7 @@ ClientChannelFilter::ClientChannelFilter(grpc_channel_element_args* args,
}
default_service_config_ = std::move(*service_config);
// Get URI to resolve, using proxy mapper if needed.
absl::optional<std::string> target_uri =
std::optional<std::string> target_uri =
channel_args_.GetOwnedString(GRPC_ARG_SERVER_URI);
if (!target_uri.has_value()) {
*error = GRPC_ERROR_CREATE(
@ -1146,7 +1105,7 @@ ClientChannelFilter::ClientChannelFilter(grpc_channel_element_args* args,
keepalive_time_ = -1; // unset
}
// Set default authority.
absl::optional<std::string> default_authority =
std::optional<std::string> default_authority =
channel_args_.GetOwnedString(GRPC_ARG_DEFAULT_AUTHORITY);
if (!default_authority.has_value()) {
default_authority_ =
@ -1199,7 +1158,7 @@ RefCountedPtr<LoadBalancingPolicy::Config> ChooseLbPolicy(
}
// Try the deprecated LB policy name from the service config.
// If not, try the setting from channel args.
absl::optional<absl::string_view> policy_name;
std::optional<absl::string_view> policy_name;
if (!parsed_service_config->parsed_deprecated_lb_policy().empty()) {
policy_name = parsed_service_config->parsed_deprecated_lb_policy();
} else {
@ -1406,7 +1365,7 @@ void ClientChannelFilter::OnResolverErrorLocked(absl::Status status) {
absl::Status ClientChannelFilter::CreateOrUpdateLbPolicyLocked(
RefCountedPtr<LoadBalancingPolicy::Config> lb_policy_config,
const absl::optional<std::string>& health_check_service_name,
const std::optional<std::string>& health_check_service_name,
Resolver::Result result) {
// Construct update.
LoadBalancingPolicy::UpdateArgs update_args;
@ -1593,11 +1552,13 @@ void ClientChannelFilter::UpdateStateLocked(grpc_connectivity_state state,
state_tracker_.SetState(state, status, reason);
if (channelz_node_ != nullptr) {
channelz_node_->SetConnectivityState(state);
channelz_node_->AddTraceEvent(
channelz::ChannelTrace::Severity::Info,
grpc_slice_from_static_string(
channelz::ChannelNode::GetChannelConnectivityStateChangeString(
state)));
std::string trace =
channelz::ChannelNode::GetChannelConnectivityStateChangeString(state);
if (!status.ok() || state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
absl::StrAppend(&trace, " status:", status.ToString());
}
channelz_node_->AddTraceEvent(channelz::ChannelTrace::Severity::Info,
grpc_slice_from_cpp_string(std::move(trace)));
}
}
@ -1631,22 +1592,22 @@ T HandlePickResult(
std::function<T(LoadBalancingPolicy::PickResult::Fail*)> fail_func,
std::function<T(LoadBalancingPolicy::PickResult::Drop*)> drop_func) {
auto* complete_pick =
absl::get_if<LoadBalancingPolicy::PickResult::Complete>(&result->result);
std::get_if<LoadBalancingPolicy::PickResult::Complete>(&result->result);
if (complete_pick != nullptr) {
return complete_func(complete_pick);
}
auto* queue_pick =
absl::get_if<LoadBalancingPolicy::PickResult::Queue>(&result->result);
std::get_if<LoadBalancingPolicy::PickResult::Queue>(&result->result);
if (queue_pick != nullptr) {
return queue_func(queue_pick);
}
auto* fail_pick =
absl::get_if<LoadBalancingPolicy::PickResult::Fail>(&result->result);
std::get_if<LoadBalancingPolicy::PickResult::Fail>(&result->result);
if (fail_pick != nullptr) {
return fail_func(fail_pick);
}
auto* drop_pick =
absl::get_if<LoadBalancingPolicy::PickResult::Drop>(&result->result);
std::get_if<LoadBalancingPolicy::PickResult::Drop>(&result->result);
CHECK_NE(drop_pick, nullptr);
return drop_func(drop_pick);
}
@ -1768,8 +1729,7 @@ void ClientChannelFilter::StartTransportOp(grpc_channel_element* elem,
chand->work_serializer_->Run(
[chand, op]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*chand->work_serializer_) {
chand->StartTransportOpLocked(op);
},
DEBUG_LOCATION);
});
}
void ClientChannelFilter::GetChannelInfo(grpc_channel_element* elem,
@ -1806,8 +1766,7 @@ grpc_connectivity_state ClientChannelFilter::CheckConnectivityState(
if (out == GRPC_CHANNEL_IDLE && try_to_connect) {
GRPC_CHANNEL_STACK_REF(owning_stack_, "TryToConnect");
work_serializer_->Run([this]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(
*work_serializer_) { TryToConnectLocked(); },
DEBUG_LOCATION);
*work_serializer_) { TryToConnectLocked(); });
}
return out;
}
@ -1898,7 +1857,7 @@ grpc_error_handle ClientChannelFilter::CallData::ApplyServiceConfigToCallLocked(
return absl::OkStatus();
}
absl::optional<absl::Status> ClientChannelFilter::CallData::CheckResolution(
std::optional<absl::Status> ClientChannelFilter::CallData::CheckResolution(
bool was_queued) {
// Check if we have a resolver result to use.
absl::StatusOr<RefCountedPtr<ConfigSelector>> config_selector;
@ -1908,19 +1867,11 @@ absl::optional<absl::Status> ClientChannelFilter::CallData::CheckResolution(
// If no result is available, queue the call.
if (!result_ready) {
AddCallToResolverQueuedCallsLocked();
return absl::nullopt;
return std::nullopt;
}
}
// We have a result. Apply service config to call.
grpc_error_handle error = ApplyServiceConfigToCallLocked(config_selector);
// ConfigSelector must be unreffed inside the WorkSerializer.
if (!IsWorkSerializerDispatchEnabled() && config_selector.ok()) {
chand()->work_serializer_->Run(
[config_selector = std::move(*config_selector)]() mutable {
config_selector.reset();
},
DEBUG_LOCATION);
}
// Handle errors.
if (!error.ok()) {
GRPC_TRACE_LOG(client_channel_call, INFO)
@ -1974,8 +1925,7 @@ bool ClientChannelFilter::CallData::CheckResolutionLocked(
ClientChannelFilter::FilterBasedCallData::FilterBasedCallData(
grpc_call_element* elem, const grpc_call_element_args& args)
: path_(CSliceRef(args.path)),
call_start_time_(args.start_time),
: call_start_time_(args.start_time),
deadline_(args.deadline),
arena_(args.arena),
elem_(elem),
@ -1986,7 +1936,6 @@ ClientChannelFilter::FilterBasedCallData::FilterBasedCallData(
}
ClientChannelFilter::FilterBasedCallData::~FilterBasedCallData() {
CSliceUnref(path_);
// Make sure there are no remaining pending batches.
for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches_); ++i) {
CHECK_EQ(pending_batches_[i], nullptr);
@ -2097,8 +2046,7 @@ void ClientChannelFilter::FilterBasedCallData::StartTransportStreamOpBatch(
[chand]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*chand->work_serializer_) {
chand->CheckConnectivityState(/*try_to_connect=*/true);
GRPC_CHANNEL_STACK_UNREF(chand->owning_stack_, "ExitIdle");
},
DEBUG_LOCATION);
});
}
calld->TryCheckResolution(/*was_queued=*/false);
} else {
@ -2293,16 +2241,15 @@ void ClientChannelFilter::FilterBasedCallData::RetryCheckResolutionLocked() {
// Do an async callback to resume call processing, so that we're not
// doing it while holding the channel's resolution mutex.
chand()->owning_stack_->EventEngine()->Run([this]() {
ApplicationCallbackExecCtx application_exec_ctx;
ExecCtx exec_ctx;
TryCheckResolution(/*was_queued=*/true);
});
}
void ClientChannelFilter::FilterBasedCallData::CreateDynamicCall() {
DynamicFilters::Call::Args args = {dynamic_filters(), pollent_, path_,
call_start_time_, deadline_, arena(),
call_combiner()};
DynamicFilters::Call::Args args = {dynamic_filters(), pollent_,
call_start_time_, deadline_,
arena(), call_combiner()};
grpc_error_handle error;
DynamicFilters* channel_stack = args.channel_stack.get();
GRPC_TRACE_LOG(client_channel_call, INFO)
@ -2427,12 +2374,14 @@ class ClientChannelFilter::LoadBalancedCall::BackendMetricAccessor final
namespace {
void CreateCallAttemptTracer(Arena* arena, bool is_transparent_retry) {
ClientCallTracer::CallAttemptTracer* CreateCallAttemptTracer(
Arena* arena, bool is_transparent_retry) {
auto* call_tracer = DownCast<ClientCallTracer*>(
arena->GetContext<CallTracerAnnotationInterface>());
if (call_tracer == nullptr) return;
if (call_tracer == nullptr) return nullptr;
auto* tracer = call_tracer->StartNewAttempt(is_transparent_retry);
arena->SetContext<CallTracerInterface>(tracer);
return tracer;
}
} // namespace
@ -2444,9 +2393,10 @@ ClientChannelFilter::LoadBalancedCall::LoadBalancedCall(
? "LoadBalancedCall"
: nullptr),
chand_(chand),
call_attempt_tracer_(
CreateCallAttemptTracer(arena, is_transparent_retry)),
on_commit_(std::move(on_commit)),
arena_(arena) {
CreateCallAttemptTracer(arena, is_transparent_retry);
GRPC_TRACE_LOG(client_channel_lb_call, INFO)
<< "chand=" << chand_ << " lb_call=" << this << ": created";
}
@ -2481,9 +2431,7 @@ void ClientChannelFilter::LoadBalancedCall::RecordCallCompletion(
void ClientChannelFilter::LoadBalancedCall::RecordLatency() {
// Compute latency and report it to the tracer.
if (call_attempt_tracer() != nullptr) {
gpr_timespec latency =
gpr_cycle_counter_sub(gpr_get_cycle_counter(), lb_call_start_time_);
call_attempt_tracer()->RecordEnd(latency);
call_attempt_tracer()->RecordEnd();
}
}
@ -2514,51 +2462,21 @@ void ClientChannelFilter::LoadBalancedCall::AddCallToLbQueuedCallsLocked() {
OnAddToQueueLocked();
}
absl::optional<absl::Status>
std::optional<absl::Status>
ClientChannelFilter::LoadBalancedCall::PickSubchannel(bool was_queued) {
// We may accumulate multiple pickers here, because if a picker says
// to queue the call, we check again to see if the picker has been
// updated before we queue it.
// We need to unref pickers in the WorkSerializer.
std::vector<RefCountedPtr<LoadBalancingPolicy::SubchannelPicker>> pickers;
auto cleanup = absl::MakeCleanup(
[work_serializer = chand_->work_serializer_, &pickers]() {
if (IsWorkSerializerDispatchEnabled()) return;
work_serializer->Run(
[pickers = std::move(pickers)]() mutable {
for (auto& picker : pickers) {
picker.reset(DEBUG_LOCATION, "PickSubchannel");
}
},
DEBUG_LOCATION);
});
absl::AnyInvocable<void(RefCountedPtr<LoadBalancingPolicy::SubchannelPicker>)>
set_picker;
if (!IsWorkSerializerDispatchEnabled()) {
set_picker =
[&](RefCountedPtr<LoadBalancingPolicy::SubchannelPicker> picker) {
pickers.emplace_back(std::move(picker));
};
} else {
pickers.emplace_back();
set_picker =
[&](RefCountedPtr<LoadBalancingPolicy::SubchannelPicker> picker) {
pickers[0] = std::move(picker);
};
}
RefCountedPtr<LoadBalancingPolicy::SubchannelPicker> picker;
// Grab mutex and take a ref to the picker.
GRPC_TRACE_LOG(client_channel_lb_call, INFO)
<< "chand=" << chand_ << " lb_call=" << this
<< ": grabbing LB mutex to get picker";
RefCountedPtr<LoadBalancingPolicy::SubchannelPicker> picker;
{
MutexLock lock(&chand_->lb_mu_);
set_picker(chand_->picker_);
picker = chand_->picker_;
}
while (true) {
// TODO(roth): Fix race condition in channel_idle filter and any
// other possible causes of this.
if (pickers.back() == nullptr) {
if (picker == nullptr) {
GRPC_TRACE_LOG(client_channel_lb_call, INFO)
<< "chand=" << chand_ << " lb_call=" << this
<< ": picker is null, failing call";
@ -2567,27 +2485,25 @@ ClientChannelFilter::LoadBalancedCall::PickSubchannel(bool was_queued) {
// Do pick.
GRPC_TRACE_LOG(client_channel_lb_call, INFO)
<< "chand=" << chand_ << " lb_call=" << this
<< ": performing pick with picker=" << pickers.back().get();
<< ": performing pick with picker=" << picker.get();
grpc_error_handle error;
bool pick_complete = PickSubchannelImpl(pickers.back().get(), &error);
bool pick_complete = PickSubchannelImpl(picker.get(), &error);
if (!pick_complete) {
RefCountedPtr<LoadBalancingPolicy::SubchannelPicker> old_picker;
MutexLock lock(&chand_->lb_mu_);
// If picker has been swapped out since we grabbed it, try again.
if (pickers.back() != chand_->picker_) {
if (picker != chand_->picker_) {
GRPC_TRACE_LOG(client_channel_lb_call, INFO)
<< "chand=" << chand_ << " lb_call=" << this
<< ": pick not complete, but picker changed";
if (IsWorkSerializerDispatchEnabled()) {
// Don't unref until after we release the mutex.
old_picker = std::move(pickers.back());
}
set_picker(chand_->picker_);
// Don't unref until after we release the mutex.
old_picker = std::move(picker);
picker = chand_->picker_;
continue;
}
// Otherwise queue the pick to try again later when we get a new picker.
AddCallToLbQueuedCallsLocked();
return absl::nullopt;
return std::nullopt;
}
// Pick is complete.
// If it was queued, add a trace annotation.
@ -3119,10 +3035,8 @@ void ClientChannelFilter::FilterBasedLoadBalancedCall::RetryPickLocked() {
}
void ClientChannelFilter::FilterBasedLoadBalancedCall::CreateSubchannelCall() {
Slice* path = send_initial_metadata()->get_pointer(HttpPathMetadata());
CHECK_NE(path, nullptr);
SubchannelCall::Args call_args = {
connected_subchannel()->Ref(), pollent_, path->Ref(), /*start_time=*/0,
connected_subchannel()->Ref(), pollent_, /*start_time=*/0,
arena()->GetContext<Call>()->deadline(),
// TODO(roth): When we implement hedging support, we will probably
// need to use a separate call arena for each subchannel call.

View File

@ -25,6 +25,7 @@
#include <atomic>
#include <map>
#include <memory>
#include <optional>
#include <string>
#include <utility>
@ -33,7 +34,7 @@
#include "absl/functional/any_invocable.h"
#include "absl/status/status.h"
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "src/core/call/metadata_batch.h"
#include "src/core/channelz/channelz.h"
#include "src/core/client_channel/client_channel_args.h"
#include "src/core/client_channel/client_channel_factory.h"
@ -53,7 +54,6 @@
#include "src/core/lib/resource_quota/arena.h"
#include "src/core/lib/slice/slice.h"
#include "src/core/lib/transport/connectivity_state.h"
#include "src/core/lib/transport/metadata_batch.h"
#include "src/core/lib/transport/transport.h"
#include "src/core/load_balancing/backend_metric_data.h"
#include "src/core/load_balancing/lb_policy.h"
@ -223,7 +223,7 @@ class ClientChannelFilter final {
absl::Status CreateOrUpdateLbPolicyLocked(
RefCountedPtr<LoadBalancingPolicy::Config> lb_policy_config,
const absl::optional<std::string>& health_check_service_name,
const std::optional<std::string>& health_check_service_name,
Resolver::Result result) ABSL_EXCLUSIVE_LOCKS_REQUIRED(*work_serializer_);
OrphanablePtr<LoadBalancingPolicy> CreateLbPolicyLocked(
const ChannelArgs& args) ABSL_EXCLUSIVE_LOCKS_REQUIRED(*work_serializer_);
@ -374,8 +374,7 @@ class ClientChannelFilter::LoadBalancedCall
protected:
ClientChannelFilter* chand() const { return chand_; }
ClientCallTracer::CallAttemptTracer* call_attempt_tracer() const {
return DownCast<ClientCallTracer::CallAttemptTracer*>(
arena_->GetContext<CallTracerInterface>());
return call_attempt_tracer_;
}
ConnectedSubchannel* connected_subchannel() const {
return connected_subchannel_.get();
@ -401,7 +400,7 @@ class ClientChannelFilter::LoadBalancedCall
// it will be queued instead.)
// - The pick completed successfully. A connected subchannel is
// stored and an OK status will be returned.
absl::optional<absl::Status> PickSubchannel(bool was_queued);
std::optional<absl::Status> PickSubchannel(bool was_queued);
void RecordCallCompletion(absl::Status status,
grpc_metadata_batch* recv_trailing_metadata,
@ -431,11 +430,14 @@ class ClientChannelFilter::LoadBalancedCall
ABSL_EXCLUSIVE_LOCKS_REQUIRED(&ClientChannelFilter::lb_mu_) = 0;
ClientChannelFilter* chand_;
// When we start a new attempt for a call, we might not have cleaned up the
// previous attempt yet leading to a situation where we have two active call
// attempt tracers, and so we cannot rely on the arena to give us the right
// tracer when performing cleanup.
ClientCallTracer::CallAttemptTracer* call_attempt_tracer_;
absl::AnyInvocable<void()> on_commit_;
gpr_cycle_counter lb_call_start_time_ = gpr_get_cycle_counter();
RefCountedPtr<ConnectedSubchannel> connected_subchannel_;
const BackendMetricData* backend_metric_data_ = nullptr;
std::unique_ptr<LoadBalancingPolicy::SubchannelCallTrackerInterface>
@ -534,7 +536,7 @@ class ClientChannelFilter::FilterBasedLoadBalancedCall final
CallCombiner* call_combiner_;
grpc_polling_entity* pollent_;
grpc_closure* on_call_destruction_complete_;
absl::optional<Slice> peer_string_;
std::optional<Slice> peer_string_;
// Set when we get a cancel_stream op.
grpc_error_handle cancel_error_;

View File

@ -23,8 +23,8 @@
#include "absl/functional/any_invocable.h"
#include "absl/log/check.h"
#include "src/core/call/call_destination.h"
#include "src/core/lib/resource_quota/arena.h"
#include "src/core/lib/transport/call_destination.h"
#include "src/core/load_balancing/lb_policy.h"
#include "src/core/service_config/service_config_call_data.h"
#include "src/core/telemetry/call_tracer.h"

View File

@ -19,7 +19,8 @@
#include <grpc/impl/channel_arg_names.h>
#include <grpc/support/port_platform.h>
#include "absl/types/optional.h"
#include <optional>
#include "src/core/client_channel/client_channel_filter.h"
#include "src/core/client_channel/client_channel_service_config.h"
#include "src/core/client_channel/retry_service_config.h"

View File

@ -19,13 +19,13 @@
#include <grpc/support/port_platform.h>
#include <map>
#include <optional>
#include <utility>
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/ascii.h"
#include "absl/strings/str_cat.h"
#include "absl/types/optional.h"
#include "src/core/load_balancing/lb_policy_registry.h"
// As per the retry design, we do not allow more than 5 retry attempts.

View File

@ -21,10 +21,10 @@
#include <stddef.h>
#include <memory>
#include <optional>
#include <string>
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "src/core/config/core_configuration.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/load_balancing/lb_policy.h"
@ -50,7 +50,7 @@ class ClientChannelGlobalParsedConfig final
return parsed_deprecated_lb_policy_;
}
const absl::optional<std::string>& health_check_service_name() const {
const std::optional<std::string>& health_check_service_name() const {
return health_check_config_.service_name;
}
@ -60,7 +60,7 @@ class ClientChannelGlobalParsedConfig final
private:
struct HealthCheckConfig {
absl::optional<std::string> service_name;
std::optional<std::string> service_name;
static const JsonLoaderInterface* JsonLoader(const JsonArgs&);
};
@ -75,13 +75,13 @@ class ClientChannelMethodParsedConfig final
public:
Duration timeout() const { return timeout_; }
absl::optional<bool> wait_for_ready() const { return wait_for_ready_; }
std::optional<bool> wait_for_ready() const { return wait_for_ready_; }
static const JsonLoaderInterface* JsonLoader(const JsonArgs&);
private:
Duration timeout_;
absl::optional<bool> wait_for_ready_;
std::optional<bool> wait_for_ready_;
};
class ClientChannelServiceConfigParser final

View File

@ -27,12 +27,12 @@
#include "absl/log/check.h"
#include "absl/status/status.h"
#include "absl/strings/string_view.h"
#include "src/core/call/interception_chain.h"
#include "src/core/call/metadata_batch.h"
#include "src/core/client_channel/client_channel_internal.h"
#include "src/core/lib/channel/channel_fwd.h"
#include "src/core/lib/resource_quota/arena.h"
#include "src/core/lib/slice/slice.h"
#include "src/core/lib/transport/interception_chain.h"
#include "src/core/lib/transport/metadata_batch.h"
#include "src/core/service_config/service_config.h"
#include "src/core/util/ref_counted.h"
#include "src/core/util/ref_counted_ptr.h"

View File

@ -53,8 +53,6 @@ class SubchannelConnector : public InternallyRefCounted<SubchannelConnector> {
Transport* transport = nullptr;
// Channel args to be passed to filters.
ChannelArgs channel_args;
// Channelz socket node of the connected transport, if any.
RefCountedPtr<channelz::SocketNode> socket_node;
void Reset() {
if (transport != nullptr) {
@ -62,7 +60,6 @@ class SubchannelConnector : public InternallyRefCounted<SubchannelConnector> {
transport = nullptr;
}
channel_args = ChannelArgs();
socket_node.reset();
}
};

View File

@ -14,11 +14,11 @@
#include "src/core/client_channel/direct_channel.h"
#include "src/core/call/client_call.h"
#include "src/core/call/interception_chain.h"
#include "src/core/config/core_configuration.h"
#include "src/core/lib/event_engine/event_engine_context.h"
#include "src/core/lib/surface/channel_stack_type.h"
#include "src/core/lib/surface/client_call.h"
#include "src/core/lib/transport/interception_chain.h"
#include "src/core/util/orphanable.h"
namespace grpc_core {
@ -70,7 +70,7 @@ void DirectChannel::GetInfo(const grpc_channel_info*) {
grpc_call* DirectChannel::CreateCall(
grpc_call* parent_call, uint32_t propagation_mask,
grpc_completion_queue* cq, grpc_pollset_set* /*pollset_set_alternative*/,
Slice path, absl::optional<Slice> authority, Timestamp deadline,
Slice path, std::optional<Slice> authority, Timestamp deadline,
bool /*registered_method*/) {
auto arena = call_arena_allocator()->MakeArena();
arena->SetContext<grpc_event_engine::experimental::EventEngine>(

View File

@ -61,7 +61,7 @@ class DirectChannel final : public Channel {
grpc_call* CreateCall(grpc_call* parent_call, uint32_t propagation_mask,
grpc_completion_queue* cq,
grpc_pollset_set* pollset_set_alternative, Slice path,
absl::optional<Slice> authority, Timestamp deadline,
std::optional<Slice> authority, Timestamp deadline,
bool registered_method) override;
grpc_event_engine::experimental::EventEngine* event_engine() const override {
return event_engine_.get();

View File

@ -55,7 +55,6 @@ DynamicFilters::Call::Call(Args args, grpc_error_handle* error)
const grpc_call_element_args call_args = {
call_stack, // call_stack
nullptr, // server_transport_data
args.path, // path
args.start_time, // start_time
args.deadline, // deadline
args.arena, // arena

View File

@ -49,7 +49,6 @@ class DynamicFilters final : public RefCounted<DynamicFilters> {
struct Args {
RefCountedPtr<DynamicFilters> channel_stack;
grpc_polling_entity* pollent;
grpc_slice path;
gpr_cycle_counter start_time;
Timestamp deadline;
Arena* arena;

View File

@ -26,12 +26,13 @@
namespace grpc_core {
RefCountedPtr<GlobalSubchannelPool> GlobalSubchannelPool::instance() {
static GlobalSubchannelPool* p = new GlobalSubchannelPool();
return p->RefAsSubclass<GlobalSubchannelPool>();
RefCountedPtr<LegacyGlobalSubchannelPool>
LegacyGlobalSubchannelPool::instance() {
static LegacyGlobalSubchannelPool* p = new LegacyGlobalSubchannelPool();
return p->RefAsSubclass<LegacyGlobalSubchannelPool>();
}
RefCountedPtr<Subchannel> GlobalSubchannelPool::RegisterSubchannel(
RefCountedPtr<Subchannel> LegacyGlobalSubchannelPool::RegisterSubchannel(
const SubchannelKey& key, RefCountedPtr<Subchannel> constructed) {
MutexLock lock(&mu_);
auto it = subchannel_map_.find(key);
@ -43,8 +44,8 @@ RefCountedPtr<Subchannel> GlobalSubchannelPool::RegisterSubchannel(
return constructed;
}
void GlobalSubchannelPool::UnregisterSubchannel(const SubchannelKey& key,
Subchannel* subchannel) {
void LegacyGlobalSubchannelPool::UnregisterSubchannel(const SubchannelKey& key,
Subchannel* subchannel) {
MutexLock lock(&mu_);
auto it = subchannel_map_.find(key);
// delete only if key hasn't been re-registered to a different subchannel
@ -54,7 +55,7 @@ void GlobalSubchannelPool::UnregisterSubchannel(const SubchannelKey& key,
}
}
RefCountedPtr<Subchannel> GlobalSubchannelPool::FindSubchannel(
RefCountedPtr<Subchannel> LegacyGlobalSubchannelPool::FindSubchannel(
const SubchannelKey& key) {
MutexLock lock(&mu_);
auto it = subchannel_map_.find(key);
@ -62,4 +63,64 @@ RefCountedPtr<Subchannel> GlobalSubchannelPool::FindSubchannel(
return it->second->RefIfNonZero();
}
RefCountedPtr<GlobalSubchannelPool> GlobalSubchannelPool::instance() {
static GlobalSubchannelPool* p = new GlobalSubchannelPool();
return p->RefAsSubclass<GlobalSubchannelPool>();
}
RefCountedPtr<Subchannel> GlobalSubchannelPool::RegisterSubchannel(
const SubchannelKey& key, RefCountedPtr<Subchannel> constructed) {
auto shard_index = ShardIndex(key);
auto& write_shard = write_shards_[shard_index];
auto& read_shard = read_shards_[shard_index];
SubchannelMap old_map1;
SubchannelMap old_map2;
MutexLock lock(&write_shard.mu);
auto* existing = write_shard.map.Lookup(key);
if (existing != nullptr) return (*existing)->RefIfNonZero();
old_map1 = std::exchange(write_shard.map,
write_shard.map.Add(key, constructed->WeakRef()));
MutexLock lock_read(&read_shard.mu);
old_map2 = std::exchange(read_shard.map, write_shard.map);
return constructed;
}
void GlobalSubchannelPool::UnregisterSubchannel(const SubchannelKey& key,
Subchannel* subchannel) {
auto shard_index = ShardIndex(key);
auto& write_shard = write_shards_[shard_index];
auto& read_shard = read_shards_[shard_index];
SubchannelMap old_map1;
SubchannelMap old_map2;
MutexLock lock(&write_shard.mu);
auto* existing = write_shard.map.Lookup(key);
// delete only if key hasn't been re-registered to a different subchannel
// between strong-unreffing and unregistration of subchannel.
if (existing == nullptr || existing->get() != subchannel) return;
old_map1 = std::exchange(write_shard.map, write_shard.map.Remove(key));
MutexLock lock_read(&read_shard.mu);
old_map2 = std::exchange(read_shard.map, write_shard.map);
}
RefCountedPtr<Subchannel> GlobalSubchannelPool::FindSubchannel(
const SubchannelKey& key) {
auto shard_index = ShardIndex(key);
auto& read_shard = read_shards_[shard_index];
read_shard.mu.Lock();
auto map = read_shard.map;
read_shard.mu.Unlock();
auto* subchannel = map.Lookup(key);
if (subchannel == nullptr) return nullptr;
return (*subchannel)->RefIfNonZero();
}
size_t GlobalSubchannelPool::ShardIndex(const SubchannelKey& key) {
absl::string_view addr(key.address().addr, key.address().len);
return absl::HashOf(addr) % kShards;
}
GlobalSubchannelPool::GlobalSubchannelPool() = default;
GlobalSubchannelPool::~GlobalSubchannelPool() = default;
} // namespace grpc_core

View File

@ -32,10 +32,10 @@ namespace grpc_core {
// The global subchannel pool. It shares subchannels among channels. There
// should be only one instance of this class.
class GlobalSubchannelPool final : public SubchannelPoolInterface {
class LegacyGlobalSubchannelPool final : public SubchannelPoolInterface {
public:
// Gets the singleton instance.
static RefCountedPtr<GlobalSubchannelPool> instance();
static RefCountedPtr<LegacyGlobalSubchannelPool> instance();
// Implements interface methods.
RefCountedPtr<Subchannel> RegisterSubchannel(
@ -48,8 +48,8 @@ class GlobalSubchannelPool final : public SubchannelPoolInterface {
ABSL_LOCKS_EXCLUDED(mu_);
private:
GlobalSubchannelPool() {}
~GlobalSubchannelPool() override {}
LegacyGlobalSubchannelPool() {}
~LegacyGlobalSubchannelPool() override {}
// A map from subchannel key to subchannel.
std::map<SubchannelKey, Subchannel*> subchannel_map_ ABSL_GUARDED_BY(mu_);
@ -57,6 +57,39 @@ class GlobalSubchannelPool final : public SubchannelPoolInterface {
Mutex mu_;
};
// The global subchannel pool. It shares subchannels among channels. There
// should be only one instance of this class.
class GlobalSubchannelPool final : public SubchannelPoolInterface {
public:
// Gets the singleton instance.
static RefCountedPtr<GlobalSubchannelPool> instance();
// Implements interface methods.
RefCountedPtr<Subchannel> RegisterSubchannel(
const SubchannelKey& key, RefCountedPtr<Subchannel> constructed) override;
void UnregisterSubchannel(const SubchannelKey& key,
Subchannel* subchannel) override;
RefCountedPtr<Subchannel> FindSubchannel(const SubchannelKey& key) override;
private:
GlobalSubchannelPool();
~GlobalSubchannelPool() override;
static const size_t kShards = 127;
using SubchannelMap = AVL<SubchannelKey, WeakRefCountedPtr<Subchannel>>;
struct LockedMap {
Mutex mu;
SubchannelMap map ABSL_GUARDED_BY(mu);
};
using ShardedMap = std::array<LockedMap, kShards>;
static size_t ShardIndex(const SubchannelKey& key);
ShardedMap write_shards_;
ShardedMap read_shards_;
};
} // namespace grpc_core
#endif // GRPC_SRC_CORE_CLIENT_CHANNEL_GLOBAL_SUBCHANNEL_POOL_H

View File

@ -54,9 +54,9 @@ class Encoder {
} // namespace
absl::optional<absl::string_view> LbMetadata::Lookup(
absl::string_view key, std::string* buffer) const {
if (batch_ == nullptr) return absl::nullopt;
std::optional<absl::string_view> LbMetadata::Lookup(absl::string_view key,
std::string* buffer) const {
if (batch_ == nullptr) return std::nullopt;
return batch_->GetStringValue(key, buffer);
}
@ -75,10 +75,9 @@ LbMetadata::TestOnlyCopyToVector() const {
void MetadataMutationHandler::Apply(
LoadBalancingPolicy::MetadataMutations& metadata_mutations,
grpc_metadata_batch* metadata) {
for (auto& p : metadata_mutations.metadata_) {
absl::string_view key = p.first;
Slice& value =
grpc_event_engine::experimental::internal::SliceCast<Slice>(p.second);
for (auto& [key, value_slice] : metadata_mutations.metadata_) {
Slice& value = grpc_event_engine::experimental::internal::SliceCast<Slice>(
value_slice);
// TODO(roth): Should we prevent this from setting special keys like
// :authority, :path, content-type, etc?
metadata->Remove(key);
@ -92,7 +91,7 @@ void MetadataMutationHandler::Apply(
continue;
}
metadata->Append(key, std::move(value),
[key](absl::string_view error, const Slice& value) {
[key = key](absl::string_view error, const Slice& value) {
LOG(ERROR) << error << " key:" << key
<< " value:" << value.as_string_view();
});

View File

@ -17,12 +17,12 @@
#include <grpc/event_engine/slice.h>
#include <optional>
#include <string>
#include <vector>
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "src/core/lib/transport/metadata_batch.h"
#include "src/core/call/metadata_batch.h"
#include "src/core/load_balancing/lb_policy.h"
namespace grpc_core {
@ -31,8 +31,8 @@ class LbMetadata : public LoadBalancingPolicy::MetadataInterface {
public:
explicit LbMetadata(grpc_metadata_batch* batch) : batch_(batch) {}
absl::optional<absl::string_view> Lookup(absl::string_view key,
std::string* buffer) const override;
std::optional<absl::string_view> Lookup(absl::string_view key,
std::string* buffer) const override;
std::vector<std::pair<std::string, std::string>> TestOnlyCopyToVector() const;

View File

@ -15,12 +15,12 @@
#include "src/core/client_channel/load_balanced_call_destination.h"
#include "absl/log/log.h"
#include "src/core/call/status_util.h"
#include "src/core/client_channel/client_channel.h"
#include "src/core/client_channel/client_channel_internal.h"
#include "src/core/client_channel/lb_metadata.h"
#include "src/core/client_channel/subchannel.h"
#include "src/core/config/core_configuration.h"
#include "src/core/lib/channel/status_util.h"
#include "src/core/lib/promise/loop.h"
#include "src/core/telemetry/call_tracer.h"
@ -62,22 +62,22 @@ T HandlePickResult(
std::function<T(LoadBalancingPolicy::PickResult::Fail*)> fail_func,
std::function<T(LoadBalancingPolicy::PickResult::Drop*)> drop_func) {
auto* complete_pick =
absl::get_if<LoadBalancingPolicy::PickResult::Complete>(&result->result);
std::get_if<LoadBalancingPolicy::PickResult::Complete>(&result->result);
if (complete_pick != nullptr) {
return complete_func(complete_pick);
}
auto* queue_pick =
absl::get_if<LoadBalancingPolicy::PickResult::Queue>(&result->result);
std::get_if<LoadBalancingPolicy::PickResult::Queue>(&result->result);
if (queue_pick != nullptr) {
return queue_func(queue_pick);
}
auto* fail_pick =
absl::get_if<LoadBalancingPolicy::PickResult::Fail>(&result->result);
std::get_if<LoadBalancingPolicy::PickResult::Fail>(&result->result);
if (fail_pick != nullptr) {
return fail_func(fail_pick);
}
auto* drop_pick =
absl::get_if<LoadBalancingPolicy::PickResult::Drop>(&result->result);
std::get_if<LoadBalancingPolicy::PickResult::Drop>(&result->result);
CHECK(drop_pick != nullptr);
return drop_func(drop_pick);
}

View File

@ -16,9 +16,9 @@
#define GRPC_SRC_CORE_CLIENT_CHANNEL_LOAD_BALANCED_CALL_DESTINATION_H
#include "absl/functional/any_invocable.h"
#include "src/core/call/call_destination.h"
#include "src/core/client_channel/client_channel.h"
#include "src/core/lib/promise/context.h"
#include "src/core/lib/transport/call_destination.h"
#include "src/core/load_balancing/lb_policy.h"
namespace grpc_core {

View File

@ -19,11 +19,11 @@
#include <grpc/event_engine/event_engine.h>
#include <grpc/support/port_platform.h>
#include <optional>
#include <string>
#include "absl/status/statusor.h"
#include "absl/strings/strip.h"
#include "absl/types/optional.h"
#include "src/core/client_channel/client_channel_filter.h"
#include "src/core/client_channel/retry_filter_legacy_call_data.h"
#include "src/core/client_channel/retry_service_config.h"

View File

@ -25,9 +25,9 @@
#include <stddef.h>
#include <new>
#include <optional>
#include "absl/log/check.h"
#include "absl/types/optional.h"
#include "src/core/client_channel/client_channel_filter.h"
#include "src/core/client_channel/retry_service_config.h"
#include "src/core/client_channel/retry_throttle.h"

View File

@ -24,11 +24,12 @@
#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/strings/str_cat.h"
#include "src/core/call/metadata_batch.h"
#include "src/core/call/status_util.h"
#include "src/core/client_channel/client_channel_internal.h"
#include "src/core/client_channel/retry_service_config.h"
#include "src/core/client_channel/retry_throttle.h"
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/channel/status_util.h"
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/iomgr/call_combiner.h"
#include "src/core/lib/iomgr/closure.h"
@ -39,7 +40,6 @@
#include "src/core/lib/slice/slice.h"
#include "src/core/lib/slice/slice_buffer.h"
#include "src/core/lib/transport/error_utils.h"
#include "src/core/lib/transport/metadata_batch.h"
#include "src/core/lib/transport/transport.h"
#include "src/core/util/backoff.h"
#include "src/core/util/construct_destruct.h"
@ -53,6 +53,8 @@
namespace grpc_core {
using TaskHandle = grpc_event_engine::experimental::EventEngine::TaskHandle;
//
// RetryFilter::LegacyCallData::CallStackDestructionBarrier
//
@ -154,7 +156,6 @@ RetryFilter::LegacyCallData::CallAttempt::CallAttempt(
Ref(DEBUG_LOCATION, "OnPerAttemptRecvTimer").release();
per_attempt_recv_timer_handle_ = calld_->chand_->event_engine()->RunAfter(
per_attempt_recv_timeout, [this] {
ApplicationCallbackExecCtx callback_exec_ctx;
ExecCtx exec_ctx;
OnPerAttemptRecvTimer();
});
@ -221,7 +222,7 @@ void RetryFilter::LegacyCallData::CallAttempt::MaybeSwitchToFastPath() {
// If we've already switched to fast path, there's nothing to do here.
if (calld_->committed_call_ != nullptr) return;
// If the perAttemptRecvTimeout timer is pending, we can't switch yet.
if (per_attempt_recv_timer_handle_.has_value()) return;
if (per_attempt_recv_timer_handle_ != TaskHandle::kInvalid) return;
// If there are still send ops to replay, we can't switch yet.
if (HaveSendOpsToReplay()) return;
// If we started an internal batch for recv_trailing_metadata but have not
@ -529,8 +530,8 @@ void RetryFilter::LegacyCallData::CallAttempt::CancelFromSurface(
}
bool RetryFilter::LegacyCallData::CallAttempt::ShouldRetry(
absl::optional<grpc_status_code> status,
absl::optional<Duration> server_pushback) {
std::optional<grpc_status_code> status,
std::optional<Duration> server_pushback) {
// If no retry policy, don't retry.
if (calld_->retry_policy_ == nullptr) return false;
// Check status.
@ -644,31 +645,33 @@ void RetryFilter::LegacyCallData::CallAttempt::OnPerAttemptRecvTimerLocked(
<< "chand=" << calld->chand_ << " calld=" << calld
<< " attempt=" << call_attempt
<< ": perAttemptRecvTimeout timer fired: error=" << StatusToString(error)
<< ", per_attempt_recv_timer_handle_.has_value()="
<< call_attempt->per_attempt_recv_timer_handle_.has_value();
<< ", per_attempt_recv_timer_handle_ is valid ="
<< (call_attempt->per_attempt_recv_timer_handle_ != TaskHandle::kInvalid);
CallCombinerClosureList closures;
call_attempt->per_attempt_recv_timer_handle_.reset();
// Cancel this attempt.
// TODO(roth): When implementing hedging, we should not cancel the
// current attempt.
call_attempt->MaybeAddBatchForCancelOp(
grpc_error_set_int(
GRPC_ERROR_CREATE("retry perAttemptRecvTimeout exceeded"),
StatusIntProperty::kRpcStatus, GRPC_STATUS_CANCELLED),
&closures);
// Check whether we should retry.
if (call_attempt->ShouldRetry(/*status=*/absl::nullopt,
/*server_pushback_ms=*/absl::nullopt)) {
// Mark current attempt as abandoned.
call_attempt->Abandon();
// We are retrying. Start backoff timer.
calld->StartRetryTimer(/*server_pushback=*/absl::nullopt);
} else {
// Not retrying, so commit the call.
calld->RetryCommit(call_attempt);
// If retry state is no longer needed, switch to fast path for
// subsequent batches.
call_attempt->MaybeSwitchToFastPath();
if (call_attempt->per_attempt_recv_timer_handle_ != TaskHandle::kInvalid) {
call_attempt->per_attempt_recv_timer_handle_ = TaskHandle::kInvalid;
// Cancel this attempt.
// TODO(roth): When implementing hedging, we should not cancel the
// current attempt.
call_attempt->MaybeAddBatchForCancelOp(
grpc_error_set_int(
GRPC_ERROR_CREATE("retry perAttemptRecvTimeout exceeded"),
StatusIntProperty::kRpcStatus, GRPC_STATUS_CANCELLED),
&closures);
// Check whether we should retry.
if (call_attempt->ShouldRetry(/*status=*/std::nullopt,
/*server_pushback_ms=*/std::nullopt)) {
// Mark current attempt as abandoned.
call_attempt->Abandon();
// We are retrying. Start backoff timer.
calld->StartRetryTimer(/*server_pushback=*/std::nullopt);
} else {
// Not retrying, so commit the call.
calld->RetryCommit(call_attempt);
// If retry state is no longer needed, switch to fast path for
// subsequent batches.
call_attempt->MaybeSwitchToFastPath();
}
}
closures.RunClosures(calld->call_combiner_);
call_attempt->Unref(DEBUG_LOCATION, "OnPerAttemptRecvTimer");
@ -677,16 +680,16 @@ void RetryFilter::LegacyCallData::CallAttempt::OnPerAttemptRecvTimerLocked(
void RetryFilter::LegacyCallData::CallAttempt::
MaybeCancelPerAttemptRecvTimer() {
if (per_attempt_recv_timer_handle_.has_value()) {
if (per_attempt_recv_timer_handle_ != TaskHandle::kInvalid) {
GRPC_TRACE_LOG(retry, INFO)
<< "chand=" << calld_->chand_ << " calld=" << calld_
<< " attempt=" << this << ": cancelling perAttemptRecvTimeout timer";
if (calld_->chand_->event_engine()->Cancel(
*per_attempt_recv_timer_handle_)) {
per_attempt_recv_timer_handle_)) {
Unref(DEBUG_LOCATION, "OnPerAttemptRecvTimer");
GRPC_CALL_STACK_UNREF(calld_->owning_call_, "OnPerAttemptRecvTimer");
}
per_attempt_recv_timer_handle_.reset();
per_attempt_recv_timer_handle_ = TaskHandle::kInvalid;
}
}
@ -953,9 +956,9 @@ namespace {
// and error.
void GetCallStatus(
Timestamp deadline, grpc_metadata_batch* md_batch, grpc_error_handle error,
grpc_status_code* status, absl::optional<Duration>* server_pushback,
grpc_status_code* status, std::optional<Duration>* server_pushback,
bool* is_lb_drop,
absl::optional<GrpcStreamNetworkState::ValueType>* stream_network_state) {
std::optional<GrpcStreamNetworkState::ValueType>* stream_network_state) {
if (!error.ok()) {
grpc_error_get_status(error, deadline, status, nullptr, nullptr, nullptr);
intptr_t value = 0;
@ -1092,9 +1095,9 @@ void RetryFilter::LegacyCallData::CallAttempt::BatchData::
call_attempt->MaybeCancelPerAttemptRecvTimer();
// Get the call's status and check for server pushback metadata.
grpc_status_code status = GRPC_STATUS_OK;
absl::optional<Duration> server_pushback;
std::optional<Duration> server_pushback;
bool is_lb_drop = false;
absl::optional<GrpcStreamNetworkState::ValueType> stream_network_state;
std::optional<GrpcStreamNetworkState::ValueType> stream_network_state;
grpc_metadata_batch* md_batch =
batch_data->batch_.payload->recv_trailing_metadata.recv_trailing_metadata;
GetCallStatus(calld->deadline_, md_batch, error, &status, &server_pushback,
@ -1482,7 +1485,6 @@ RetryFilter::LegacyCallData::LegacyCallData(RetryFilter* chand,
.set_max_backoff(retry_policy_ == nullptr
? Duration::Zero()
: retry_policy_->max_backoff())),
path_(CSliceRef(args.path)),
deadline_(args.deadline),
arena_(args.arena),
owning_call_(args.call_stack),
@ -1498,7 +1500,6 @@ RetryFilter::LegacyCallData::LegacyCallData(RetryFilter* chand,
RetryFilter::LegacyCallData::~LegacyCallData() {
FreeAllCachedSendOpData();
CSliceUnref(path_);
// Make sure there are no remaining pending batches.
for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches_); ++i) {
CHECK_EQ(pending_batches_[i].batch, nullptr);
@ -1551,13 +1552,13 @@ void RetryFilter::LegacyCallData::StartTransportStreamOpBatch(
return;
}
// Cancel retry timer if needed.
if (retry_timer_handle_.has_value()) {
if (retry_timer_handle_ != TaskHandle::kInvalid) {
GRPC_TRACE_LOG(retry, INFO) << "chand=" << chand_ << " calld=" << this
<< ": cancelling retry timer";
if (chand_->event_engine()->Cancel(*retry_timer_handle_)) {
if (chand_->event_engine()->Cancel(retry_timer_handle_)) {
GRPC_CALL_STACK_UNREF(owning_call_, "OnRetryTimer");
}
retry_timer_handle_.reset();
retry_timer_handle_ = TaskHandle::kInvalid;
FreeAllCachedSendOpData();
}
// We have no call attempt, so there's nowhere to send the cancellation
@ -1571,7 +1572,7 @@ void RetryFilter::LegacyCallData::StartTransportStreamOpBatch(
PendingBatch* pending = PendingBatchesAdd(batch);
// If the timer is pending, yield the call combiner and wait for it to
// run, since we don't want to start another call attempt until it does.
if (retry_timer_handle_.has_value()) {
if (retry_timer_handle_ != TaskHandle::kInvalid) {
GRPC_CALL_COMBINER_STOP(call_combiner_,
"added pending batch while retry timer pending");
return;
@ -1628,9 +1629,9 @@ void RetryFilter::LegacyCallData::StartTransportStreamOpBatch(
OrphanablePtr<ClientChannelFilter::FilterBasedLoadBalancedCall>
RetryFilter::LegacyCallData::CreateLoadBalancedCall(
absl::AnyInvocable<void()> on_commit, bool is_transparent_retry) {
grpc_call_element_args args = {owning_call_, nullptr, path_,
/*start_time=*/0, deadline_, arena_,
call_combiner_};
grpc_call_element_args args = {owning_call_, nullptr,
/*start_time=*/0, deadline_,
arena_, call_combiner_};
return chand_->client_channel()->CreateLoadBalancedCall(
args, pollent_,
// This callback holds a ref to the CallStackDestructionBarrier
@ -1880,7 +1881,7 @@ void RetryFilter::LegacyCallData::RetryCommit(CallAttempt* call_attempt) {
}
void RetryFilter::LegacyCallData::StartRetryTimer(
absl::optional<Duration> server_pushback) {
std::optional<Duration> server_pushback) {
// Reset call attempt.
call_attempt_.reset(DEBUG_LOCATION, "StartRetryTimer");
// Compute backoff delay.
@ -1899,7 +1900,6 @@ void RetryFilter::LegacyCallData::StartRetryTimer(
GRPC_CALL_STACK_REF(owning_call_, "OnRetryTimer");
retry_timer_handle_ =
chand_->event_engine()->RunAfter(next_attempt_timeout, [this] {
ApplicationCallbackExecCtx callback_exec_ctx;
ExecCtx exec_ctx;
OnRetryTimer();
});
@ -1914,8 +1914,8 @@ void RetryFilter::LegacyCallData::OnRetryTimer() {
void RetryFilter::LegacyCallData::OnRetryTimerLocked(
void* arg, grpc_error_handle /*error*/) {
auto* calld = static_cast<RetryFilter::LegacyCallData*>(arg);
if (calld->retry_timer_handle_.has_value()) {
calld->retry_timer_handle_.reset();
if (calld->retry_timer_handle_ != TaskHandle::kInvalid) {
calld->retry_timer_handle_ = TaskHandle::kInvalid;
calld->CreateCallAttempt(/*is_transparent_retry=*/false);
}
GRPC_CALL_STACK_UNREF(calld->owning_call_, "OnRetryTimer");

View File

@ -22,11 +22,12 @@
#include <stddef.h>
#include <stdint.h>
#include <optional>
#include <utility>
#include "absl/container/inlined_vector.h"
#include "absl/functional/any_invocable.h"
#include "absl/types/optional.h"
#include "src/core/call/metadata_batch.h"
#include "src/core/client_channel/client_channel_filter.h"
#include "src/core/client_channel/retry_filter.h"
#include "src/core/client_channel/retry_service_config.h"
@ -39,7 +40,6 @@
#include "src/core/lib/iomgr/polling_entity.h"
#include "src/core/lib/resource_quota/arena.h"
#include "src/core/lib/slice/slice_buffer.h"
#include "src/core/lib/transport/metadata_batch.h"
#include "src/core/lib/transport/transport.h"
#include "src/core/util/backoff.h"
#include "src/core/util/debug_location.h"
@ -241,8 +241,8 @@ class RetryFilter::LegacyCallData final {
void MaybeSwitchToFastPath();
// Returns true if the call should be retried.
bool ShouldRetry(absl::optional<grpc_status_code> status,
absl::optional<Duration> server_pushback_ms);
bool ShouldRetry(std::optional<grpc_status_code> status,
std::optional<Duration> server_pushback_ms);
// Abandons the call attempt. Unrefs any deferred batches.
void Abandon();
@ -256,8 +256,9 @@ class RetryFilter::LegacyCallData final {
bool lb_call_committed_ = false;
grpc_closure on_per_attempt_recv_timer_;
absl::optional<grpc_event_engine::experimental::EventEngine::TaskHandle>
per_attempt_recv_timer_handle_;
grpc_event_engine::experimental::EventEngine::TaskHandle
per_attempt_recv_timer_handle_ =
grpc_event_engine::experimental::EventEngine::TaskHandle::kInvalid;
// BatchData.batch.payload points to this.
grpc_transport_stream_op_batch_payload batch_payload_;
@ -273,7 +274,7 @@ class RetryFilter::LegacyCallData final {
bool trailing_metadata_available_ = false;
// For intercepting recv_message.
grpc_closure recv_message_ready_;
absl::optional<SliceBuffer> recv_message_;
std::optional<SliceBuffer> recv_message_;
uint32_t recv_message_flags_;
// For intercepting recv_trailing_metadata.
grpc_metadata_batch recv_trailing_metadata_;
@ -352,7 +353,7 @@ class RetryFilter::LegacyCallData final {
// Starts a timer to retry after appropriate back-off.
// If server_pushback is nullopt, retry_backoff_ is used.
void StartRetryTimer(absl::optional<Duration> server_pushback);
void StartRetryTimer(std::optional<Duration> server_pushback);
void OnRetryTimer();
static void OnRetryTimerLocked(void* arg, grpc_error_handle /*error*/);
@ -373,7 +374,6 @@ class RetryFilter::LegacyCallData final {
const internal::RetryMethodConfig* retry_policy_ = nullptr;
BackOff retry_backoff_;
grpc_slice path_; // Request path.
Timestamp deadline_;
Arena* arena_;
grpc_call_stack* owning_call_;
@ -410,8 +410,8 @@ class RetryFilter::LegacyCallData final {
bool retry_codepath_started_ : 1;
bool sent_transparent_retry_not_seen_by_server_ : 1;
int num_attempts_completed_ = 0;
absl::optional<grpc_event_engine::experimental::EventEngine::TaskHandle>
retry_timer_handle_;
grpc_event_engine::experimental::EventEngine::TaskHandle retry_timer_handle_ =
grpc_event_engine::experimental::EventEngine::TaskHandle::kInvalid;
grpc_closure retry_closure_;
// Cached data for retrying send ops.

View File

@ -55,14 +55,14 @@ RetryState::RetryState(
? Duration::Zero()
: retry_policy_->max_backoff())) {}
absl::optional<Duration> RetryState::ShouldRetry(
std::optional<Duration> RetryState::ShouldRetry(
const ServerMetadata& md, bool committed,
absl::FunctionRef<std::string()> lazy_attempt_debug_string) {
// If no retry policy, don't retry.
if (retry_policy_ == nullptr) {
GRPC_TRACE_LOG(retry, INFO)
<< lazy_attempt_debug_string() << " no retry policy";
return absl::nullopt;
return std::nullopt;
}
const auto status = md.get(GrpcStatusMetadata());
if (status.has_value()) {
@ -72,14 +72,14 @@ absl::optional<Duration> RetryState::ShouldRetry(
}
GRPC_TRACE_LOG(retry, INFO)
<< lazy_attempt_debug_string() << " call succeeded";
return absl::nullopt;
return std::nullopt;
}
// Status is not OK. Check whether the status is retryable.
if (!retry_policy_->retryable_status_codes().Contains(*status)) {
GRPC_TRACE_LOG(retry, INFO) << lazy_attempt_debug_string() << ": status "
<< grpc_status_code_to_string(*status)
<< " not configured as retryable";
return absl::nullopt;
return std::nullopt;
}
}
// Record the failure and check whether retries are throttled.
@ -93,13 +93,13 @@ absl::optional<Duration> RetryState::ShouldRetry(
!retry_throttle_data_->RecordFailure()) {
GRPC_TRACE_LOG(retry, INFO)
<< lazy_attempt_debug_string() << " retries throttled";
return absl::nullopt;
return std::nullopt;
}
// Check whether the call is committed.
if (committed) {
GRPC_TRACE_LOG(retry, INFO)
<< lazy_attempt_debug_string() << " retries already committed";
return absl::nullopt;
return std::nullopt;
}
// Check whether we have retries remaining.
++num_attempts_completed_;
@ -107,14 +107,14 @@ absl::optional<Duration> RetryState::ShouldRetry(
GRPC_TRACE_LOG(retry, INFO)
<< lazy_attempt_debug_string() << " exceeded "
<< retry_policy_->max_attempts() << " retry attempts";
return absl::nullopt;
return std::nullopt;
}
// Check server push-back.
const auto server_pushback = md.get(GrpcRetryPushbackMsMetadata());
if (server_pushback.has_value() && server_pushback < Duration::Zero()) {
GRPC_TRACE_LOG(retry, INFO) << lazy_attempt_debug_string()
<< " not retrying due to server push-back";
return absl::nullopt;
return std::nullopt;
}
// We should retry.
Duration next_attempt_timeout;
@ -298,8 +298,9 @@ auto RetryInterceptor::Attempt::ServerToClientGotInitialMetadata(
GRPC_TRACE_LOG(retry, INFO)
<< call->DebugTag() << " got server message "
<< message->DebugString();
return call->call_handler()->SpawnPushMessage(
call->call_handler()->SpawnPushMessage(
std::move(message));
return Success{};
}),
initiator_.PullServerTrailingMetadata(),
[call = call_](ServerMetadataHandle md) {
@ -346,7 +347,7 @@ auto RetryInterceptor::Attempt::ServerToClientGotTrailersOnlyResponse() {
auto RetryInterceptor::Attempt::ServerToClient() {
return TrySeq(
initiator_.PullServerInitialMetadata(),
[self = Ref()](absl::optional<ServerMetadataHandle> metadata) {
[self = Ref()](std::optional<ServerMetadataHandle> metadata) {
const bool has_md = metadata.has_value();
return If(
has_md,
@ -385,10 +386,11 @@ auto RetryInterceptor::Attempt::ClientToServer() {
self->call_->call_handler()->AddChildCall(self->initiator_);
self->initiator_.SpawnGuarded(
"server_to_client", [self]() { return self->ServerToClient(); });
return ForEach(
MessagesFrom(&self->reader_), [self](MessageHandle message) {
return self->initiator_.SpawnPushMessage(std::move(message));
});
return ForEach(MessagesFrom(&self->reader_),
[self](MessageHandle message) {
self->initiator_.SpawnPushMessage(std::move(message));
return Success{};
});
});
}

Some files were not shown because too many files have changed in this diff Show More