diff --git a/BUILD b/BUILD index daff7f0d857..136396788ec 100644 --- a/BUILD +++ b/BUILD @@ -1789,6 +1789,7 @@ grpc_cc_library( "//src/core:connectivity_state", "//src/core:iomgr_fwd", "//src/core:ref_counted", + "//src/core:resource_quota", "//src/core:slice", "//src/core:stats_data", "//src/core:time", @@ -1866,6 +1867,7 @@ grpc_cc_library( "config", "gpr", "grpc_base", + "grpc_client_channel", "grpc_public_hdrs", "legacy_channel", "ref_counted_ptr", @@ -1873,6 +1875,7 @@ grpc_cc_library( "//src/core:arena", "//src/core:channel_args", "//src/core:channel_stack_type", + "//src/core:experiments", "//src/core:iomgr_fwd", "//src/core:ref_counted", "//src/core:slice", @@ -3637,6 +3640,7 @@ grpc_cc_library( grpc_cc_library( name = "grpc_client_channel", srcs = [ + "//src/core:client_channel/client_channel.cc", "//src/core:client_channel/client_channel_factory.cc", "//src/core:client_channel/client_channel_filter.cc", "//src/core:client_channel/client_channel_plugin.cc", @@ -3649,6 +3653,7 @@ grpc_cc_library( "//src/core:client_channel/subchannel_stream_client.cc", ], hdrs = [ + "//src/core:client_channel/client_channel.h", "//src/core:client_channel/client_channel_factory.h", "//src/core:client_channel/client_channel_filter.h", "//src/core:client_channel/dynamic_filters.h", @@ -3684,6 +3689,7 @@ grpc_cc_library( "backoff", "call_combiner", "call_tracer", + "channel", "channel_arg_names", "channelz", "config", @@ -3718,6 +3724,8 @@ grpc_cc_library( "//src/core:arena", "//src/core:arena_promise", "//src/core:backend_metric_parser", + "//src/core:call_filters", + "//src/core:call_spine", "//src/core:cancel_callback", "//src/core:channel_args", "//src/core:channel_fwd", @@ -3736,12 +3744,15 @@ grpc_cc_library( "//src/core:env", "//src/core:error", "//src/core:error_utils", + "//src/core:exec_ctx_wakeup_scheduler", "//src/core:experiments", "//src/core:gpr_atm", "//src/core:gpr_manual_constructor", "//src/core:grpc_backend_metric_data", + "//src/core:grpc_channel_idle_filter", "//src/core:grpc_message_size_filter", "//src/core:grpc_service_config", + "//src/core:idle_filter_state", "//src/core:init_internally", "//src/core:iomgr_fwd", "//src/core:json", @@ -3751,9 +3762,13 @@ grpc_cc_library( "//src/core:latch", "//src/core:lb_policy", "//src/core:lb_policy_registry", + "//src/core:loop", "//src/core:map", "//src/core:memory_quota", + "//src/core:metadata", "//src/core:metadata_batch", + "//src/core:metrics", + "//src/core:observable", "//src/core:pipe", "//src/core:poll", "//src/core:pollset_set", @@ -3766,10 +3781,13 @@ grpc_cc_library( "//src/core:retry_throttle", "//src/core:seq", "//src/core:service_config_parser", + "//src/core:single_set_ptr", + "//src/core:sleep", "//src/core:slice", "//src/core:slice_buffer", "//src/core:slice_refcount", "//src/core:stats_data", + "//src/core:status_flag", "//src/core:status_helper", "//src/core:subchannel_connector", "//src/core:subchannel_interface", diff --git a/CMakeLists.txt b/CMakeLists.txt index 23a19b19cdb..355823877fb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1829,6 +1829,7 @@ add_library(grpc src/core/channelz/channelz.cc src/core/channelz/channelz_registry.cc src/core/client_channel/backup_poller.cc + src/core/client_channel/client_channel.cc src/core/client_channel/client_channel_factory.cc src/core/client_channel/client_channel_filter.cc src/core/client_channel/client_channel_plugin.cc @@ -2925,6 +2926,7 @@ add_library(grpc_unsecure src/core/channelz/channelz.cc src/core/channelz/channelz_registry.cc src/core/client_channel/backup_poller.cc + src/core/client_channel/client_channel.cc src/core/client_channel/client_channel_factory.cc src/core/client_channel/client_channel_filter.cc src/core/client_channel/client_channel_plugin.cc diff --git a/Makefile b/Makefile index b8cbbb15fb6..144ce2d092e 100644 --- a/Makefile +++ b/Makefile @@ -670,6 +670,7 @@ LIBGRPC_SRC = \ src/core/channelz/channelz.cc \ src/core/channelz/channelz_registry.cc \ src/core/client_channel/backup_poller.cc \ + src/core/client_channel/client_channel.cc \ src/core/client_channel/client_channel_factory.cc \ src/core/client_channel/client_channel_filter.cc \ src/core/client_channel/client_channel_plugin.cc \ diff --git a/Package.swift b/Package.swift index 3452fbf6736..4c37f83205b 100644 --- a/Package.swift +++ b/Package.swift @@ -125,6 +125,8 @@ let package = Package( "src/core/channelz/channelz_registry.h", "src/core/client_channel/backup_poller.cc", "src/core/client_channel/backup_poller.h", + "src/core/client_channel/client_channel.cc", + "src/core/client_channel/client_channel.h", "src/core/client_channel/client_channel_factory.cc", "src/core/client_channel/client_channel_factory.h", "src/core/client_channel/client_channel_filter.cc", @@ -1541,6 +1543,7 @@ let package = Package( "src/core/lib/promise/latch.h", "src/core/lib/promise/loop.h", "src/core/lib/promise/map.h", + "src/core/lib/promise/observable.h", "src/core/lib/promise/party.cc", "src/core/lib/promise/party.h", "src/core/lib/promise/pipe.h", diff --git a/bazel/experiments.bzl b/bazel/experiments.bzl index f45d505b2ce..0cd7f66dbce 100644 --- a/bazel/experiments.bzl +++ b/bazel/experiments.bzl @@ -18,7 +18,6 @@ EXPERIMENT_ENABLES = { "call_status_override_on_cancellation": "call_status_override_on_cancellation", - "call_v3": "call_v3", "canary_client_privacy": "canary_client_privacy", "client_privacy": "client_privacy", "event_engine_client": "event_engine_client", @@ -44,6 +43,8 @@ EXPERIMENT_ENABLES = { "unconstrained_max_quota_buffer_size": "unconstrained_max_quota_buffer_size", "work_serializer_clears_time_cache": "work_serializer_clears_time_cache", "work_serializer_dispatch": "event_engine_client,work_serializer_dispatch", + "call_v3": "call_v3,event_engine_client,event_engine_listener,work_serializer_dispatch", + "wrr_delegate_to_pick_first": "wrr_delegate_to_pick_first", } EXPERIMENT_POLLERS = [ diff --git a/build_autogenerated.yaml b/build_autogenerated.yaml index d5045c64ebc..8138997d4d0 100644 --- a/build_autogenerated.yaml +++ b/build_autogenerated.yaml @@ -226,6 +226,7 @@ libs: - src/core/channelz/channelz.h - src/core/channelz/channelz_registry.h - src/core/client_channel/backup_poller.h + - src/core/client_channel/client_channel.h - src/core/client_channel/client_channel_factory.h - src/core/client_channel/client_channel_filter.h - src/core/client_channel/client_channel_internal.h @@ -1008,6 +1009,7 @@ libs: - src/core/lib/promise/latch.h - src/core/lib/promise/loop.h - src/core/lib/promise/map.h + - src/core/lib/promise/observable.h - src/core/lib/promise/party.h - src/core/lib/promise/pipe.h - src/core/lib/promise/poll.h @@ -1250,6 +1252,7 @@ libs: - src/core/channelz/channelz.cc - src/core/channelz/channelz_registry.cc - src/core/client_channel/backup_poller.cc + - src/core/client_channel/client_channel.cc - src/core/client_channel/client_channel_factory.cc - src/core/client_channel/client_channel_filter.cc - src/core/client_channel/client_channel_plugin.cc @@ -2213,6 +2216,7 @@ libs: - src/core/channelz/channelz.h - src/core/channelz/channelz_registry.h - src/core/client_channel/backup_poller.h + - src/core/client_channel/client_channel.h - src/core/client_channel/client_channel_factory.h - src/core/client_channel/client_channel_filter.h - src/core/client_channel/client_channel_internal.h @@ -2540,6 +2544,7 @@ libs: - src/core/lib/promise/latch.h - src/core/lib/promise/loop.h - src/core/lib/promise/map.h + - src/core/lib/promise/observable.h - src/core/lib/promise/party.h - src/core/lib/promise/pipe.h - src/core/lib/promise/poll.h @@ -2706,6 +2711,7 @@ libs: - src/core/channelz/channelz.cc - src/core/channelz/channelz_registry.cc - src/core/client_channel/backup_poller.cc + - src/core/client_channel/client_channel.cc - src/core/client_channel/client_channel_factory.cc - src/core/client_channel/client_channel_filter.cc - src/core/client_channel/client_channel_plugin.cc diff --git a/config.m4 b/config.m4 index 4b72ff9577e..b0049612b2d 100644 --- a/config.m4 +++ b/config.m4 @@ -45,6 +45,7 @@ if test "$PHP_GRPC" != "no"; then src/core/channelz/channelz.cc \ src/core/channelz/channelz_registry.cc \ src/core/client_channel/backup_poller.cc \ + src/core/client_channel/client_channel.cc \ src/core/client_channel/client_channel_factory.cc \ src/core/client_channel/client_channel_filter.cc \ src/core/client_channel/client_channel_plugin.cc \ diff --git a/config.w32 b/config.w32 index f71331b6d7d..bc584e5434e 100644 --- a/config.w32 +++ b/config.w32 @@ -10,6 +10,7 @@ if (PHP_GRPC != "no") { "src\\core\\channelz\\channelz.cc " + "src\\core\\channelz\\channelz_registry.cc " + "src\\core\\client_channel\\backup_poller.cc " + + "src\\core\\client_channel\\client_channel.cc " + "src\\core\\client_channel\\client_channel_factory.cc " + "src\\core\\client_channel\\client_channel_filter.cc " + "src\\core\\client_channel\\client_channel_plugin.cc " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index cb31ce8929d..cdfe26d4865 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -267,6 +267,7 @@ Pod::Spec.new do |s| 'src/core/channelz/channelz.h', 'src/core/channelz/channelz_registry.h', 'src/core/client_channel/backup_poller.h', + 'src/core/client_channel/client_channel.h', 'src/core/client_channel/client_channel_factory.h', 'src/core/client_channel/client_channel_filter.h', 'src/core/client_channel/client_channel_internal.h', @@ -1111,6 +1112,7 @@ Pod::Spec.new do |s| 'src/core/lib/promise/latch.h', 'src/core/lib/promise/loop.h', 'src/core/lib/promise/map.h', + 'src/core/lib/promise/observable.h', 'src/core/lib/promise/party.h', 'src/core/lib/promise/pipe.h', 'src/core/lib/promise/poll.h', @@ -1556,6 +1558,7 @@ Pod::Spec.new do |s| 'src/core/channelz/channelz.h', 'src/core/channelz/channelz_registry.h', 'src/core/client_channel/backup_poller.h', + 'src/core/client_channel/client_channel.h', 'src/core/client_channel/client_channel_factory.h', 'src/core/client_channel/client_channel_filter.h', 'src/core/client_channel/client_channel_internal.h', @@ -2382,6 +2385,7 @@ Pod::Spec.new do |s| 'src/core/lib/promise/latch.h', 'src/core/lib/promise/loop.h', 'src/core/lib/promise/map.h', + 'src/core/lib/promise/observable.h', 'src/core/lib/promise/party.h', 'src/core/lib/promise/pipe.h', 'src/core/lib/promise/poll.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index e70fc2d7894..2a2cc1d465c 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -244,6 +244,8 @@ Pod::Spec.new do |s| 'src/core/channelz/channelz_registry.h', 'src/core/client_channel/backup_poller.cc', 'src/core/client_channel/backup_poller.h', + 'src/core/client_channel/client_channel.cc', + 'src/core/client_channel/client_channel.h', 'src/core/client_channel/client_channel_factory.cc', 'src/core/client_channel/client_channel_factory.h', 'src/core/client_channel/client_channel_filter.cc', @@ -1660,6 +1662,7 @@ Pod::Spec.new do |s| 'src/core/lib/promise/latch.h', 'src/core/lib/promise/loop.h', 'src/core/lib/promise/map.h', + 'src/core/lib/promise/observable.h', 'src/core/lib/promise/party.cc', 'src/core/lib/promise/party.h', 'src/core/lib/promise/pipe.h', @@ -2356,6 +2359,7 @@ Pod::Spec.new do |s| 'src/core/channelz/channelz.h', 'src/core/channelz/channelz_registry.h', 'src/core/client_channel/backup_poller.h', + 'src/core/client_channel/client_channel.h', 'src/core/client_channel/client_channel_factory.h', 'src/core/client_channel/client_channel_filter.h', 'src/core/client_channel/client_channel_internal.h', @@ -3162,6 +3166,7 @@ Pod::Spec.new do |s| 'src/core/lib/promise/latch.h', 'src/core/lib/promise/loop.h', 'src/core/lib/promise/map.h', + 'src/core/lib/promise/observable.h', 'src/core/lib/promise/party.h', 'src/core/lib/promise/pipe.h', 'src/core/lib/promise/poll.h', diff --git a/grpc.gemspec b/grpc.gemspec index 4ea7d9088d6..8c717042702 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -131,6 +131,8 @@ Gem::Specification.new do |s| s.files += %w( src/core/channelz/channelz_registry.h ) s.files += %w( src/core/client_channel/backup_poller.cc ) s.files += %w( src/core/client_channel/backup_poller.h ) + s.files += %w( src/core/client_channel/client_channel.cc ) + s.files += %w( src/core/client_channel/client_channel.h ) s.files += %w( src/core/client_channel/client_channel_factory.cc ) s.files += %w( src/core/client_channel/client_channel_factory.h ) s.files += %w( src/core/client_channel/client_channel_filter.cc ) @@ -1547,6 +1549,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/promise/latch.h ) s.files += %w( src/core/lib/promise/loop.h ) s.files += %w( src/core/lib/promise/map.h ) + s.files += %w( src/core/lib/promise/observable.h ) s.files += %w( src/core/lib/promise/party.cc ) s.files += %w( src/core/lib/promise/party.h ) s.files += %w( src/core/lib/promise/pipe.h ) diff --git a/grpc.gyp b/grpc.gyp new file mode 100644 index 00000000000..2327e4ad03a --- /dev/null +++ b/grpc.gyp @@ -0,0 +1,2669 @@ +# GRPC GYP build file + +# This file has been automatically generated from a template file. +# Please look at the templates directory instead. +# This file can be regenerated from the template by running +# tools/buildgen/generate_projects.sh + +# 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. + +{ + 'variables': { + # The openssl and zlib dependencies must be passed in as variables + # defined in an included gypi file, usually common.gypi. + 'openssl_gyp_target%': 'Please Define openssl_gyp_target variable', + 'zlib_gyp_target%': 'Please Define zlib_gyp_target variable', + + 'grpc_gcov%': 'false', + 'grpc_alpine%': 'false', + }, + 'target_defaults': { + 'configurations': { + 'Debug': { + 'cflags': [ + '-O0', + ], + 'defines': [ + '_DEBUG', + 'DEBUG', + ], + }, + 'Release': { + 'cflags': [ + '-O2', + '-Wframe-larger-than=16384', + ], + 'defines': [ + 'NDEBUG', + ], + }, + }, + 'cflags': [ + '-g', + '-Wall', + '-Wextra', + '-DOSATOMIC_USE_INLINED=1', + '-Ithird_party/abseil-cpp', + '-Ithird_party/re2', + '-Ithird_party/upb', + '-Isrc/core/ext/upb-gen', + '-Isrc/core/ext/upbdefs-gen', + '-Ithird_party/utf8_range', + '-Ithird_party/xxhash', + ], + 'ldflags': [ + '-g', + ], + 'cflags_c': [ + '-Werror', + '-std=c11', + ], + 'cflags_cc': [ + '-Werror', + '-std=c++14', + ], + 'include_dirs': [ + '.', + '../..', + 'include', + ], + 'defines': [ + 'GRPC_ARES=0', + ], + 'dependencies': [ + '<(openssl_gyp_target)', + '<(zlib_gyp_target)', + ], + 'conditions': [ + ['grpc_gcov=="true"', { + 'cflags': [ + '-O0', + '-fprofile-arcs', + '-ftest-coverage', + '-Wno-return-type', + ], + 'defines': [ + '_DEBUG', + 'DEBUG', + 'GPR_GCOV', + ], + 'ldflags': [ + '-fprofile-arcs', + '-ftest-coverage', + '-rdynamic', + '-lstdc++', + ], + }], + ['grpc_alpine=="true"', { + 'defines': [ + 'GPR_MUSL_LIBC_COMPAT' + ] + }], + ['OS == "win"', { + 'defines': [ + '_WIN32_WINNT=0x0600', + 'WIN32_LEAN_AND_MEAN', + '_HAS_EXCEPTIONS=0', + 'UNICODE', + '_UNICODE', + 'NOMINMAX', + ], + 'msvs_settings': { + 'VCCLCompilerTool': { + 'RuntimeLibrary': 1, # static debug + } + }, + "libraries": [ + "ws2_32" + ] + }], + ['OS == "mac"', { + 'xcode_settings': { + 'OTHER_CFLAGS': [ + '-g', + '-Wall', + '-Wextra', + '-DOSATOMIC_USE_INLINED=1', + '-Ithird_party/abseil-cpp', + '-Ithird_party/re2', + '-Ithird_party/upb', + '-Isrc/core/ext/upb-gen', + '-Isrc/core/ext/upbdefs-gen', + '-Ithird_party/utf8_range', + '-Ithird_party/xxhash', + ], + 'OTHER_CPLUSPLUSFLAGS': [ + '-g', + '-Wall', + '-Wextra', + '-DOSATOMIC_USE_INLINED=1', + '-Ithird_party/abseil-cpp', + '-Ithird_party/re2', + '-Ithird_party/upb', + '-Isrc/core/ext/upb-gen', + '-Isrc/core/ext/upbdefs-gen', + '-Ithird_party/utf8_range', + '-Ithird_party/xxhash', + '-stdlib=libc++', + '-std=c++14', + '-Wno-error=deprecated-declarations', + ], + }, + }] + ] + }, + 'targets': [ + { + 'target_name': 'address_sorting', + 'type': 'static_library', + 'dependencies': [ + ], + 'sources': [ + 'third_party/address_sorting/address_sorting.c', + 'third_party/address_sorting/address_sorting_posix.c', + 'third_party/address_sorting/address_sorting_windows.c', + ], + }, + { + 'target_name': 'gpr', + 'type': 'static_library', + 'dependencies': [ + 'absl/base:base', + 'absl/base:core_headers', + 'absl/flags:flag', + 'absl/flags:marshalling', + 'absl/functional:any_invocable', + 'absl/memory:memory', + 'absl/random:random', + 'absl/status:status', + 'absl/strings:cord', + 'absl/strings:str_format', + 'absl/strings:strings', + 'absl/synchronization:synchronization', + 'absl/time:time', + 'absl/types:optional', + 'absl/types:variant', + ], + 'sources': [ + 'src/core/lib/config/config_vars.cc', + 'src/core/lib/config/config_vars_non_generated.cc', + 'src/core/lib/config/load_config.cc', + 'src/core/lib/event_engine/thread_local.cc', + 'src/core/lib/gpr/alloc.cc', + 'src/core/lib/gpr/android/log.cc', + 'src/core/lib/gpr/atm.cc', + 'src/core/lib/gpr/iphone/cpu.cc', + 'src/core/lib/gpr/linux/cpu.cc', + 'src/core/lib/gpr/linux/log.cc', + 'src/core/lib/gpr/log.cc', + 'src/core/lib/gpr/msys/tmpfile.cc', + 'src/core/lib/gpr/posix/cpu.cc', + 'src/core/lib/gpr/posix/log.cc', + 'src/core/lib/gpr/posix/string.cc', + 'src/core/lib/gpr/posix/sync.cc', + 'src/core/lib/gpr/posix/time.cc', + 'src/core/lib/gpr/posix/tmpfile.cc', + 'src/core/lib/gpr/string.cc', + 'src/core/lib/gpr/sync.cc', + 'src/core/lib/gpr/sync_abseil.cc', + 'src/core/lib/gpr/time.cc', + 'src/core/lib/gpr/time_precise.cc', + 'src/core/lib/gpr/windows/cpu.cc', + 'src/core/lib/gpr/windows/log.cc', + 'src/core/lib/gpr/windows/string.cc', + 'src/core/lib/gpr/windows/string_util.cc', + 'src/core/lib/gpr/windows/sync.cc', + 'src/core/lib/gpr/windows/time.cc', + 'src/core/lib/gpr/windows/tmpfile.cc', + 'src/core/lib/gprpp/crash.cc', + 'src/core/lib/gprpp/examine_stack.cc', + 'src/core/lib/gprpp/fork.cc', + 'src/core/lib/gprpp/host_port.cc', + 'src/core/lib/gprpp/linux/env.cc', + 'src/core/lib/gprpp/mpscq.cc', + 'src/core/lib/gprpp/posix/env.cc', + 'src/core/lib/gprpp/posix/stat.cc', + 'src/core/lib/gprpp/posix/thd.cc', + 'src/core/lib/gprpp/strerror.cc', + 'src/core/lib/gprpp/tchar.cc', + 'src/core/lib/gprpp/time_util.cc', + 'src/core/lib/gprpp/windows/env.cc', + 'src/core/lib/gprpp/windows/stat.cc', + 'src/core/lib/gprpp/windows/thd.cc', + ], + }, + { + 'target_name': 'grpc', + 'type': 'static_library', + 'dependencies': [ + 'upb_json_lib', + 'upb_textformat_lib', + 're2', + 'z', + 'absl/algorithm:container', + 'absl/base:config', + 'absl/base:no_destructor', + 'absl/cleanup:cleanup', + 'absl/container:flat_hash_map', + 'absl/container:flat_hash_set', + 'absl/container:inlined_vector', + 'absl/functional:bind_front', + 'absl/functional:function_ref', + 'absl/hash:hash', + 'absl/meta:type_traits', + 'absl/random:bit_gen_ref', + 'absl/random:distributions', + 'absl/status:statusor', + 'absl/types:span', + 'absl/utility:utility', + 'cares', + 'gpr', + 'address_sorting', + ], + 'sources': [ + 'src/core/client_channel/backup_poller.cc', + 'src/core/client_channel/client_channel.cc', + 'src/core/client_channel/client_channel_channelz.cc', + 'src/core/client_channel/client_channel_factory.cc', + 'src/core/client_channel/client_channel_filter.cc', + 'src/core/client_channel/client_channel_plugin.cc', + 'src/core/client_channel/client_channel_service_config.cc', + 'src/core/client_channel/config_selector.cc', + 'src/core/client_channel/dynamic_filters.cc', + 'src/core/client_channel/global_subchannel_pool.cc', + 'src/core/client_channel/http_proxy_mapper.cc', + 'src/core/client_channel/local_subchannel_pool.cc', + 'src/core/client_channel/retry_filter.cc', + 'src/core/client_channel/retry_filter_legacy_call_data.cc', + 'src/core/client_channel/retry_service_config.cc', + 'src/core/client_channel/retry_throttle.cc', + 'src/core/client_channel/subchannel.cc', + 'src/core/client_channel/subchannel_pool_interface.cc', + 'src/core/client_channel/subchannel_stream_client.cc', + 'src/core/ext/filters/backend_metrics/backend_metric_filter.cc', + 'src/core/ext/filters/census/grpc_context.cc', + 'src/core/ext/filters/channel_idle/channel_idle_filter.cc', + 'src/core/ext/filters/channel_idle/idle_filter_state.cc', + 'src/core/ext/filters/channel_idle/legacy_channel_idle_filter.cc', + 'src/core/ext/filters/deadline/deadline_filter.cc', + 'src/core/ext/filters/fault_injection/fault_injection_filter.cc', + 'src/core/ext/filters/fault_injection/fault_injection_service_config_parser.cc', + 'src/core/ext/filters/http/client/http_client_filter.cc', + 'src/core/ext/filters/http/client_authority_filter.cc', + 'src/core/ext/filters/http/http_filters_plugin.cc', + 'src/core/ext/filters/http/message_compress/compression_filter.cc', + 'src/core/ext/filters/http/message_compress/legacy_compression_filter.cc', + 'src/core/ext/filters/http/server/http_server_filter.cc', + 'src/core/ext/filters/message_size/message_size_filter.cc', + 'src/core/ext/filters/rbac/rbac_filter.cc', + 'src/core/ext/filters/rbac/rbac_service_config_parser.cc', + 'src/core/ext/filters/server_config_selector/server_config_selector_filter.cc', + 'src/core/ext/filters/stateful_session/stateful_session_filter.cc', + 'src/core/ext/filters/stateful_session/stateful_session_service_config_parser.cc', + 'src/core/ext/gcp/metadata_query.cc', + 'src/core/ext/transport/chttp2/alpn/alpn.cc', + 'src/core/ext/transport/chttp2/client/chttp2_connector.cc', + 'src/core/ext/transport/chttp2/server/chttp2_server.cc', + 'src/core/ext/transport/chttp2/transport/bin_decoder.cc', + 'src/core/ext/transport/chttp2/transport/bin_encoder.cc', + 'src/core/ext/transport/chttp2/transport/chttp2_transport.cc', + 'src/core/ext/transport/chttp2/transport/decode_huff.cc', + 'src/core/ext/transport/chttp2/transport/flow_control.cc', + 'src/core/ext/transport/chttp2/transport/frame.cc', + 'src/core/ext/transport/chttp2/transport/frame_data.cc', + 'src/core/ext/transport/chttp2/transport/frame_goaway.cc', + 'src/core/ext/transport/chttp2/transport/frame_ping.cc', + 'src/core/ext/transport/chttp2/transport/frame_rst_stream.cc', + 'src/core/ext/transport/chttp2/transport/frame_settings.cc', + 'src/core/ext/transport/chttp2/transport/frame_window_update.cc', + 'src/core/ext/transport/chttp2/transport/hpack_encoder.cc', + 'src/core/ext/transport/chttp2/transport/hpack_encoder_table.cc', + 'src/core/ext/transport/chttp2/transport/hpack_parse_result.cc', + 'src/core/ext/transport/chttp2/transport/hpack_parser.cc', + 'src/core/ext/transport/chttp2/transport/hpack_parser_table.cc', + 'src/core/ext/transport/chttp2/transport/http2_settings.cc', + 'src/core/ext/transport/chttp2/transport/http_trace.cc', + 'src/core/ext/transport/chttp2/transport/huffsyms.cc', + 'src/core/ext/transport/chttp2/transport/max_concurrent_streams_policy.cc', + 'src/core/ext/transport/chttp2/transport/parsing.cc', + 'src/core/ext/transport/chttp2/transport/ping_abuse_policy.cc', + 'src/core/ext/transport/chttp2/transport/ping_callbacks.cc', + 'src/core/ext/transport/chttp2/transport/ping_rate_policy.cc', + 'src/core/ext/transport/chttp2/transport/stream_lists.cc', + 'src/core/ext/transport/chttp2/transport/varint.cc', + 'src/core/ext/transport/chttp2/transport/write_size_policy.cc', + 'src/core/ext/transport/chttp2/transport/writing.cc', + 'src/core/ext/transport/inproc/inproc_plugin.cc', + 'src/core/ext/transport/inproc/inproc_transport.cc', + 'src/core/ext/transport/inproc/legacy_inproc_transport.cc', + 'src/core/ext/upb-gen/envoy/admin/v3/certs.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/admin/v3/clusters.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/admin/v3/config_dump.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/admin/v3/config_dump_shared.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/admin/v3/init_dump.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/admin/v3/listeners.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/admin/v3/memory.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/admin/v3/metrics.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/admin/v3/mutex_stats.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/admin/v3/server_info.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/admin/v3/tap.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/annotations/deprecation.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/annotations/resource.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/accesslog/v3/accesslog.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/bootstrap/v3/bootstrap.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/cluster/v3/circuit_breaker.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/cluster/v3/cluster.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/cluster/v3/filter.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/cluster/v3/outlier_detection.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/common/matcher/v3/matcher.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/core/v3/address.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/core/v3/backoff.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/core/v3/base.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/core/v3/config_source.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/core/v3/event_service_config.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/core/v3/extension.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/core/v3/grpc_method_list.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/core/v3/grpc_service.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/core/v3/health_check.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/core/v3/http_service.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/core/v3/http_uri.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/core/v3/protocol.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/core/v3/proxy_protocol.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/core/v3/resolver.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/core/v3/socket_option.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/core/v3/substitution_format_string.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/core/v3/udp_socket_config.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/endpoint/v3/endpoint.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/endpoint/v3/endpoint_components.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/endpoint/v3/load_report.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/listener/v3/api_listener.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/listener/v3/listener.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/listener/v3/listener_components.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/listener/v3/quic_config.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/listener/v3/udp_listener_config.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/metrics/v3/metrics_service.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/metrics/v3/stats.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/overload/v3/overload.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/rbac/v3/rbac.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/route/v3/route.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/route/v3/route_components.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/route/v3/scoped_route.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/tap/v3/common.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/trace/v3/datadog.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/trace/v3/dynamic_ot.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/trace/v3/http_tracer.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/trace/v3/lightstep.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/trace/v3/opencensus.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/trace/v3/opentelemetry.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/trace/v3/service.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/trace/v3/skywalking.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/trace/v3/trace.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/trace/v3/xray.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/config/trace/v3/zipkin.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/data/accesslog/v3/accesslog.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/extensions/clusters/aggregate/v3/cluster.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/extensions/filters/common/fault/v3/fault.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/extensions/filters/http/fault/v3/fault.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/extensions/filters/http/rbac/v3/rbac.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/extensions/filters/http/router/v3/router.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/extensions/filters/http/stateful_session/v3/stateful_session.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/extensions/http/stateful_session/cookie/v3/cookie.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/extensions/load_balancing_policies/client_side_weighted_round_robin/v3/client_side_weighted_round_robin.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/extensions/load_balancing_policies/common/v3/common.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/extensions/load_balancing_policies/pick_first/v3/pick_first.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/extensions/load_balancing_policies/ring_hash/v3/ring_hash.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/extensions/load_balancing_policies/wrr_locality/v3/wrr_locality.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/cert.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/common.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/secret.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/service/discovery/v3/ads.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/service/discovery/v3/discovery.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/service/load_stats/v3/lrs.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/service/status/v3/csds.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/type/http/v3/cookie.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/type/http/v3/path_transformation.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/type/matcher/v3/filter_state.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/type/matcher/v3/http_inputs.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/type/matcher/v3/metadata.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/type/matcher/v3/node.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/type/matcher/v3/number.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/type/matcher/v3/path.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/type/matcher/v3/regex.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/type/matcher/v3/status_code_input.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/type/matcher/v3/string.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/type/matcher/v3/struct.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/type/matcher/v3/value.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/type/metadata/v3/metadata.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/type/tracing/v3/custom_tag.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/type/v3/hash_policy.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/type/v3/http.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/type/v3/http_status.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/type/v3/percent.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/type/v3/range.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/type/v3/ratelimit_strategy.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/type/v3/ratelimit_unit.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/type/v3/semantic_version.upb_minitable.c', + 'src/core/ext/upb-gen/envoy/type/v3/token_bucket.upb_minitable.c', + 'src/core/ext/upb-gen/google/api/annotations.upb_minitable.c', + 'src/core/ext/upb-gen/google/api/expr/v1alpha1/checked.upb_minitable.c', + 'src/core/ext/upb-gen/google/api/expr/v1alpha1/syntax.upb_minitable.c', + 'src/core/ext/upb-gen/google/api/http.upb_minitable.c', + 'src/core/ext/upb-gen/google/api/httpbody.upb_minitable.c', + 'src/core/ext/upb-gen/google/protobuf/any.upb_minitable.c', + 'src/core/ext/upb-gen/google/protobuf/descriptor.upb_minitable.c', + 'src/core/ext/upb-gen/google/protobuf/duration.upb_minitable.c', + 'src/core/ext/upb-gen/google/protobuf/empty.upb_minitable.c', + 'src/core/ext/upb-gen/google/protobuf/struct.upb_minitable.c', + 'src/core/ext/upb-gen/google/protobuf/timestamp.upb_minitable.c', + 'src/core/ext/upb-gen/google/protobuf/wrappers.upb_minitable.c', + 'src/core/ext/upb-gen/google/rpc/status.upb_minitable.c', + 'src/core/ext/upb-gen/opencensus/proto/trace/v1/trace_config.upb_minitable.c', + 'src/core/ext/upb-gen/src/proto/grpc/gcp/altscontext.upb_minitable.c', + 'src/core/ext/upb-gen/src/proto/grpc/gcp/handshaker.upb_minitable.c', + 'src/core/ext/upb-gen/src/proto/grpc/gcp/transport_security_common.upb_minitable.c', + 'src/core/ext/upb-gen/src/proto/grpc/health/v1/health.upb_minitable.c', + 'src/core/ext/upb-gen/src/proto/grpc/lb/v1/load_balancer.upb_minitable.c', + 'src/core/ext/upb-gen/src/proto/grpc/lookup/v1/rls.upb_minitable.c', + 'src/core/ext/upb-gen/src/proto/grpc/lookup/v1/rls_config.upb_minitable.c', + 'src/core/ext/upb-gen/udpa/annotations/migrate.upb_minitable.c', + 'src/core/ext/upb-gen/udpa/annotations/security.upb_minitable.c', + 'src/core/ext/upb-gen/udpa/annotations/sensitive.upb_minitable.c', + 'src/core/ext/upb-gen/udpa/annotations/status.upb_minitable.c', + 'src/core/ext/upb-gen/udpa/annotations/versioning.upb_minitable.c', + 'src/core/ext/upb-gen/validate/validate.upb_minitable.c', + 'src/core/ext/upb-gen/xds/annotations/v3/migrate.upb_minitable.c', + 'src/core/ext/upb-gen/xds/annotations/v3/security.upb_minitable.c', + 'src/core/ext/upb-gen/xds/annotations/v3/sensitive.upb_minitable.c', + 'src/core/ext/upb-gen/xds/annotations/v3/status.upb_minitable.c', + 'src/core/ext/upb-gen/xds/annotations/v3/versioning.upb_minitable.c', + 'src/core/ext/upb-gen/xds/core/v3/authority.upb_minitable.c', + 'src/core/ext/upb-gen/xds/core/v3/cidr.upb_minitable.c', + 'src/core/ext/upb-gen/xds/core/v3/collection_entry.upb_minitable.c', + 'src/core/ext/upb-gen/xds/core/v3/context_params.upb_minitable.c', + 'src/core/ext/upb-gen/xds/core/v3/extension.upb_minitable.c', + 'src/core/ext/upb-gen/xds/core/v3/resource.upb_minitable.c', + 'src/core/ext/upb-gen/xds/core/v3/resource_locator.upb_minitable.c', + 'src/core/ext/upb-gen/xds/core/v3/resource_name.upb_minitable.c', + 'src/core/ext/upb-gen/xds/data/orca/v3/orca_load_report.upb_minitable.c', + 'src/core/ext/upb-gen/xds/service/orca/v3/orca.upb_minitable.c', + 'src/core/ext/upb-gen/xds/type/matcher/v3/cel.upb_minitable.c', + 'src/core/ext/upb-gen/xds/type/matcher/v3/domain.upb_minitable.c', + 'src/core/ext/upb-gen/xds/type/matcher/v3/http_inputs.upb_minitable.c', + 'src/core/ext/upb-gen/xds/type/matcher/v3/ip.upb_minitable.c', + 'src/core/ext/upb-gen/xds/type/matcher/v3/matcher.upb_minitable.c', + 'src/core/ext/upb-gen/xds/type/matcher/v3/range.upb_minitable.c', + 'src/core/ext/upb-gen/xds/type/matcher/v3/regex.upb_minitable.c', + 'src/core/ext/upb-gen/xds/type/matcher/v3/string.upb_minitable.c', + 'src/core/ext/upb-gen/xds/type/v3/cel.upb_minitable.c', + 'src/core/ext/upb-gen/xds/type/v3/range.upb_minitable.c', + 'src/core/ext/upb-gen/xds/type/v3/typed_struct.upb_minitable.c', + 'src/core/ext/upbdefs-gen/envoy/admin/v3/certs.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/admin/v3/clusters.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/admin/v3/config_dump.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/admin/v3/config_dump_shared.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/admin/v3/init_dump.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/admin/v3/listeners.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/admin/v3/memory.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/admin/v3/metrics.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/admin/v3/mutex_stats.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/admin/v3/server_info.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/admin/v3/tap.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/annotations/deprecation.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/annotations/resource.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/accesslog/v3/accesslog.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/bootstrap/v3/bootstrap.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/cluster/v3/circuit_breaker.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/cluster/v3/cluster.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/cluster/v3/filter.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/cluster/v3/outlier_detection.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/common/matcher/v3/matcher.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/core/v3/address.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/core/v3/backoff.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/core/v3/base.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/core/v3/config_source.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/core/v3/event_service_config.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/core/v3/extension.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/core/v3/grpc_method_list.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/core/v3/grpc_service.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/core/v3/health_check.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/core/v3/http_service.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/core/v3/http_uri.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/core/v3/protocol.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/core/v3/proxy_protocol.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/core/v3/resolver.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/core/v3/socket_option.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/core/v3/substitution_format_string.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/core/v3/udp_socket_config.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/endpoint/v3/endpoint.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/endpoint/v3/endpoint_components.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/endpoint/v3/load_report.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/listener/v3/api_listener.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/listener/v3/listener.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/listener/v3/listener_components.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/listener/v3/quic_config.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/listener/v3/udp_listener_config.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/metrics/v3/metrics_service.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/metrics/v3/stats.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/overload/v3/overload.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/rbac/v3/rbac.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/route/v3/route.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/route/v3/route_components.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/route/v3/scoped_route.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/tap/v3/common.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/trace/v3/datadog.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/trace/v3/dynamic_ot.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/trace/v3/http_tracer.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/trace/v3/lightstep.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/trace/v3/opencensus.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/trace/v3/opentelemetry.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/trace/v3/service.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/trace/v3/skywalking.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/trace/v3/trace.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/trace/v3/xray.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/config/trace/v3/zipkin.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/data/accesslog/v3/accesslog.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/extensions/clusters/aggregate/v3/cluster.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/extensions/filters/common/fault/v3/fault.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/extensions/filters/http/fault/v3/fault.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/extensions/filters/http/rbac/v3/rbac.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/extensions/filters/http/router/v3/router.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/extensions/filters/http/stateful_session/v3/stateful_session.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/extensions/http/stateful_session/cookie/v3/cookie.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/cert.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/common.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/secret.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/tls.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/service/discovery/v3/ads.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/service/discovery/v3/discovery.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/service/load_stats/v3/lrs.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/service/status/v3/csds.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/type/http/v3/cookie.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/type/http/v3/path_transformation.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/type/matcher/v3/filter_state.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/type/matcher/v3/http_inputs.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/type/matcher/v3/metadata.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/type/matcher/v3/node.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/type/matcher/v3/number.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/type/matcher/v3/path.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/type/matcher/v3/regex.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/type/matcher/v3/status_code_input.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/type/matcher/v3/string.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/type/matcher/v3/struct.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/type/matcher/v3/value.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/type/metadata/v3/metadata.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/type/tracing/v3/custom_tag.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/type/v3/hash_policy.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/type/v3/http.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/type/v3/http_status.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/type/v3/percent.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/type/v3/range.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/type/v3/ratelimit_strategy.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/type/v3/ratelimit_unit.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/type/v3/semantic_version.upbdefs.c', + 'src/core/ext/upbdefs-gen/envoy/type/v3/token_bucket.upbdefs.c', + 'src/core/ext/upbdefs-gen/google/api/annotations.upbdefs.c', + 'src/core/ext/upbdefs-gen/google/api/expr/v1alpha1/checked.upbdefs.c', + 'src/core/ext/upbdefs-gen/google/api/expr/v1alpha1/syntax.upbdefs.c', + 'src/core/ext/upbdefs-gen/google/api/http.upbdefs.c', + 'src/core/ext/upbdefs-gen/google/api/httpbody.upbdefs.c', + 'src/core/ext/upbdefs-gen/google/protobuf/any.upbdefs.c', + 'src/core/ext/upbdefs-gen/google/protobuf/descriptor.upbdefs.c', + 'src/core/ext/upbdefs-gen/google/protobuf/duration.upbdefs.c', + 'src/core/ext/upbdefs-gen/google/protobuf/empty.upbdefs.c', + 'src/core/ext/upbdefs-gen/google/protobuf/struct.upbdefs.c', + 'src/core/ext/upbdefs-gen/google/protobuf/timestamp.upbdefs.c', + 'src/core/ext/upbdefs-gen/google/protobuf/wrappers.upbdefs.c', + 'src/core/ext/upbdefs-gen/google/rpc/status.upbdefs.c', + 'src/core/ext/upbdefs-gen/opencensus/proto/trace/v1/trace_config.upbdefs.c', + 'src/core/ext/upbdefs-gen/src/proto/grpc/lookup/v1/rls_config.upbdefs.c', + 'src/core/ext/upbdefs-gen/udpa/annotations/migrate.upbdefs.c', + 'src/core/ext/upbdefs-gen/udpa/annotations/security.upbdefs.c', + 'src/core/ext/upbdefs-gen/udpa/annotations/sensitive.upbdefs.c', + 'src/core/ext/upbdefs-gen/udpa/annotations/status.upbdefs.c', + 'src/core/ext/upbdefs-gen/udpa/annotations/versioning.upbdefs.c', + 'src/core/ext/upbdefs-gen/validate/validate.upbdefs.c', + 'src/core/ext/upbdefs-gen/xds/annotations/v3/migrate.upbdefs.c', + 'src/core/ext/upbdefs-gen/xds/annotations/v3/security.upbdefs.c', + 'src/core/ext/upbdefs-gen/xds/annotations/v3/sensitive.upbdefs.c', + 'src/core/ext/upbdefs-gen/xds/annotations/v3/status.upbdefs.c', + 'src/core/ext/upbdefs-gen/xds/annotations/v3/versioning.upbdefs.c', + 'src/core/ext/upbdefs-gen/xds/core/v3/authority.upbdefs.c', + 'src/core/ext/upbdefs-gen/xds/core/v3/cidr.upbdefs.c', + 'src/core/ext/upbdefs-gen/xds/core/v3/collection_entry.upbdefs.c', + 'src/core/ext/upbdefs-gen/xds/core/v3/context_params.upbdefs.c', + 'src/core/ext/upbdefs-gen/xds/core/v3/extension.upbdefs.c', + 'src/core/ext/upbdefs-gen/xds/core/v3/resource.upbdefs.c', + 'src/core/ext/upbdefs-gen/xds/core/v3/resource_locator.upbdefs.c', + 'src/core/ext/upbdefs-gen/xds/core/v3/resource_name.upbdefs.c', + 'src/core/ext/upbdefs-gen/xds/type/matcher/v3/cel.upbdefs.c', + 'src/core/ext/upbdefs-gen/xds/type/matcher/v3/domain.upbdefs.c', + 'src/core/ext/upbdefs-gen/xds/type/matcher/v3/http_inputs.upbdefs.c', + 'src/core/ext/upbdefs-gen/xds/type/matcher/v3/ip.upbdefs.c', + 'src/core/ext/upbdefs-gen/xds/type/matcher/v3/matcher.upbdefs.c', + 'src/core/ext/upbdefs-gen/xds/type/matcher/v3/range.upbdefs.c', + 'src/core/ext/upbdefs-gen/xds/type/matcher/v3/regex.upbdefs.c', + 'src/core/ext/upbdefs-gen/xds/type/matcher/v3/string.upbdefs.c', + 'src/core/ext/upbdefs-gen/xds/type/v3/cel.upbdefs.c', + 'src/core/ext/upbdefs-gen/xds/type/v3/range.upbdefs.c', + 'src/core/ext/upbdefs-gen/xds/type/v3/typed_struct.upbdefs.c', + 'src/core/ext/xds/certificate_provider_store.cc', + 'src/core/ext/xds/file_watcher_certificate_provider_factory.cc', + 'src/core/ext/xds/xds_api.cc', + 'src/core/ext/xds/xds_audit_logger_registry.cc', + 'src/core/ext/xds/xds_bootstrap.cc', + 'src/core/ext/xds/xds_bootstrap_grpc.cc', + 'src/core/ext/xds/xds_certificate_provider.cc', + 'src/core/ext/xds/xds_channel_stack_modifier.cc', + 'src/core/ext/xds/xds_client.cc', + 'src/core/ext/xds/xds_client_grpc.cc', + 'src/core/ext/xds/xds_client_stats.cc', + 'src/core/ext/xds/xds_cluster.cc', + 'src/core/ext/xds/xds_cluster_specifier_plugin.cc', + 'src/core/ext/xds/xds_common_types.cc', + 'src/core/ext/xds/xds_endpoint.cc', + 'src/core/ext/xds/xds_health_status.cc', + 'src/core/ext/xds/xds_http_fault_filter.cc', + 'src/core/ext/xds/xds_http_filters.cc', + 'src/core/ext/xds/xds_http_rbac_filter.cc', + 'src/core/ext/xds/xds_http_stateful_session_filter.cc', + 'src/core/ext/xds/xds_lb_policy_registry.cc', + 'src/core/ext/xds/xds_listener.cc', + 'src/core/ext/xds/xds_route_config.cc', + 'src/core/ext/xds/xds_routing.cc', + 'src/core/ext/xds/xds_server_config_fetcher.cc', + 'src/core/ext/xds/xds_transport_grpc.cc', + 'src/core/lib/address_utils/parse_address.cc', + 'src/core/lib/address_utils/sockaddr_utils.cc', + 'src/core/lib/backoff/backoff.cc', + 'src/core/lib/backoff/random_early_detection.cc', + 'src/core/lib/channel/call_tracer.cc', + 'src/core/lib/channel/channel_args.cc', + 'src/core/lib/channel/channel_args_preconditioning.cc', + 'src/core/lib/channel/channel_stack.cc', + 'src/core/lib/channel/channel_stack_builder.cc', + 'src/core/lib/channel/channel_stack_builder_impl.cc', + 'src/core/lib/channel/channel_stack_trace.cc', + 'src/core/lib/channel/channel_trace.cc', + 'src/core/lib/channel/channelz.cc', + 'src/core/lib/channel/channelz_registry.cc', + 'src/core/lib/channel/connected_channel.cc', + 'src/core/lib/channel/metrics.cc', + 'src/core/lib/channel/promise_based_filter.cc', + 'src/core/lib/channel/server_call_tracer_filter.cc', + 'src/core/lib/channel/status_util.cc', + 'src/core/lib/compression/compression.cc', + 'src/core/lib/compression/compression_internal.cc', + 'src/core/lib/compression/message_compress.cc', + 'src/core/lib/config/core_configuration.cc', + 'src/core/lib/debug/event_log.cc', + 'src/core/lib/debug/histogram_view.cc', + 'src/core/lib/debug/stats.cc', + 'src/core/lib/debug/stats_data.cc', + 'src/core/lib/debug/trace.cc', + 'src/core/lib/event_engine/ares_resolver.cc', + 'src/core/lib/event_engine/cf_engine/cf_engine.cc', + 'src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc', + 'src/core/lib/event_engine/cf_engine/dns_service_resolver.cc', + 'src/core/lib/event_engine/channel_args_endpoint_config.cc', + 'src/core/lib/event_engine/default_event_engine.cc', + 'src/core/lib/event_engine/default_event_engine_factory.cc', + 'src/core/lib/event_engine/event_engine.cc', + 'src/core/lib/event_engine/forkable.cc', + 'src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc', + 'src/core/lib/event_engine/posix_engine/ev_poll_posix.cc', + 'src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc', + 'src/core/lib/event_engine/posix_engine/internal_errqueue.cc', + 'src/core/lib/event_engine/posix_engine/lockfree_event.cc', + 'src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc', + 'src/core/lib/event_engine/posix_engine/posix_endpoint.cc', + 'src/core/lib/event_engine/posix_engine/posix_engine.cc', + 'src/core/lib/event_engine/posix_engine/posix_engine_listener.cc', + 'src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.cc', + 'src/core/lib/event_engine/posix_engine/tcp_socket_utils.cc', + 'src/core/lib/event_engine/posix_engine/timer.cc', + 'src/core/lib/event_engine/posix_engine/timer_heap.cc', + 'src/core/lib/event_engine/posix_engine/timer_manager.cc', + 'src/core/lib/event_engine/posix_engine/traced_buffer_list.cc', + 'src/core/lib/event_engine/posix_engine/wakeup_fd_eventfd.cc', + 'src/core/lib/event_engine/posix_engine/wakeup_fd_pipe.cc', + 'src/core/lib/event_engine/posix_engine/wakeup_fd_posix_default.cc', + 'src/core/lib/event_engine/resolved_address.cc', + 'src/core/lib/event_engine/shim.cc', + 'src/core/lib/event_engine/slice.cc', + 'src/core/lib/event_engine/slice_buffer.cc', + 'src/core/lib/event_engine/tcp_socket_utils.cc', + 'src/core/lib/event_engine/thread_pool/thread_count.cc', + 'src/core/lib/event_engine/thread_pool/thread_pool_factory.cc', + 'src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.cc', + 'src/core/lib/event_engine/thready_event_engine/thready_event_engine.cc', + 'src/core/lib/event_engine/time_util.cc', + 'src/core/lib/event_engine/trace.cc', + 'src/core/lib/event_engine/utils.cc', + 'src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc', + 'src/core/lib/event_engine/windows/iocp.cc', + 'src/core/lib/event_engine/windows/native_windows_dns_resolver.cc', + 'src/core/lib/event_engine/windows/win_socket.cc', + 'src/core/lib/event_engine/windows/windows_endpoint.cc', + 'src/core/lib/event_engine/windows/windows_engine.cc', + 'src/core/lib/event_engine/windows/windows_listener.cc', + 'src/core/lib/event_engine/work_queue/basic_work_queue.cc', + 'src/core/lib/experiments/config.cc', + 'src/core/lib/experiments/experiments.cc', + 'src/core/lib/gprpp/load_file.cc', + 'src/core/lib/gprpp/per_cpu.cc', + 'src/core/lib/gprpp/posix/directory_reader.cc', + 'src/core/lib/gprpp/ref_counted_string.cc', + 'src/core/lib/gprpp/status_helper.cc', + 'src/core/lib/gprpp/time.cc', + 'src/core/lib/gprpp/time_averaged_stats.cc', + 'src/core/lib/gprpp/validation_errors.cc', + 'src/core/lib/gprpp/windows/directory_reader.cc', + 'src/core/lib/gprpp/work_serializer.cc', + 'src/core/lib/handshaker/proxy_mapper_registry.cc', + 'src/core/lib/http/format_request.cc', + 'src/core/lib/http/httpcli.cc', + 'src/core/lib/http/httpcli_security_connector.cc', + 'src/core/lib/http/parser.cc', + 'src/core/lib/iomgr/buffer_list.cc', + 'src/core/lib/iomgr/call_combiner.cc', + 'src/core/lib/iomgr/cfstream_handle.cc', + 'src/core/lib/iomgr/closure.cc', + 'src/core/lib/iomgr/combiner.cc', + 'src/core/lib/iomgr/dualstack_socket_posix.cc', + 'src/core/lib/iomgr/endpoint.cc', + 'src/core/lib/iomgr/endpoint_cfstream.cc', + 'src/core/lib/iomgr/endpoint_pair_posix.cc', + 'src/core/lib/iomgr/endpoint_pair_windows.cc', + 'src/core/lib/iomgr/error.cc', + 'src/core/lib/iomgr/error_cfstream.cc', + 'src/core/lib/iomgr/ev_apple.cc', + 'src/core/lib/iomgr/ev_epoll1_linux.cc', + 'src/core/lib/iomgr/ev_poll_posix.cc', + 'src/core/lib/iomgr/ev_posix.cc', + 'src/core/lib/iomgr/ev_windows.cc', + 'src/core/lib/iomgr/event_engine_shims/closure.cc', + 'src/core/lib/iomgr/event_engine_shims/endpoint.cc', + 'src/core/lib/iomgr/event_engine_shims/tcp_client.cc', + 'src/core/lib/iomgr/exec_ctx.cc', + 'src/core/lib/iomgr/executor.cc', + 'src/core/lib/iomgr/fork_posix.cc', + 'src/core/lib/iomgr/fork_windows.cc', + 'src/core/lib/iomgr/gethostname_fallback.cc', + 'src/core/lib/iomgr/gethostname_host_name_max.cc', + 'src/core/lib/iomgr/gethostname_sysconf.cc', + 'src/core/lib/iomgr/grpc_if_nametoindex_posix.cc', + 'src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc', + 'src/core/lib/iomgr/internal_errqueue.cc', + 'src/core/lib/iomgr/iocp_windows.cc', + 'src/core/lib/iomgr/iomgr.cc', + 'src/core/lib/iomgr/iomgr_internal.cc', + 'src/core/lib/iomgr/iomgr_posix.cc', + 'src/core/lib/iomgr/iomgr_posix_cfstream.cc', + 'src/core/lib/iomgr/iomgr_windows.cc', + 'src/core/lib/iomgr/lockfree_event.cc', + 'src/core/lib/iomgr/polling_entity.cc', + 'src/core/lib/iomgr/pollset.cc', + 'src/core/lib/iomgr/pollset_set.cc', + 'src/core/lib/iomgr/pollset_set_windows.cc', + 'src/core/lib/iomgr/pollset_windows.cc', + 'src/core/lib/iomgr/resolve_address.cc', + 'src/core/lib/iomgr/resolve_address_posix.cc', + 'src/core/lib/iomgr/resolve_address_windows.cc', + 'src/core/lib/iomgr/sockaddr_utils_posix.cc', + 'src/core/lib/iomgr/socket_factory_posix.cc', + 'src/core/lib/iomgr/socket_mutator.cc', + 'src/core/lib/iomgr/socket_utils_common_posix.cc', + 'src/core/lib/iomgr/socket_utils_linux.cc', + 'src/core/lib/iomgr/socket_utils_posix.cc', + 'src/core/lib/iomgr/socket_utils_windows.cc', + 'src/core/lib/iomgr/socket_windows.cc', + 'src/core/lib/iomgr/systemd_utils.cc', + 'src/core/lib/iomgr/tcp_client.cc', + 'src/core/lib/iomgr/tcp_client_cfstream.cc', + 'src/core/lib/iomgr/tcp_client_posix.cc', + 'src/core/lib/iomgr/tcp_client_windows.cc', + 'src/core/lib/iomgr/tcp_posix.cc', + 'src/core/lib/iomgr/tcp_server.cc', + 'src/core/lib/iomgr/tcp_server_posix.cc', + 'src/core/lib/iomgr/tcp_server_utils_posix_common.cc', + 'src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.cc', + 'src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.cc', + 'src/core/lib/iomgr/tcp_server_windows.cc', + 'src/core/lib/iomgr/tcp_windows.cc', + 'src/core/lib/iomgr/timer.cc', + 'src/core/lib/iomgr/timer_generic.cc', + 'src/core/lib/iomgr/timer_heap.cc', + 'src/core/lib/iomgr/timer_manager.cc', + 'src/core/lib/iomgr/unix_sockets_posix.cc', + 'src/core/lib/iomgr/unix_sockets_posix_noop.cc', + 'src/core/lib/iomgr/vsock.cc', + 'src/core/lib/iomgr/wakeup_fd_eventfd.cc', + 'src/core/lib/iomgr/wakeup_fd_nospecial.cc', + 'src/core/lib/iomgr/wakeup_fd_pipe.cc', + 'src/core/lib/iomgr/wakeup_fd_posix.cc', + 'src/core/lib/json/json_object_loader.cc', + 'src/core/lib/json/json_reader.cc', + 'src/core/lib/json/json_util.cc', + 'src/core/lib/json/json_writer.cc', + 'src/core/lib/matchers/matchers.cc', + 'src/core/lib/promise/activity.cc', + 'src/core/lib/promise/party.cc', + 'src/core/lib/promise/sleep.cc', + 'src/core/lib/promise/trace.cc', + 'src/core/lib/resource_quota/api.cc', + 'src/core/lib/resource_quota/arena.cc', + 'src/core/lib/resource_quota/memory_quota.cc', + 'src/core/lib/resource_quota/periodic_update.cc', + 'src/core/lib/resource_quota/resource_quota.cc', + 'src/core/lib/resource_quota/thread_quota.cc', + 'src/core/lib/resource_quota/trace.cc', + 'src/core/lib/security/authorization/audit_logging.cc', + 'src/core/lib/security/authorization/authorization_policy_provider_vtable.cc', + 'src/core/lib/security/authorization/evaluate_args.cc', + 'src/core/lib/security/authorization/grpc_authorization_engine.cc', + 'src/core/lib/security/authorization/grpc_server_authz_filter.cc', + 'src/core/lib/security/authorization/matchers.cc', + 'src/core/lib/security/authorization/rbac_policy.cc', + 'src/core/lib/security/authorization/stdout_logger.cc', + 'src/core/lib/security/certificate_provider/certificate_provider_registry.cc', + 'src/core/lib/security/context/security_context.cc', + 'src/core/lib/security/credentials/alts/alts_credentials.cc', + 'src/core/lib/security/credentials/alts/check_gcp_environment.cc', + '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_server_options.cc', + 'src/core/lib/security/credentials/call_creds_util.cc', + 'src/core/lib/security/credentials/channel_creds_registry_init.cc', + 'src/core/lib/security/credentials/composite/composite_credentials.cc', + 'src/core/lib/security/credentials/credentials.cc', + 'src/core/lib/security/credentials/external/aws_external_account_credentials.cc', + 'src/core/lib/security/credentials/external/aws_request_signer.cc', + 'src/core/lib/security/credentials/external/external_account_credentials.cc', + 'src/core/lib/security/credentials/external/file_external_account_credentials.cc', + 'src/core/lib/security/credentials/external/url_external_account_credentials.cc', + 'src/core/lib/security/credentials/fake/fake_credentials.cc', + '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/iam/iam_credentials.cc', + 'src/core/lib/security/credentials/insecure/insecure_credentials.cc', + 'src/core/lib/security/credentials/jwt/json_token.cc', + 'src/core/lib/security/credentials/jwt/jwt_credentials.cc', + 'src/core/lib/security/credentials/jwt/jwt_verifier.cc', + 'src/core/lib/security/credentials/local/local_credentials.cc', + 'src/core/lib/security/credentials/oauth2/oauth2_credentials.cc', + 'src/core/lib/security/credentials/plugin/plugin_credentials.cc', + 'src/core/lib/security/credentials/ssl/ssl_credentials.cc', + 'src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.cc', + '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_verifier.cc', + 'src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc', + 'src/core/lib/security/credentials/tls/grpc_tls_crl_provider.cc', + 'src/core/lib/security/credentials/tls/tls_credentials.cc', + 'src/core/lib/security/credentials/tls/tls_utils.cc', + 'src/core/lib/security/credentials/xds/xds_credentials.cc', + 'src/core/lib/security/security_connector/alts/alts_security_connector.cc', + 'src/core/lib/security/security_connector/fake/fake_security_connector.cc', + 'src/core/lib/security/security_connector/insecure/insecure_security_connector.cc', + '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_windows.cc', + 'src/core/lib/security/security_connector/local/local_security_connector.cc', + 'src/core/lib/security/security_connector/security_connector.cc', + 'src/core/lib/security/security_connector/ssl/ssl_security_connector.cc', + 'src/core/lib/security/security_connector/ssl_utils.cc', + 'src/core/lib/security/security_connector/tls/tls_security_connector.cc', + 'src/core/lib/security/transport/client_auth_filter.cc', + 'src/core/lib/security/transport/legacy_server_auth_filter.cc', + 'src/core/lib/security/transport/secure_endpoint.cc', + 'src/core/lib/security/transport/security_handshaker.cc', + 'src/core/lib/security/transport/server_auth_filter.cc', + 'src/core/lib/security/transport/tsi_error.cc', + 'src/core/lib/security/util/json_util.cc', + 'src/core/lib/slice/b64.cc', + 'src/core/lib/slice/percent_encoding.cc', + 'src/core/lib/slice/slice.cc', + 'src/core/lib/slice/slice_buffer.cc', + 'src/core/lib/slice/slice_refcount.cc', + 'src/core/lib/slice/slice_string_helpers.cc', + 'src/core/lib/surface/api_trace.cc', + 'src/core/lib/surface/byte_buffer.cc', + 'src/core/lib/surface/byte_buffer_reader.cc', + 'src/core/lib/surface/call.cc', + 'src/core/lib/surface/call_details.cc', + 'src/core/lib/surface/call_log_batch.cc', + 'src/core/lib/surface/channel.cc', + 'src/core/lib/surface/channel_create.cc', + 'src/core/lib/surface/channel_init.cc', + 'src/core/lib/surface/channel_stack_type.cc', + 'src/core/lib/surface/completion_queue.cc', + 'src/core/lib/surface/completion_queue_factory.cc', + 'src/core/lib/surface/event_string.cc', + 'src/core/lib/surface/init.cc', + 'src/core/lib/surface/init_internally.cc', + 'src/core/lib/surface/lame_client.cc', + 'src/core/lib/surface/legacy_channel.cc', + 'src/core/lib/surface/metadata_array.cc', + 'src/core/lib/surface/server.cc', + 'src/core/lib/surface/validate_metadata.cc', + 'src/core/lib/surface/version.cc', + 'src/core/lib/surface/wait_for_cq_end_op.cc', + 'src/core/lib/transport/batch_builder.cc', + 'src/core/lib/transport/bdp_estimator.cc', + 'src/core/lib/transport/call_filters.cc', + 'src/core/lib/transport/call_final_info.cc', + 'src/core/lib/transport/call_size_estimator.cc', + 'src/core/lib/transport/call_spine.cc', + 'src/core/lib/transport/connectivity_state.cc', + 'src/core/lib/transport/error_utils.cc', + 'src/core/lib/transport/handshaker.cc', + 'src/core/lib/transport/handshaker_registry.cc', + 'src/core/lib/transport/http_connect_handshaker.cc', + 'src/core/lib/transport/message.cc', + 'src/core/lib/transport/metadata.cc', + 'src/core/lib/transport/metadata_batch.cc', + 'src/core/lib/transport/metadata_info.cc', + 'src/core/lib/transport/parsed_metadata.cc', + 'src/core/lib/transport/status_conversion.cc', + 'src/core/lib/transport/tcp_connect_handshaker.cc', + 'src/core/lib/transport/timeout_encoding.cc', + 'src/core/lib/transport/transport.cc', + 'src/core/lib/transport/transport_op_string.cc', + 'src/core/lib/uri/uri_parser.cc', + 'src/core/load_balancing/address_filtering.cc', + 'src/core/load_balancing/backend_metric_parser.cc', + 'src/core/load_balancing/child_policy_handler.cc', + 'src/core/load_balancing/endpoint_list.cc', + 'src/core/load_balancing/grpclb/client_load_reporting_filter.cc', + 'src/core/load_balancing/grpclb/grpclb.cc', + 'src/core/load_balancing/grpclb/grpclb_balancer_addresses.cc', + 'src/core/load_balancing/grpclb/grpclb_client_stats.cc', + 'src/core/load_balancing/grpclb/load_balancer_api.cc', + 'src/core/load_balancing/health_check_client.cc', + 'src/core/load_balancing/lb_policy.cc', + 'src/core/load_balancing/lb_policy_registry.cc', + 'src/core/load_balancing/oob_backend_metric.cc', + 'src/core/load_balancing/outlier_detection/outlier_detection.cc', + 'src/core/load_balancing/pick_first/pick_first.cc', + 'src/core/load_balancing/priority/priority.cc', + 'src/core/load_balancing/ring_hash/ring_hash.cc', + 'src/core/load_balancing/rls/rls.cc', + 'src/core/load_balancing/round_robin/round_robin.cc', + 'src/core/load_balancing/weighted_round_robin/static_stride_scheduler.cc', + 'src/core/load_balancing/weighted_round_robin/weighted_round_robin.cc', + 'src/core/load_balancing/weighted_target/weighted_target.cc', + 'src/core/load_balancing/xds/cds.cc', + 'src/core/load_balancing/xds/xds_cluster_impl.cc', + 'src/core/load_balancing/xds/xds_cluster_manager.cc', + 'src/core/load_balancing/xds/xds_override_host.cc', + 'src/core/load_balancing/xds/xds_wrr_locality.cc', + 'src/core/plugin_registry/grpc_plugin_registry.cc', + 'src/core/plugin_registry/grpc_plugin_registry_extra.cc', + 'src/core/resolver/binder/binder_resolver.cc', + 'src/core/resolver/dns/c_ares/dns_resolver_ares.cc', + 'src/core/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc', + 'src/core/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc', + 'src/core/resolver/dns/c_ares/grpc_ares_wrapper.cc', + 'src/core/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc', + 'src/core/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc', + 'src/core/resolver/dns/dns_resolver_plugin.cc', + 'src/core/resolver/dns/event_engine/event_engine_client_channel_resolver.cc', + 'src/core/resolver/dns/event_engine/service_config_helper.cc', + 'src/core/resolver/dns/native/dns_resolver.cc', + 'src/core/resolver/endpoint_addresses.cc', + 'src/core/resolver/fake/fake_resolver.cc', + 'src/core/resolver/google_c2p/google_c2p_resolver.cc', + 'src/core/resolver/polling_resolver.cc', + 'src/core/resolver/resolver.cc', + 'src/core/resolver/resolver_registry.cc', + 'src/core/resolver/sockaddr/sockaddr_resolver.cc', + 'src/core/resolver/xds/xds_dependency_manager.cc', + 'src/core/resolver/xds/xds_resolver.cc', + 'src/core/resolver/xds/xds_resolver_trace.cc', + 'src/core/service_config/service_config_channel_arg_filter.cc', + 'src/core/service_config/service_config_impl.cc', + 'src/core/service_config/service_config_parser.cc', + 'src/core/tsi/alts/crypt/aes_gcm.cc', + 'src/core/tsi/alts/crypt/gsec.cc', + 'src/core/tsi/alts/frame_protector/alts_counter.cc', + 'src/core/tsi/alts/frame_protector/alts_crypter.cc', + 'src/core/tsi/alts/frame_protector/alts_frame_protector.cc', + 'src/core/tsi/alts/frame_protector/alts_record_protocol_crypter_common.cc', + 'src/core/tsi/alts/frame_protector/alts_seal_privacy_integrity_crypter.cc', + 'src/core/tsi/alts/frame_protector/alts_unseal_privacy_integrity_crypter.cc', + 'src/core/tsi/alts/frame_protector/frame_handler.cc', + 'src/core/tsi/alts/handshaker/alts_handshaker_client.cc', + 'src/core/tsi/alts/handshaker/alts_shared_resource.cc', + 'src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc', + 'src/core/tsi/alts/handshaker/alts_tsi_utils.cc', + 'src/core/tsi/alts/handshaker/transport_security_common_api.cc', + 'src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.cc', + 'src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.cc', + 'src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.cc', + 'src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.cc', + 'src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc', + 'src/core/tsi/fake_transport_security.cc', + 'src/core/tsi/local_transport_security.cc', + 'src/core/tsi/ssl/key_logging/ssl_key_logging.cc', + 'src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc', + 'src/core/tsi/ssl/session_cache/ssl_session_cache.cc', + 'src/core/tsi/ssl/session_cache/ssl_session_openssl.cc', + 'src/core/tsi/ssl_transport_security.cc', + 'src/core/tsi/ssl_transport_security_utils.cc', + 'src/core/tsi/transport_security.cc', + 'src/core/tsi/transport_security_grpc.cc', + ], + }, + { + 'target_name': 'grpc_test_util', + 'type': 'static_library', + 'dependencies': [ + 'absl/debugging:failure_signal_handler', + 'absl/debugging:stacktrace', + 'absl/debugging:symbolize', + 'grpc', + ], + 'sources': [ + 'test/core/event_engine/test_init.cc', + 'test/core/util/build.cc', + 'test/core/util/port.cc', + 'test/core/util/port_isolated_runtime_environment.cc', + 'test/core/util/port_server_client.cc', + 'test/core/util/reconnect_server.cc', + 'test/core/util/stack_tracer.cc', + 'test/core/util/test_config.cc', + 'test/core/util/test_tcp_server.cc', + 'test/core/util/tls_utils.cc', + ], + }, + { + 'target_name': 'grpc_test_util_unsecure', + 'type': 'static_library', + 'dependencies': [ + 'absl/debugging:failure_signal_handler', + 'absl/debugging:stacktrace', + 'absl/debugging:symbolize', + 'grpc_unsecure', + ], + 'sources': [ + 'test/core/event_engine/test_init.cc', + 'test/core/util/build.cc', + 'test/core/util/port.cc', + 'test/core/util/port_isolated_runtime_environment.cc', + 'test/core/util/port_server_client.cc', + 'test/core/util/reconnect_server.cc', + 'test/core/util/stack_tracer.cc', + 'test/core/util/test_config.cc', + 'test/core/util/test_tcp_server.cc', + ], + }, + { + 'target_name': 'grpc_unsecure', + 'type': 'static_library', + 'dependencies': [ + 'upb_message_lib', + 'utf8_range_lib', + 'z', + 'absl/algorithm:container', + 'absl/base:config', + 'absl/base:no_destructor', + 'absl/cleanup:cleanup', + 'absl/container:flat_hash_map', + 'absl/container:flat_hash_set', + 'absl/container:inlined_vector', + 'absl/functional:bind_front', + 'absl/functional:function_ref', + 'absl/hash:hash', + 'absl/meta:type_traits', + 'absl/random:bit_gen_ref', + 'absl/random:distributions', + 'absl/status:statusor', + 'absl/types:span', + 'absl/utility:utility', + 'cares', + 'gpr', + 'address_sorting', + ], + 'sources': [ + 'src/core/client_channel/backup_poller.cc', + 'src/core/client_channel/client_channel.cc', + 'src/core/client_channel/client_channel_channelz.cc', + 'src/core/client_channel/client_channel_factory.cc', + 'src/core/client_channel/client_channel_filter.cc', + 'src/core/client_channel/client_channel_plugin.cc', + 'src/core/client_channel/client_channel_service_config.cc', + 'src/core/client_channel/config_selector.cc', + 'src/core/client_channel/dynamic_filters.cc', + 'src/core/client_channel/global_subchannel_pool.cc', + 'src/core/client_channel/http_proxy_mapper.cc', + 'src/core/client_channel/local_subchannel_pool.cc', + 'src/core/client_channel/retry_filter.cc', + 'src/core/client_channel/retry_filter_legacy_call_data.cc', + 'src/core/client_channel/retry_service_config.cc', + 'src/core/client_channel/retry_throttle.cc', + 'src/core/client_channel/subchannel.cc', + 'src/core/client_channel/subchannel_pool_interface.cc', + 'src/core/client_channel/subchannel_stream_client.cc', + 'src/core/ext/filters/backend_metrics/backend_metric_filter.cc', + 'src/core/ext/filters/census/grpc_context.cc', + 'src/core/ext/filters/channel_idle/channel_idle_filter.cc', + 'src/core/ext/filters/channel_idle/idle_filter_state.cc', + 'src/core/ext/filters/channel_idle/legacy_channel_idle_filter.cc', + 'src/core/ext/filters/deadline/deadline_filter.cc', + 'src/core/ext/filters/fault_injection/fault_injection_filter.cc', + 'src/core/ext/filters/fault_injection/fault_injection_service_config_parser.cc', + 'src/core/ext/filters/http/client/http_client_filter.cc', + 'src/core/ext/filters/http/client_authority_filter.cc', + 'src/core/ext/filters/http/http_filters_plugin.cc', + 'src/core/ext/filters/http/message_compress/compression_filter.cc', + 'src/core/ext/filters/http/message_compress/legacy_compression_filter.cc', + 'src/core/ext/filters/http/server/http_server_filter.cc', + 'src/core/ext/filters/message_size/message_size_filter.cc', + 'src/core/ext/transport/chttp2/client/chttp2_connector.cc', + 'src/core/ext/transport/chttp2/server/chttp2_server.cc', + 'src/core/ext/transport/chttp2/transport/bin_decoder.cc', + 'src/core/ext/transport/chttp2/transport/bin_encoder.cc', + 'src/core/ext/transport/chttp2/transport/chttp2_transport.cc', + 'src/core/ext/transport/chttp2/transport/decode_huff.cc', + 'src/core/ext/transport/chttp2/transport/flow_control.cc', + 'src/core/ext/transport/chttp2/transport/frame.cc', + 'src/core/ext/transport/chttp2/transport/frame_data.cc', + 'src/core/ext/transport/chttp2/transport/frame_goaway.cc', + 'src/core/ext/transport/chttp2/transport/frame_ping.cc', + 'src/core/ext/transport/chttp2/transport/frame_rst_stream.cc', + 'src/core/ext/transport/chttp2/transport/frame_settings.cc', + 'src/core/ext/transport/chttp2/transport/frame_window_update.cc', + 'src/core/ext/transport/chttp2/transport/hpack_encoder.cc', + 'src/core/ext/transport/chttp2/transport/hpack_encoder_table.cc', + 'src/core/ext/transport/chttp2/transport/hpack_parse_result.cc', + 'src/core/ext/transport/chttp2/transport/hpack_parser.cc', + 'src/core/ext/transport/chttp2/transport/hpack_parser_table.cc', + 'src/core/ext/transport/chttp2/transport/http2_settings.cc', + 'src/core/ext/transport/chttp2/transport/http_trace.cc', + 'src/core/ext/transport/chttp2/transport/huffsyms.cc', + 'src/core/ext/transport/chttp2/transport/max_concurrent_streams_policy.cc', + 'src/core/ext/transport/chttp2/transport/parsing.cc', + 'src/core/ext/transport/chttp2/transport/ping_abuse_policy.cc', + 'src/core/ext/transport/chttp2/transport/ping_callbacks.cc', + 'src/core/ext/transport/chttp2/transport/ping_rate_policy.cc', + 'src/core/ext/transport/chttp2/transport/stream_lists.cc', + 'src/core/ext/transport/chttp2/transport/varint.cc', + 'src/core/ext/transport/chttp2/transport/write_size_policy.cc', + 'src/core/ext/transport/chttp2/transport/writing.cc', + 'src/core/ext/transport/inproc/inproc_plugin.cc', + 'src/core/ext/transport/inproc/inproc_transport.cc', + 'src/core/ext/transport/inproc/legacy_inproc_transport.cc', + 'src/core/ext/upb-gen/google/api/annotations.upb_minitable.c', + 'src/core/ext/upb-gen/google/api/http.upb_minitable.c', + 'src/core/ext/upb-gen/google/protobuf/any.upb_minitable.c', + 'src/core/ext/upb-gen/google/protobuf/descriptor.upb_minitable.c', + 'src/core/ext/upb-gen/google/protobuf/duration.upb_minitable.c', + 'src/core/ext/upb-gen/google/protobuf/empty.upb_minitable.c', + 'src/core/ext/upb-gen/google/protobuf/struct.upb_minitable.c', + 'src/core/ext/upb-gen/google/protobuf/timestamp.upb_minitable.c', + 'src/core/ext/upb-gen/google/protobuf/wrappers.upb_minitable.c', + 'src/core/ext/upb-gen/google/rpc/status.upb_minitable.c', + 'src/core/ext/upb-gen/src/proto/grpc/gcp/altscontext.upb_minitable.c', + 'src/core/ext/upb-gen/src/proto/grpc/gcp/handshaker.upb_minitable.c', + 'src/core/ext/upb-gen/src/proto/grpc/gcp/transport_security_common.upb_minitable.c', + 'src/core/ext/upb-gen/src/proto/grpc/health/v1/health.upb_minitable.c', + 'src/core/ext/upb-gen/src/proto/grpc/lb/v1/load_balancer.upb_minitable.c', + 'src/core/ext/upb-gen/src/proto/grpc/lookup/v1/rls.upb_minitable.c', + 'src/core/ext/upb-gen/validate/validate.upb_minitable.c', + 'src/core/ext/upb-gen/xds/data/orca/v3/orca_load_report.upb_minitable.c', + 'src/core/ext/upb-gen/xds/service/orca/v3/orca.upb_minitable.c', + 'src/core/lib/address_utils/parse_address.cc', + 'src/core/lib/address_utils/sockaddr_utils.cc', + 'src/core/lib/backoff/backoff.cc', + 'src/core/lib/backoff/random_early_detection.cc', + 'src/core/lib/channel/call_tracer.cc', + 'src/core/lib/channel/channel_args.cc', + 'src/core/lib/channel/channel_args_preconditioning.cc', + 'src/core/lib/channel/channel_stack.cc', + 'src/core/lib/channel/channel_stack_builder.cc', + 'src/core/lib/channel/channel_stack_builder_impl.cc', + 'src/core/lib/channel/channel_stack_trace.cc', + 'src/core/lib/channel/channel_trace.cc', + 'src/core/lib/channel/channelz.cc', + 'src/core/lib/channel/channelz_registry.cc', + 'src/core/lib/channel/connected_channel.cc', + 'src/core/lib/channel/metrics.cc', + 'src/core/lib/channel/promise_based_filter.cc', + 'src/core/lib/channel/server_call_tracer_filter.cc', + 'src/core/lib/channel/status_util.cc', + 'src/core/lib/compression/compression.cc', + 'src/core/lib/compression/compression_internal.cc', + 'src/core/lib/compression/message_compress.cc', + 'src/core/lib/config/core_configuration.cc', + 'src/core/lib/debug/event_log.cc', + 'src/core/lib/debug/histogram_view.cc', + 'src/core/lib/debug/stats.cc', + 'src/core/lib/debug/stats_data.cc', + 'src/core/lib/debug/trace.cc', + 'src/core/lib/event_engine/ares_resolver.cc', + 'src/core/lib/event_engine/cf_engine/cf_engine.cc', + 'src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc', + 'src/core/lib/event_engine/cf_engine/dns_service_resolver.cc', + 'src/core/lib/event_engine/channel_args_endpoint_config.cc', + 'src/core/lib/event_engine/default_event_engine.cc', + 'src/core/lib/event_engine/default_event_engine_factory.cc', + 'src/core/lib/event_engine/event_engine.cc', + 'src/core/lib/event_engine/forkable.cc', + 'src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc', + 'src/core/lib/event_engine/posix_engine/ev_poll_posix.cc', + 'src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc', + 'src/core/lib/event_engine/posix_engine/internal_errqueue.cc', + 'src/core/lib/event_engine/posix_engine/lockfree_event.cc', + 'src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc', + 'src/core/lib/event_engine/posix_engine/posix_endpoint.cc', + 'src/core/lib/event_engine/posix_engine/posix_engine.cc', + 'src/core/lib/event_engine/posix_engine/posix_engine_listener.cc', + 'src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.cc', + 'src/core/lib/event_engine/posix_engine/tcp_socket_utils.cc', + 'src/core/lib/event_engine/posix_engine/timer.cc', + 'src/core/lib/event_engine/posix_engine/timer_heap.cc', + 'src/core/lib/event_engine/posix_engine/timer_manager.cc', + 'src/core/lib/event_engine/posix_engine/traced_buffer_list.cc', + 'src/core/lib/event_engine/posix_engine/wakeup_fd_eventfd.cc', + 'src/core/lib/event_engine/posix_engine/wakeup_fd_pipe.cc', + 'src/core/lib/event_engine/posix_engine/wakeup_fd_posix_default.cc', + 'src/core/lib/event_engine/resolved_address.cc', + 'src/core/lib/event_engine/shim.cc', + 'src/core/lib/event_engine/slice.cc', + 'src/core/lib/event_engine/slice_buffer.cc', + 'src/core/lib/event_engine/tcp_socket_utils.cc', + 'src/core/lib/event_engine/thread_pool/thread_count.cc', + 'src/core/lib/event_engine/thread_pool/thread_pool_factory.cc', + 'src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.cc', + 'src/core/lib/event_engine/thready_event_engine/thready_event_engine.cc', + 'src/core/lib/event_engine/time_util.cc', + 'src/core/lib/event_engine/trace.cc', + 'src/core/lib/event_engine/utils.cc', + 'src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc', + 'src/core/lib/event_engine/windows/iocp.cc', + 'src/core/lib/event_engine/windows/native_windows_dns_resolver.cc', + 'src/core/lib/event_engine/windows/win_socket.cc', + 'src/core/lib/event_engine/windows/windows_endpoint.cc', + 'src/core/lib/event_engine/windows/windows_engine.cc', + 'src/core/lib/event_engine/windows/windows_listener.cc', + 'src/core/lib/event_engine/work_queue/basic_work_queue.cc', + 'src/core/lib/experiments/config.cc', + 'src/core/lib/experiments/experiments.cc', + 'src/core/lib/gprpp/load_file.cc', + 'src/core/lib/gprpp/per_cpu.cc', + 'src/core/lib/gprpp/ref_counted_string.cc', + 'src/core/lib/gprpp/status_helper.cc', + 'src/core/lib/gprpp/time.cc', + 'src/core/lib/gprpp/time_averaged_stats.cc', + 'src/core/lib/gprpp/validation_errors.cc', + 'src/core/lib/gprpp/work_serializer.cc', + 'src/core/lib/handshaker/proxy_mapper_registry.cc', + 'src/core/lib/http/format_request.cc', + 'src/core/lib/http/httpcli.cc', + 'src/core/lib/http/parser.cc', + 'src/core/lib/iomgr/buffer_list.cc', + 'src/core/lib/iomgr/call_combiner.cc', + 'src/core/lib/iomgr/cfstream_handle.cc', + 'src/core/lib/iomgr/closure.cc', + 'src/core/lib/iomgr/combiner.cc', + 'src/core/lib/iomgr/dualstack_socket_posix.cc', + 'src/core/lib/iomgr/endpoint.cc', + 'src/core/lib/iomgr/endpoint_cfstream.cc', + 'src/core/lib/iomgr/endpoint_pair_posix.cc', + 'src/core/lib/iomgr/endpoint_pair_windows.cc', + 'src/core/lib/iomgr/error.cc', + 'src/core/lib/iomgr/error_cfstream.cc', + 'src/core/lib/iomgr/ev_apple.cc', + 'src/core/lib/iomgr/ev_epoll1_linux.cc', + 'src/core/lib/iomgr/ev_poll_posix.cc', + 'src/core/lib/iomgr/ev_posix.cc', + 'src/core/lib/iomgr/ev_windows.cc', + 'src/core/lib/iomgr/event_engine_shims/closure.cc', + 'src/core/lib/iomgr/event_engine_shims/endpoint.cc', + 'src/core/lib/iomgr/event_engine_shims/tcp_client.cc', + 'src/core/lib/iomgr/exec_ctx.cc', + 'src/core/lib/iomgr/executor.cc', + 'src/core/lib/iomgr/fork_posix.cc', + 'src/core/lib/iomgr/fork_windows.cc', + 'src/core/lib/iomgr/gethostname_fallback.cc', + 'src/core/lib/iomgr/gethostname_host_name_max.cc', + 'src/core/lib/iomgr/gethostname_sysconf.cc', + 'src/core/lib/iomgr/grpc_if_nametoindex_posix.cc', + 'src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc', + 'src/core/lib/iomgr/internal_errqueue.cc', + 'src/core/lib/iomgr/iocp_windows.cc', + 'src/core/lib/iomgr/iomgr.cc', + 'src/core/lib/iomgr/iomgr_internal.cc', + 'src/core/lib/iomgr/iomgr_posix.cc', + 'src/core/lib/iomgr/iomgr_posix_cfstream.cc', + 'src/core/lib/iomgr/iomgr_windows.cc', + 'src/core/lib/iomgr/lockfree_event.cc', + 'src/core/lib/iomgr/polling_entity.cc', + 'src/core/lib/iomgr/pollset.cc', + 'src/core/lib/iomgr/pollset_set.cc', + 'src/core/lib/iomgr/pollset_set_windows.cc', + 'src/core/lib/iomgr/pollset_windows.cc', + 'src/core/lib/iomgr/resolve_address.cc', + 'src/core/lib/iomgr/resolve_address_posix.cc', + 'src/core/lib/iomgr/resolve_address_windows.cc', + 'src/core/lib/iomgr/sockaddr_utils_posix.cc', + 'src/core/lib/iomgr/socket_factory_posix.cc', + 'src/core/lib/iomgr/socket_mutator.cc', + 'src/core/lib/iomgr/socket_utils_common_posix.cc', + 'src/core/lib/iomgr/socket_utils_linux.cc', + 'src/core/lib/iomgr/socket_utils_posix.cc', + 'src/core/lib/iomgr/socket_utils_windows.cc', + 'src/core/lib/iomgr/socket_windows.cc', + 'src/core/lib/iomgr/systemd_utils.cc', + 'src/core/lib/iomgr/tcp_client.cc', + 'src/core/lib/iomgr/tcp_client_cfstream.cc', + 'src/core/lib/iomgr/tcp_client_posix.cc', + 'src/core/lib/iomgr/tcp_client_windows.cc', + 'src/core/lib/iomgr/tcp_posix.cc', + 'src/core/lib/iomgr/tcp_server.cc', + 'src/core/lib/iomgr/tcp_server_posix.cc', + 'src/core/lib/iomgr/tcp_server_utils_posix_common.cc', + 'src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.cc', + 'src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.cc', + 'src/core/lib/iomgr/tcp_server_windows.cc', + 'src/core/lib/iomgr/tcp_windows.cc', + 'src/core/lib/iomgr/timer.cc', + 'src/core/lib/iomgr/timer_generic.cc', + 'src/core/lib/iomgr/timer_heap.cc', + 'src/core/lib/iomgr/timer_manager.cc', + 'src/core/lib/iomgr/unix_sockets_posix.cc', + 'src/core/lib/iomgr/unix_sockets_posix_noop.cc', + 'src/core/lib/iomgr/vsock.cc', + 'src/core/lib/iomgr/wakeup_fd_eventfd.cc', + 'src/core/lib/iomgr/wakeup_fd_nospecial.cc', + 'src/core/lib/iomgr/wakeup_fd_pipe.cc', + 'src/core/lib/iomgr/wakeup_fd_posix.cc', + 'src/core/lib/json/json_object_loader.cc', + 'src/core/lib/json/json_reader.cc', + 'src/core/lib/json/json_writer.cc', + 'src/core/lib/promise/activity.cc', + 'src/core/lib/promise/party.cc', + 'src/core/lib/promise/sleep.cc', + 'src/core/lib/promise/trace.cc', + 'src/core/lib/resource_quota/api.cc', + 'src/core/lib/resource_quota/arena.cc', + 'src/core/lib/resource_quota/memory_quota.cc', + 'src/core/lib/resource_quota/periodic_update.cc', + 'src/core/lib/resource_quota/resource_quota.cc', + 'src/core/lib/resource_quota/thread_quota.cc', + 'src/core/lib/resource_quota/trace.cc', + 'src/core/lib/security/authorization/authorization_policy_provider_vtable.cc', + 'src/core/lib/security/authorization/evaluate_args.cc', + 'src/core/lib/security/authorization/grpc_server_authz_filter.cc', + 'src/core/lib/security/certificate_provider/certificate_provider_registry.cc', + 'src/core/lib/security/context/security_context.cc', + 'src/core/lib/security/credentials/alts/check_gcp_environment.cc', + '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_server_options.cc', + 'src/core/lib/security/credentials/call_creds_util.cc', + 'src/core/lib/security/credentials/composite/composite_credentials.cc', + 'src/core/lib/security/credentials/credentials.cc', + 'src/core/lib/security/credentials/fake/fake_credentials.cc', + 'src/core/lib/security/credentials/insecure/insecure_credentials.cc', + 'src/core/lib/security/credentials/plugin/plugin_credentials.cc', + 'src/core/lib/security/credentials/tls/tls_utils.cc', + 'src/core/lib/security/security_connector/fake/fake_security_connector.cc', + 'src/core/lib/security/security_connector/insecure/insecure_security_connector.cc', + '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_windows.cc', + 'src/core/lib/security/security_connector/security_connector.cc', + 'src/core/lib/security/transport/client_auth_filter.cc', + 'src/core/lib/security/transport/legacy_server_auth_filter.cc', + 'src/core/lib/security/transport/secure_endpoint.cc', + 'src/core/lib/security/transport/security_handshaker.cc', + 'src/core/lib/security/transport/server_auth_filter.cc', + 'src/core/lib/security/transport/tsi_error.cc', + 'src/core/lib/security/util/json_util.cc', + 'src/core/lib/slice/b64.cc', + 'src/core/lib/slice/percent_encoding.cc', + 'src/core/lib/slice/slice.cc', + 'src/core/lib/slice/slice_buffer.cc', + 'src/core/lib/slice/slice_refcount.cc', + 'src/core/lib/slice/slice_string_helpers.cc', + 'src/core/lib/surface/api_trace.cc', + 'src/core/lib/surface/byte_buffer.cc', + 'src/core/lib/surface/byte_buffer_reader.cc', + 'src/core/lib/surface/call.cc', + 'src/core/lib/surface/call_details.cc', + 'src/core/lib/surface/call_log_batch.cc', + 'src/core/lib/surface/channel.cc', + 'src/core/lib/surface/channel_create.cc', + 'src/core/lib/surface/channel_init.cc', + 'src/core/lib/surface/channel_stack_type.cc', + 'src/core/lib/surface/completion_queue.cc', + 'src/core/lib/surface/completion_queue_factory.cc', + 'src/core/lib/surface/event_string.cc', + 'src/core/lib/surface/init.cc', + 'src/core/lib/surface/init_internally.cc', + 'src/core/lib/surface/lame_client.cc', + 'src/core/lib/surface/legacy_channel.cc', + 'src/core/lib/surface/metadata_array.cc', + 'src/core/lib/surface/server.cc', + 'src/core/lib/surface/validate_metadata.cc', + 'src/core/lib/surface/version.cc', + 'src/core/lib/surface/wait_for_cq_end_op.cc', + 'src/core/lib/transport/batch_builder.cc', + 'src/core/lib/transport/bdp_estimator.cc', + 'src/core/lib/transport/call_filters.cc', + 'src/core/lib/transport/call_final_info.cc', + 'src/core/lib/transport/call_size_estimator.cc', + 'src/core/lib/transport/call_spine.cc', + 'src/core/lib/transport/connectivity_state.cc', + 'src/core/lib/transport/error_utils.cc', + 'src/core/lib/transport/handshaker.cc', + 'src/core/lib/transport/handshaker_registry.cc', + 'src/core/lib/transport/http_connect_handshaker.cc', + 'src/core/lib/transport/message.cc', + 'src/core/lib/transport/metadata.cc', + 'src/core/lib/transport/metadata_batch.cc', + 'src/core/lib/transport/metadata_info.cc', + 'src/core/lib/transport/parsed_metadata.cc', + 'src/core/lib/transport/status_conversion.cc', + 'src/core/lib/transport/tcp_connect_handshaker.cc', + 'src/core/lib/transport/timeout_encoding.cc', + 'src/core/lib/transport/transport.cc', + 'src/core/lib/transport/transport_op_string.cc', + 'src/core/lib/uri/uri_parser.cc', + 'src/core/load_balancing/address_filtering.cc', + 'src/core/load_balancing/backend_metric_parser.cc', + 'src/core/load_balancing/child_policy_handler.cc', + 'src/core/load_balancing/endpoint_list.cc', + 'src/core/load_balancing/grpclb/client_load_reporting_filter.cc', + 'src/core/load_balancing/grpclb/grpclb.cc', + 'src/core/load_balancing/grpclb/grpclb_balancer_addresses.cc', + 'src/core/load_balancing/grpclb/grpclb_client_stats.cc', + 'src/core/load_balancing/grpclb/load_balancer_api.cc', + 'src/core/load_balancing/health_check_client.cc', + 'src/core/load_balancing/lb_policy.cc', + 'src/core/load_balancing/lb_policy_registry.cc', + 'src/core/load_balancing/oob_backend_metric.cc', + 'src/core/load_balancing/outlier_detection/outlier_detection.cc', + 'src/core/load_balancing/pick_first/pick_first.cc', + 'src/core/load_balancing/priority/priority.cc', + 'src/core/load_balancing/rls/rls.cc', + 'src/core/load_balancing/round_robin/round_robin.cc', + 'src/core/load_balancing/weighted_round_robin/static_stride_scheduler.cc', + 'src/core/load_balancing/weighted_round_robin/weighted_round_robin.cc', + 'src/core/load_balancing/weighted_target/weighted_target.cc', + 'src/core/plugin_registry/grpc_plugin_registry.cc', + 'src/core/plugin_registry/grpc_plugin_registry_noextra.cc', + 'src/core/resolver/binder/binder_resolver.cc', + 'src/core/resolver/dns/c_ares/dns_resolver_ares.cc', + 'src/core/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc', + 'src/core/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc', + 'src/core/resolver/dns/c_ares/grpc_ares_wrapper.cc', + 'src/core/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc', + 'src/core/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc', + 'src/core/resolver/dns/dns_resolver_plugin.cc', + 'src/core/resolver/dns/event_engine/event_engine_client_channel_resolver.cc', + 'src/core/resolver/dns/event_engine/service_config_helper.cc', + 'src/core/resolver/dns/native/dns_resolver.cc', + 'src/core/resolver/endpoint_addresses.cc', + 'src/core/resolver/fake/fake_resolver.cc', + 'src/core/resolver/polling_resolver.cc', + 'src/core/resolver/resolver.cc', + 'src/core/resolver/resolver_registry.cc', + 'src/core/resolver/sockaddr/sockaddr_resolver.cc', + 'src/core/service_config/service_config_channel_arg_filter.cc', + 'src/core/service_config/service_config_impl.cc', + 'src/core/service_config/service_config_parser.cc', + 'src/core/tsi/alts/handshaker/transport_security_common_api.cc', + 'src/core/tsi/fake_transport_security.cc', + 'src/core/tsi/local_transport_security.cc', + 'src/core/tsi/transport_security.cc', + 'src/core/tsi/transport_security_grpc.cc', + 'third_party/upb/upb/message/accessors.c', + 'third_party/upb/upb/mini_descriptor/build_enum.c', + 'third_party/upb/upb/mini_descriptor/decode.c', + 'third_party/upb/upb/mini_descriptor/internal/base92.c', + 'third_party/upb/upb/mini_descriptor/internal/encode.c', + 'third_party/upb/upb/mini_descriptor/link.c', + 'third_party/upb/upb/wire/decode.c', + 'third_party/upb/upb/wire/decode_fast.c', + 'third_party/upb/upb/wire/encode.c', + 'third_party/upb/upb/wire/eps_copy_input_stream.c', + 'third_party/upb/upb/wire/reader.c', + ], + }, + { + 'target_name': 'gtest', + 'type': 'static_library', + 'dependencies': [ + 're2', + 'absl/container:flat_hash_set', + 'absl/debugging:failure_signal_handler', + 'absl/debugging:stacktrace', + 'absl/debugging:symbolize', + 'absl/flags:flag', + 'absl/flags:parse', + 'absl/flags:reflection', + 'absl/flags:usage', + 'absl/strings:strings', + 'absl/types:any', + 'absl/types:optional', + 'absl/types:variant', + ], + 'sources': [ + 'third_party/googletest/googlemock/src/gmock-cardinalities.cc', + 'third_party/googletest/googlemock/src/gmock-internal-utils.cc', + 'third_party/googletest/googlemock/src/gmock-matchers.cc', + 'third_party/googletest/googlemock/src/gmock-spec-builders.cc', + 'third_party/googletest/googlemock/src/gmock.cc', + 'third_party/googletest/googletest/src/gtest-assertion-result.cc', + 'third_party/googletest/googletest/src/gtest-death-test.cc', + 'third_party/googletest/googletest/src/gtest-filepath.cc', + 'third_party/googletest/googletest/src/gtest-matchers.cc', + 'third_party/googletest/googletest/src/gtest-port.cc', + 'third_party/googletest/googletest/src/gtest-printers.cc', + 'third_party/googletest/googletest/src/gtest-test-part.cc', + 'third_party/googletest/googletest/src/gtest-typed-test.cc', + 'third_party/googletest/googletest/src/gtest.cc', + ], + }, + { + 'target_name': 're2', + 'type': 'static_library', + 'dependencies': [ + ], + 'sources': [ + 'third_party/re2/re2/bitstate.cc', + 'third_party/re2/re2/compile.cc', + 'third_party/re2/re2/dfa.cc', + 'third_party/re2/re2/filtered_re2.cc', + 'third_party/re2/re2/mimics_pcre.cc', + 'third_party/re2/re2/nfa.cc', + 'third_party/re2/re2/onepass.cc', + 'third_party/re2/re2/parse.cc', + 'third_party/re2/re2/perl_groups.cc', + 'third_party/re2/re2/prefilter.cc', + 'third_party/re2/re2/prefilter_tree.cc', + 'third_party/re2/re2/prog.cc', + 'third_party/re2/re2/re2.cc', + 'third_party/re2/re2/regexp.cc', + 'third_party/re2/re2/set.cc', + 'third_party/re2/re2/simplify.cc', + 'third_party/re2/re2/stringpiece.cc', + 'third_party/re2/re2/tostring.cc', + 'third_party/re2/re2/unicode_casefold.cc', + 'third_party/re2/re2/unicode_groups.cc', + 'third_party/re2/util/rune.cc', + 'third_party/re2/util/strutil.cc', + ], + }, + { + 'target_name': 'upb_base_lib', + 'type': 'static_library', + 'dependencies': [ + ], + 'sources': [ + 'third_party/upb/upb/base/status.c', + ], + }, + { + 'target_name': 'upb_json_lib', + 'type': 'static_library', + 'dependencies': [ + 'upb_message_lib', + 'utf8_range_lib', + ], + 'sources': [ + 'src/core/ext/upb-gen/google/protobuf/descriptor.upb_minitable.c', + 'third_party/upb/upb/json/decode.c', + 'third_party/upb/upb/json/encode.c', + 'third_party/upb/upb/lex/atoi.c', + 'third_party/upb/upb/lex/round_trip.c', + 'third_party/upb/upb/lex/strtod.c', + 'third_party/upb/upb/lex/unicode.c', + 'third_party/upb/upb/message/accessors.c', + 'third_party/upb/upb/mini_descriptor/build_enum.c', + 'third_party/upb/upb/mini_descriptor/decode.c', + 'third_party/upb/upb/mini_descriptor/internal/base92.c', + 'third_party/upb/upb/mini_descriptor/internal/encode.c', + 'third_party/upb/upb/mini_descriptor/link.c', + 'third_party/upb/upb/reflection/def_pool.c', + 'third_party/upb/upb/reflection/def_type.c', + 'third_party/upb/upb/reflection/desc_state.c', + 'third_party/upb/upb/reflection/enum_def.c', + 'third_party/upb/upb/reflection/enum_reserved_range.c', + 'third_party/upb/upb/reflection/enum_value_def.c', + 'third_party/upb/upb/reflection/extension_range.c', + 'third_party/upb/upb/reflection/field_def.c', + 'third_party/upb/upb/reflection/file_def.c', + 'third_party/upb/upb/reflection/internal/def_builder.c', + 'third_party/upb/upb/reflection/internal/strdup2.c', + 'third_party/upb/upb/reflection/message.c', + 'third_party/upb/upb/reflection/message_def.c', + 'third_party/upb/upb/reflection/message_reserved_range.c', + 'third_party/upb/upb/reflection/method_def.c', + 'third_party/upb/upb/reflection/oneof_def.c', + 'third_party/upb/upb/reflection/service_def.c', + 'third_party/upb/upb/wire/decode.c', + 'third_party/upb/upb/wire/decode_fast.c', + 'third_party/upb/upb/wire/encode.c', + 'third_party/upb/upb/wire/eps_copy_input_stream.c', + 'third_party/upb/upb/wire/reader.c', + ], + }, + { + 'target_name': 'upb_mem_lib', + 'type': 'static_library', + 'dependencies': [ + ], + 'sources': [ + 'third_party/upb/upb/mem/alloc.c', + 'third_party/upb/upb/mem/arena.c', + ], + }, + { + 'target_name': 'upb_message_lib', + 'type': 'static_library', + 'dependencies': [ + 'upb_base_lib', + 'upb_mem_lib', + ], + 'sources': [ + 'third_party/upb/upb/hash/common.c', + 'third_party/upb/upb/message/array.c', + 'third_party/upb/upb/message/map.c', + 'third_party/upb/upb/message/map_sorter.c', + 'third_party/upb/upb/message/message.c', + 'third_party/upb/upb/mini_table/extension_registry.c', + 'third_party/upb/upb/mini_table/internal/message.c', + 'third_party/upb/upb/mini_table/message.c', + ], + }, + { + 'target_name': 'upb_textformat_lib', + 'type': 'static_library', + 'dependencies': [ + 'upb_message_lib', + 'utf8_range_lib', + ], + 'sources': [ + 'src/core/ext/upb-gen/google/protobuf/descriptor.upb_minitable.c', + 'third_party/upb/upb/lex/atoi.c', + 'third_party/upb/upb/lex/round_trip.c', + 'third_party/upb/upb/lex/strtod.c', + 'third_party/upb/upb/lex/unicode.c', + 'third_party/upb/upb/message/accessors.c', + 'third_party/upb/upb/mini_descriptor/build_enum.c', + 'third_party/upb/upb/mini_descriptor/decode.c', + 'third_party/upb/upb/mini_descriptor/internal/base92.c', + 'third_party/upb/upb/mini_descriptor/internal/encode.c', + 'third_party/upb/upb/mini_descriptor/link.c', + 'third_party/upb/upb/reflection/def_pool.c', + 'third_party/upb/upb/reflection/def_type.c', + 'third_party/upb/upb/reflection/desc_state.c', + 'third_party/upb/upb/reflection/enum_def.c', + 'third_party/upb/upb/reflection/enum_reserved_range.c', + 'third_party/upb/upb/reflection/enum_value_def.c', + 'third_party/upb/upb/reflection/extension_range.c', + 'third_party/upb/upb/reflection/field_def.c', + 'third_party/upb/upb/reflection/file_def.c', + 'third_party/upb/upb/reflection/internal/def_builder.c', + 'third_party/upb/upb/reflection/internal/strdup2.c', + 'third_party/upb/upb/reflection/message.c', + 'third_party/upb/upb/reflection/message_def.c', + 'third_party/upb/upb/reflection/message_reserved_range.c', + 'third_party/upb/upb/reflection/method_def.c', + 'third_party/upb/upb/reflection/oneof_def.c', + 'third_party/upb/upb/reflection/service_def.c', + 'third_party/upb/upb/text/encode.c', + 'third_party/upb/upb/wire/decode.c', + 'third_party/upb/upb/wire/decode_fast.c', + 'third_party/upb/upb/wire/encode.c', + 'third_party/upb/upb/wire/eps_copy_input_stream.c', + 'third_party/upb/upb/wire/reader.c', + ], + }, + { + 'target_name': 'utf8_range_lib', + 'type': 'static_library', + 'dependencies': [ + ], + 'sources': [ + 'third_party/utf8_range/naive.c', + 'third_party/utf8_range/range2-neon.c', + 'third_party/utf8_range/range2-sse.c', + ], + }, + { + 'target_name': 'z', + 'type': 'static_library', + 'dependencies': [ + ], + 'sources': [ + 'third_party/zlib/adler32.c', + 'third_party/zlib/compress.c', + 'third_party/zlib/crc32.c', + 'third_party/zlib/deflate.c', + 'third_party/zlib/infback.c', + 'third_party/zlib/inffast.c', + 'third_party/zlib/inflate.c', + 'third_party/zlib/inftrees.c', + 'third_party/zlib/trees.c', + 'third_party/zlib/uncompr.c', + 'third_party/zlib/zutil.c', + ], + }, + { + 'target_name': 'benchmark_helpers', + 'type': 'static_library', + 'dependencies': [ + 'benchmark', + 'grpc++_unsecure', + 'grpc_test_util_unsecure', + 'grpc++_test_config', + ], + 'sources': [ + 'src/proto/grpc/testing/echo.proto', + 'src/proto/grpc/testing/echo_messages.proto', + 'src/proto/grpc/testing/simple_messages.proto', + 'src/proto/grpc/testing/xds/v3/orca_load_report.proto', + 'test/core/util/cmdline.cc', + 'test/core/util/fuzzer_util.cc', + 'test/core/util/grpc_profiler.cc', + 'test/core/util/histogram.cc', + 'test/core/util/mock_endpoint.cc', + 'test/core/util/parse_hexstring.cc', + 'test/core/util/resolve_localhost_ip46.cc', + 'test/core/util/slice_splitter.cc', + 'test/core/util/tracer_util.cc', + 'test/cpp/microbenchmarks/helpers.cc', + ], + }, + { + 'target_name': 'grpc++', + 'type': 'static_library', + 'dependencies': [ + 'grpc', + 'protobuf', + ], + 'sources': [ + 'src/core/ext/transport/binder/client/binder_connector.cc', + 'src/core/ext/transport/binder/client/channel_create.cc', + 'src/core/ext/transport/binder/client/channel_create_impl.cc', + 'src/core/ext/transport/binder/client/connection_id_generator.cc', + 'src/core/ext/transport/binder/client/endpoint_binder_pool.cc', + 'src/core/ext/transport/binder/client/jni_utils.cc', + 'src/core/ext/transport/binder/client/security_policy_setting.cc', + 'src/core/ext/transport/binder/security_policy/binder_security_policy.cc', + 'src/core/ext/transport/binder/server/binder_server.cc', + 'src/core/ext/transport/binder/server/binder_server_credentials.cc', + 'src/core/ext/transport/binder/transport/binder_transport.cc', + 'src/core/ext/transport/binder/utils/ndk_binder.cc', + 'src/core/ext/transport/binder/utils/transport_stream_receiver_impl.cc', + 'src/core/ext/transport/binder/wire_format/binder_android.cc', + 'src/core/ext/transport/binder/wire_format/binder_constants.cc', + 'src/core/ext/transport/binder/wire_format/transaction.cc', + 'src/core/ext/transport/binder/wire_format/wire_reader_impl.cc', + 'src/core/ext/transport/binder/wire_format/wire_writer.cc', + 'src/cpp/client/channel_cc.cc', + 'src/cpp/client/client_callback.cc', + 'src/cpp/client/client_context.cc', + 'src/cpp/client/client_interceptor.cc', + 'src/cpp/client/client_stats_interceptor.cc', + 'src/cpp/client/create_channel.cc', + 'src/cpp/client/create_channel_internal.cc', + 'src/cpp/client/create_channel_posix.cc', + 'src/cpp/client/insecure_credentials.cc', + 'src/cpp/client/secure_credentials.cc', + 'src/cpp/client/xds_credentials.cc', + 'src/cpp/common/alarm.cc', + 'src/cpp/common/auth_property_iterator.cc', + 'src/cpp/common/channel_arguments.cc', + 'src/cpp/common/completion_queue_cc.cc', + 'src/cpp/common/resource_quota_cc.cc', + 'src/cpp/common/rpc_method.cc', + 'src/cpp/common/secure_auth_context.cc', + 'src/cpp/common/secure_channel_arguments.cc', + 'src/cpp/common/secure_create_auth_context.cc', + 'src/cpp/common/tls_certificate_provider.cc', + 'src/cpp/common/tls_certificate_verifier.cc', + 'src/cpp/common/tls_credentials_options.cc', + 'src/cpp/common/validate_service_config.cc', + 'src/cpp/common/version_cc.cc', + 'src/cpp/server/async_generic_service.cc', + 'src/cpp/server/backend_metric_recorder.cc', + 'src/cpp/server/channel_argument_option.cc', + 'src/cpp/server/create_default_thread_pool.cc', + 'src/cpp/server/external_connection_acceptor_impl.cc', + 'src/cpp/server/health/default_health_check_service.cc', + 'src/cpp/server/health/health_check_service.cc', + 'src/cpp/server/health/health_check_service_server_builder_option.cc', + 'src/cpp/server/insecure_server_credentials.cc', + 'src/cpp/server/secure_server_credentials.cc', + 'src/cpp/server/server_builder.cc', + 'src/cpp/server/server_callback.cc', + 'src/cpp/server/server_cc.cc', + 'src/cpp/server/server_context.cc', + 'src/cpp/server/server_posix.cc', + 'src/cpp/server/xds_server_builder.cc', + 'src/cpp/server/xds_server_credentials.cc', + 'src/cpp/thread_manager/thread_manager.cc', + 'src/cpp/util/byte_buffer_cc.cc', + 'src/cpp/util/status.cc', + 'src/cpp/util/string_ref.cc', + 'src/cpp/util/time_cc.cc', + ], + }, + { + 'target_name': 'grpc++_alts', + 'type': 'static_library', + 'dependencies': [ + 'grpc++', + ], + 'sources': [ + 'src/cpp/common/alts_context.cc', + 'src/cpp/common/alts_util.cc', + ], + }, + { + 'target_name': 'grpc++_error_details', + 'type': 'static_library', + 'dependencies': [ + 'grpc++', + ], + 'sources': [ + 'src/cpp/util/error_details.cc', + ], + }, + { + 'target_name': 'grpc++_reflection', + 'type': 'static_library', + 'dependencies': [ + 'grpc++', + ], + 'sources': [ + 'src/proto/grpc/reflection/v1/reflection.proto', + 'src/proto/grpc/reflection/v1alpha/reflection.proto', + 'src/cpp/ext/proto_server_reflection.cc', + 'src/cpp/ext/proto_server_reflection_plugin.cc', + ], + }, + { + 'target_name': 'grpc++_test', + 'type': 'static_library', + 'dependencies': [ + 'gtest', + 'grpc++', + ], + 'sources': [ + 'src/cpp/client/channel_test_peer.cc', + ], + }, + { + 'target_name': 'grpc++_test_config', + 'type': 'static_library', + 'dependencies': [ + 'absl/flags:parse', + 'gpr', + ], + 'sources': [ + 'test/cpp/util/test_config_cc.cc', + ], + }, + { + 'target_name': 'grpc++_test_util', + 'type': 'static_library', + 'dependencies': [ + 'grpc++', + 'grpc_test_util', + ], + 'sources': [ + 'src/core/lib/gpr/subprocess_posix.cc', + 'src/core/lib/gpr/subprocess_windows.cc', + 'test/core/end2end/data/client_certs.cc', + 'test/core/end2end/data/server1_cert.cc', + 'test/core/end2end/data/server1_key.cc', + 'test/core/end2end/data/test_root_cert.cc', + 'test/core/util/cmdline.cc', + 'test/core/util/fuzzer_util.cc', + 'test/core/util/grpc_profiler.cc', + 'test/core/util/histogram.cc', + 'test/core/util/mock_endpoint.cc', + 'test/core/util/parse_hexstring.cc', + 'test/core/util/resolve_localhost_ip46.cc', + 'test/core/util/slice_splitter.cc', + 'test/core/util/tracer_util.cc', + 'test/cpp/util/byte_buffer_proto_helper.cc', + 'test/cpp/util/create_test_channel.cc', + 'test/cpp/util/string_ref_helper.cc', + 'test/cpp/util/subprocess.cc', + 'test/cpp/util/test_credentials_provider.cc', + ], + }, + { + 'target_name': 'grpc++_unsecure', + 'type': 'static_library', + 'dependencies': [ + 'grpc_unsecure', + 'protobuf', + ], + 'sources': [ + 'src/cpp/client/channel_cc.cc', + 'src/cpp/client/client_callback.cc', + 'src/cpp/client/client_context.cc', + 'src/cpp/client/client_interceptor.cc', + 'src/cpp/client/client_stats_interceptor.cc', + 'src/cpp/client/create_channel.cc', + 'src/cpp/client/create_channel_internal.cc', + 'src/cpp/client/create_channel_posix.cc', + 'src/cpp/client/insecure_credentials.cc', + 'src/cpp/common/alarm.cc', + 'src/cpp/common/channel_arguments.cc', + 'src/cpp/common/completion_queue_cc.cc', + 'src/cpp/common/insecure_create_auth_context.cc', + 'src/cpp/common/resource_quota_cc.cc', + 'src/cpp/common/rpc_method.cc', + 'src/cpp/common/validate_service_config.cc', + 'src/cpp/common/version_cc.cc', + 'src/cpp/server/async_generic_service.cc', + 'src/cpp/server/backend_metric_recorder.cc', + 'src/cpp/server/channel_argument_option.cc', + 'src/cpp/server/create_default_thread_pool.cc', + 'src/cpp/server/external_connection_acceptor_impl.cc', + 'src/cpp/server/health/default_health_check_service.cc', + 'src/cpp/server/health/health_check_service.cc', + 'src/cpp/server/health/health_check_service_server_builder_option.cc', + 'src/cpp/server/insecure_server_credentials.cc', + 'src/cpp/server/server_builder.cc', + 'src/cpp/server/server_callback.cc', + 'src/cpp/server/server_cc.cc', + 'src/cpp/server/server_context.cc', + 'src/cpp/server/server_posix.cc', + 'src/cpp/thread_manager/thread_manager.cc', + 'src/cpp/util/byte_buffer_cc.cc', + 'src/cpp/util/status.cc', + 'src/cpp/util/string_ref.cc', + 'src/cpp/util/time_cc.cc', + ], + }, + { + 'target_name': 'grpc_authorization_provider', + 'type': 'static_library', + 'dependencies': [ + 'upb_message_lib', + 're2', + 'utf8_range_lib', + 'z', + 'absl/base:config', + 'absl/base:no_destructor', + 'absl/cleanup:cleanup', + 'absl/container:flat_hash_map', + 'absl/container:flat_hash_set', + 'absl/container:inlined_vector', + 'absl/functional:function_ref', + 'absl/hash:hash', + 'absl/meta:type_traits', + 'absl/random:bit_gen_ref', + 'absl/random:distributions', + 'absl/status:statusor', + 'absl/types:span', + 'absl/utility:utility', + 'cares', + 'gpr', + 'address_sorting', + ], + 'sources': [ + 'src/core/ext/upb-gen/google/protobuf/any.upb_minitable.c', + 'src/core/ext/upb-gen/google/protobuf/descriptor.upb_minitable.c', + 'src/core/ext/upb-gen/google/rpc/status.upb_minitable.c', + 'src/core/ext/upb-gen/src/proto/grpc/gcp/altscontext.upb_minitable.c', + 'src/core/ext/upb-gen/src/proto/grpc/gcp/handshaker.upb_minitable.c', + 'src/core/ext/upb-gen/src/proto/grpc/gcp/transport_security_common.upb_minitable.c', + 'src/core/lib/address_utils/parse_address.cc', + 'src/core/lib/address_utils/sockaddr_utils.cc', + 'src/core/lib/backoff/backoff.cc', + 'src/core/lib/backoff/random_early_detection.cc', + 'src/core/lib/channel/call_tracer.cc', + 'src/core/lib/channel/channel_args.cc', + 'src/core/lib/channel/channel_args_preconditioning.cc', + 'src/core/lib/channel/channel_stack.cc', + 'src/core/lib/channel/channel_stack_builder.cc', + 'src/core/lib/channel/channel_stack_builder_impl.cc', + 'src/core/lib/channel/channel_stack_trace.cc', + 'src/core/lib/channel/channel_trace.cc', + 'src/core/lib/channel/channelz.cc', + 'src/core/lib/channel/channelz_registry.cc', + 'src/core/lib/channel/connected_channel.cc', + 'src/core/lib/channel/metrics.cc', + 'src/core/lib/channel/promise_based_filter.cc', + 'src/core/lib/channel/status_util.cc', + 'src/core/lib/compression/compression.cc', + 'src/core/lib/compression/compression_internal.cc', + 'src/core/lib/compression/message_compress.cc', + 'src/core/lib/config/core_configuration.cc', + 'src/core/lib/debug/event_log.cc', + 'src/core/lib/debug/histogram_view.cc', + 'src/core/lib/debug/stats.cc', + 'src/core/lib/debug/stats_data.cc', + 'src/core/lib/debug/trace.cc', + 'src/core/lib/event_engine/ares_resolver.cc', + 'src/core/lib/event_engine/cf_engine/cf_engine.cc', + 'src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc', + 'src/core/lib/event_engine/cf_engine/dns_service_resolver.cc', + 'src/core/lib/event_engine/channel_args_endpoint_config.cc', + 'src/core/lib/event_engine/default_event_engine.cc', + 'src/core/lib/event_engine/default_event_engine_factory.cc', + 'src/core/lib/event_engine/event_engine.cc', + 'src/core/lib/event_engine/forkable.cc', + 'src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc', + 'src/core/lib/event_engine/posix_engine/ev_poll_posix.cc', + 'src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc', + 'src/core/lib/event_engine/posix_engine/internal_errqueue.cc', + 'src/core/lib/event_engine/posix_engine/lockfree_event.cc', + 'src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc', + 'src/core/lib/event_engine/posix_engine/posix_endpoint.cc', + 'src/core/lib/event_engine/posix_engine/posix_engine.cc', + 'src/core/lib/event_engine/posix_engine/posix_engine_listener.cc', + 'src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.cc', + 'src/core/lib/event_engine/posix_engine/tcp_socket_utils.cc', + 'src/core/lib/event_engine/posix_engine/timer.cc', + 'src/core/lib/event_engine/posix_engine/timer_heap.cc', + 'src/core/lib/event_engine/posix_engine/timer_manager.cc', + 'src/core/lib/event_engine/posix_engine/traced_buffer_list.cc', + 'src/core/lib/event_engine/posix_engine/wakeup_fd_eventfd.cc', + 'src/core/lib/event_engine/posix_engine/wakeup_fd_pipe.cc', + 'src/core/lib/event_engine/posix_engine/wakeup_fd_posix_default.cc', + 'src/core/lib/event_engine/resolved_address.cc', + 'src/core/lib/event_engine/shim.cc', + 'src/core/lib/event_engine/slice.cc', + 'src/core/lib/event_engine/slice_buffer.cc', + 'src/core/lib/event_engine/tcp_socket_utils.cc', + 'src/core/lib/event_engine/thread_pool/thread_count.cc', + 'src/core/lib/event_engine/thread_pool/thread_pool_factory.cc', + 'src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.cc', + 'src/core/lib/event_engine/thready_event_engine/thready_event_engine.cc', + 'src/core/lib/event_engine/time_util.cc', + 'src/core/lib/event_engine/trace.cc', + 'src/core/lib/event_engine/utils.cc', + 'src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc', + 'src/core/lib/event_engine/windows/iocp.cc', + 'src/core/lib/event_engine/windows/native_windows_dns_resolver.cc', + 'src/core/lib/event_engine/windows/win_socket.cc', + 'src/core/lib/event_engine/windows/windows_endpoint.cc', + 'src/core/lib/event_engine/windows/windows_engine.cc', + 'src/core/lib/event_engine/windows/windows_listener.cc', + 'src/core/lib/event_engine/work_queue/basic_work_queue.cc', + 'src/core/lib/experiments/config.cc', + 'src/core/lib/experiments/experiments.cc', + 'src/core/lib/gprpp/load_file.cc', + 'src/core/lib/gprpp/per_cpu.cc', + 'src/core/lib/gprpp/ref_counted_string.cc', + 'src/core/lib/gprpp/status_helper.cc', + 'src/core/lib/gprpp/time.cc', + 'src/core/lib/gprpp/time_averaged_stats.cc', + 'src/core/lib/gprpp/validation_errors.cc', + 'src/core/lib/gprpp/work_serializer.cc', + 'src/core/lib/handshaker/proxy_mapper_registry.cc', + 'src/core/lib/iomgr/buffer_list.cc', + 'src/core/lib/iomgr/call_combiner.cc', + 'src/core/lib/iomgr/cfstream_handle.cc', + 'src/core/lib/iomgr/closure.cc', + 'src/core/lib/iomgr/combiner.cc', + 'src/core/lib/iomgr/dualstack_socket_posix.cc', + 'src/core/lib/iomgr/endpoint.cc', + 'src/core/lib/iomgr/endpoint_cfstream.cc', + 'src/core/lib/iomgr/endpoint_pair_posix.cc', + 'src/core/lib/iomgr/endpoint_pair_windows.cc', + 'src/core/lib/iomgr/error.cc', + 'src/core/lib/iomgr/error_cfstream.cc', + 'src/core/lib/iomgr/ev_apple.cc', + 'src/core/lib/iomgr/ev_epoll1_linux.cc', + 'src/core/lib/iomgr/ev_poll_posix.cc', + 'src/core/lib/iomgr/ev_posix.cc', + 'src/core/lib/iomgr/ev_windows.cc', + 'src/core/lib/iomgr/event_engine_shims/closure.cc', + 'src/core/lib/iomgr/event_engine_shims/endpoint.cc', + 'src/core/lib/iomgr/event_engine_shims/tcp_client.cc', + 'src/core/lib/iomgr/exec_ctx.cc', + 'src/core/lib/iomgr/executor.cc', + 'src/core/lib/iomgr/fork_posix.cc', + 'src/core/lib/iomgr/fork_windows.cc', + 'src/core/lib/iomgr/gethostname_fallback.cc', + 'src/core/lib/iomgr/gethostname_host_name_max.cc', + 'src/core/lib/iomgr/gethostname_sysconf.cc', + 'src/core/lib/iomgr/grpc_if_nametoindex_posix.cc', + 'src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc', + 'src/core/lib/iomgr/internal_errqueue.cc', + 'src/core/lib/iomgr/iocp_windows.cc', + 'src/core/lib/iomgr/iomgr.cc', + 'src/core/lib/iomgr/iomgr_internal.cc', + 'src/core/lib/iomgr/iomgr_posix.cc', + 'src/core/lib/iomgr/iomgr_posix_cfstream.cc', + 'src/core/lib/iomgr/iomgr_windows.cc', + 'src/core/lib/iomgr/lockfree_event.cc', + 'src/core/lib/iomgr/polling_entity.cc', + 'src/core/lib/iomgr/pollset.cc', + 'src/core/lib/iomgr/pollset_set.cc', + 'src/core/lib/iomgr/pollset_set_windows.cc', + 'src/core/lib/iomgr/pollset_windows.cc', + 'src/core/lib/iomgr/resolve_address.cc', + 'src/core/lib/iomgr/resolve_address_posix.cc', + 'src/core/lib/iomgr/resolve_address_windows.cc', + 'src/core/lib/iomgr/sockaddr_utils_posix.cc', + 'src/core/lib/iomgr/socket_factory_posix.cc', + 'src/core/lib/iomgr/socket_mutator.cc', + 'src/core/lib/iomgr/socket_utils_common_posix.cc', + 'src/core/lib/iomgr/socket_utils_linux.cc', + 'src/core/lib/iomgr/socket_utils_posix.cc', + 'src/core/lib/iomgr/socket_utils_windows.cc', + 'src/core/lib/iomgr/socket_windows.cc', + 'src/core/lib/iomgr/systemd_utils.cc', + 'src/core/lib/iomgr/tcp_client.cc', + 'src/core/lib/iomgr/tcp_client_cfstream.cc', + 'src/core/lib/iomgr/tcp_client_posix.cc', + 'src/core/lib/iomgr/tcp_client_windows.cc', + 'src/core/lib/iomgr/tcp_posix.cc', + 'src/core/lib/iomgr/tcp_server.cc', + 'src/core/lib/iomgr/tcp_server_posix.cc', + 'src/core/lib/iomgr/tcp_server_utils_posix_common.cc', + 'src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.cc', + 'src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.cc', + 'src/core/lib/iomgr/tcp_server_windows.cc', + 'src/core/lib/iomgr/tcp_windows.cc', + 'src/core/lib/iomgr/timer.cc', + 'src/core/lib/iomgr/timer_generic.cc', + 'src/core/lib/iomgr/timer_heap.cc', + 'src/core/lib/iomgr/timer_manager.cc', + 'src/core/lib/iomgr/unix_sockets_posix.cc', + 'src/core/lib/iomgr/unix_sockets_posix_noop.cc', + 'src/core/lib/iomgr/vsock.cc', + 'src/core/lib/iomgr/wakeup_fd_eventfd.cc', + 'src/core/lib/iomgr/wakeup_fd_nospecial.cc', + 'src/core/lib/iomgr/wakeup_fd_pipe.cc', + 'src/core/lib/iomgr/wakeup_fd_posix.cc', + 'src/core/lib/json/json_reader.cc', + 'src/core/lib/json/json_writer.cc', + 'src/core/lib/matchers/matchers.cc', + 'src/core/lib/promise/activity.cc', + 'src/core/lib/promise/party.cc', + 'src/core/lib/promise/trace.cc', + 'src/core/lib/resource_quota/api.cc', + 'src/core/lib/resource_quota/arena.cc', + 'src/core/lib/resource_quota/memory_quota.cc', + 'src/core/lib/resource_quota/periodic_update.cc', + 'src/core/lib/resource_quota/resource_quota.cc', + 'src/core/lib/resource_quota/thread_quota.cc', + 'src/core/lib/resource_quota/trace.cc', + 'src/core/lib/security/authorization/audit_logging.cc', + 'src/core/lib/security/authorization/authorization_policy_provider_vtable.cc', + 'src/core/lib/security/authorization/evaluate_args.cc', + 'src/core/lib/security/authorization/grpc_authorization_engine.cc', + 'src/core/lib/security/authorization/grpc_authorization_policy_provider.cc', + 'src/core/lib/security/authorization/grpc_server_authz_filter.cc', + 'src/core/lib/security/authorization/matchers.cc', + 'src/core/lib/security/authorization/rbac_policy.cc', + 'src/core/lib/security/authorization/rbac_translator.cc', + 'src/core/lib/security/authorization/stdout_logger.cc', + 'src/core/lib/security/certificate_provider/certificate_provider_registry.cc', + 'src/core/lib/security/context/security_context.cc', + 'src/core/lib/security/credentials/alts/check_gcp_environment.cc', + '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_server_options.cc', + 'src/core/lib/security/credentials/call_creds_util.cc', + 'src/core/lib/security/credentials/composite/composite_credentials.cc', + 'src/core/lib/security/credentials/credentials.cc', + 'src/core/lib/security/credentials/plugin/plugin_credentials.cc', + 'src/core/lib/security/credentials/tls/tls_utils.cc', + '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_windows.cc', + 'src/core/lib/security/security_connector/security_connector.cc', + 'src/core/lib/security/transport/client_auth_filter.cc', + 'src/core/lib/security/transport/legacy_server_auth_filter.cc', + 'src/core/lib/security/transport/secure_endpoint.cc', + 'src/core/lib/security/transport/security_handshaker.cc', + 'src/core/lib/security/transport/server_auth_filter.cc', + 'src/core/lib/security/transport/tsi_error.cc', + 'src/core/lib/security/util/json_util.cc', + 'src/core/lib/slice/b64.cc', + 'src/core/lib/slice/percent_encoding.cc', + 'src/core/lib/slice/slice.cc', + 'src/core/lib/slice/slice_buffer.cc', + 'src/core/lib/slice/slice_refcount.cc', + 'src/core/lib/slice/slice_string_helpers.cc', + 'src/core/lib/surface/api_trace.cc', + 'src/core/lib/surface/byte_buffer.cc', + 'src/core/lib/surface/byte_buffer_reader.cc', + 'src/core/lib/surface/call.cc', + 'src/core/lib/surface/call_details.cc', + 'src/core/lib/surface/call_log_batch.cc', + 'src/core/lib/surface/channel.cc', + 'src/core/lib/surface/channel_init.cc', + 'src/core/lib/surface/channel_stack_type.cc', + 'src/core/lib/surface/completion_queue.cc', + 'src/core/lib/surface/completion_queue_factory.cc', + 'src/core/lib/surface/event_string.cc', + 'src/core/lib/surface/init_internally.cc', + 'src/core/lib/surface/lame_client.cc', + 'src/core/lib/surface/metadata_array.cc', + 'src/core/lib/surface/validate_metadata.cc', + 'src/core/lib/surface/version.cc', + 'src/core/lib/surface/wait_for_cq_end_op.cc', + 'src/core/lib/transport/batch_builder.cc', + 'src/core/lib/transport/call_filters.cc', + 'src/core/lib/transport/call_final_info.cc', + 'src/core/lib/transport/call_size_estimator.cc', + 'src/core/lib/transport/call_spine.cc', + 'src/core/lib/transport/connectivity_state.cc', + 'src/core/lib/transport/error_utils.cc', + 'src/core/lib/transport/handshaker.cc', + 'src/core/lib/transport/handshaker_registry.cc', + 'src/core/lib/transport/message.cc', + 'src/core/lib/transport/metadata.cc', + 'src/core/lib/transport/metadata_batch.cc', + 'src/core/lib/transport/parsed_metadata.cc', + 'src/core/lib/transport/status_conversion.cc', + 'src/core/lib/transport/timeout_encoding.cc', + 'src/core/lib/transport/transport.cc', + 'src/core/lib/transport/transport_op_string.cc', + 'src/core/lib/uri/uri_parser.cc', + 'src/core/load_balancing/lb_policy.cc', + 'src/core/load_balancing/lb_policy_registry.cc', + 'src/core/resolver/endpoint_addresses.cc', + 'src/core/resolver/resolver.cc', + 'src/core/resolver/resolver_registry.cc', + 'src/core/service_config/service_config_parser.cc', + 'src/core/tsi/alts/handshaker/transport_security_common_api.cc', + 'src/core/tsi/transport_security.cc', + 'src/core/tsi/transport_security_grpc.cc', + 'third_party/upb/upb/message/accessors.c', + 'third_party/upb/upb/mini_descriptor/build_enum.c', + 'third_party/upb/upb/mini_descriptor/decode.c', + 'third_party/upb/upb/mini_descriptor/internal/base92.c', + 'third_party/upb/upb/mini_descriptor/internal/encode.c', + 'third_party/upb/upb/mini_descriptor/link.c', + 'third_party/upb/upb/wire/decode.c', + 'third_party/upb/upb/wire/decode_fast.c', + 'third_party/upb/upb/wire/encode.c', + 'third_party/upb/upb/wire/eps_copy_input_stream.c', + 'third_party/upb/upb/wire/reader.c', + ], + }, + { + 'target_name': 'grpc_plugin_support', + 'type': 'static_library', + 'dependencies': [ + 'protobuf', + 'protoc', + ], + 'sources': [ + 'src/compiler/cpp_generator.cc', + 'src/compiler/csharp_generator.cc', + 'src/compiler/node_generator.cc', + 'src/compiler/objective_c_generator.cc', + 'src/compiler/php_generator.cc', + 'src/compiler/proto_parser_helper.cc', + 'src/compiler/python_generator.cc', + 'src/compiler/ruby_generator.cc', + ], + }, + { + 'target_name': 'grpcpp_channelz', + 'type': 'static_library', + 'dependencies': [ + 'grpc++', + ], + 'sources': [ + 'src/proto/grpc/channelz/channelz.proto', + 'src/cpp/server/channelz/channelz_service.cc', + 'src/cpp/server/channelz/channelz_service_plugin.cc', + ], + }, + { + 'target_name': 'boringssl', + 'type': 'static_library', + 'dependencies': [ + ], + 'sources': [ + 'third_party/boringssl-with-bazel/err_data.c', + 'third_party/boringssl-with-bazel/src/crypto/asn1/a_bitstr.c', + 'third_party/boringssl-with-bazel/src/crypto/asn1/a_bool.c', + 'third_party/boringssl-with-bazel/src/crypto/asn1/a_d2i_fp.c', + 'third_party/boringssl-with-bazel/src/crypto/asn1/a_dup.c', + 'third_party/boringssl-with-bazel/src/crypto/asn1/a_gentm.c', + 'third_party/boringssl-with-bazel/src/crypto/asn1/a_i2d_fp.c', + 'third_party/boringssl-with-bazel/src/crypto/asn1/a_int.c', + 'third_party/boringssl-with-bazel/src/crypto/asn1/a_mbstr.c', + 'third_party/boringssl-with-bazel/src/crypto/asn1/a_object.c', + 'third_party/boringssl-with-bazel/src/crypto/asn1/a_octet.c', + 'third_party/boringssl-with-bazel/src/crypto/asn1/a_strex.c', + 'third_party/boringssl-with-bazel/src/crypto/asn1/a_strnid.c', + 'third_party/boringssl-with-bazel/src/crypto/asn1/a_time.c', + 'third_party/boringssl-with-bazel/src/crypto/asn1/a_type.c', + 'third_party/boringssl-with-bazel/src/crypto/asn1/a_utctm.c', + 'third_party/boringssl-with-bazel/src/crypto/asn1/asn1_lib.c', + 'third_party/boringssl-with-bazel/src/crypto/asn1/asn1_par.c', + 'third_party/boringssl-with-bazel/src/crypto/asn1/asn_pack.c', + 'third_party/boringssl-with-bazel/src/crypto/asn1/f_int.c', + 'third_party/boringssl-with-bazel/src/crypto/asn1/f_string.c', + 'third_party/boringssl-with-bazel/src/crypto/asn1/posix_time.c', + 'third_party/boringssl-with-bazel/src/crypto/asn1/tasn_dec.c', + 'third_party/boringssl-with-bazel/src/crypto/asn1/tasn_enc.c', + 'third_party/boringssl-with-bazel/src/crypto/asn1/tasn_fre.c', + 'third_party/boringssl-with-bazel/src/crypto/asn1/tasn_new.c', + 'third_party/boringssl-with-bazel/src/crypto/asn1/tasn_typ.c', + 'third_party/boringssl-with-bazel/src/crypto/asn1/tasn_utl.c', + 'third_party/boringssl-with-bazel/src/crypto/base64/base64.c', + 'third_party/boringssl-with-bazel/src/crypto/bio/bio.c', + 'third_party/boringssl-with-bazel/src/crypto/bio/bio_mem.c', + 'third_party/boringssl-with-bazel/src/crypto/bio/connect.c', + 'third_party/boringssl-with-bazel/src/crypto/bio/errno.c', + 'third_party/boringssl-with-bazel/src/crypto/bio/fd.c', + 'third_party/boringssl-with-bazel/src/crypto/bio/file.c', + 'third_party/boringssl-with-bazel/src/crypto/bio/hexdump.c', + 'third_party/boringssl-with-bazel/src/crypto/bio/pair.c', + 'third_party/boringssl-with-bazel/src/crypto/bio/printf.c', + 'third_party/boringssl-with-bazel/src/crypto/bio/socket.c', + 'third_party/boringssl-with-bazel/src/crypto/bio/socket_helper.c', + 'third_party/boringssl-with-bazel/src/crypto/blake2/blake2.c', + 'third_party/boringssl-with-bazel/src/crypto/bn_extra/bn_asn1.c', + 'third_party/boringssl-with-bazel/src/crypto/bn_extra/convert.c', + 'third_party/boringssl-with-bazel/src/crypto/buf/buf.c', + 'third_party/boringssl-with-bazel/src/crypto/bytestring/asn1_compat.c', + 'third_party/boringssl-with-bazel/src/crypto/bytestring/ber.c', + 'third_party/boringssl-with-bazel/src/crypto/bytestring/cbb.c', + 'third_party/boringssl-with-bazel/src/crypto/bytestring/cbs.c', + 'third_party/boringssl-with-bazel/src/crypto/bytestring/unicode.c', + 'third_party/boringssl-with-bazel/src/crypto/chacha/chacha.c', + 'third_party/boringssl-with-bazel/src/crypto/cipher_extra/cipher_extra.c', + 'third_party/boringssl-with-bazel/src/crypto/cipher_extra/derive_key.c', + 'third_party/boringssl-with-bazel/src/crypto/cipher_extra/e_aesctrhmac.c', + 'third_party/boringssl-with-bazel/src/crypto/cipher_extra/e_aesgcmsiv.c', + 'third_party/boringssl-with-bazel/src/crypto/cipher_extra/e_chacha20poly1305.c', + 'third_party/boringssl-with-bazel/src/crypto/cipher_extra/e_des.c', + 'third_party/boringssl-with-bazel/src/crypto/cipher_extra/e_null.c', + 'third_party/boringssl-with-bazel/src/crypto/cipher_extra/e_rc2.c', + 'third_party/boringssl-with-bazel/src/crypto/cipher_extra/e_rc4.c', + 'third_party/boringssl-with-bazel/src/crypto/cipher_extra/e_tls.c', + 'third_party/boringssl-with-bazel/src/crypto/cipher_extra/tls_cbc.c', + 'third_party/boringssl-with-bazel/src/crypto/conf/conf.c', + 'third_party/boringssl-with-bazel/src/crypto/cpu_aarch64_apple.c', + 'third_party/boringssl-with-bazel/src/crypto/cpu_aarch64_fuchsia.c', + 'third_party/boringssl-with-bazel/src/crypto/cpu_aarch64_linux.c', + 'third_party/boringssl-with-bazel/src/crypto/cpu_aarch64_openbsd.c', + 'third_party/boringssl-with-bazel/src/crypto/cpu_aarch64_sysreg.c', + 'third_party/boringssl-with-bazel/src/crypto/cpu_aarch64_win.c', + 'third_party/boringssl-with-bazel/src/crypto/cpu_arm_freebsd.c', + 'third_party/boringssl-with-bazel/src/crypto/cpu_arm_linux.c', + 'third_party/boringssl-with-bazel/src/crypto/cpu_intel.c', + 'third_party/boringssl-with-bazel/src/crypto/crypto.c', + 'third_party/boringssl-with-bazel/src/crypto/curve25519/curve25519.c', + 'third_party/boringssl-with-bazel/src/crypto/curve25519/curve25519_64_adx.c', + 'third_party/boringssl-with-bazel/src/crypto/curve25519/spake25519.c', + 'third_party/boringssl-with-bazel/src/crypto/des/des.c', + 'third_party/boringssl-with-bazel/src/crypto/dh_extra/dh_asn1.c', + 'third_party/boringssl-with-bazel/src/crypto/dh_extra/params.c', + 'third_party/boringssl-with-bazel/src/crypto/digest_extra/digest_extra.c', + 'third_party/boringssl-with-bazel/src/crypto/dsa/dsa.c', + 'third_party/boringssl-with-bazel/src/crypto/dsa/dsa_asn1.c', + 'third_party/boringssl-with-bazel/src/crypto/ec_extra/ec_asn1.c', + 'third_party/boringssl-with-bazel/src/crypto/ec_extra/ec_derive.c', + 'third_party/boringssl-with-bazel/src/crypto/ec_extra/hash_to_curve.c', + 'third_party/boringssl-with-bazel/src/crypto/ecdh_extra/ecdh_extra.c', + 'third_party/boringssl-with-bazel/src/crypto/ecdsa_extra/ecdsa_asn1.c', + 'third_party/boringssl-with-bazel/src/crypto/engine/engine.c', + 'third_party/boringssl-with-bazel/src/crypto/err/err.c', + 'third_party/boringssl-with-bazel/src/crypto/evp/evp.c', + 'third_party/boringssl-with-bazel/src/crypto/evp/evp_asn1.c', + 'third_party/boringssl-with-bazel/src/crypto/evp/evp_ctx.c', + 'third_party/boringssl-with-bazel/src/crypto/evp/p_dsa_asn1.c', + 'third_party/boringssl-with-bazel/src/crypto/evp/p_ec.c', + 'third_party/boringssl-with-bazel/src/crypto/evp/p_ec_asn1.c', + 'third_party/boringssl-with-bazel/src/crypto/evp/p_ed25519.c', + 'third_party/boringssl-with-bazel/src/crypto/evp/p_ed25519_asn1.c', + 'third_party/boringssl-with-bazel/src/crypto/evp/p_hkdf.c', + 'third_party/boringssl-with-bazel/src/crypto/evp/p_rsa.c', + 'third_party/boringssl-with-bazel/src/crypto/evp/p_rsa_asn1.c', + 'third_party/boringssl-with-bazel/src/crypto/evp/p_x25519.c', + 'third_party/boringssl-with-bazel/src/crypto/evp/p_x25519_asn1.c', + 'third_party/boringssl-with-bazel/src/crypto/evp/pbkdf.c', + 'third_party/boringssl-with-bazel/src/crypto/evp/print.c', + 'third_party/boringssl-with-bazel/src/crypto/evp/scrypt.c', + 'third_party/boringssl-with-bazel/src/crypto/evp/sign.c', + 'third_party/boringssl-with-bazel/src/crypto/ex_data.c', + 'third_party/boringssl-with-bazel/src/crypto/fipsmodule/bcm.c', + 'third_party/boringssl-with-bazel/src/crypto/fipsmodule/fips_shared_support.c', + 'third_party/boringssl-with-bazel/src/crypto/hpke/hpke.c', + 'third_party/boringssl-with-bazel/src/crypto/hrss/hrss.c', + 'third_party/boringssl-with-bazel/src/crypto/keccak/keccak.c', + 'third_party/boringssl-with-bazel/src/crypto/kyber/kyber.c', + 'third_party/boringssl-with-bazel/src/crypto/lhash/lhash.c', + 'third_party/boringssl-with-bazel/src/crypto/mem.c', + 'third_party/boringssl-with-bazel/src/crypto/obj/obj.c', + 'third_party/boringssl-with-bazel/src/crypto/obj/obj_xref.c', + 'third_party/boringssl-with-bazel/src/crypto/pem/pem_all.c', + 'third_party/boringssl-with-bazel/src/crypto/pem/pem_info.c', + 'third_party/boringssl-with-bazel/src/crypto/pem/pem_lib.c', + 'third_party/boringssl-with-bazel/src/crypto/pem/pem_oth.c', + 'third_party/boringssl-with-bazel/src/crypto/pem/pem_pk8.c', + 'third_party/boringssl-with-bazel/src/crypto/pem/pem_pkey.c', + 'third_party/boringssl-with-bazel/src/crypto/pem/pem_x509.c', + 'third_party/boringssl-with-bazel/src/crypto/pem/pem_xaux.c', + 'third_party/boringssl-with-bazel/src/crypto/pkcs7/pkcs7.c', + 'third_party/boringssl-with-bazel/src/crypto/pkcs7/pkcs7_x509.c', + 'third_party/boringssl-with-bazel/src/crypto/pkcs8/p5_pbev2.c', + 'third_party/boringssl-with-bazel/src/crypto/pkcs8/pkcs8.c', + 'third_party/boringssl-with-bazel/src/crypto/pkcs8/pkcs8_x509.c', + 'third_party/boringssl-with-bazel/src/crypto/poly1305/poly1305.c', + 'third_party/boringssl-with-bazel/src/crypto/poly1305/poly1305_arm.c', + 'third_party/boringssl-with-bazel/src/crypto/poly1305/poly1305_vec.c', + 'third_party/boringssl-with-bazel/src/crypto/pool/pool.c', + 'third_party/boringssl-with-bazel/src/crypto/rand_extra/deterministic.c', + 'third_party/boringssl-with-bazel/src/crypto/rand_extra/forkunsafe.c', + 'third_party/boringssl-with-bazel/src/crypto/rand_extra/getentropy.c', + 'third_party/boringssl-with-bazel/src/crypto/rand_extra/ios.c', + 'third_party/boringssl-with-bazel/src/crypto/rand_extra/passive.c', + 'third_party/boringssl-with-bazel/src/crypto/rand_extra/rand_extra.c', + 'third_party/boringssl-with-bazel/src/crypto/rand_extra/trusty.c', + 'third_party/boringssl-with-bazel/src/crypto/rand_extra/windows.c', + 'third_party/boringssl-with-bazel/src/crypto/rc4/rc4.c', + 'third_party/boringssl-with-bazel/src/crypto/refcount.c', + 'third_party/boringssl-with-bazel/src/crypto/rsa_extra/rsa_asn1.c', + 'third_party/boringssl-with-bazel/src/crypto/rsa_extra/rsa_crypt.c', + 'third_party/boringssl-with-bazel/src/crypto/rsa_extra/rsa_print.c', + 'third_party/boringssl-with-bazel/src/crypto/siphash/siphash.c', + 'third_party/boringssl-with-bazel/src/crypto/spx/address.c', + 'third_party/boringssl-with-bazel/src/crypto/spx/fors.c', + 'third_party/boringssl-with-bazel/src/crypto/spx/merkle.c', + 'third_party/boringssl-with-bazel/src/crypto/spx/spx.c', + 'third_party/boringssl-with-bazel/src/crypto/spx/spx_util.c', + 'third_party/boringssl-with-bazel/src/crypto/spx/thash.c', + 'third_party/boringssl-with-bazel/src/crypto/spx/wots.c', + 'third_party/boringssl-with-bazel/src/crypto/stack/stack.c', + 'third_party/boringssl-with-bazel/src/crypto/thread.c', + 'third_party/boringssl-with-bazel/src/crypto/thread_none.c', + 'third_party/boringssl-with-bazel/src/crypto/thread_pthread.c', + 'third_party/boringssl-with-bazel/src/crypto/thread_win.c', + 'third_party/boringssl-with-bazel/src/crypto/trust_token/pmbtoken.c', + 'third_party/boringssl-with-bazel/src/crypto/trust_token/trust_token.c', + 'third_party/boringssl-with-bazel/src/crypto/trust_token/voprf.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/a_digest.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/a_sign.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/a_verify.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/algorithm.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/asn1_gen.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/by_dir.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/by_file.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/i2d_pr.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/name_print.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/policy.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/rsa_pss.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/t_crl.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/t_req.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/t_x509.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/t_x509a.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/v3_akey.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/v3_akeya.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/v3_alt.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/v3_bcons.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/v3_bitst.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/v3_conf.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/v3_cpols.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/v3_crld.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/v3_enum.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/v3_extku.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/v3_genn.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/v3_ia5.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/v3_info.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/v3_int.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/v3_lib.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/v3_ncons.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/v3_ocsp.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/v3_pcons.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/v3_pmaps.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/v3_prn.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/v3_purp.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/v3_skey.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/v3_utl.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/x509.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/x509_att.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/x509_cmp.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/x509_d2.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/x509_def.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/x509_ext.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/x509_lu.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/x509_obj.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/x509_req.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/x509_set.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/x509_trs.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/x509_txt.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/x509_v3.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/x509_vfy.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/x509_vpm.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/x509cset.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/x509name.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/x509rset.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/x509spki.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/x_algor.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/x_all.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/x_attrib.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/x_crl.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/x_exten.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/x_name.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/x_pubkey.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/x_req.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/x_sig.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/x_spki.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/x_val.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/x_x509.c', + 'third_party/boringssl-with-bazel/src/crypto/x509/x_x509a.c', + 'third_party/boringssl-with-bazel/src/ssl/bio_ssl.cc', + 'third_party/boringssl-with-bazel/src/ssl/d1_both.cc', + 'third_party/boringssl-with-bazel/src/ssl/d1_lib.cc', + 'third_party/boringssl-with-bazel/src/ssl/d1_pkt.cc', + 'third_party/boringssl-with-bazel/src/ssl/d1_srtp.cc', + 'third_party/boringssl-with-bazel/src/ssl/dtls_method.cc', + 'third_party/boringssl-with-bazel/src/ssl/dtls_record.cc', + 'third_party/boringssl-with-bazel/src/ssl/encrypted_client_hello.cc', + 'third_party/boringssl-with-bazel/src/ssl/extensions.cc', + 'third_party/boringssl-with-bazel/src/ssl/handoff.cc', + 'third_party/boringssl-with-bazel/src/ssl/handshake.cc', + 'third_party/boringssl-with-bazel/src/ssl/handshake_client.cc', + 'third_party/boringssl-with-bazel/src/ssl/handshake_server.cc', + 'third_party/boringssl-with-bazel/src/ssl/s3_both.cc', + 'third_party/boringssl-with-bazel/src/ssl/s3_lib.cc', + 'third_party/boringssl-with-bazel/src/ssl/s3_pkt.cc', + 'third_party/boringssl-with-bazel/src/ssl/ssl_aead_ctx.cc', + 'third_party/boringssl-with-bazel/src/ssl/ssl_asn1.cc', + 'third_party/boringssl-with-bazel/src/ssl/ssl_buffer.cc', + 'third_party/boringssl-with-bazel/src/ssl/ssl_cert.cc', + 'third_party/boringssl-with-bazel/src/ssl/ssl_cipher.cc', + 'third_party/boringssl-with-bazel/src/ssl/ssl_file.cc', + 'third_party/boringssl-with-bazel/src/ssl/ssl_key_share.cc', + 'third_party/boringssl-with-bazel/src/ssl/ssl_lib.cc', + 'third_party/boringssl-with-bazel/src/ssl/ssl_privkey.cc', + 'third_party/boringssl-with-bazel/src/ssl/ssl_session.cc', + 'third_party/boringssl-with-bazel/src/ssl/ssl_stat.cc', + 'third_party/boringssl-with-bazel/src/ssl/ssl_transcript.cc', + 'third_party/boringssl-with-bazel/src/ssl/ssl_versions.cc', + 'third_party/boringssl-with-bazel/src/ssl/ssl_x509.cc', + 'third_party/boringssl-with-bazel/src/ssl/t1_enc.cc', + 'third_party/boringssl-with-bazel/src/ssl/tls13_both.cc', + 'third_party/boringssl-with-bazel/src/ssl/tls13_client.cc', + 'third_party/boringssl-with-bazel/src/ssl/tls13_enc.cc', + 'third_party/boringssl-with-bazel/src/ssl/tls13_server.cc', + 'third_party/boringssl-with-bazel/src/ssl/tls_method.cc', + 'third_party/boringssl-with-bazel/src/ssl/tls_record.cc', + ], + }, + { + 'target_name': 'boringssl_test_util', + 'type': 'static_library', + 'dependencies': [ + ], + 'sources': [ + 'third_party/boringssl-with-bazel/src/crypto/test/abi_test.cc', + 'third_party/boringssl-with-bazel/src/crypto/test/file_test.cc', + 'third_party/boringssl-with-bazel/src/crypto/test/test_util.cc', + 'third_party/boringssl-with-bazel/src/crypto/test/wycheproof_util.cc', + ], + }, + { + 'target_name': 'benchmark', + 'type': 'static_library', + 'dependencies': [ + ], + 'sources': [ + 'third_party/benchmark/src/benchmark.cc', + 'third_party/benchmark/src/benchmark_api_internal.cc', + 'third_party/benchmark/src/benchmark_main.cc', + 'third_party/benchmark/src/benchmark_name.cc', + 'third_party/benchmark/src/benchmark_register.cc', + 'third_party/benchmark/src/benchmark_runner.cc', + 'third_party/benchmark/src/check.cc', + 'third_party/benchmark/src/colorprint.cc', + 'third_party/benchmark/src/commandlineflags.cc', + 'third_party/benchmark/src/complexity.cc', + 'third_party/benchmark/src/console_reporter.cc', + 'third_party/benchmark/src/counter.cc', + 'third_party/benchmark/src/csv_reporter.cc', + 'third_party/benchmark/src/json_reporter.cc', + 'third_party/benchmark/src/perf_counters.cc', + 'third_party/benchmark/src/reporter.cc', + 'third_party/benchmark/src/statistics.cc', + 'third_party/benchmark/src/string_util.cc', + 'third_party/benchmark/src/sysinfo.cc', + 'third_party/benchmark/src/timers.cc', + ], + }, + ] +} diff --git a/package.xml b/package.xml index 647d5677ee5..ece4e779a1e 100644 --- a/package.xml +++ b/package.xml @@ -113,6 +113,8 @@ + + @@ -1529,6 +1531,7 @@ + diff --git a/src/core/BUILD b/src/core/BUILD index c0432c3f37f..81adcd19b91 100644 --- a/src/core/BUILD +++ b/src/core/BUILD @@ -7483,6 +7483,8 @@ grpc_cc_library( "1999", "call_arena_allocator", "call_filters", + "call_final_info", + "dual_ref_counted", "for_each", "if", "latch", diff --git a/src/core/client_channel/client_channel.cc b/src/core/client_channel/client_channel.cc new file mode 100644 index 00000000000..57a30a517e0 --- /dev/null +++ b/src/core/client_channel/client_channel.cc @@ -0,0 +1,1977 @@ +// +// 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 + +#include "src/core/client_channel/client_channel.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "absl/cleanup/cleanup.h" +#include "absl/status/status.h" +#include "absl/status/statusor.h" +#include "absl/strings/cord.h" +#include "absl/strings/numbers.h" +#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 +#include +#include +#include +#include +#include +#include +#include + +#include "src/core/ext/filters/channel_idle/channel_idle_filter.h" +#include "src/core/client_channel/backup_poller.h" +#include "src/core/client_channel/client_channel_channelz.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" +#include "src/core/client_channel/dynamic_filters.h" +#include "src/core/client_channel/global_subchannel_pool.h" +#include "src/core/client_channel/local_subchannel_pool.h" +#include "src/core/client_channel/retry_filter.h" +#include "src/core/client_channel/subchannel.h" +#include "src/core/client_channel/subchannel_interface_internal.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/channel/channel_stack.h" +#include "src/core/lib/channel/channel_trace.h" +#include "src/core/lib/channel/metrics.h" +#include "src/core/lib/channel/promise_based_filter.h" +#include "src/core/lib/channel/status_util.h" +#include "src/core/lib/config/core_configuration.h" +#include "src/core/lib/debug/trace.h" +#include "src/core/lib/experiments/experiments.h" +#include "src/core/lib/gpr/useful.h" +#include "src/core/lib/gprpp/crash.h" +#include "src/core/lib/gprpp/debug_location.h" +#include "src/core/lib/gprpp/manual_constructor.h" +#include "src/core/lib/gprpp/status_helper.h" +#include "src/core/lib/gprpp/sync.h" +#include "src/core/lib/gprpp/unique_type_name.h" +#include "src/core/lib/gprpp/work_serializer.h" +#include "src/core/lib/handshaker/proxy_mapper_registry.h" +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/iomgr/resolved_address.h" +#include "src/core/lib/json/json.h" +#include "src/core/lib/promise/cancel_callback.h" +#include "src/core/lib/promise/context.h" +#include "src/core/lib/promise/exec_ctx_wakeup_scheduler.h" +#include "src/core/lib/promise/latch.h" +#include "src/core/lib/promise/map.h" +#include "src/core/lib/promise/pipe.h" +#include "src/core/lib/promise/poll.h" +#include "src/core/lib/promise/promise.h" +#include "src/core/lib/promise/sleep.h" +#include "src/core/lib/promise/status_flag.h" +#include "src/core/lib/promise/try_seq.h" +#include "src/core/lib/resource_quota/resource_quota.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/completion_queue.h" +#include "src/core/lib/transport/call_spine.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.h" +#include "src/core/load_balancing/lb_policy_registry.h" +#include "src/core/load_balancing/subchannel_interface.h" +#include "src/core/resolver/endpoint_addresses.h" +#include "src/core/resolver/resolver_registry.h" +#include "src/core/service_config/service_config_call_data.h" +#include "src/core/service_config/service_config_impl.h" + +namespace grpc_core { + +using grpc_event_engine::experimental::EventEngine; + +using internal::ClientChannelMethodParsedConfig; + +// Defined in legacy client channel filter. +// TODO(roth): Move these here when we remove the legacy filter. +extern TraceFlag grpc_client_channel_trace; +extern TraceFlag grpc_client_channel_call_trace; +extern TraceFlag grpc_client_channel_lb_call_trace; + +// +// ClientChannel::ResolverResultHandler +// + +class ClientChannel::ResolverResultHandler : public Resolver::ResultHandler { + public: + explicit ResolverResultHandler( + RefCountedPtr client_channel) + : client_channel_(std::move(client_channel)) {} + + ~ResolverResultHandler() override { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) { + gpr_log(GPR_INFO, "client_channel=%p: resolver shutdown complete", + client_channel_.get()); + } + } + + void ReportResult(Resolver::Result result) override + ABSL_EXCLUSIVE_LOCKS_REQUIRED(*client_channel_->work_serializer_) { + client_channel_->OnResolverResultChangedLocked(std::move(result)); + } + + private: + RefCountedPtr client_channel_; +}; + +// +// ClientChannel::SubchannelWrapper +// + +// This class is a wrapper for Subchannel that hides details of the +// channel's implementation (such as the connected subchannel) from the +// LB policy API. +// +// Note that no synchronization is needed here, because even if the +// underlying subchannel is shared between channels, this wrapper will only +// be used within one channel, so it will always be synchronized by the +// control plane work_serializer. +class ClientChannel::SubchannelWrapper : public SubchannelInterface { + public: + SubchannelWrapper(RefCountedPtr client_channel, + RefCountedPtr subchannel) + : SubchannelInterface(GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace) + ? "SubchannelWrapper" + : nullptr), + client_channel_(std::move(client_channel)), + subchannel_(std::move(subchannel)) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) { + gpr_log( + GPR_INFO, + "client_channel=%p: creating subchannel wrapper %p for subchannel %p", + client_channel_.get(), this, subchannel_.get()); + } + GPR_DEBUG_ASSERT( + client_channel_->work_serializer_->RunningInWorkSerializer()); + if (client_channel_->channelz_node_ != nullptr) { + auto* subchannel_node = subchannel_->channelz_node(); + if (subchannel_node != nullptr) { + 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()); + it = client_channel_->subchannel_refcount_map_.emplace( + subchannel_.get(), 0) + .first; + } + ++it->second; + } + } + client_channel_->subchannel_wrappers_.insert(this); + } + + ~SubchannelWrapper() override { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) { + gpr_log(GPR_INFO, + "client_channel=%p: destroying subchannel wrapper %p " + "for subchannel %p", + client_channel_.get(), this, subchannel_.get()); + } + } + + void Orphan() override { + // Make sure we clean up the channel's subchannel maps inside the + // WorkSerializer. + WeakRefAsSubclass( + DEBUG_LOCATION, "subchannel map cleanup") + .release(); + client_channel_->work_serializer_->Run( + [this]() + ABSL_EXCLUSIVE_LOCKS_REQUIRED(*client_channel_->work_serializer_) { + client_channel_->subchannel_wrappers_.erase(this); + if (client_channel_->channelz_node_ != nullptr) { + auto* subchannel_node = subchannel_->channelz_node(); + if (subchannel_node != nullptr) { + auto it = client_channel_->subchannel_refcount_map_.find( + subchannel_.get()); + GPR_ASSERT(it != client_channel_->subchannel_refcount_map_.end()); + --it->second; + if (it->second == 0) { + client_channel_->channelz_node_->RemoveChildSubchannel( + subchannel_node->uuid()); + client_channel_->subchannel_refcount_map_.erase(it); + } + } + } + WeakUnref(DEBUG_LOCATION, "subchannel map cleanup"); + }, + DEBUG_LOCATION); + } + + void WatchConnectivityState( + std::unique_ptr watcher) override + ABSL_EXCLUSIVE_LOCKS_REQUIRED(*client_channel_->work_serializer_) { + auto& watcher_wrapper = watcher_map_[watcher.get()]; + GPR_ASSERT(watcher_wrapper == nullptr); + watcher_wrapper = new WatcherWrapper( + std::move(watcher), + RefAsSubclass(DEBUG_LOCATION, "WatcherWrapper")); + subchannel_->WatchConnectivityState( + RefCountedPtr( + watcher_wrapper)); + } + + void CancelConnectivityStateWatch(ConnectivityStateWatcherInterface* watcher) + override + ABSL_EXCLUSIVE_LOCKS_REQUIRED(*client_channel_->work_serializer_) { + auto it = watcher_map_.find(watcher); + GPR_ASSERT(it != watcher_map_.end()); + subchannel_->CancelConnectivityStateWatch(it->second); + watcher_map_.erase(it); + } + + RefCountedPtr connected_subchannel() const { + return subchannel_->connected_subchannel(); + } + + void RequestConnection() override { subchannel_->RequestConnection(); } + + void ResetBackoff() override { subchannel_->ResetBackoff(); } + + void AddDataWatcher(std::unique_ptr watcher) override + ABSL_EXCLUSIVE_LOCKS_REQUIRED(*client_channel_->work_serializer_) { + static_cast(watcher.get()) + ->SetSubchannel(subchannel_.get()); + GPR_ASSERT(data_watchers_.insert(std::move(watcher)).second); + } + + void CancelDataWatcher(DataWatcherInterface* watcher) override + ABSL_EXCLUSIVE_LOCKS_REQUIRED(*client_channel_->work_serializer_) { + auto it = data_watchers_.find(watcher); + if (it != data_watchers_.end()) data_watchers_.erase(it); + } + + void ThrottleKeepaliveTime(int new_keepalive_time) { + subchannel_->ThrottleKeepaliveTime(new_keepalive_time); + } + + private: + // This wrapper provides a bridge between the internal Subchannel API + // and the SubchannelInterface API that we expose to LB policies. + // It implements Subchannel::ConnectivityStateWatcherInterface and wraps + // the instance of SubchannelInterface::ConnectivityStateWatcherInterface + // that was passed in by the LB policy. We pass an instance of this + // class to the underlying Subchannel, and when we get updates from + // the subchannel, we pass those on to the wrapped watcher to return + // the update to the LB policy. + // + // This class handles things like hopping into the WorkSerializer + // before passing notifications to the LB policy and propagating + // keepalive information betwen subchannels. + class WatcherWrapper : public Subchannel::ConnectivityStateWatcherInterface { + public: + WatcherWrapper( + std::unique_ptr + watcher, + RefCountedPtr subchannel_wrapper) + : watcher_(std::move(watcher)), + subchannel_wrapper_(std::move(subchannel_wrapper)) {} + + ~WatcherWrapper() override { + subchannel_wrapper_.reset(DEBUG_LOCATION, "WatcherWrapper"); + } + + void OnConnectivityStateChange( + RefCountedPtr self, + grpc_connectivity_state state, const absl::Status& status) override { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) { + gpr_log(GPR_INFO, + "client_channel=%p: connectivity change for subchannel " + "wrapper %p subchannel %p; hopping into work_serializer", + subchannel_wrapper_->client_channel_.get(), + subchannel_wrapper_.get(), + subchannel_wrapper_->subchannel_.get()); + } + self.release(); // Held by callback. + 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); + } + + grpc_pollset_set* interested_parties() override { + return watcher_->interested_parties(); + } + + private: + void ApplyUpdateInControlPlaneWorkSerializer(grpc_connectivity_state state, + const absl::Status& status) + ABSL_EXCLUSIVE_LOCKS_REQUIRED( + *subchannel_wrapper_->client_channel_->work_serializer_) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) { + gpr_log(GPR_INFO, + "client_channel=%p: processing connectivity change in work " + "serializer for subchannel wrapper %p subchannel %p watcher=%p " + "state=%s status=%s", + subchannel_wrapper_->client_channel_.get(), + subchannel_wrapper_.get(), + subchannel_wrapper_->subchannel_.get(), watcher_.get(), + ConnectivityStateName(state), status.ToString().c_str()); + } + absl::optional keepalive_throttling = + status.GetPayload(kKeepaliveThrottlingKey); + if (keepalive_throttling.has_value()) { + int new_keepalive_time = -1; + if (absl::SimpleAtoi(std::string(keepalive_throttling.value()), + &new_keepalive_time)) { + if (new_keepalive_time > + subchannel_wrapper_->client_channel_->keepalive_time_) { + subchannel_wrapper_->client_channel_->keepalive_time_ = + new_keepalive_time; + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) { + gpr_log(GPR_INFO, + "client_channel=%p: throttling keepalive time to %d", + subchannel_wrapper_->client_channel_.get(), + subchannel_wrapper_->client_channel_->keepalive_time_); + } + // Propagate the new keepalive time to all subchannels. This is so + // that new transports created by any subchannel (and not just the + // subchannel that received the GOAWAY), use the new keepalive time. + for (auto* subchannel_wrapper : + subchannel_wrapper_->client_channel_->subchannel_wrappers_) { + subchannel_wrapper->ThrottleKeepaliveTime(new_keepalive_time); + } + } + } else { + gpr_log(GPR_ERROR, + "client_channel=%p: Illegal keepalive throttling value %s", + subchannel_wrapper_->client_channel_.get(), + std::string(keepalive_throttling.value()).c_str()); + } + } + // Propagate status only in state TF. + // We specifically want to avoid propagating the status for + // state IDLE that the real subchannel gave us only for the + // purpose of keepalive propagation. + watcher_->OnConnectivityStateChange( + state, + state == GRPC_CHANNEL_TRANSIENT_FAILURE ? status : absl::OkStatus()); + } + + std::unique_ptr + watcher_; + RefCountedPtr subchannel_wrapper_; + }; + + // A heterogenous lookup comparator for data watchers that allows + // unique_ptr keys to be looked up as raw pointers. + struct DataWatcherLessThan { + using is_transparent = void; + bool operator()(const std::unique_ptr& p1, + const std::unique_ptr& p2) const { + return p1 < p2; + } + bool operator()(const std::unique_ptr& p1, + const DataWatcherInterface* p2) const { + return p1.get() < p2; + } + bool operator()(const DataWatcherInterface* p1, + const std::unique_ptr& p2) const { + return p1 < p2.get(); + } + }; + + RefCountedPtr client_channel_; + RefCountedPtr subchannel_; + // Maps from the address of the watcher passed to us by the LB policy + // to the address of the WrapperWatcher that we passed to the underlying + // subchannel. This is needed so that when the LB policy calls + // CancelConnectivityStateWatch() with its watcher, we know the + // corresponding WrapperWatcher to cancel on the underlying subchannel. + std::map watcher_map_ + ABSL_GUARDED_BY(*client_channel_->work_serializer_); + std::set, DataWatcherLessThan> + data_watchers_ ABSL_GUARDED_BY(*client_channel_->work_serializer_); +}; + +// +// ClientChannel::ClientChannelControlHelper +// + +class ClientChannel::ClientChannelControlHelper + : public LoadBalancingPolicy::ChannelControlHelper { + public: + explicit ClientChannelControlHelper( + RefCountedPtr client_channel) + : client_channel_(std::move(client_channel)) {} + + ~ClientChannelControlHelper() override { + client_channel_.reset(DEBUG_LOCATION, "ClientChannelControlHelper"); + } + + RefCountedPtr CreateSubchannel( + const grpc_resolved_address& address, const ChannelArgs& per_address_args, + const ChannelArgs& args) override + ABSL_EXCLUSIVE_LOCKS_REQUIRED(*client_channel_->work_serializer_) { + // If shutting down, do nothing. + if (client_channel_->resolver_ == nullptr) return nullptr; + ChannelArgs subchannel_args = Subchannel::MakeSubchannelArgs( + args, per_address_args, client_channel_->subchannel_pool_, + client_channel_->default_authority_); + // Create subchannel. + RefCountedPtr subchannel = + client_channel_->client_channel_factory_->CreateSubchannel( + address, subchannel_args); + if (subchannel == nullptr) return nullptr; + // Make sure the subchannel has updated keepalive time. + subchannel->ThrottleKeepaliveTime(client_channel_->keepalive_time_); + // Create and return wrapper for the subchannel. + return MakeRefCounted(client_channel_, + std::move(subchannel)); + } + + void UpdateState(grpc_connectivity_state state, const absl::Status& status, + RefCountedPtr picker) + override ABSL_EXCLUSIVE_LOCKS_REQUIRED( + *client_channel_->work_serializer_) { + if (client_channel_->resolver_ == nullptr) return; // Shutting down. + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) { + const char* extra = client_channel_->disconnect_error_.ok() + ? "" + : " (ignoring -- channel shutting down)"; + gpr_log(GPR_INFO, + "client_channel=%p: update: state=%s status=(%s) picker=%p%s", + client_channel_.get(), ConnectivityStateName(state), + status.ToString().c_str(), picker.get(), extra); + } + // Do update only if not shutting down. + if (client_channel_->disconnect_error_.ok()) { + client_channel_->UpdateStateAndPickerLocked(state, status, "helper", + std::move(picker)); + } + } + + void RequestReresolution() override + ABSL_EXCLUSIVE_LOCKS_REQUIRED(*client_channel_->work_serializer_) { + if (client_channel_->resolver_ == nullptr) return; // Shutting down. + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) { + gpr_log(GPR_INFO, "client_channel=%p: started name re-resolving", + client_channel_.get()); + } + client_channel_->resolver_->RequestReresolutionLocked(); + } + + absl::string_view GetTarget() override { return client_channel_->target(); } + + absl::string_view GetAuthority() override { + return client_channel_->default_authority_; + } + + RefCountedPtr GetChannelCredentials() override { + return client_channel_->channel_args_.GetObject() + ->duplicate_without_call_credentials(); + } + + RefCountedPtr GetUnsafeChannelCredentials() + override { + return client_channel_->channel_args_.GetObject() + ->Ref(); + } + + EventEngine* GetEventEngine() override { + return client_channel_->event_engine(); + } + + GlobalStatsPluginRegistry::StatsPluginGroup& GetStatsPluginGroup() override { + return client_channel_->stats_plugin_group_; + } + + void AddTraceEvent(TraceSeverity severity, absl::string_view message) override + ABSL_EXCLUSIVE_LOCKS_REQUIRED(*client_channel_->work_serializer_) { + if (client_channel_->resolver_ == nullptr) return; // Shutting down. + if (client_channel_->channelz_node_ != nullptr) { + client_channel_->channelz_node_->AddTraceEvent( + ConvertSeverityEnum(severity), + grpc_slice_from_copied_buffer(message.data(), message.size())); + } + } + + private: + static channelz::ChannelTrace::Severity ConvertSeverityEnum( + TraceSeverity severity) { + if (severity == TRACE_INFO) return channelz::ChannelTrace::Info; + if (severity == TRACE_WARNING) return channelz::ChannelTrace::Warning; + return channelz::ChannelTrace::Error; + } + + RefCountedPtr client_channel_; +}; + +// +// ClientChannel::LoadBalancedCallDestination +// + +// Context type for subchannel call tracker. +template <> +struct ContextType {}; + +// Context type for LB on_commit callback. +using LbOnCommit = absl::AnyInvocable; +template <> +struct ContextType {}; + +namespace { + +class LbMetadata : public LoadBalancingPolicy::MetadataInterface { + public: + explicit LbMetadata(grpc_metadata_batch* batch) : batch_(batch) {} + + void Add(absl::string_view key, absl::string_view value) override { + if (batch_ == nullptr) return; + // Gross, egregious hack to support legacy grpclb behavior. + // TODO(ctiller): Use a promise context for this once that plumbing is done. + if (key == GrpcLbClientStatsMetadata::key()) { + batch_->Set( + GrpcLbClientStatsMetadata(), + const_cast( + reinterpret_cast(value.data()))); + return; + } + batch_->Append(key, Slice::FromStaticString(value), + [key](absl::string_view error, const Slice& value) { + gpr_log(GPR_ERROR, "%s", + absl::StrCat(error, " key:", key, + " value:", value.as_string_view()) + .c_str()); + }); + } + + std::vector> TestOnlyCopyToVector() + override { + if (batch_ == nullptr) return {}; + Encoder encoder; + batch_->Encode(&encoder); + return encoder.Take(); + } + + absl::optional Lookup(absl::string_view key, + std::string* buffer) const override { + if (batch_ == nullptr) return absl::nullopt; + return batch_->GetStringValue(key, buffer); + } + + private: + class Encoder { + public: + void Encode(const Slice& key, const Slice& value) { + out_.emplace_back(std::string(key.as_string_view()), + std::string(value.as_string_view())); + } + + template + void Encode(Which, const typename Which::ValueType& value) { + auto value_slice = Which::Encode(value); + out_.emplace_back(std::string(Which::key()), + std::string(value_slice.as_string_view())); + } + + void Encode(GrpcTimeoutMetadata, + const typename GrpcTimeoutMetadata::ValueType&) {} + void Encode(HttpPathMetadata, const Slice&) {} + void Encode(HttpMethodMetadata, + const typename HttpMethodMetadata::ValueType&) {} + + std::vector> Take() { + return std::move(out_); + } + + private: + std::vector> out_; + }; + + grpc_metadata_batch* batch_; +}; + +ClientCallTracer* GetCallTracerFromContext() { + auto* legacy_context = GetContext(); + return static_cast( + legacy_context[GRPC_CONTEXT_CALL_TRACER_ANNOTATION_INTERFACE].value); +} + +void MaybeCreateCallAttemptTracer(bool is_transparent_retry) { + auto* call_tracer = GetCallTracerFromContext(); + if (call_tracer == nullptr) return; + auto* tracer = call_tracer->StartNewAttempt(is_transparent_retry); + auto* legacy_context = GetContext(); + legacy_context[GRPC_CONTEXT_CALL_TRACER].value = tracer; +} + +ClientCallTracer::CallAttemptTracer* GetCallAttemptTracerFromContext() { + auto* legacy_context = GetContext(); + return static_cast( + legacy_context[GRPC_CONTEXT_CALL_TRACER].value); +} + +// A filter to handle updating with the call tracer and LB subchannel +// call tracker inside the LB call. +// FIXME: move this to its own file, register only when call v3 +// experiment is enabled +class LbCallTracingFilter : public ImplementChannelFilter { + public: + static absl::StatusOr Create(const ChannelArgs&, + ChannelFilter::Args) { + return LbCallTracingFilter(); + } + + class Call { + public: + void OnClientInitialMetadata(ClientMetadata& metadata) { + auto* tracer = GetCallAttemptTracerFromContext(); + if (tracer == nullptr) return; + tracer->RecordSendInitialMetadata(&metadata); + } + + void OnServerInitialMetadata(ServerMetadata& metadata) { + auto* tracer = GetCallAttemptTracerFromContext(); + if (tracer == nullptr) return; + tracer->RecordReceivedInitialMetadata(&metadata); + // Save peer string for later use. + Slice* peer_string = metadata.get_pointer(PeerString()); + if (peer_string != nullptr) peer_string_ = peer_string->Ref(); + } + + static const NoInterceptor OnClientToServerMessage; + static const NoInterceptor OnServerToClientMessage; + + // FIXME(ctiller): Add this hook to the L1 filter API + void OnClientToServerMessagesClosed() { + auto* tracer = GetCallAttemptTracerFromContext(); + if (tracer == nullptr) return; + // TODO(roth): Change CallTracer API to not pass metadata + // batch to this method, since the batch is always empty. + grpc_metadata_batch metadata(GetContext()); + tracer->RecordSendTrailingMetadata(&metadata); + } + + void OnServerTrailingMetadata(ServerMetadata& metadata) { + auto* tracer = GetCallAttemptTracerFromContext(); + auto* call_tracker = + GetContext(); + absl::Status status; + if (tracer != nullptr || + (call_tracker != nullptr && *call_tracker != nullptr)) { + grpc_status_code code = metadata.get(GrpcStatusMetadata()) + .value_or(GRPC_STATUS_UNKNOWN); + if (code != GRPC_STATUS_OK) { + absl::string_view message; + if (const auto* grpc_message = + metadata.get_pointer(GrpcMessageMetadata())) { + message = grpc_message->as_string_view(); + } + status = + absl::Status(static_cast(code), message); + } + } + if (tracer != nullptr) { + tracer->RecordReceivedTrailingMetadata( + status, &metadata, + &GetContext()->call_stats()->transport_stream_stats); + } + if (call_tracker != nullptr && *call_tracker != nullptr) { + LbMetadata lb_metadata(&metadata); + BackendMetricAccessor backend_metric_accessor(&metadata); + LoadBalancingPolicy::SubchannelCallTrackerInterface::FinishArgs args = { + peer_string_.as_string_view(), status, &lb_metadata, + &backend_metric_accessor}; + (*call_tracker)->Finish(args); + delete *call_tracker; + } + } + + void OnFinalize(const grpc_call_final_info*) { + auto* tracer = GetCallAttemptTracerFromContext(); + if (tracer == nullptr) return; + gpr_timespec latency = + gpr_cycle_counter_sub(gpr_get_cycle_counter(), lb_call_start_time_); + tracer->RecordEnd(latency); + } + + private: + // Interface for accessing backend metric data in the LB call tracker. + class BackendMetricAccessor + : public LoadBalancingPolicy::BackendMetricAccessor { + public: + explicit BackendMetricAccessor( + grpc_metadata_batch* server_trailing_metadata) + : server_trailing_metadata_(server_trailing_metadata) {} + + ~BackendMetricAccessor() override { + if (backend_metric_data_ != nullptr) { + backend_metric_data_->BackendMetricData::~BackendMetricData(); + } + } + + const BackendMetricData* GetBackendMetricData() override { + if (backend_metric_data_ == nullptr) { + if (const auto* md = server_trailing_metadata_->get_pointer( + EndpointLoadMetricsBinMetadata())) { + BackendMetricAllocator allocator; + backend_metric_data_ = + ParseBackendMetricData(md->as_string_view(), &allocator); + } + } + return backend_metric_data_; + } + + private: + class BackendMetricAllocator : public BackendMetricAllocatorInterface { + public: + BackendMetricData* AllocateBackendMetricData() override { + return GetContext()->New(); + } + + char* AllocateString(size_t size) override { + return static_cast(GetContext()->Alloc(size)); + } + }; + + grpc_metadata_batch* server_trailing_metadata_; + const BackendMetricData* backend_metric_data_ = nullptr; + }; + +// FIXME: this isn't the right place to measure this from -- should be +// doing it from before we do the LB pick + gpr_cycle_counter lb_call_start_time_ = gpr_get_cycle_counter(); + Slice peer_string_; + }; +}; + +const NoInterceptor LbCallTracingFilter::Call::OnClientToServerMessage; +const NoInterceptor LbCallTracingFilter::Call::OnServerToClientMessage; + +} // namespace + +class ClientChannel::LoadBalancedCallDestination : public CallDestination { + public: + explicit LoadBalancedCallDestination( + RefCountedPtr client_channel) + : client_channel_(std::move(client_channel)) {} + + void Orphan() override {} + + void StartCall(UnstartedCallHandler unstarted_handler) override { + // If there is a call tracer, create a call attempt tracer. + bool* is_transparent_retry_metadata = + unstarted_handler.UnprocessedClientInitialMetadata()->get_pointer( + IsTransparentRetry()); + bool is_transparent_retry = + is_transparent_retry_metadata != nullptr + ? *is_transparent_retry_metadata + : false; + MaybeCreateCallAttemptTracer(is_transparent_retry); + // Spawn a promise to do the LB pick. + // This will eventually start the call. + unstarted_handler.SpawnGuarded( + "lb_pick", + [client_channel = client_channel_, was_queued = true, + unstarted_handler = std::move(unstarted_handler)]() mutable { + return Map( + // Wait for the LB picker. + Loop([last_picker = + RefCountedPtr(), + client_channel = std::move(client_channel), + unstarted_handler, &was_queued]() mutable { + return Map( + client_channel->picker_.Next(last_picker), + [client_channel, unstarted_handler, &last_picker, + &was_queued]( + RefCountedPtr + picker) mutable { + last_picker = std::move(picker); + // Returns 3 possible things: + // - Continue to queue the pick + // - non-OK status to fail the pick + // - a connected subchannel to complete the pick + auto result = client_channel->PickSubchannel( + *last_picker, unstarted_handler); + if (absl::holds_alternative(result)) { + was_queued = true; + } + return result; + }); + }), + // Create call stack on the connected subchannel. + [unstarted_handler = std::move(unstarted_handler), + &was_queued]( + absl::StatusOr> + connected_subchannel) { + if (!connected_subchannel.ok()) { + return connected_subchannel.status(); + } + // LB pick is done, so indicate that we've committed. + auto* on_commit = GetContext(); + if (on_commit != nullptr && *on_commit != nullptr) { + (*on_commit)(); + } + // If it was queued, add a trace annotation. + if (was_queued) { + auto* tracer = GetCallAttemptTracerFromContext(); + if (tracer != nullptr) { + tracer->RecordAnnotation("Delayed LB pick complete."); + } + } + // Delegate to connected subchannel. +// FIXME: need to insert LbCallTracingFilter at the top of the stack + (*connected_subchannel)->StartCall( + std::move(unstarted_handler)); + return absl::OkStatus(); + }); + }); + } + + private: + RefCountedPtr client_channel_; +}; + +// +// NoRetryCallDestination +// + +namespace { + +ClientChannelServiceConfigCallData* GetServiceConfigCallDataFromContext() { + auto* legacy_context = GetContext(); + return static_cast( + legacy_context[GRPC_CONTEXT_SERVICE_CONFIG_CALL_DATA].value); +} + +// A call destination that does not support retries. +// To be used as an L2 filter. +class NoRetryCallDestination : public DelegatingCallDestination { + public: + NoRetryCallDestination(RefCountedPtr next, + RefCountedPtr filter_stack, + const ChannelArgs& channel_args) + : DelegatingCallDestination(std::move(next)), + filter_stack_(std::move(filter_stack)), + call_size_estimator_(1024), + allocator_(channel_args.GetObject() + ->memory_quota() + ->CreateMemoryOwner()) {} + + void Orphan() override {} + + void StartCall(UnstartedCallHandler unstarted_handler) override { + // Start the parent call. We take ownership of the handler. + CallHandler handler = unstarted_handler.StartCall(filter_stack_); + // Start a promise to drain the client initial metadata from the + // parent call, create a new child call, and forward between them. + handler.SpawnGuarded( + "drain_send_initial_metadata", + [self = RefAsSubclass(), handler]() mutable { + return Map( + handler.PullClientInitialMetadata(), + [self = std::move(self), handler]( + ValueOrFailure client_initial_metadata) + mutable -> StatusFlag { + if (!client_initial_metadata.ok()) return Failure{}; + // Indicate that this is not a transparent retry. + *(*client_initial_metadata)->GetOrCreatePointer( + IsTransparentRetry()) = + false; + // Set on_commit callback in context. + handler.SetContext( + []() { GetServiceConfigCallDataFromContext()->Commit(); }); + // Create an arena for the child call. + const size_t initial_size = + self->call_size_estimator_.CallSizeEstimate(); +// FIXME: do we want to do this for LB calls, or do we want a separate stat for this? + //global_stats().IncrementCallInitialSize(initial_size); + Arena* arena = Arena::Create(initial_size, &self->allocator_); + // Create an initiator/unstarted-handler pair using the arena. +// FIXME: pass in a callback that the CallSpine will use to destroy the arena: +// [](Arena* arena) { +// call_size_estimator_.UpdateCallSizeEstimate(arena->TotalUsedBytes()); +// arena->Destroy(); +// } + auto child_call = MakeCall(std::move(*client_initial_metadata), + GetContext(), arena); + // Pass the child call's unstarted handler to the next + // destination. + self->wrapped_destination()->StartCall( + std::move(child_call.unstarted_handler)); + // Forward everything from the parent call to the child call. + ForwardCall(std::move(handler), + std::move(child_call.initiator)); + return Success{}; + }); + }); + } + + private: + RefCountedPtr filter_stack_; + CallSizeEstimator call_size_estimator_; + MemoryAllocator allocator_; +}; + +} // namespace + +// +// ClientChannel implementation +// + +namespace { + +RefCountedPtr GetSubchannelPool( + const ChannelArgs& args) { + if (args.GetBool(GRPC_ARG_USE_LOCAL_SUBCHANNEL_POOL).value_or(false)) { + return MakeRefCounted(); + } + return GlobalSubchannelPool::instance(); +} + +} // namespace + +absl::StatusOr> ClientChannel::Create( + std::string target, ChannelArgs channel_args, + grpc_channel_stack_type channel_stack_type) { + GPR_ASSERT(channel_stack_type == GRPC_CLIENT_CHANNEL); + // Get URI to resolve, using proxy mapper if needed. + if (target.empty()) { + return absl::InternalError("target URI is empty in client channel"); + } + std::string uri_to_resolve = CoreConfiguration::Get() + .proxy_mapper_registry() + .MapName(target, &channel_args) + .value_or(target); + // Make sure the URI to resolve is valid, so that we know that + // resolver creation will succeed later. + if (!CoreConfiguration::Get().resolver_registry().IsValidTarget( + uri_to_resolve)) { + return absl::InvalidArgumentError( + absl::StrCat("invalid target URI: ", uri_to_resolve)); + } + // Get default service config. If none is specified via the client API, + // we use an empty config. + absl::optional service_config_json = + channel_args.GetString(GRPC_ARG_SERVICE_CONFIG); + if (!service_config_json.has_value()) service_config_json = "{}"; + auto default_service_config = + ServiceConfigImpl::Create(channel_args, *service_config_json); + if (!default_service_config.ok()) return default_service_config.status(); + // Strip out service config channel arg, so that it doesn't affect + // subchannel uniqueness when the args flow down to that layer. + channel_args = channel_args.Remove(GRPC_ARG_SERVICE_CONFIG); + // Check client channel factory. + auto* client_channel_factory = + channel_args.GetObject(); + if (client_channel_factory == nullptr) { + return absl::InternalError( + "Missing client channel factory in args for client channel"); + } + // Success. Construct channel. + return MakeOrphanable( + std::move(target), std::move(channel_args), std::move(uri_to_resolve), + std::move(*default_service_config), client_channel_factory); +} + +ClientChannel::ClientChannel( + std::string target, ChannelArgs channel_args, std::string uri_to_resolve, + RefCountedPtr default_service_config, + ClientChannelFactory* client_channel_factory) + : Channel(std::move(target), channel_args), + channel_args_(std::move(channel_args)), + event_engine_(channel_args.GetObjectRef()), + 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), + channelz_node_(channel_args_.GetObject()), + interested_parties_(grpc_pollset_set_create()), + lb_call_size_estimator_(1024), + lb_call_allocator_(channel_args_.GetObject() + ->memory_quota() + ->CreateMemoryOwner()), + idle_timeout_(GetClientIdleTimeout(channel_args_)), + resolver_data_for_calls_(ResolverDataForCalls{}), + picker_(nullptr), + work_serializer_(std::make_shared(event_engine_)), + state_tracker_("client_channel", GRPC_CHANNEL_IDLE), + subchannel_pool_(GetSubchannelPool(channel_args_)) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) { + gpr_log(GPR_INFO, "client_channel=%p: creating client_channel", this); + } + // Set initial keepalive time. + auto keepalive_arg = channel_args_.GetInt(GRPC_ARG_KEEPALIVE_TIME_MS); + if (keepalive_arg.has_value()) { + keepalive_time_ = Clamp(*keepalive_arg, 1, INT_MAX); + } else { + keepalive_time_ = -1; // unset + } + // Set default authority. + absl::optional default_authority = + channel_args_.GetOwnedString(GRPC_ARG_DEFAULT_AUTHORITY); + if (!default_authority.has_value()) { + default_authority_ = + CoreConfiguration::Get().resolver_registry().GetDefaultAuthority( + target); + } else { + default_authority_ = std::move(*default_authority); + } + // Get stats plugins for channel. + StatsPlugin::ChannelScope scope(this->target(), default_authority_); + stats_plugin_group_ = + GlobalStatsPluginRegistry::GetStatsPluginsForChannel(scope); +} + +ClientChannel::~ClientChannel() { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) { + gpr_log(GPR_INFO, "client_channel=%p: destroying", this); + } + grpc_pollset_set_destroy(interested_parties_); +} + +void ClientChannel::Orphan() { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) { + gpr_log(GPR_INFO, "client_channel=%p: shutting down", this); + } + Ref().release(); + work_serializer_->Run( + [this]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*work_serializer_) { + DestroyResolverAndLbPolicyLocked(); + Unref(); + }, + DEBUG_LOCATION); + // IncreaseCallCount() introduces a phony call and prevents the idle + // timer from being reset by other threads. + idle_state_.IncreaseCallCount(); + idle_activity_.Reset(); +} + +grpc_connectivity_state ClientChannel::CheckConnectivityState( + bool try_to_connect) { + // state_tracker_ is guarded by work_serializer_, which we're not + // holding here. But the one method of state_tracker_ that *is* + // thread-safe to call without external synchronization is the state() + // method, so we can disable thread-safety analysis for this one read. + grpc_connectivity_state state = + ABSL_TS_UNCHECKED_READ(state_tracker_).state(); + if (state == GRPC_CHANNEL_IDLE && try_to_connect) { + RefAsSubclass().release(); // Held by callback. + work_serializer_->Run( + [this]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*work_serializer_) { + TryToConnectLocked(); + Unref(); + }, + DEBUG_LOCATION); + } + return state; +} + +void ClientChannel::WatchConnectivityState( + grpc_connectivity_state last_observed_state, Timestamp deadline, + grpc_completion_queue* cq, void* tag) { +// FIXME: implement +} + +void ClientChannel::AddConnectivityWatcher( + grpc_connectivity_state initial_state, + OrphanablePtr watcher) { +// FIXME: to make this work, need to change WorkSerializer to use +// absl::AnyInvocable<> instead of std::function<> +// work_serializer_->Run( +// [self = RefAsSubclass(), initial_state, +// watcher = std::move(watcher)]() +// ABSL_EXCLUSIVE_LOCKS_REQUIRED(*work_serializer_) { +// self->state_tracker_.AddWatcher(initial_state, std::move(watcher)); +// }, +// DEBUG_LOCATION); +} + +void ClientChannel::RemoveConnectivityWatcher( + AsyncConnectivityStateWatcherInterface* watcher) { + RefAsSubclass().release(); // Held by callback. + work_serializer_->Run( + [this, watcher]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*work_serializer_) { + state_tracker_.RemoveWatcher(watcher); + Unref(); + }, + DEBUG_LOCATION); +} + +void ClientChannel::GetInfo(const grpc_channel_info* info) { + MutexLock lock(&info_mu_); + if (info->lb_policy_name != nullptr) { + *info->lb_policy_name = gpr_strdup(info_lb_policy_name_.c_str()); + } + if (info->service_config_json != nullptr) { + *info->service_config_json = gpr_strdup(info_service_config_json_.c_str()); + } +} + +void ClientChannel::ResetConnectionBackoff() { + RefAsSubclass().release(); // Held by callback. + work_serializer_->Run( + [this]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*work_serializer_) { + if (lb_policy_ != nullptr) lb_policy_->ResetBackoffLocked(); + Unref(); + }, + DEBUG_LOCATION); +} + +namespace { + +// TODO(roth): Remove this in favor of the gprpp Match() function once +// we can do that without breaking lock annotations. +template +T HandlePickResult( + LoadBalancingPolicy::PickResult* result, + std::function complete_func, + std::function queue_func, + std::function fail_func, + std::function drop_func) { + auto* complete_pick = + absl::get_if(&result->result); + if (complete_pick != nullptr) { + return complete_func(complete_pick); + } + auto* queue_pick = + absl::get_if(&result->result); + if (queue_pick != nullptr) { + return queue_func(queue_pick); + } + auto* fail_pick = + absl::get_if(&result->result); + if (fail_pick != nullptr) { + return fail_func(fail_pick); + } + auto* drop_pick = + absl::get_if(&result->result); + GPR_ASSERT(drop_pick != nullptr); + return drop_func(drop_pick); +} + +// A class to handle CQ completion for a ping. +class PingRequest { + public: + PingRequest(grpc_completion_queue* cq, void* tag) : cq_(cq), tag_(tag) { + grpc_cq_begin_op(cq, tag); + } + + // Triggers CQ completion and eventually deletes the PingRequest object. + void Complete(grpc_error_handle error) { + grpc_cq_end_op(cq_, tag_, error, Destroy, this, &completion_storage_); + } + + private: + static void Destroy(void* arg, grpc_cq_completion* /*storage*/) { + delete static_cast(arg); + } + + grpc_completion_queue* cq_; + void* tag_; + grpc_cq_completion completion_storage_; +}; + +} // namespace + +void ClientChannel::Ping(grpc_completion_queue* cq, void* tag) { + auto* request = new PingRequest(cq, tag); + // Get picker. + auto picker = NowOrNever(picker_.NextWhen( + [](const RefCountedPtr& picker) { + return true; + })); + if (!picker.has_value() || *picker == nullptr) { + request->Complete(absl::UnavailableError("channel not connected")); + return; + } + // Do pick. + LoadBalancingPolicy::PickResult result = + (*picker)->Pick(LoadBalancingPolicy::PickArgs()); + HandlePickResult( + &result, + // Complete pick. + [&](LoadBalancingPolicy::PickResult::Complete* complete_pick) { + SubchannelWrapper* subchannel = static_cast( + complete_pick->subchannel.get()); + RefCountedPtr connected_subchannel = + subchannel->connected_subchannel(); + if (connected_subchannel == nullptr) { + request->Complete( + absl::UnavailableError("LB pick for ping not connected")); + return; + } + connected_subchannel->Ping([request](absl::Status status) { + request->Complete(std::move(status)); + }); + }, + // Queue pick. + [&](LoadBalancingPolicy::PickResult::Queue* /*queue_pick*/) { + request->Complete(absl::UnavailableError("LB picker queued call")); + }, + // Fail pick. + [&](LoadBalancingPolicy::PickResult::Fail* fail_pick) { + request->Complete(fail_pick->status); + }, + // Drop pick. + [&](LoadBalancingPolicy::PickResult::Drop* drop_pick) { + request->Complete(drop_pick->status); + }); +} + +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 authority, Timestamp deadline, + bool registered_method) { +// FIXME: code to convert from C-core batch API to v3 call, then invoke +// CreateCall(client_initial_metadata, arena) +// FIXME: make sure call holds a ref to ClientChannel for its entire lifetime + return nullptr; +} + +CallInitiator ClientChannel::CreateCall( + ClientMetadataHandle client_initial_metadata, Arena* arena) { + // Increment call count. + if (idle_timeout_ != Duration::Zero()) idle_state_.IncreaseCallCount(); + // Exit IDLE if needed. + CheckConnectivityState(/*try_to_connect=*/true); + // Create an initiator/unstarted-handler pair. + auto call = MakeCall(std::move(client_initial_metadata), + GetContext(), arena); + // Spawn a promise to wait for the resolver result. + // This will eventually start the call. + call.initiator.SpawnGuarded( + "wait-for-name-resolution", + [self = RefAsSubclass(), + unstarted_handler = std::move(call.unstarted_handler), + was_queued = false]() mutable { + const bool wait_for_ready = + unstarted_handler.UnprocessedClientInitialMetadata() + ->GetOrCreatePointer(WaitForReady()) + ->value; + return Map( + // Wait for the resolver result. + self->resolver_data_for_calls_.NextWhen( + [wait_for_ready, &was_queued]( + const absl::StatusOr result) { + bool got_result = false; + // If the resolver reports an error but the call is + // wait_for_ready, keep waiting for the next result + // instead of failing the call. + if (!result.ok()) { + got_result = !wait_for_ready; + } else { + // Not an error. Make sure we actually have a result. + got_result = result->config_selector != nullptr; + } + if (!got_result) was_queued = true; + return got_result; + }), + // Handle resolver result. + [self, &was_queued, &unstarted_handler]( + absl::StatusOr resolver_data) + mutable { + if (!resolver_data.ok()) return resolver_data.status(); + // Apply service config to call. + absl::Status status = self->ApplyServiceConfigToCall( + *resolver_data->config_selector, + unstarted_handler.UnprocessedClientInitialMetadata()); + if (!status.ok()) return status; + // If the call was queued, add trace annotation. + if (was_queued) { + auto* call_tracer = GetCallTracerFromContext(); + if (call_tracer != nullptr) { + call_tracer->RecordAnnotation( + "Delayed name resolution complete."); + } + } + // Start the call on the destination provided by the + // resolver. + resolver_data->call_destination->StartCall( + std::move(unstarted_handler)); + return absl::OkStatus(); + }); + }); + // Return the initiator. + return call.initiator; +} + +void ClientChannel::CreateResolverLocked() { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) { + gpr_log(GPR_INFO, "client_channel=%p: starting name resolution for %s", + this, uri_to_resolve_.c_str()); + } + resolver_ = CoreConfiguration::Get().resolver_registry().CreateResolver( + uri_to_resolve_, channel_args_, + interested_parties_, // FIXME: remove somehow + work_serializer_, + std::make_unique( + RefAsSubclass())); + // Since the validity of the args was checked when the channel was created, + // CreateResolver() must return a non-null result. + GPR_ASSERT(resolver_ != nullptr); + UpdateStateLocked(GRPC_CHANNEL_CONNECTING, absl::Status(), + "started resolving"); + resolver_->StartLocked(); + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) { + gpr_log(GPR_INFO, "client_channel=%p: created resolver=%p", this, + resolver_.get()); + } +} + +void ClientChannel::DestroyResolverAndLbPolicyLocked() { + if (resolver_ != nullptr) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) { + gpr_log(GPR_INFO, "client_channel=%p: shutting down resolver=%p", this, + resolver_.get()); + } + resolver_.reset(); + saved_service_config_.reset(); + saved_config_selector_.reset(); + resolver_data_for_calls_.Set(ResolverDataForCalls{nullptr, nullptr}); + // Clear LB policy if set. + if (lb_policy_ != nullptr) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) { + gpr_log(GPR_INFO, "client_channel=%p: shutting down lb_policy=%p", + this, lb_policy_.get()); + } + lb_policy_.reset(); + picker_.Set(nullptr); + } + } +} + +void ClientChannel::TryToConnectLocked() { + if (disconnect_error_.ok()) { + if (lb_policy_ != nullptr) { + lb_policy_->ExitIdleLocked(); + } else if (resolver_ == nullptr) { + CreateResolverLocked(); + } + } +} + +namespace { + +RefCountedPtr ChooseLbPolicy( + const Resolver::Result& resolver_result, + const internal::ClientChannelGlobalParsedConfig* parsed_service_config) { + // Prefer the LB policy config found in the service config. + if (parsed_service_config->parsed_lb_config() != nullptr) { + return parsed_service_config->parsed_lb_config(); + } + // Try the deprecated LB policy name from the service config. + // If not, try the setting from channel args. + absl::optional policy_name; + if (!parsed_service_config->parsed_deprecated_lb_policy().empty()) { + policy_name = parsed_service_config->parsed_deprecated_lb_policy(); + } else { + policy_name = resolver_result.args.GetString(GRPC_ARG_LB_POLICY_NAME); + bool requires_config = false; + if (policy_name.has_value() && + (!CoreConfiguration::Get() + .lb_policy_registry() + .LoadBalancingPolicyExists(*policy_name, &requires_config) || + requires_config)) { + if (requires_config) { + gpr_log(GPR_ERROR, + "LB policy: %s passed through channel_args must not " + "require a config. Using pick_first instead.", + std::string(*policy_name).c_str()); + } else { + gpr_log(GPR_ERROR, + "LB policy: %s passed through channel_args does not exist. " + "Using pick_first instead.", + std::string(*policy_name).c_str()); + } + policy_name = "pick_first"; + } + } + // Use pick_first if nothing was specified and we didn't select grpclb + // above. + if (!policy_name.has_value()) policy_name = "pick_first"; + // Now that we have the policy name, construct an empty config for it. + Json config_json = Json::FromArray({Json::FromObject({ + {std::string(*policy_name), Json::FromObject({})}, + })}); + auto lb_policy_config = + CoreConfiguration::Get().lb_policy_registry().ParseLoadBalancingConfig( + config_json); + // The policy name came from one of three places: + // - The deprecated loadBalancingPolicy field in the service config, + // in which case the code in ClientChannelServiceConfigParser + // already verified that the policy does not require a config. + // - One of the hard-coded values here, all of which are known to not + // require a config. + // - A channel arg, in which case we check that the specified policy exists + // and accepts an empty config. If not, we revert to using pick_first + // lb_policy + GPR_ASSERT(lb_policy_config.ok()); + return std::move(*lb_policy_config); +} + +} // namespace + +void ClientChannel::OnResolverResultChangedLocked( + Resolver::Result result) { + // Handle race conditions. + if (resolver_ == nullptr) return; + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) { + gpr_log(GPR_INFO, "client_channel=%p: got resolver result", this); + } + // Grab resolver result health callback. + auto resolver_callback = std::move(result.result_health_callback); + absl::Status resolver_result_status; + // We only want to trace the address resolution in the follow cases: + // (a) Address resolution resulted in service config change. + // (b) Address resolution that causes number of backends to go from + // zero to non-zero. + // (c) Address resolution that causes number of backends to go from + // non-zero to zero. + // (d) Address resolution that causes a new LB policy to be created. + // + // We track a list of strings to eventually be concatenated and traced. + std::vector trace_strings; + const bool resolution_contains_addresses = + result.addresses.ok() && !result.addresses->empty(); + if (!resolution_contains_addresses && + previous_resolution_contained_addresses_) { + trace_strings.push_back("Address list became empty"); + } else if (resolution_contains_addresses && + !previous_resolution_contained_addresses_) { + trace_strings.push_back("Address list became non-empty"); + } + previous_resolution_contained_addresses_ = resolution_contains_addresses; + std::string service_config_error_string_storage; + if (!result.service_config.ok()) { + service_config_error_string_storage = + result.service_config.status().ToString(); + trace_strings.push_back(service_config_error_string_storage.c_str()); + } + // Choose the service config. + RefCountedPtr service_config; + RefCountedPtr config_selector; + if (!result.service_config.ok()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) { + gpr_log(GPR_INFO, + "client_channel=%p: resolver returned service config error: %s", + this, result.service_config.status().ToString().c_str()); + } + // If the service config was invalid, then fallback to the + // previously returned service config, if any. + if (saved_service_config_ != nullptr) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) { + gpr_log(GPR_INFO, + "client_channel=%p: resolver returned invalid service config; " + "continuing to use previous service config", + this); + } + service_config = saved_service_config_; + config_selector = saved_config_selector_; + } else { + // We received a service config error and we don't have a + // previous service config to fall back to. Put the channel into + // TRANSIENT_FAILURE. + OnResolverErrorLocked(result.service_config.status()); + trace_strings.push_back("no valid service config"); + resolver_result_status = + absl::UnavailableError("no valid service config"); + } + } else if (*result.service_config == nullptr) { + // Resolver did not return any service config. + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) { + gpr_log(GPR_INFO, + "client_channel=%p: resolver returned no service config; " + "using default service config for channel", + this); + } + service_config = default_service_config_; + } else { + // Use ServiceConfig and ConfigSelector returned by resolver. + service_config = std::move(*result.service_config); + config_selector = result.args.GetObjectRef(); + } + // Note: The only case in which service_config is null here is if the + // resolver returned a service config error and we don't have a previous + // service config to fall back to. + if (service_config != nullptr) { + // Extract global config for client channel. + const internal::ClientChannelGlobalParsedConfig* parsed_service_config = + static_cast( + service_config->GetGlobalParsedConfig( + service_config_parser_index_)); + // Choose LB policy config. + RefCountedPtr lb_policy_config = + ChooseLbPolicy(result, parsed_service_config); + // Check if the ServiceConfig has changed. + const bool service_config_changed = + saved_service_config_ == nullptr || + service_config->json_string() != saved_service_config_->json_string(); + // Check if the ConfigSelector has changed. + const bool config_selector_changed = !ConfigSelector::Equals( + saved_config_selector_.get(), config_selector.get()); + // If either has changed, apply the global parameters now. + if (service_config_changed || config_selector_changed) { + // Update service config in control plane. + UpdateServiceConfigInControlPlaneLocked( + std::move(service_config), std::move(config_selector), + std::string(lb_policy_config->name())); + // TODO(ncteisen): might be worth somehow including a snippet of the + // config in the trace, at the risk of bloating the trace logs. + trace_strings.push_back("Service config changed"); + } else if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) { + gpr_log(GPR_INFO, "client_channel=%p: service config not changed", this); + } + // Create or update LB policy, as needed. + resolver_result_status = CreateOrUpdateLbPolicyLocked( + std::move(lb_policy_config), + parsed_service_config->health_check_service_name(), std::move(result)); + // Start using new service config for calls. + // This needs to happen after the LB policy has been updated, since + // the ConfigSelector may need the LB policy to know about new + // destinations before it can send RPCs to those destinations. + if (service_config_changed || config_selector_changed) { + UpdateServiceConfigInDataPlaneLocked(); + } + } + // Invoke resolver callback if needed. + if (resolver_callback != nullptr) { + resolver_callback(std::move(resolver_result_status)); + } + // Add channel trace event. + if (!trace_strings.empty()) { + std::string message = + absl::StrCat("Resolution event: ", absl::StrJoin(trace_strings, ", ")); + if (channelz_node_ != nullptr) { + channelz_node_->AddTraceEvent(channelz::ChannelTrace::Severity::Info, + grpc_slice_from_cpp_string(message)); + } + } +} + +void ClientChannel::OnResolverErrorLocked(absl::Status status) { + if (resolver_ == nullptr) return; + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) { + gpr_log(GPR_INFO, "client_channel=%p: resolver transient failure: %s", this, + status.ToString().c_str()); + } + // If we already have an LB policy from a previous resolution + // result, then we continue to let it set the connectivity state. + // Otherwise, we go into TRANSIENT_FAILURE. + if (lb_policy_ == nullptr) { + // Update connectivity state. + UpdateStateLocked(GRPC_CHANNEL_TRANSIENT_FAILURE, status, + "resolver failure"); + // Send updated resolver result. + resolver_data_for_calls_.Set( + MaybeRewriteIllegalStatusCode(status, "resolver")); + } +} + +absl::Status ClientChannel::CreateOrUpdateLbPolicyLocked( + RefCountedPtr lb_policy_config, + const absl::optional& health_check_service_name, + Resolver::Result result) { + // Construct update. + LoadBalancingPolicy::UpdateArgs update_args; + if (!result.addresses.ok()) { + update_args.addresses = result.addresses.status(); + } else { + update_args.addresses = std::make_shared( + std::move(*result.addresses)); + } + update_args.config = std::move(lb_policy_config); + update_args.resolution_note = std::move(result.resolution_note); + // Remove the config selector from channel args so that we're not holding + // unnecessary refs that cause it to be destroyed somewhere other than in the + // WorkSerializer. + update_args.args = result.args.Remove(GRPC_ARG_CONFIG_SELECTOR); + // Add health check service name to channel args. + if (health_check_service_name.has_value()) { + update_args.args = update_args.args.Set(GRPC_ARG_HEALTH_CHECK_SERVICE_NAME, + *health_check_service_name); + } + // Create policy if needed. + if (lb_policy_ == nullptr) { + lb_policy_ = CreateLbPolicyLocked(update_args.args); + } + // Update the policy. + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) { + gpr_log(GPR_INFO, "client_channel=%p: Updating child policy %p", this, + lb_policy_.get()); + } + return lb_policy_->UpdateLocked(std::move(update_args)); +} + +// Creates a new LB policy. +OrphanablePtr ClientChannel::CreateLbPolicyLocked( + const ChannelArgs& args) { + // The LB policy will start in state CONNECTING but will not + // necessarily send us an update synchronously, so set state to + // CONNECTING (in case the resolver had previously failed and put the + // channel into TRANSIENT_FAILURE) and make sure we have a queueing picker. + UpdateStateAndPickerLocked( + GRPC_CHANNEL_CONNECTING, absl::Status(), "started resolving", + MakeRefCounted(nullptr)); + // Now create the LB policy. + LoadBalancingPolicy::Args lb_policy_args; + lb_policy_args.work_serializer = work_serializer_; + lb_policy_args.channel_control_helper = + std::make_unique( + RefAsSubclass()); + lb_policy_args.args = args; + OrphanablePtr lb_policy = + MakeOrphanable(std::move(lb_policy_args), + &grpc_client_channel_trace); + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) { + gpr_log(GPR_INFO, "client_channel=%p: created new LB policy %p", this, + lb_policy.get()); + } + return lb_policy; +} + +void ClientChannel::UpdateServiceConfigInControlPlaneLocked( + RefCountedPtr service_config, + RefCountedPtr config_selector, std::string lb_policy_name) { + std::string service_config_json(service_config->json_string()); + // Update service config. + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) { + gpr_log(GPR_INFO, "client_channel=%p: using service config: \"%s\"", this, + service_config_json.c_str()); + } + saved_service_config_ = std::move(service_config); + // Update config selector. + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) { + gpr_log(GPR_INFO, "client_channel=%p: using ConfigSelector %p", this, + config_selector.get()); + } + saved_config_selector_ = std::move(config_selector); + // Update the data used by GetChannelInfo(). + { + MutexLock lock(&info_mu_); + info_lb_policy_name_ = std::move(lb_policy_name); + info_service_config_json_ = std::move(service_config_json); + } +} + +void ClientChannel::UpdateServiceConfigInDataPlaneLocked() { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) { + gpr_log(GPR_INFO, "client_channel=%p: switching to ConfigSelector %p", this, + saved_config_selector_.get()); + } + // Use default config selector if resolver didn't supply one. + RefCountedPtr config_selector = saved_config_selector_; + if (config_selector == nullptr) { + config_selector = + MakeRefCounted(saved_service_config_); + } + // Construct filter stack. + CallFilters::StackBuilder builder; + if (idle_timeout_ != Duration::Zero()) { + builder.AddOnServerTrailingMetadata( + [this](ServerMetadata&) { + if (idle_state_.DecreaseCallCount()) StartIdleTimer(); + }); + } +// FIXME: add filters registered for CLIENT_CHANNEL plus filters returned +// by config selector +#if 0 + std::vector filters = + config_selector->GetFilters(); + ChannelArgs new_args = + channel_args_.SetObject(this).SetObject(service_config); + RefCountedPtr dynamic_filters = + DynamicFilters::Create(new_args, std::move(filters)); + GPR_ASSERT(dynamic_filters != nullptr); +#endif + auto filter_stack = builder.Build(); + // Create call destination. + RefCountedPtr call_destination; + const bool enable_retries = + !channel_args_.WantMinimalStack() && + channel_args_.GetBool(GRPC_ARG_ENABLE_RETRIES).value_or(true); + if (enable_retries) { + Crash("call v3 stack does not yet support retries"); + } else { + call_destination = MakeRefCounted( + MakeRefCounted( + RefAsSubclass()), + std::move(filter_stack), channel_args_); + } + // Send result to data plane. + resolver_data_for_calls_.Set( + ResolverDataForCalls{std::move(config_selector), + std::move(call_destination)}); +} + +void ClientChannel::UpdateStateLocked(grpc_connectivity_state state, + const absl::Status& status, + const char* reason) { + if (state != GRPC_CHANNEL_SHUTDOWN && + state_tracker_.state() == GRPC_CHANNEL_SHUTDOWN) { + Crash("Illegal transition SHUTDOWN -> anything"); + } + 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))); + } +} + +void ClientChannel::UpdateStateAndPickerLocked( + grpc_connectivity_state state, const absl::Status& status, + const char* reason, + RefCountedPtr picker) { + UpdateStateLocked(state, status, reason); + picker_.Set(std::move(picker)); +} + +void ClientChannel::StartIdleTimer() { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) { + gpr_log(GPR_INFO, "client_channel=%p: idle timer started", this); + } + auto self = RefAsSubclass(); + auto promise = Loop([self]() { + return TrySeq(Sleep(Timestamp::Now() + self->idle_timeout_), + [&self]() -> Poll> { + if (self->idle_state_.CheckTimer()) { + return Continue{}; + } else { + return absl::OkStatus(); + } + }); + }); + idle_activity_.Set(MakeActivity( + std::move(promise), ExecCtxWakeupScheduler{}, + [this, self = std::move(self)](absl::Status status) mutable { + if (status.ok()) { + work_serializer_->Run( + [this, self = std::move(self)]() + ABSL_EXCLUSIVE_LOCKS_REQUIRED(*work_serializer_) { + DestroyResolverAndLbPolicyLocked(); + UpdateStateAndPickerLocked( + GRPC_CHANNEL_IDLE, absl::OkStatus(), + "channel entering IDLE", nullptr); + // TODO(roth): In case there's a race condition, we + // might need to check for any calls that are queued + // waiting for a resolver result or an LB pick. + }, + DEBUG_LOCATION); + } + }, + GetContext())); +} + +absl::Status ClientChannel::ApplyServiceConfigToCall( + ConfigSelector& config_selector, + ClientMetadataHandle& client_initial_metadata) const { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) { + gpr_log(GPR_INFO, "client_channel=%p: %sapplying service config to call", + this, GetContext()->DebugTag().c_str()); + } + // Create a ClientChannelServiceConfigCallData for the call. This stores + // a ref to the ServiceConfig and caches the right set of parsed configs + // to use for the call. The ClientChannelServiceConfigCallData will store + // itself in the call context, so that it can be accessed by filters + // below us in the stack, and it will be cleaned up when the call ends. + auto* service_config_call_data = + GetContext()->New( + GetContext(), GetContext()); + // Use the ConfigSelector to determine the config for the call. + absl::Status call_config_status = config_selector.GetCallConfig( + {client_initial_metadata.get(), GetContext(), + service_config_call_data}); + if (!call_config_status.ok()) { + return MaybeRewriteIllegalStatusCode(call_config_status, "ConfigSelector"); + } + // Apply our own method params to the call. + auto* method_params = static_cast( + service_config_call_data->GetMethodParsedConfig( + service_config_parser_index_)); + if (method_params != nullptr) { + // If the service config specifies a deadline, update the call's + // deadline timer. + if (method_params->timeout() != Duration::Zero()) { + CallContext* call_context = GetContext(); + const Timestamp per_method_deadline = + Timestamp::FromCycleCounterRoundUp(call_context->call_start_time()) + + method_params->timeout(); + call_context->UpdateDeadline(per_method_deadline); + } + // If the service config set wait_for_ready and the application + // did not explicitly set it, use the value from the service config. + auto* wait_for_ready = + client_initial_metadata->GetOrCreatePointer(WaitForReady()); + if (method_params->wait_for_ready().has_value() && + !wait_for_ready->explicitly_set) { + wait_for_ready->value = method_params->wait_for_ready().value(); + } + } + return absl::OkStatus(); +} + +namespace { + +class LbCallState : public ClientChannelLbCallState { + public: + void* Alloc(size_t size) override { return GetContext()->Alloc(size); } + + // Internal API to allow first-party LB policies to access per-call + // attributes set by the ConfigSelector. + ServiceConfigCallData::CallAttributeInterface* GetCallAttribute( + UniqueTypeName type) const override { + auto* service_config_call_data = GetServiceConfigCallDataFromContext(); + return service_config_call_data->GetCallAttribute(type); + } + + ClientCallTracer::CallAttemptTracer* GetCallAttemptTracer() const override { + auto* legacy_context = GetContext(); + return static_cast( + legacy_context[GRPC_CONTEXT_CALL_TRACER].value); + } +}; + +} // namespace + +LoopCtl>> +ClientChannel::PickSubchannel(LoadBalancingPolicy::SubchannelPicker& picker, + UnstartedCallHandler& unstarted_handler) { + // Perform LB pick. + auto& client_initial_metadata = + unstarted_handler.UnprocessedClientInitialMetadata(); + LoadBalancingPolicy::PickArgs pick_args; + Slice* path = client_initial_metadata->get_pointer(HttpPathMetadata()); + GPR_ASSERT(path != nullptr); + pick_args.path = path->as_string_view(); + LbCallState lb_call_state; + pick_args.call_state = &lb_call_state; + LbMetadata initial_metadata(client_initial_metadata.get()); + pick_args.initial_metadata = &initial_metadata; + auto result = picker.Pick(pick_args); + // Handle result. + return HandlePickResult< + LoopCtl>>>( + &result, + // CompletePick + [&](LoadBalancingPolicy::PickResult::Complete* complete_pick) + -> LoopCtl>> { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_lb_call_trace)) { + gpr_log(GPR_INFO, + "client_channel=%p: %sLB pick succeeded: subchannel=%p", + this, GetContext()->DebugTag().c_str(), + complete_pick->subchannel.get()); + } + GPR_ASSERT(complete_pick->subchannel != nullptr); + // Grab a ref to the connected subchannel while we're still + // holding the data plane mutex. + SubchannelWrapper* subchannel = + static_cast(complete_pick->subchannel.get()); + auto connected_subchannel = subchannel->connected_subchannel(); + // If the subchannel has no connected subchannel (e.g., if the + // subchannel has moved out of state READY but the LB policy hasn't + // yet seen that change and given us a new picker), then just + // queue the pick. We'll try again as soon as we get a new picker. + if (connected_subchannel == nullptr) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_lb_call_trace)) { + gpr_log(GPR_INFO, + "client_channel=%p: %ssubchannel returned by LB picker " + "has no connected subchannel; queueing pick", + this, GetContext()->DebugTag().c_str()); + } + return Continue{}; + } + // If the LB policy returned a call tracker, inform it that the + // call is starting and add it to context, so that we can notify + // it when the call finishes. + if (complete_pick->subchannel_call_tracker != nullptr) { + complete_pick->subchannel_call_tracker->Start(); + unstarted_handler.SetContext( + complete_pick->subchannel_call_tracker.release()); + } + // Return the connected subchannel. + return connected_subchannel; + }, + // QueuePick + [&](LoadBalancingPolicy::PickResult::Queue* /*queue_pick*/) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_lb_call_trace)) { + gpr_log(GPR_INFO, "client_channel=%p: %sLB pick queued", + this, GetContext()->DebugTag().c_str()); + } + return Continue{}; + }, + // FailPick + [&](LoadBalancingPolicy::PickResult::Fail* fail_pick) + -> LoopCtl>> { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_lb_call_trace)) { + gpr_log(GPR_INFO, "client_channel=%p: %sLB pick failed: %s", + this, GetContext()->DebugTag().c_str(), + fail_pick->status.ToString().c_str()); + } + // If wait_for_ready is false, then the error indicates the RPC + // attempt's final status. + if (!unstarted_handler.UnprocessedClientInitialMetadata() + ->GetOrCreatePointer(WaitForReady()) + ->value) { + return MaybeRewriteIllegalStatusCode(std::move(fail_pick->status), + "LB pick"); + } + // If wait_for_ready is true, then queue to retry when we get a new + // picker. + return Continue{}; + }, + // DropPick + [&](LoadBalancingPolicy::PickResult::Drop* drop_pick) + -> LoopCtl>> { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_lb_call_trace)) { + gpr_log(GPR_INFO, "client_channel=%p: %sLB pick dropped: %s", + this, GetContext()->DebugTag().c_str(), + drop_pick->status.ToString().c_str()); + } + return grpc_error_set_int( + MaybeRewriteIllegalStatusCode(std::move(drop_pick->status), + "LB drop"), + StatusIntProperty::kLbPolicyDrop, 1); + }); +} + +} // namespace grpc_core diff --git a/src/core/client_channel/client_channel.h b/src/core/client_channel/client_channel.h new file mode 100644 index 00000000000..2b5cd79f5fd --- /dev/null +++ b/src/core/client_channel/client_channel.h @@ -0,0 +1,249 @@ +// +// 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_CLIENT_CHANNEL_CLIENT_CHANNEL_H +#define GRPC_SRC_CORE_CLIENT_CHANNEL_CLIENT_CHANNEL_H + +#include + +#include "absl/status/status.h" +#include "absl/status/statusor.h" +#include "absl/strings/string_view.h" + +#include "src/core/client_channel/config_selector.h" +#include "src/core/client_channel/client_channel_factory.h" +#include "src/core/client_channel/subchannel.h" +#include "src/core/ext/filters/channel_idle/idle_filter_state.h" +#include "src/core/lib/gprpp/single_set_ptr.h" +#include "src/core/lib/promise/loop.h" +#include "src/core/lib/promise/observable.h" +#include "src/core/lib/surface/channel.h" +#include "src/core/lib/transport/call_filters.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" + +namespace grpc_core { + +class ClientChannel : public Channel { + public: + static absl::StatusOr> Create( + std::string target, ChannelArgs channel_args, + grpc_channel_stack_type channel_stack_type); + + // Do not instantiate directly -- use Create() instead. + ClientChannel(std::string target_uri, ChannelArgs args, + std::string uri_to_resolve, + RefCountedPtr default_service_config, + ClientChannelFactory* client_channel_factory); + + ~ClientChannel() override; + + void Orphan() override; + + 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 authority, + Timestamp deadline, bool registered_method) override; + + grpc_event_engine::experimental::EventEngine* event_engine() + const override { + return event_engine_.get(); + } + +// FIXME: should we support lame channels somehow? + bool IsLame() const override { return false; } + + bool SupportsConnectivityWatcher() const override { return true; } + + // Returns the current connectivity state. If try_to_connect is true, + // triggers a connection attempt if not already connected. + grpc_connectivity_state CheckConnectivityState(bool try_to_connect) override; + + void WatchConnectivityState( + grpc_connectivity_state last_observed_state, Timestamp deadline, + grpc_completion_queue* cq, void* tag) override; + + // Starts and stops a connectivity watch. The watcher will be initially + // notified as soon as the state changes from initial_state and then on + // every subsequent state change until either the watch is stopped or + // it is notified that the state has changed to SHUTDOWN. + // + // This is intended to be used when starting watches from code inside of + // C-core (e.g., for a nested control plane channel for things like xds). + void AddConnectivityWatcher( + grpc_connectivity_state initial_state, + OrphanablePtr watcher) override; + void RemoveConnectivityWatcher( + AsyncConnectivityStateWatcherInterface* watcher) override; + + void GetInfo(const grpc_channel_info* channel_info) override; + + void ResetConnectionBackoff() override; + + void Ping(grpc_completion_queue* cq, void* tag) override; + + // Flag that this object gets stored in channel args as a raw pointer. + struct RawPointerChannelArgTag {}; + static absl::string_view ChannelArgName() { + return "grpc.internal.client_channel"; + } + + private: + class ResolverResultHandler; + class ClientChannelControlHelper; + class SubchannelWrapper; + class LoadBalancedCallDestination; + + void CreateResolverLocked() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*work_serializer_); + void DestroyResolverAndLbPolicyLocked() + ABSL_EXCLUSIVE_LOCKS_REQUIRED(*work_serializer_); + + void TryToConnectLocked() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*work_serializer_); + + void OnResolverResultChangedLocked(Resolver::Result result) + ABSL_EXCLUSIVE_LOCKS_REQUIRED(*work_serializer_); + void OnResolverErrorLocked(absl::Status status) + ABSL_EXCLUSIVE_LOCKS_REQUIRED(*work_serializer_); + + absl::Status CreateOrUpdateLbPolicyLocked( + RefCountedPtr lb_policy_config, + const absl::optional& health_check_service_name, + Resolver::Result result) ABSL_EXCLUSIVE_LOCKS_REQUIRED(*work_serializer_); + OrphanablePtr CreateLbPolicyLocked( + const ChannelArgs& args) ABSL_EXCLUSIVE_LOCKS_REQUIRED(*work_serializer_); + + void UpdateServiceConfigInControlPlaneLocked( + RefCountedPtr service_config, + RefCountedPtr config_selector, std::string lb_policy_name) + ABSL_EXCLUSIVE_LOCKS_REQUIRED(*work_serializer_); + + void UpdateServiceConfigInDataPlaneLocked() + ABSL_EXCLUSIVE_LOCKS_REQUIRED(*work_serializer_); + + void UpdateStateLocked(grpc_connectivity_state state, + const absl::Status& status, const char* reason) + ABSL_EXCLUSIVE_LOCKS_REQUIRED(*work_serializer_); + + void UpdateStateAndPickerLocked( + grpc_connectivity_state state, const absl::Status& status, + const char* reason, + RefCountedPtr picker) + ABSL_EXCLUSIVE_LOCKS_REQUIRED(*work_serializer_); + + void StartIdleTimer(); + + CallInitiator CreateCall(ClientMetadataHandle client_initial_metadata, + Arena* arena); + + // Applies service config settings from config_selector to the call. + // May modify call context and client_initial_metadata. + absl::Status ApplyServiceConfigToCall( + ConfigSelector& config_selector, + ClientMetadataHandle& client_initial_metadata) const; + + // Does an LB pick for a call. Returns one of the following things: + // - Continue{}, meaning to queue the pick + // - a non-OK status, meaning to fail the call + // - a connected subchannel, meaning that the pick is complete + // When the pick is complete, pushes client_initial_metadata onto + // call_initiator. Also adds the subchannel call tracker (if any) to + // context. + LoopCtl>> PickSubchannel( + LoadBalancingPolicy::SubchannelPicker& picker, + UnstartedCallHandler& unstarted_handler); + + // + // Fields set at construction and never modified. + // + ChannelArgs channel_args_; + std::shared_ptr event_engine_; + std::string uri_to_resolve_; + const size_t service_config_parser_index_; + RefCountedPtr default_service_config_; + ClientChannelFactory* client_channel_factory_; + std::string default_authority_; + channelz::ChannelNode* channelz_node_; + GlobalStatsPluginRegistry::StatsPluginGroup stats_plugin_group_; + grpc_pollset_set* interested_parties_; + + // + // State for LB calls. + // + CallSizeEstimator lb_call_size_estimator_; + MemoryAllocator lb_call_allocator_; + + // + // Idleness state. + // + const Duration idle_timeout_; + IdleFilterState idle_state_{false}; + SingleSetPtr idle_activity_; + + // + // Fields related to name resolution. + // + struct ResolverDataForCalls { + RefCountedPtr config_selector; + RefCountedPtr call_destination; + }; + Observable> resolver_data_for_calls_; + + // + // Fields related to LB picks. + // + Observable> picker_; + + // + // Fields used in the control plane. Guarded by work_serializer. + // + std::shared_ptr work_serializer_; + ConnectivityStateTracker state_tracker_ ABSL_GUARDED_BY(*work_serializer_); + OrphanablePtr resolver_ ABSL_GUARDED_BY(*work_serializer_); + bool previous_resolution_contained_addresses_ + ABSL_GUARDED_BY(*work_serializer_) = false; + RefCountedPtr saved_service_config_ + ABSL_GUARDED_BY(*work_serializer_); + RefCountedPtr saved_config_selector_ + ABSL_GUARDED_BY(*work_serializer_); + OrphanablePtr lb_policy_ + ABSL_GUARDED_BY(*work_serializer_); + RefCountedPtr subchannel_pool_ + ABSL_GUARDED_BY(*work_serializer_); + // The number of SubchannelWrapper instances referencing a given Subchannel. + std::map subchannel_refcount_map_ + ABSL_GUARDED_BY(*work_serializer_); + // The set of SubchannelWrappers that currently exist. + // No need to hold a ref, since the set is updated in the control-plane + // work_serializer when the SubchannelWrappers are created and destroyed. + absl::flat_hash_set subchannel_wrappers_ + ABSL_GUARDED_BY(*work_serializer_); + int keepalive_time_ ABSL_GUARDED_BY(*work_serializer_) = -1; + absl::Status disconnect_error_ ABSL_GUARDED_BY(*work_serializer_); + + // + // Fields accessed via GetChannelInfo(). + // + Mutex info_mu_; + std::string info_lb_policy_name_ ABSL_GUARDED_BY(info_mu_); + std::string info_service_config_json_ ABSL_GUARDED_BY(info_mu_); +}; + +} // namespace grpc_core + +#endif // GRPC_SRC_CORE_CLIENT_CHANNEL_CLIENT_CHANNEL_H diff --git a/src/core/client_channel/client_channel_filter.cc b/src/core/client_channel/client_channel_filter.cc index 1ffcfb5e4ca..cf73a023b74 100644 --- a/src/core/client_channel/client_channel_filter.cc +++ b/src/core/client_channel/client_channel_filter.cc @@ -1109,7 +1109,7 @@ class ClientChannelFilter::ClientChannelControlHelper final const ChannelArgs& args) override ABSL_EXCLUSIVE_LOCKS_REQUIRED(*chand_->work_serializer_) { if (chand_->resolver_ == nullptr) return nullptr; // Shutting down. - ChannelArgs subchannel_args = ClientChannelFilter::MakeSubchannelArgs( + ChannelArgs subchannel_args = Subchannel::MakeSubchannelArgs( args, per_address_args, chand_->subchannel_pool_, chand_->default_authority_); // Create subchannel. @@ -1359,31 +1359,6 @@ ClientChannelFilter::CreateLoadBalancedCallPromise( return call_ptr->MakeCallPromise(std::move(call_args), std::move(lb_call)); } -ChannelArgs ClientChannelFilter::MakeSubchannelArgs( - const ChannelArgs& channel_args, const ChannelArgs& address_args, - const RefCountedPtr& subchannel_pool, - const std::string& channel_default_authority) { - // Note that we start with the channel-level args and then apply the - // per-address args, so that if a value is present in both, the one - // in the channel-level args is used. This is particularly important - // for the GRPC_ARG_DEFAULT_AUTHORITY arg, which we want to allow - // resolvers to set on a per-address basis only if the application - // did not explicitly set it at the channel level. - return channel_args.UnionWith(address_args) - .SetObject(subchannel_pool) - // If we haven't already set the default authority arg (i.e., it - // was not explicitly set by the application nor overridden by - // the resolver), add it from the channel's default. - .SetIfUnset(GRPC_ARG_DEFAULT_AUTHORITY, channel_default_authority) - // Remove channel args that should not affect subchannel - // uniqueness. - .Remove(GRPC_ARG_HEALTH_CHECK_SERVICE_NAME) - .Remove(GRPC_ARG_INHIBIT_HEALTH_CHECKING) - .Remove(GRPC_ARG_CHANNELZ_CHANNEL_NODE) - // Remove all keys with the no-subchannel prefix. - .RemoveAllKeysWithPrefix(GRPC_ARG_NO_SUBCHANNEL_PREFIX); -} - void ClientChannelFilter::ReprocessQueuedResolverCalls() { for (CallData* calld : resolver_queued_calls_) { calld->RemoveCallFromResolverQueuedCallsLocked(); diff --git a/src/core/client_channel/client_channel_filter.h b/src/core/client_channel/client_channel_filter.h index 28c21d3280c..ac144f52527 100644 --- a/src/core/client_channel/client_channel_filter.h +++ b/src/core/client_channel/client_channel_filter.h @@ -86,9 +86,6 @@ // Channel arg key for server URI string. #define GRPC_ARG_SERVER_URI "grpc.server_uri" -// Channel arg containing a pointer to the ClientChannelFilter object. -#define GRPC_ARG_CLIENT_CHANNEL "grpc.internal.client_channel_filter" - // Max number of batches that can be pending on a call at any given // time. This includes one batch for each of the following ops: // recv_initial_metadata @@ -112,7 +109,9 @@ class ClientChannelFilter final { // Flag that this object gets stored in channel args as a raw pointer. struct RawPointerChannelArgTag {}; - static absl::string_view ChannelArgName() { return GRPC_ARG_CLIENT_CHANNEL; } + static absl::string_view ChannelArgName() { + return "grpc.internal.client_channel_filter"; + } static ArenaPromise MakeCallPromise( grpc_channel_element* elem, CallArgs call_args, @@ -166,12 +165,6 @@ class ClientChannelFilter final { CallArgs call_args, absl::AnyInvocable on_commit, bool is_transparent_retry); - // Exposed for testing only. - static ChannelArgs MakeSubchannelArgs( - const ChannelArgs& channel_args, const ChannelArgs& address_args, - const RefCountedPtr& subchannel_pool, - const std::string& channel_default_authority); - private: class CallData; class FilterBasedCallData; diff --git a/src/core/client_channel/subchannel.cc b/src/core/client_channel/subchannel.cc index e8ef1f5e861..bd52949a6ea 100644 --- a/src/core/client_channel/subchannel.cc +++ b/src/core/client_channel/subchannel.cc @@ -38,8 +38,12 @@ #include #include +<<<<<<< HEAD #include "src/core/channelz/channel_trace.h" #include "src/core/channelz/channelz.h" +======= +#include "src/core/client_channel/client_channel_internal.h" +>>>>>>> 513bd21ea9db49d061e0382289319ddb126f812c #include "src/core/client_channel/subchannel_pool_interface.h" #include "src/core/handshaker/proxy_mapper_registry.h" #include "src/core/lib/address_utils/sockaddr_utils.h" @@ -51,6 +55,7 @@ #include "src/core/lib/debug/stats.h" #include "src/core/lib/debug/stats_data.h" #include "src/core/lib/debug/trace.h" +#include "src/core/lib/experiments/experiments.h" #include "src/core/lib/gpr/alloc.h" #include "src/core/lib/gpr/useful.h" #include "src/core/lib/gprpp/debug_location.h" @@ -96,52 +101,31 @@ DebugOnlyTraceFlag grpc_trace_subchannel_refcount(false, "subchannel_refcount"); // ConnectedSubchannel::ConnectedSubchannel( - grpc_channel_stack* channel_stack, const ChannelArgs& args, + const ChannelArgs& args, RefCountedPtr channelz_subchannel) : RefCounted( GRPC_TRACE_FLAG_ENABLED(grpc_trace_subchannel_refcount) ? "ConnectedSubchannel" : nullptr), - channel_stack_(channel_stack), args_(args), channelz_subchannel_(std::move(channelz_subchannel)) {} -ConnectedSubchannel::~ConnectedSubchannel() { - GRPC_CHANNEL_STACK_UNREF(channel_stack_, "connected_subchannel_dtor"); -} - -void ConnectedSubchannel::StartWatch( - grpc_pollset_set* interested_parties, - OrphanablePtr watcher) { - grpc_transport_op* op = grpc_make_transport_op(nullptr); - op->start_connectivity_watch = std::move(watcher); - op->start_connectivity_watch_state = GRPC_CHANNEL_READY; - op->bind_pollset_set = interested_parties; - grpc_channel_element* elem = grpc_channel_stack_element(channel_stack_, 0); - elem->filter->start_transport_op(elem, op); -} - -void ConnectedSubchannel::Ping(grpc_closure* on_initiate, - grpc_closure* on_ack) { - grpc_transport_op* op = grpc_make_transport_op(nullptr); - grpc_channel_element* elem; - op->send_ping.on_initiate = on_initiate; - op->send_ping.on_ack = on_ack; - elem = grpc_channel_stack_element(channel_stack_, 0); - elem->filter->start_transport_op(elem, op); -} +// +// LegacyConnectedSubchannel +// -size_t ConnectedSubchannel::GetInitialCallSizeEstimate() const { - return GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(SubchannelCall)) + - channel_stack_->call_stack_size; -} +class LegacyConnectedSubchannel : public ConnectedSubchannel { + public: + LegacyConnectedSubchannel( + RefCountedPtr channel_stack, const ChannelArgs& args, + RefCountedPtr channelz_subchannel) + : ConnectedSubchannel(args, std::move(channelz_subchannel)), + channel_stack_(std::move(channel_stack)) {} -ArenaPromise ConnectedSubchannel::MakeCallPromise( - CallArgs call_args) { - // If not using channelz, we just need to call the channel stack. - if (channelz_subchannel() == nullptr) { - return channel_stack_->MakeClientCallPromise(std::move(call_args)); + ~LegacyConnectedSubchannel() override { + channel_stack_.reset(DEBUG_LOCATION, "ConnectedSubchannel"); } +<<<<<<< HEAD // Otherwise, we need to wrap the channel stack promise with code that // handles the channelz updates. return OnCancel( @@ -165,6 +149,127 @@ ArenaPromise ConnectedSubchannel::MakeCallPromise( channelz_subchannel->RecordCallFailed(); }); } +======= + + void StartWatch( + grpc_pollset_set* interested_parties, + OrphanablePtr watcher) override { + grpc_transport_op* op = grpc_make_transport_op(nullptr); + op->start_connectivity_watch = std::move(watcher); + op->start_connectivity_watch_state = GRPC_CHANNEL_READY; + op->bind_pollset_set = interested_parties; + grpc_channel_element* elem = + grpc_channel_stack_element(channel_stack_.get(), 0); + elem->filter->start_transport_op(elem, op); + } + + void Ping(absl::AnyInvocable on_ack) override { + Crash("call v3 ping method called in legacy impl"); + } + + void StartCall(UnstartedCallHandler) override { + Crash("call v3 StartCall() method called in legacy impl"); + } + + grpc_channel_stack* channel_stack() const override { + return channel_stack_.get(); + } + + size_t GetInitialCallSizeEstimate() const override { + return GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(SubchannelCall)) + + channel_stack_->call_stack_size; + } + + ArenaPromise MakeCallPromise( + CallArgs call_args) override { + // If not using channelz, we just need to call the channel stack. + if (channelz_subchannel() == nullptr) { + return channel_stack_->MakeClientCallPromise(std::move(call_args)); + } + // Otherwise, we need to wrap the channel stack promise with code that + // handles the channelz updates. + return OnCancel( + Seq(channel_stack_->MakeClientCallPromise(std::move(call_args)), + [self = Ref()](ServerMetadataHandle metadata) { + channelz::SubchannelNode* channelz_subchannel = + self->channelz_subchannel(); + GPR_ASSERT(channelz_subchannel != nullptr); + if (metadata->get(GrpcStatusMetadata()) + .value_or(GRPC_STATUS_UNKNOWN) != GRPC_STATUS_OK) { + channelz_subchannel->RecordCallFailed(); + } else { + channelz_subchannel->RecordCallSucceeded(); + } + return metadata; + }), + [self = Ref()]() { + channelz::SubchannelNode* channelz_subchannel = + self->channelz_subchannel(); + GPR_ASSERT(channelz_subchannel != nullptr); + channelz_subchannel->RecordCallFailed(); + }); + } + + void Ping(grpc_closure* on_initiate, grpc_closure* on_ack) override { + grpc_transport_op* op = grpc_make_transport_op(nullptr); + op->send_ping.on_initiate = on_initiate; + op->send_ping.on_ack = on_ack; + grpc_channel_element* elem = + grpc_channel_stack_element(channel_stack_.get(), 0); + elem->filter->start_transport_op(elem, op); + } + + private: + RefCountedPtr channel_stack_; +}; + +// +// NewConnectedSubchannel +// + +class NewConnectedSubchannel : public ConnectedSubchannel { + public: + NewConnectedSubchannel( + RefCountedPtr filter_stack, + OrphanablePtr transport, const ChannelArgs& args, + RefCountedPtr channelz_subchannel) + : ConnectedSubchannel(args, std::move(channelz_subchannel)), + filter_stack_(std::move(filter_stack)), + transport_(std::move(transport)) {} + + void StartWatch( + grpc_pollset_set* interested_parties, + OrphanablePtr watcher) override { +// FIXME: add new transport API for this in v3 stack + } + + void Ping(absl::AnyInvocable on_ack) override { +// FIXME: add new transport API for this in v3 stack + } + + void StartCall(UnstartedCallHandler unstarted_handler) override { + auto handler = unstarted_handler.StartCall(filter_stack_); + transport_->client_transport()->StartCall(std::move(handler)); + } + + grpc_channel_stack* channel_stack() const override { return nullptr; } + + size_t GetInitialCallSizeEstimate() const override { return 0; } + + ArenaPromise MakeCallPromise( + CallArgs call_args) override { + Crash("legacy MakeCallPromise() method called in call v3 impl"); + } + + void Ping(grpc_closure* on_initiate, grpc_closure* on_ack) override { + Crash("legacy ping method called in call v3 impl"); + } + + private: + RefCountedPtr filter_stack_; + OrphanablePtr transport_; +}; +>>>>>>> 513bd21ea9db49d061e0382289319ddb126f812c // // SubchannelCall @@ -769,37 +874,46 @@ void Subchannel::OnConnectingFinishedLocked(grpc_error_handle error) { } bool Subchannel::PublishTransportLocked() { - // Construct channel stack. - // Builder takes ownership of transport. - ChannelStackBuilderImpl builder( - "subchannel", GRPC_CLIENT_SUBCHANNEL, - connecting_result_.channel_args.SetObject( - std::exchange(connecting_result_.transport, nullptr))); - if (!CoreConfiguration::Get().channel_init().CreateStack(&builder)) { - return false; - } - absl::StatusOr> stk = builder.Build(); - if (!stk.ok()) { - auto error = absl_status_to_grpc_error(stk.status()); - connecting_result_.Reset(); - gpr_log(GPR_ERROR, - "subchannel %p %s: error initializing subchannel stack: %s", this, - key_.ToString().c_str(), StatusToString(error).c_str()); - return false; + auto socket_node = std::move(connecting_result_.socket_node); + if (!IsCallV3Enabled()) { + // Construct channel stack. + // Builder takes ownership of transport. + ChannelStackBuilderImpl builder( + "subchannel", GRPC_CLIENT_SUBCHANNEL, + connecting_result_.channel_args.SetObject( + std::exchange(connecting_result_.transport, nullptr))); + if (!CoreConfiguration::Get().channel_init().CreateStack(&builder)) { + return false; + } + absl::StatusOr> stack = builder.Build(); + if (!stack.ok()) { + connecting_result_.Reset(); + gpr_log(GPR_ERROR, + "subchannel %p %s: error initializing subchannel stack: %s", this, + key_.ToString().c_str(), stack.status().ToString().c_str()); + return false; + } + connected_subchannel_ = MakeRefCounted( + std::move(*stack), args_, channelz_node_); + } else { + // Call v3 stack. + CallFilters::StackBuilder builder; +// FIXME: add filters registered for CLIENT_SUBCHANNEL + auto filter_stack = builder.Build(); + connected_subchannel_ = MakeRefCounted( + std::move(filter_stack), + OrphanablePtr( + std::exchange(connecting_result_.transport, nullptr)), + args_, channelz_node_); } - RefCountedPtr socket = - std::move(connecting_result_.socket_node); connecting_result_.Reset(); - if (shutdown_) return false; // Publish. - connected_subchannel_.reset( - new ConnectedSubchannel(stk->release(), args_, channelz_node_)); if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_subchannel)) { gpr_log(GPR_INFO, "subchannel %p %s: new connected subchannel at %p", this, key_.ToString().c_str(), connected_subchannel_.get()); } if (channelz_node_ != nullptr) { - channelz_node_->SetChildSocket(std::move(socket)); + channelz_node_->SetChildSocket(std::move(socket_node)); } // Start watching connected subchannel. connected_subchannel_->StartWatch( @@ -810,4 +924,29 @@ bool Subchannel::PublishTransportLocked() { return true; } +ChannelArgs Subchannel::MakeSubchannelArgs( + const ChannelArgs& channel_args, const ChannelArgs& address_args, + const RefCountedPtr& subchannel_pool, + const std::string& channel_default_authority) { + // Note that we start with the channel-level args and then apply the + // per-address args, so that if a value is present in both, the one + // in the channel-level args is used. This is particularly important + // for the GRPC_ARG_DEFAULT_AUTHORITY arg, which we want to allow + // resolvers to set on a per-address basis only if the application + // did not explicitly set it at the channel level. + return channel_args.UnionWith(address_args) + .SetObject(subchannel_pool) + // If we haven't already set the default authority arg (i.e., it + // was not explicitly set by the application nor overridden by + // the resolver), add it from the channel's default. + .SetIfUnset(GRPC_ARG_DEFAULT_AUTHORITY, channel_default_authority) + // Remove channel args that should not affect subchannel + // uniqueness. + .Remove(GRPC_ARG_HEALTH_CHECK_SERVICE_NAME) + .Remove(GRPC_ARG_INHIBIT_HEALTH_CHECKING) + .Remove(GRPC_ARG_CHANNELZ_CHANNEL_NODE) + // Remove all keys with the no-subchannel prefix. + .RemoveAllKeysWithPrefix(GRPC_ARG_NO_SUBCHANNEL_PREFIX); +} + } // namespace grpc_core diff --git a/src/core/client_channel/subchannel.h b/src/core/client_channel/subchannel.h index 6fbe389da5c..35247d3af2f 100644 --- a/src/core/client_channel/subchannel.h +++ b/src/core/client_channel/subchannel.h @@ -66,28 +66,32 @@ class SubchannelCall; class ConnectedSubchannel final : public RefCounted { public: - ConnectedSubchannel( - grpc_channel_stack* channel_stack, const ChannelArgs& args, - RefCountedPtr channelz_subchannel); - ~ConnectedSubchannel() override; - - void StartWatch(grpc_pollset_set* interested_parties, - OrphanablePtr watcher); - - void Ping(grpc_closure* on_initiate, grpc_closure* on_ack); - - grpc_channel_stack* channel_stack() const { return channel_stack_; } const ChannelArgs& args() const { return args_; } channelz::SubchannelNode* channelz_subchannel() const { return channelz_subchannel_.get(); } - size_t GetInitialCallSizeEstimate() const; + virtual void StartWatch( + grpc_pollset_set* interested_parties, + OrphanablePtr watcher) = 0; - ArenaPromise MakeCallPromise(CallArgs call_args); + // Methods for v3 stack. + virtual void StartCall(UnstartedCallHandler unstarted_handler) = 0; + virtual void Ping(absl::AnyInvocable on_ack) = 0; + + // Methods for legacy stack. + virtual grpc_channel_stack* channel_stack() const = 0; + virtual size_t GetInitialCallSizeEstimate() const = 0; + virtual ArenaPromise MakeCallPromise( + CallArgs call_args) = 0; + virtual void Ping(grpc_closure* on_initiate, grpc_closure* on_ack) = 0; + + protected: + ConnectedSubchannel( + const ChannelArgs& args, + RefCountedPtr channelz_subchannel); private: - grpc_channel_stack* channel_stack_; ChannelArgs args_; // ref counted pointer to the channelz node in this connected subchannel's // owning subchannel. @@ -272,6 +276,12 @@ class Subchannel final : public DualRefCounted { return event_engine_; } + // Exposed for testing purposes only. + static ChannelArgs MakeSubchannelArgs( + const ChannelArgs& channel_args, const ChannelArgs& address_args, + const RefCountedPtr& subchannel_pool, + const std::string& channel_default_authority); + private: // Tears down any existing connection, and arranges for destruction void Orphaned() override ABSL_LOCKS_EXCLUDED(mu_); diff --git a/src/core/ext/filters/channel_idle/channel_idle_filter.cc b/src/core/ext/filters/channel_idle/channel_idle_filter.cc new file mode 100644 index 00000000000..6f90704a04f --- /dev/null +++ b/src/core/ext/filters/channel_idle/channel_idle_filter.cc @@ -0,0 +1,316 @@ +// 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. + +// TODO(ctiller): Add a unit test suite for these filters once it's practical to +// mock transport operations. + +#include + +#include "src/core/ext/filters/channel_idle/channel_idle_filter.h" + +#include +#include + +#include "absl/base/thread_annotations.h" +#include "absl/meta/type_traits.h" +#include "absl/random/random.h" +#include "absl/types/optional.h" + +#include +#include + +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/channel/promise_based_filter.h" +#include "src/core/lib/config/core_configuration.h" +#include "src/core/lib/debug/trace.h" +#include "src/core/lib/experiments/experiments.h" +#include "src/core/lib/gprpp/debug_location.h" +#include "src/core/lib/gprpp/no_destruct.h" +#include "src/core/lib/gprpp/orphanable.h" +#include "src/core/lib/gprpp/per_cpu.h" +#include "src/core/lib/gprpp/status_helper.h" +#include "src/core/lib/gprpp/sync.h" +#include "src/core/lib/iomgr/closure.h" +#include "src/core/lib/iomgr/error.h" +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/promise/exec_ctx_wakeup_scheduler.h" +#include "src/core/lib/promise/loop.h" +#include "src/core/lib/promise/poll.h" +#include "src/core/lib/promise/promise.h" +#include "src/core/lib/promise/sleep.h" +#include "src/core/lib/promise/try_seq.h" +#include "src/core/lib/surface/channel_stack_type.h" +#include "src/core/lib/transport/http2_errors.h" +#include "src/core/lib/transport/metadata_batch.h" + +namespace grpc_core { + +const NoInterceptor ChannelIdleFilter::Call::OnClientInitialMetadata; +const NoInterceptor ChannelIdleFilter::Call::OnServerInitialMetadata; +const NoInterceptor ChannelIdleFilter::Call::OnServerTrailingMetadata; +const NoInterceptor ChannelIdleFilter::Call::OnClientToServerMessage; +const NoInterceptor ChannelIdleFilter::Call::OnServerToClientMessage; + +namespace { + +// TODO(roth): This can go back to being a constant when the experiment +// is removed. +Duration DefaultIdleTimeout() { + if (IsClientIdlenessEnabled()) return Duration::Minutes(30); + return Duration::Infinity(); +} + +// If these settings change, make sure that we are not sending a GOAWAY for +// inproc transport, since a GOAWAY to inproc ends up destroying the transport. +const auto kDefaultMaxConnectionAge = Duration::Infinity(); +const auto kDefaultMaxConnectionAgeGrace = Duration::Infinity(); +const auto kDefaultMaxConnectionIdle = Duration::Infinity(); +const auto kMaxConnectionAgeJitter = 0.1; + +TraceFlag grpc_trace_client_idle_filter(false, "client_idle_filter"); +} // namespace + +#define GRPC_IDLE_FILTER_LOG(format, ...) \ + do { \ + if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_client_idle_filter)) { \ + gpr_log(GPR_INFO, "(client idle filter) " format, ##__VA_ARGS__); \ + } \ + } while (0) + +Duration GetClientIdleTimeout(const ChannelArgs& args) { + return args.GetDurationFromIntMillis(GRPC_ARG_CLIENT_IDLE_TIMEOUT_MS) + .value_or(DefaultIdleTimeout()); +} + +struct MaxAgeFilter::Config { + Duration max_connection_age; + Duration max_connection_idle; + Duration max_connection_age_grace; + + bool enable() const { + return max_connection_age != Duration::Infinity() || + max_connection_idle != Duration::Infinity(); + } + + // A random jitter of +/-10% will be added to MAX_CONNECTION_AGE and + // MAX_CONNECTION_IDLE to spread out reconnection storms. + static Config FromChannelArgs(const ChannelArgs& args) { + const Duration args_max_age = + args.GetDurationFromIntMillis(GRPC_ARG_MAX_CONNECTION_AGE_MS) + .value_or(kDefaultMaxConnectionAge); + const Duration args_max_idle = + args.GetDurationFromIntMillis(GRPC_ARG_MAX_CONNECTION_IDLE_MS) + .value_or(kDefaultMaxConnectionIdle); + const Duration args_max_age_grace = + args.GetDurationFromIntMillis(GRPC_ARG_MAX_CONNECTION_AGE_GRACE_MS) + .value_or(kDefaultMaxConnectionAgeGrace); + // generate a random number between 1 - kMaxConnectionAgeJitter and + // 1 + kMaxConnectionAgeJitter + struct BitGen { + Mutex mu; + absl::BitGen bit_gen ABSL_GUARDED_BY(mu); + double MakeUniformDouble(double min, double max) { + MutexLock lock(&mu); + return absl::Uniform(bit_gen, min, max); + } + }; + static NoDestruct> bit_gen(PerCpuOptions().SetMaxShards(8)); + const double multiplier = bit_gen->this_cpu().MakeUniformDouble( + 1.0 - kMaxConnectionAgeJitter, 1.0 + kMaxConnectionAgeJitter); + // GRPC_MILLIS_INF_FUTURE - 0.5 converts the value to float, so that result + // will not be cast to int implicitly before the comparison. + return Config{args_max_age * multiplier, args_max_idle * multiplier, + args_max_age_grace}; + } +}; + +absl::StatusOr ClientIdleFilter::Create( + const ChannelArgs& args, ChannelFilter::Args filter_args) { + ClientIdleFilter filter(filter_args.channel_stack(), + GetClientIdleTimeout(args)); + return absl::StatusOr(std::move(filter)); +} + +absl::StatusOr MaxAgeFilter::Create( + const ChannelArgs& args, ChannelFilter::Args filter_args) { + MaxAgeFilter filter(filter_args.channel_stack(), + Config::FromChannelArgs(args)); + return absl::StatusOr(std::move(filter)); +} + +void MaxAgeFilter::Shutdown() { + max_age_activity_.Reset(); + ChannelIdleFilter::Shutdown(); +} + +void MaxAgeFilter::PostInit() { + struct StartupClosure { + RefCountedPtr channel_stack; + MaxAgeFilter* filter; + grpc_closure closure; + }; + auto run_startup = [](void* p, grpc_error_handle) { + auto* startup = static_cast(p); + // Trigger idle timer + startup->filter->IncreaseCallCount(); + startup->filter->DecreaseCallCount(); + grpc_transport_op* op = grpc_make_transport_op(nullptr); + op->start_connectivity_watch.reset( + new ConnectivityWatcher(startup->filter)); + op->start_connectivity_watch_state = GRPC_CHANNEL_IDLE; + grpc_channel_next_op( + grpc_channel_stack_element(startup->channel_stack.get(), 0), op); + delete startup; + }; + auto* startup = + new StartupClosure{this->channel_stack()->Ref(), this, grpc_closure{}}; + GRPC_CLOSURE_INIT(&startup->closure, run_startup, startup, nullptr); + ExecCtx::Run(DEBUG_LOCATION, &startup->closure, absl::OkStatus()); + + auto channel_stack = this->channel_stack()->Ref(); + + // Start the max age timer + if (max_connection_age_ != Duration::Infinity()) { + max_age_activity_.Set(MakeActivity( + TrySeq( + // First sleep until the max connection age + Sleep(Timestamp::Now() + max_connection_age_), + // Then send a goaway. + [this] { + GRPC_CHANNEL_STACK_REF(this->channel_stack(), + "max_age send_goaway"); + // Jump out of the activity to send the goaway. + auto fn = [](void* arg, grpc_error_handle) { + auto* channel_stack = static_cast(arg); + grpc_transport_op* op = grpc_make_transport_op(nullptr); + op->goaway_error = grpc_error_set_int( + GRPC_ERROR_CREATE("max_age"), + StatusIntProperty::kHttp2Error, GRPC_HTTP2_NO_ERROR); + grpc_channel_element* elem = + grpc_channel_stack_element(channel_stack, 0); + elem->filter->start_transport_op(elem, op); + GRPC_CHANNEL_STACK_UNREF(channel_stack, "max_age send_goaway"); + }; + ExecCtx::Run( + DEBUG_LOCATION, + GRPC_CLOSURE_CREATE(fn, this->channel_stack(), nullptr), + absl::OkStatus()); + return Immediate(absl::OkStatus()); + }, + // Sleep for the grace period + [this] { + return Sleep(Timestamp::Now() + max_connection_age_grace_); + }), + ExecCtxWakeupScheduler(), + [channel_stack, this](absl::Status status) { + // OnDone -- close the connection if the promise completed + // successfully. + // (if it did not, it was cancelled) + if (status.ok()) CloseChannel(); + }, + channel_stack->EventEngine())); + } +} + +bool ChannelIdleFilter::StartTransportOp(grpc_transport_op* op) { + // Catch the disconnect_with_error transport op. + if (!op->disconnect_with_error.ok()) Shutdown(); + // Pass the op to the next filter. + return false; +} + +void ChannelIdleFilter::Shutdown() { + // IncreaseCallCount() introduces a phony call and prevent the timer from + // being reset by other threads. + IncreaseCallCount(); + activity_.Reset(); +} + +void ChannelIdleFilter::IncreaseCallCount() { + idle_filter_state_->IncreaseCallCount(); +} + +void ChannelIdleFilter::DecreaseCallCount() { + if (idle_filter_state_->DecreaseCallCount()) { + // If there are no more calls in progress, start the idle timer. + StartIdleTimer(); + } +} + +void ChannelIdleFilter::StartIdleTimer() { + GRPC_IDLE_FILTER_LOG("timer has started"); + auto idle_filter_state = idle_filter_state_; + // Hold a ref to the channel stack for the timer callback. + auto channel_stack = channel_stack_->Ref(); + auto timeout = client_idle_timeout_; + auto promise = Loop([timeout, idle_filter_state]() { + return TrySeq(Sleep(Timestamp::Now() + timeout), + [idle_filter_state]() -> Poll> { + if (idle_filter_state->CheckTimer()) { + return Continue{}; + } else { + return absl::OkStatus(); + } + }); + }); + activity_.Set(MakeActivity( + std::move(promise), ExecCtxWakeupScheduler{}, + [channel_stack, this](absl::Status status) { + if (status.ok()) CloseChannel(); + }, + channel_stack->EventEngine())); +} + +void ChannelIdleFilter::CloseChannel() { + auto* op = grpc_make_transport_op(nullptr); + op->disconnect_with_error = grpc_error_set_int( + GRPC_ERROR_CREATE("enter idle"), + StatusIntProperty::ChannelConnectivityState, GRPC_CHANNEL_IDLE); + // Pass the transport op down to the channel stack. + auto* elem = grpc_channel_stack_element(channel_stack_, 0); + elem->filter->start_transport_op(elem, op); +} + +const grpc_channel_filter ClientIdleFilter::kFilter = + MakePromiseBasedFilter( + "client_idle"); +const grpc_channel_filter MaxAgeFilter::kFilter = + MakePromiseBasedFilter("max_age"); + +void RegisterChannelIdleFilters(CoreConfiguration::Builder* builder) { + GPR_ASSERT(MaxAgeFilter::kFilter.init_call != nullptr); + if (!IsV3ChannelIdleFiltersEnabled()) return; + if (!IsCallV3Enabled()) { + builder->channel_init() + ->RegisterFilter(GRPC_CLIENT_CHANNEL) + .ExcludeFromMinimalStack() + .If([](const ChannelArgs& channel_args) { + return GetClientIdleTimeout(channel_args) != Duration::Infinity(); + }); + } + builder->channel_init() + ->RegisterFilter(GRPC_SERVER_CHANNEL) + .ExcludeFromMinimalStack() + .If([](const ChannelArgs& channel_args) { + return MaxAgeFilter::Config::FromChannelArgs(channel_args).enable(); + }); +} + +MaxAgeFilter::MaxAgeFilter(grpc_channel_stack* channel_stack, + const Config& max_age_config) + : ChannelIdleFilter(channel_stack, max_age_config.max_connection_idle), + max_connection_age_(max_age_config.max_connection_age), + max_connection_age_grace_(max_age_config.max_connection_age_grace) {} + +} // namespace grpc_core diff --git a/src/core/ext/filters/channel_idle/channel_idle_filter.h b/src/core/ext/filters/channel_idle/channel_idle_filter.h new file mode 100644 index 00000000000..f4f02f71107 --- /dev/null +++ b/src/core/ext/filters/channel_idle/channel_idle_filter.h @@ -0,0 +1,156 @@ +// 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_SRC_CORE_EXT_FILTERS_CHANNEL_IDLE_CHANNEL_IDLE_FILTER_H +#define GRPC_SRC_CORE_EXT_FILTERS_CHANNEL_IDLE_CHANNEL_IDLE_FILTER_H + +#include + +#include + +#include "absl/status/status.h" +#include "absl/status/statusor.h" + +#include + +#include "src/core/ext/filters/channel_idle/idle_filter_state.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/channel/channel_fwd.h" +#include "src/core/lib/channel/channel_stack.h" +#include "src/core/lib/channel/promise_based_filter.h" +#include "src/core/lib/gprpp/orphanable.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/gprpp/single_set_ptr.h" +#include "src/core/lib/gprpp/time.h" +#include "src/core/lib/promise/activity.h" +#include "src/core/lib/promise/arena_promise.h" +#include "src/core/lib/transport/connectivity_state.h" +#include "src/core/lib/transport/transport.h" + +namespace grpc_core { + +Duration GetClientIdleTimeout(const ChannelArgs& args); + +class ChannelIdleFilter : public ImplementChannelFilter { + public: + ~ChannelIdleFilter() override = default; + + ChannelIdleFilter(const ChannelIdleFilter&) = delete; + ChannelIdleFilter& operator=(const ChannelIdleFilter&) = delete; + ChannelIdleFilter(ChannelIdleFilter&&) = default; + ChannelIdleFilter& operator=(ChannelIdleFilter&&) = default; + + class Call { + public: + explicit Call(ChannelIdleFilter* filter) : filter_(filter) { + filter_->IncreaseCallCount(); + } + ~Call() { MaybeDecrement(); } + + static const NoInterceptor OnClientInitialMetadata; + static const NoInterceptor OnServerInitialMetadata; + static const NoInterceptor OnServerTrailingMetadata; + static const NoInterceptor OnClientToServerMessage; + static const NoInterceptor OnServerToClientMessage; + void OnFinalize(const grpc_call_final_info*) { MaybeDecrement(); } + + private: + void MaybeDecrement() { + auto* filter = std::exchange(filter_, nullptr); + if (filter != nullptr) filter->DecreaseCallCount(); + } + ChannelIdleFilter* filter_; + }; + + bool StartTransportOp(grpc_transport_op* op) override; + + protected: + using SingleSetActivityPtr = + SingleSetPtr; + + ChannelIdleFilter(grpc_channel_stack* channel_stack, + Duration client_idle_timeout) + : channel_stack_(channel_stack), + client_idle_timeout_(client_idle_timeout) {} + + grpc_channel_stack* channel_stack() { return channel_stack_; }; + + virtual void Shutdown(); + void CloseChannel(); + + void IncreaseCallCount(); + void DecreaseCallCount(); + + private: + void StartIdleTimer(); + + // The channel stack to which we take refs for pending callbacks. + grpc_channel_stack* channel_stack_; + Duration client_idle_timeout_; + std::shared_ptr idle_filter_state_{ + std::make_shared(false)}; + + SingleSetActivityPtr activity_; +}; + +class ClientIdleFilter final : public ChannelIdleFilter { + public: + static const grpc_channel_filter kFilter; + + static absl::StatusOr Create( + const ChannelArgs& args, ChannelFilter::Args filter_args); + + private: + using ChannelIdleFilter::ChannelIdleFilter; +}; + +class MaxAgeFilter final : public ChannelIdleFilter { + public: + static const grpc_channel_filter kFilter; + struct Config; + + static absl::StatusOr Create(const ChannelArgs& args, + ChannelFilter::Args filter_args); + + void PostInit() override; + + private: + class ConnectivityWatcher : public AsyncConnectivityStateWatcherInterface { + public: + explicit ConnectivityWatcher(MaxAgeFilter* filter) + : channel_stack_(filter->channel_stack()->Ref()), filter_(filter) {} + ~ConnectivityWatcher() override = default; + + void OnConnectivityStateChange(grpc_connectivity_state new_state, + const absl::Status&) override { + if (new_state == GRPC_CHANNEL_SHUTDOWN) filter_->Shutdown(); + } + + private: + RefCountedPtr channel_stack_; + MaxAgeFilter* filter_; + }; + + MaxAgeFilter(grpc_channel_stack* channel_stack, const Config& max_age_config); + + void Shutdown() override; + + SingleSetActivityPtr max_age_activity_; + Duration max_connection_age_; + Duration max_connection_age_grace_; +}; + +} // namespace grpc_core + +#endif // GRPC_SRC_CORE_EXT_FILTERS_CHANNEL_IDLE_CHANNEL_IDLE_FILTER_H diff --git a/src/core/lib/channel/channel_stack.h b/src/core/lib/channel/channel_stack.h index 030173fcd31..2a481376494 100644 --- a/src/core/lib/channel/channel_stack.h +++ b/src/core/lib/channel/channel_stack.h @@ -230,6 +230,7 @@ struct grpc_channel_stack { // full C++-ification for now. void IncrementRefCount(); void Unref(); + void Unref(const grpc_core::DebugLocation& location, const char* reason); grpc_core::RefCountedPtr Ref() { IncrementRefCount(); return grpc_core::RefCountedPtr(this); @@ -345,6 +346,11 @@ inline void grpc_channel_stack::Unref() { GRPC_CHANNEL_STACK_UNREF(this, "smart_pointer"); } +inline void grpc_channel_stack::Unref(const grpc_core::DebugLocation&, + const char* reason) { + GRPC_CHANNEL_STACK_UNREF(this, reason); +} + inline void grpc_call_stack::IncrementRefCount() { GRPC_CALL_STACK_REF(this, "smart_pointer"); } diff --git a/src/core/lib/experiments/experiments.cc b/src/core/lib/experiments/experiments.cc index d0a67a5645b..82a95b14393 100644 --- a/src/core/lib/experiments/experiments.cc +++ b/src/core/lib/experiments/experiments.cc @@ -29,8 +29,6 @@ const char* const description_call_status_override_on_cancellation = "with cancellation."; const char* const additional_constraints_call_status_override_on_cancellation = "{}"; -const char* const description_call_v3 = "Promise-based call version 3."; -const char* const additional_constraints_call_v3 = "{}"; const char* const description_canary_client_privacy = "If set, canary client privacy"; const char* const additional_constraints_canary_client_privacy = "{}"; @@ -128,6 +126,24 @@ const char* const description_work_serializer_dispatch = const char* const additional_constraints_work_serializer_dispatch = "{}"; const uint8_t required_experiments_work_serializer_dispatch[] = { static_cast(grpc_core::kExperimentIdEventEngineClient)}; +<<<<<<< HEAD +======= +const char* const description_call_v3 = "Promise-based call version 3."; +const char* const additional_constraints_call_v3 = "{}"; +const uint8_t required_experiments_call_v3[] = { + static_cast(grpc_core::kExperimentIdEventEngineClient), + static_cast(grpc_core::kExperimentIdEventEngineListener), + static_cast(grpc_core::kExperimentIdWorkSerializerDispatch)}; +const char* const description_wrr_delegate_to_pick_first = + "Change WRR code to delegate to pick_first as per dualstack backend " + "design."; +const char* const additional_constraints_wrr_delegate_to_pick_first = "{}"; +#ifdef NDEBUG +const bool kDefaultForDebugOnly = false; +#else +const bool kDefaultForDebugOnly = true; +#endif +>>>>>>> 513bd21ea9db49d061e0382289319ddb126f812c } // namespace namespace grpc_core { @@ -136,9 +152,13 @@ const ExperimentMetadata g_experiment_metadata[] = { {"call_status_override_on_cancellation", description_call_status_override_on_cancellation, additional_constraints_call_status_override_on_cancellation, nullptr, 0, +<<<<<<< HEAD true, true}, {"call_v3", description_call_v3, additional_constraints_call_v3, nullptr, 0, false, true}, +======= + kDefaultForDebugOnly, true}, +>>>>>>> 513bd21ea9db49d061e0382289319ddb126f812c {"canary_client_privacy", description_canary_client_privacy, additional_constraints_canary_client_privacy, nullptr, 0, false, false}, {"client_privacy", description_client_privacy, @@ -200,6 +220,13 @@ const ExperimentMetadata g_experiment_metadata[] = { {"work_serializer_dispatch", description_work_serializer_dispatch, additional_constraints_work_serializer_dispatch, required_experiments_work_serializer_dispatch, 1, false, true}, +<<<<<<< HEAD +======= + {"call_v3", description_call_v3, additional_constraints_call_v3, + required_experiments_call_v3, 3, false, true}, + {"wrr_delegate_to_pick_first", description_wrr_delegate_to_pick_first, + additional_constraints_wrr_delegate_to_pick_first, nullptr, 0, true, true}, +>>>>>>> 513bd21ea9db49d061e0382289319ddb126f812c }; } // namespace grpc_core @@ -211,8 +238,6 @@ const char* const description_call_status_override_on_cancellation = "with cancellation."; const char* const additional_constraints_call_status_override_on_cancellation = "{}"; -const char* const description_call_v3 = "Promise-based call version 3."; -const char* const additional_constraints_call_v3 = "{}"; const char* const description_canary_client_privacy = "If set, canary client privacy"; const char* const additional_constraints_canary_client_privacy = "{}"; @@ -310,6 +335,24 @@ const char* const description_work_serializer_dispatch = const char* const additional_constraints_work_serializer_dispatch = "{}"; const uint8_t required_experiments_work_serializer_dispatch[] = { static_cast(grpc_core::kExperimentIdEventEngineClient)}; +<<<<<<< HEAD +======= +const char* const description_call_v3 = "Promise-based call version 3."; +const char* const additional_constraints_call_v3 = "{}"; +const uint8_t required_experiments_call_v3[] = { + static_cast(grpc_core::kExperimentIdEventEngineClient), + static_cast(grpc_core::kExperimentIdEventEngineListener), + static_cast(grpc_core::kExperimentIdWorkSerializerDispatch)}; +const char* const description_wrr_delegate_to_pick_first = + "Change WRR code to delegate to pick_first as per dualstack backend " + "design."; +const char* const additional_constraints_wrr_delegate_to_pick_first = "{}"; +#ifdef NDEBUG +const bool kDefaultForDebugOnly = false; +#else +const bool kDefaultForDebugOnly = true; +#endif +>>>>>>> 513bd21ea9db49d061e0382289319ddb126f812c } // namespace namespace grpc_core { @@ -318,9 +361,13 @@ const ExperimentMetadata g_experiment_metadata[] = { {"call_status_override_on_cancellation", description_call_status_override_on_cancellation, additional_constraints_call_status_override_on_cancellation, nullptr, 0, +<<<<<<< HEAD true, true}, {"call_v3", description_call_v3, additional_constraints_call_v3, nullptr, 0, false, true}, +======= + kDefaultForDebugOnly, true}, +>>>>>>> 513bd21ea9db49d061e0382289319ddb126f812c {"canary_client_privacy", description_canary_client_privacy, additional_constraints_canary_client_privacy, nullptr, 0, false, false}, {"client_privacy", description_client_privacy, @@ -382,6 +429,13 @@ const ExperimentMetadata g_experiment_metadata[] = { {"work_serializer_dispatch", description_work_serializer_dispatch, additional_constraints_work_serializer_dispatch, required_experiments_work_serializer_dispatch, 1, false, true}, +<<<<<<< HEAD +======= + {"call_v3", description_call_v3, additional_constraints_call_v3, + required_experiments_call_v3, 3, false, true}, + {"wrr_delegate_to_pick_first", description_wrr_delegate_to_pick_first, + additional_constraints_wrr_delegate_to_pick_first, nullptr, 0, true, true}, +>>>>>>> 513bd21ea9db49d061e0382289319ddb126f812c }; } // namespace grpc_core @@ -393,8 +447,6 @@ const char* const description_call_status_override_on_cancellation = "with cancellation."; const char* const additional_constraints_call_status_override_on_cancellation = "{}"; -const char* const description_call_v3 = "Promise-based call version 3."; -const char* const additional_constraints_call_v3 = "{}"; const char* const description_canary_client_privacy = "If set, canary client privacy"; const char* const additional_constraints_canary_client_privacy = "{}"; @@ -492,6 +544,24 @@ const char* const description_work_serializer_dispatch = const char* const additional_constraints_work_serializer_dispatch = "{}"; const uint8_t required_experiments_work_serializer_dispatch[] = { static_cast(grpc_core::kExperimentIdEventEngineClient)}; +<<<<<<< HEAD +======= +const char* const description_call_v3 = "Promise-based call version 3."; +const char* const additional_constraints_call_v3 = "{}"; +const uint8_t required_experiments_call_v3[] = { + static_cast(grpc_core::kExperimentIdEventEngineClient), + static_cast(grpc_core::kExperimentIdEventEngineListener), + static_cast(grpc_core::kExperimentIdWorkSerializerDispatch)}; +const char* const description_wrr_delegate_to_pick_first = + "Change WRR code to delegate to pick_first as per dualstack backend " + "design."; +const char* const additional_constraints_wrr_delegate_to_pick_first = "{}"; +#ifdef NDEBUG +const bool kDefaultForDebugOnly = false; +#else +const bool kDefaultForDebugOnly = true; +#endif +>>>>>>> 513bd21ea9db49d061e0382289319ddb126f812c } // namespace namespace grpc_core { @@ -500,9 +570,13 @@ const ExperimentMetadata g_experiment_metadata[] = { {"call_status_override_on_cancellation", description_call_status_override_on_cancellation, additional_constraints_call_status_override_on_cancellation, nullptr, 0, +<<<<<<< HEAD true, true}, {"call_v3", description_call_v3, additional_constraints_call_v3, nullptr, 0, false, true}, +======= + kDefaultForDebugOnly, true}, +>>>>>>> 513bd21ea9db49d061e0382289319ddb126f812c {"canary_client_privacy", description_canary_client_privacy, additional_constraints_canary_client_privacy, nullptr, 0, false, false}, {"client_privacy", description_client_privacy, @@ -564,6 +638,13 @@ const ExperimentMetadata g_experiment_metadata[] = { {"work_serializer_dispatch", description_work_serializer_dispatch, additional_constraints_work_serializer_dispatch, required_experiments_work_serializer_dispatch, 1, true, true}, +<<<<<<< HEAD +======= + {"call_v3", description_call_v3, additional_constraints_call_v3, + required_experiments_call_v3, 3, false, true}, + {"wrr_delegate_to_pick_first", description_wrr_delegate_to_pick_first, + additional_constraints_wrr_delegate_to_pick_first, nullptr, 0, true, true}, +>>>>>>> 513bd21ea9db49d061e0382289319ddb126f812c }; } // namespace grpc_core diff --git a/src/core/lib/experiments/experiments.h b/src/core/lib/experiments/experiments.h index f4f623a6e87..d8828012c68 100644 --- a/src/core/lib/experiments/experiments.h +++ b/src/core/lib/experiments/experiments.h @@ -58,8 +58,19 @@ namespace grpc_core { #if defined(GRPC_CFSTREAM) #define GRPC_EXPERIMENT_IS_INCLUDED_CALL_STATUS_OVERRIDE_ON_CANCELLATION +<<<<<<< HEAD inline bool IsCallStatusOverrideOnCancellationEnabled() { return true; } inline bool IsCallV3Enabled() { return false; } +======= +#endif +inline bool IsCallStatusOverrideOnCancellationEnabled() { +#ifdef NDEBUG + return false; +#else + return true; +#endif +} +>>>>>>> 513bd21ea9db49d061e0382289319ddb126f812c inline bool IsCanaryClientPrivacyEnabled() { return false; } inline bool IsClientPrivacyEnabled() { return false; } inline bool IsEventEngineClientEnabled() { return false; } @@ -90,11 +101,28 @@ inline bool IsUnconstrainedMaxQuotaBufferSizeEnabled() { return false; } #define GRPC_EXPERIMENT_IS_INCLUDED_WORK_SERIALIZER_CLEARS_TIME_CACHE inline bool IsWorkSerializerClearsTimeCacheEnabled() { return true; } inline bool IsWorkSerializerDispatchEnabled() { return false; } +<<<<<<< HEAD +======= +inline bool IsCallV3Enabled() { return false; } +#define GRPC_EXPERIMENT_IS_INCLUDED_WRR_DELEGATE_TO_PICK_FIRST +inline bool IsWrrDelegateToPickFirstEnabled() { return true; } +>>>>>>> 513bd21ea9db49d061e0382289319ddb126f812c #elif defined(GPR_WINDOWS) #define GRPC_EXPERIMENT_IS_INCLUDED_CALL_STATUS_OVERRIDE_ON_CANCELLATION +<<<<<<< HEAD inline bool IsCallStatusOverrideOnCancellationEnabled() { return true; } inline bool IsCallV3Enabled() { return false; } +======= +#endif +inline bool IsCallStatusOverrideOnCancellationEnabled() { +#ifdef NDEBUG + return false; +#else + return true; +#endif +} +>>>>>>> 513bd21ea9db49d061e0382289319ddb126f812c inline bool IsCanaryClientPrivacyEnabled() { return false; } inline bool IsClientPrivacyEnabled() { return false; } inline bool IsEventEngineClientEnabled() { return false; } @@ -126,11 +154,28 @@ inline bool IsUnconstrainedMaxQuotaBufferSizeEnabled() { return false; } #define GRPC_EXPERIMENT_IS_INCLUDED_WORK_SERIALIZER_CLEARS_TIME_CACHE inline bool IsWorkSerializerClearsTimeCacheEnabled() { return true; } inline bool IsWorkSerializerDispatchEnabled() { return false; } +<<<<<<< HEAD +======= +inline bool IsCallV3Enabled() { return false; } +#define GRPC_EXPERIMENT_IS_INCLUDED_WRR_DELEGATE_TO_PICK_FIRST +inline bool IsWrrDelegateToPickFirstEnabled() { return true; } +>>>>>>> 513bd21ea9db49d061e0382289319ddb126f812c #else #define GRPC_EXPERIMENT_IS_INCLUDED_CALL_STATUS_OVERRIDE_ON_CANCELLATION +<<<<<<< HEAD inline bool IsCallStatusOverrideOnCancellationEnabled() { return true; } inline bool IsCallV3Enabled() { return false; } +======= +#endif +inline bool IsCallStatusOverrideOnCancellationEnabled() { +#ifdef NDEBUG + return false; +#else + return true; +#endif +} +>>>>>>> 513bd21ea9db49d061e0382289319ddb126f812c inline bool IsCanaryClientPrivacyEnabled() { return false; } inline bool IsClientPrivacyEnabled() { return false; } inline bool IsEventEngineClientEnabled() { return false; } @@ -164,12 +209,17 @@ inline bool IsUnconstrainedMaxQuotaBufferSizeEnabled() { return false; } inline bool IsWorkSerializerClearsTimeCacheEnabled() { return true; } #define GRPC_EXPERIMENT_IS_INCLUDED_WORK_SERIALIZER_DISPATCH inline bool IsWorkSerializerDispatchEnabled() { return true; } +<<<<<<< HEAD +======= +inline bool IsCallV3Enabled() { return false; } +#define GRPC_EXPERIMENT_IS_INCLUDED_WRR_DELEGATE_TO_PICK_FIRST +inline bool IsWrrDelegateToPickFirstEnabled() { return true; } +>>>>>>> 513bd21ea9db49d061e0382289319ddb126f812c #endif #else enum ExperimentIds { kExperimentIdCallStatusOverrideOnCancellation, - kExperimentIdCallV3, kExperimentIdCanaryClientPrivacy, kExperimentIdClientPrivacy, kExperimentIdEventEngineClient, @@ -195,16 +245,17 @@ enum ExperimentIds { kExperimentIdUnconstrainedMaxQuotaBufferSize, kExperimentIdWorkSerializerClearsTimeCache, kExperimentIdWorkSerializerDispatch, +<<<<<<< HEAD +======= + kExperimentIdCallV3, + kExperimentIdWrrDelegateToPickFirst, +>>>>>>> 513bd21ea9db49d061e0382289319ddb126f812c kNumExperiments }; #define GRPC_EXPERIMENT_IS_INCLUDED_CALL_STATUS_OVERRIDE_ON_CANCELLATION inline bool IsCallStatusOverrideOnCancellationEnabled() { return IsExperimentEnabled(kExperimentIdCallStatusOverrideOnCancellation); } -#define GRPC_EXPERIMENT_IS_INCLUDED_CALL_V3 -inline bool IsCallV3Enabled() { - return IsExperimentEnabled(kExperimentIdCallV3); -} #define GRPC_EXPERIMENT_IS_INCLUDED_CANARY_CLIENT_PRIVACY inline bool IsCanaryClientPrivacyEnabled() { return IsExperimentEnabled(kExperimentIdCanaryClientPrivacy); @@ -305,6 +356,17 @@ inline bool IsWorkSerializerClearsTimeCacheEnabled() { inline bool IsWorkSerializerDispatchEnabled() { return IsExperimentEnabled(kExperimentIdWorkSerializerDispatch); } +<<<<<<< HEAD +======= +#define GRPC_EXPERIMENT_IS_INCLUDED_CALL_V3 +inline bool IsCallV3Enabled() { + return IsExperimentEnabled(kExperimentIdCallV3); +} +#define GRPC_EXPERIMENT_IS_INCLUDED_WRR_DELEGATE_TO_PICK_FIRST +inline bool IsWrrDelegateToPickFirstEnabled() { + return IsExperimentEnabled(kExperimentIdWrrDelegateToPickFirst); +} +>>>>>>> 513bd21ea9db49d061e0382289319ddb126f812c extern const ExperimentMetadata g_experiment_metadata[kNumExperiments]; diff --git a/src/core/lib/experiments/experiments.yaml b/src/core/lib/experiments/experiments.yaml index 4d1a27e4d3c..23d0bffc785 100644 --- a/src/core/lib/experiments/experiments.yaml +++ b/src/core/lib/experiments/experiments.yaml @@ -52,6 +52,7 @@ expiry: 2024/06/01 owner: ctiller@google.com test_tags: [] + requires: ["work_serializer_dispatch", "event_engine_listener", "event_engine_client"] - name: canary_client_privacy description: If set, canary client privacy diff --git a/src/core/lib/surface/channel.cc b/src/core/lib/surface/channel.cc index 827d37f06b6..b948d64d7db 100644 --- a/src/core/lib/surface/channel.cc +++ b/src/core/lib/surface/channel.cc @@ -65,7 +65,22 @@ Channel::RegisteredCall::~RegisteredCall() {} Channel::Channel(std::string target, const ChannelArgs& channel_args) : target_(std::move(target)), channelz_node_(channel_args.GetObjectRef()), - compression_options_(CompressionOptionsFromChannelArgs(channel_args)) {} + compression_options_(CompressionOptionsFromChannelArgs(channel_args)), + call_size_estimator_(1024), + allocator_(channel_args.GetObject() + ->memory_quota() + ->CreateMemoryOwner()) {} + +Arena* Channel::CreateArena() { + const size_t initial_size = call_size_estimator_.CallSizeEstimate(); + global_stats().IncrementCallInitialSize(initial_size); + return Arena::Create(initial_size, &allocator_); +} + +void Channel::DestroyArena(Arena* arena) { + call_size_estimator_.UpdateCallSizeEstimate(arena->TotalUsedBytes()); + arena->Destroy(); +} Channel::RegisteredCall* Channel::RegisterCall(const char* method, const char* host) { diff --git a/src/core/lib/surface/channel.h b/src/core/lib/surface/channel.h index 533a944c18c..0a5e7b1c199 100644 --- a/src/core/lib/surface/channel.h +++ b/src/core/lib/surface/channel.h @@ -40,8 +40,10 @@ #include "src/core/lib/gprpp/time.h" #include "src/core/lib/iomgr/iomgr_fwd.h" #include "src/core/lib/resource_quota/arena.h" +#include "src/core/lib/resource_quota/resource_quota.h" #include "src/core/lib/slice/slice.h" #include "src/core/lib/surface/channel_stack_type.h" +#include "src/core/lib/transport/call_size_estimator.h" #include "src/core/lib/transport/connectivity_state.h" // Forward declaration to avoid dependency loop. @@ -68,9 +70,6 @@ class Channel : public RefCounted, virtual void Orphan() = 0; - virtual Arena* CreateArena() = 0; - virtual void DestroyArena(Arena* arena) = 0; - virtual bool IsLame() const = 0; // TODO(roth): This should return a C++ type. @@ -125,6 +124,8 @@ class Channel : public RefCounted, virtual void Ping(grpc_completion_queue* cq, void* tag) = 0; // TODO(roth): Remove these methods when LegacyChannel goes away. + Arena* CreateArena(); + void DestroyArena(Arena* arena); virtual grpc_channel_stack* channel_stack() const { return nullptr; } virtual bool is_client() const { return true; } virtual bool is_promising() const { return true; } @@ -137,6 +138,9 @@ class Channel : public RefCounted, const RefCountedPtr channelz_node_; const grpc_compression_options compression_options_; + CallSizeEstimator call_size_estimator_; + MemoryAllocator allocator_; + Mutex mu_; // The map key needs to be owned strings rather than unowned char*'s to // guarantee that it outlives calls on the core channel (which may outlast diff --git a/src/core/lib/surface/channel_create.cc b/src/core/lib/surface/channel_create.cc index 0ad87af1f62..5d6491bee27 100644 --- a/src/core/lib/surface/channel_create.cc +++ b/src/core/lib/surface/channel_create.cc @@ -22,10 +22,12 @@ #include #include "src/core/channelz/channelz.h" +#include "src/core/client_channel/client_channel.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/config/core_configuration.h" #include "src/core/lib/debug/stats.h" #include "src/core/lib/debug/stats_data.h" +#include "src/core/lib/experiments/experiments.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/lame_client.h" #include "src/core/lib/surface/legacy_channel.h" @@ -77,8 +79,12 @@ absl::StatusOr> ChannelCreate( if (optional_transport != nullptr) { args = args.SetObject(optional_transport); } - // Delegate to legacy channel impl. - return LegacyChannel::Create(std::move(target), std::move(args), + // Delegate to appropriate channel impl. + if (!IsCallV3Enabled()) { + return LegacyChannel::Create(std::move(target), std::move(args), + channel_stack_type); + } + return ClientChannel::Create(std::move(target), std::move(args), channel_stack_type); } diff --git a/src/core/lib/surface/legacy_channel.cc b/src/core/lib/surface/legacy_channel.cc index 104924d42b7..65c19ceaf3b 100644 --- a/src/core/lib/surface/legacy_channel.cc +++ b/src/core/lib/surface/legacy_channel.cc @@ -113,10 +113,14 @@ LegacyChannel::LegacyChannel(bool is_client, bool is_promising, : Channel(std::move(target), channel_args), is_client_(is_client), is_promising_(is_promising), +<<<<<<< HEAD channel_stack_(std::move(channel_stack)), allocator_(channel_args.GetObject() ->memory_quota() ->CreateMemoryOwner()) { +======= + channel_stack_(std::move(channel_stack)) { +>>>>>>> 513bd21ea9db49d061e0382289319ddb126f812c // We need to make sure that grpc_shutdown() does not shut things down // until after the channel is destroyed. However, the channel may not // actually be destroyed by the time grpc_channel_destroy() returns, diff --git a/src/core/lib/surface/legacy_channel.h b/src/core/lib/surface/legacy_channel.h index 3cf3fa0db22..47ff2ad42fc 100644 --- a/src/core/lib/surface/legacy_channel.h +++ b/src/core/lib/surface/legacy_channel.h @@ -39,7 +39,11 @@ #include "src/core/lib/slice/slice.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/channel_stack_type.h" +<<<<<<< HEAD #include "src/core/lib/transport/call_arena_allocator.h" +======= +#include "src/core/lib/transport/transport.h" +>>>>>>> 513bd21ea9db49d061e0382289319ddb126f812c namespace grpc_core { @@ -56,6 +60,7 @@ class LegacyChannel final : public Channel { void Orphan() override; +<<<<<<< HEAD Arena* CreateArena() override { const size_t initial_size = call_size_estimator_.CallSizeEstimate(); global_stats().IncrementCallInitialSize(initial_size); @@ -66,6 +71,8 @@ class LegacyChannel final : public Channel { arena->Destroy(); } +======= +>>>>>>> 513bd21ea9db49d061e0382289319ddb126f812c bool IsLame() const override; grpc_call* CreateCall(grpc_call* parent_call, uint32_t propagation_mask, @@ -114,8 +121,11 @@ class LegacyChannel final : public Channel { const bool is_client_; const bool is_promising_; RefCountedPtr channel_stack_; +<<<<<<< HEAD CallSizeEstimator call_size_estimator_{1024}; grpc_event_engine::experimental::MemoryAllocator allocator_; +======= +>>>>>>> 513bd21ea9db49d061e0382289319ddb126f812c }; } // namespace grpc_core diff --git a/src/core/lib/transport/call_spine.h b/src/core/lib/transport/call_spine.h index 59c1fc2da16..6f3fc5c45b6 100644 --- a/src/core/lib/transport/call_spine.h +++ b/src/core/lib/transport/call_spine.h @@ -21,6 +21,7 @@ #include #include "src/core/lib/channel/context.h" +#include "src/core/lib/gprpp/dual_ref_counted.h" #include "src/core/lib/promise/detail/status.h" #include "src/core/lib/promise/if.h" #include "src/core/lib/promise/latch.h" @@ -29,6 +30,7 @@ #include "src/core/lib/promise/promise.h" #include "src/core/lib/promise/status_flag.h" #include "src/core/lib/transport/call_arena_allocator.h" +#include "src/core/lib/promise/try_seq.h" #include "src/core/lib/transport/call_filters.h" #include "src/core/lib/transport/message.h" #include "src/core/lib/transport/metadata.h" @@ -493,6 +495,11 @@ class CallHandler { explicit CallHandler(RefCountedPtr spine) : spine_(std::move(spine)) {} + template + void SetContext(ContextType context) { +// FIXME: implement + } + auto PullClientInitialMetadata() { return spine_->PullClientInitialMetadata(); } @@ -609,6 +616,109 @@ class UnstartedCallHandler { RefCountedPtr spine_; }; +class UnstartedCallHandler; + +// CallDestination is responsible for starting an UnstartedCallHandler +// and then processing operations on the resulting CallHandler. +// +// Examples of CallDestinations include: +// - a client transport +// - the server API +// - a load-balanced call in the client channel +// - a hijacking filter (see DelegatingCallDestination below) +// +// FIXME: do we want this to be ref-counted? that might not be +// desirable for the hijacking filter case, where we want the filter stack +// to own the filter rather than having every call take its own ref to every +// hijacking filter. +class CallDestination : public DualRefCounted { + public: + virtual void StartCall(UnstartedCallHandler unstarted_call_handler) = 0; +}; + +// A delegating CallDestination for use as a hijacking filter. +// Implementations may look at the unprocessed initial metadata +// and decide to do one of two things: +// +// 1. It can be a no-op. In this case, it will simply pass the +// unstarted_call_handler to the wrapped CallDestination. +// +// 2. It can hijack the call by doing the following: +// - Start unstarted_call_handler and take ownership of the +// resulting handler. +// - Create a new CallInitiator/UnstartedCallHandler pair, and pass +// that new UnstartedCallHandler down to the wrapped CallDestination. +// - The implementation is then responsible for forwarding between +// the started handler and the new initiator. Note that in +// simple cases, this can be done via ForwardCall(). +class DelegatingCallDestination : public CallDestination { + protected: + explicit DelegatingCallDestination( + RefCountedPtr wrapped_destination) + : wrapped_destination_(std::move(wrapped_destination)) {} + + CallDestination* wrapped_destination() const { + return wrapped_destination_.get(); + } + + private: + RefCountedPtr wrapped_destination_; +}; + +class UnstartedCallHandler { + public: + UnstartedCallHandler(RefCountedPtr spine, + ClientMetadataHandle client_initial_metadata) + : spine_(std::move(spine)) { + spine_->SpawnGuarded( + "send_initial_metadata", + [client_initial_metadata = std::move(client_initial_metadata), + spine = spine_]() mutable { + GPR_DEBUG_ASSERT(GetContext() == &spine->party()); + return Map(spine->client_initial_metadata().sender.Push( + std::move(client_initial_metadata)), + [](bool ok) { return StatusFlag(ok); }); + }); + } + + // Returns the client initial metadata, which has not yet been + // processed by the stack that will ultimately be used for this call. + ClientMetadataHandle& UnprocessedClientInitialMetadata(); + + // Starts the call using the specified stack. + // This must be called only once, and the UnstartedCallHandler object + // may not be used after this is called. + CallHandler StartCall(RefCountedPtr stack); + + template + void SetContext(ContextType context) { +// FIXME: implement + } + + template + auto CancelIfFails(Promise promise) { + return spine_->CancelIfFails(std::move(promise)); + } + + template + void SpawnGuarded(absl::string_view name, PromiseFactory promise_factory) { + spine_->SpawnGuarded(name, std::move(promise_factory)); + } + + template + void SpawnInfallible(absl::string_view name, PromiseFactory promise_factory) { + spine_->SpawnInfallible(name, std::move(promise_factory)); + } + + template + auto SpawnWaitable(absl::string_view name, PromiseFactory promise_factory) { + return spine_->party().SpawnWaitable(name, std::move(promise_factory)); + } + + private: + RefCountedPtr spine_; +}; + struct CallInitiatorAndHandler { CallInitiator initiator; UnstartedCallHandler handler; diff --git a/src/core/lib/transport/metadata_batch.h b/src/core/lib/transport/metadata_batch.h index c8611a225fa..a5a934803ee 100644 --- a/src/core/lib/transport/metadata_batch.h +++ b/src/core/lib/transport/metadata_batch.h @@ -528,6 +528,14 @@ struct WaitForReady { static std::string DisplayValue(ValueType x); }; +// Annotation added by retry code to indicate a transparent retry. +struct IsTransparentRetry { + static absl::string_view DebugKey() { return "IsTransparentRetry"; } + static constexpr bool kRepeatable = false; + using ValueType = bool; + static std::string DisplayValue(ValueType x) { return x ? "true" : "false"; } +}; + // Annotation added by a transport to note that server trailing metadata // is a Trailers-Only response. struct GrpcTrailersOnly { @@ -1536,7 +1544,8 @@ using grpc_metadata_batch_base = grpc_core::MetadataMap< grpc_core::GrpcStreamNetworkState, grpc_core::PeerString, grpc_core::GrpcStatusContext, grpc_core::GrpcStatusFromWire, grpc_core::GrpcCallWasCancelled, grpc_core::WaitForReady, - grpc_core::GrpcTrailersOnly, grpc_core::GrpcTarPit, + grpc_core::IsTransparentRetry, grpc_core::GrpcTrailersOnly, + grpc_core::GrpcTarPit, grpc_core::GrpcRegisteredMethod GRPC_CUSTOM_CLIENT_METADATA GRPC_CUSTOM_SERVER_METADATA>; diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index f00614f2c35..de6416e2726 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -19,6 +19,7 @@ CORE_SOURCE_FILES = [ 'src/core/channelz/channelz.cc', 'src/core/channelz/channelz_registry.cc', 'src/core/client_channel/backup_poller.cc', + 'src/core/client_channel/client_channel.cc', 'src/core/client_channel/client_channel_factory.cc', 'src/core/client_channel/client_channel_filter.cc', 'src/core/client_channel/client_channel_plugin.cc', diff --git a/test/core/client_channel/client_channel_test.cc b/test/core/client_channel/client_channel_test.cc index 7fe497d91e8..3750a8dc42b 100644 --- a/test/core/client_channel/client_channel_test.cc +++ b/test/core/client_channel/client_channel_test.cc @@ -22,7 +22,7 @@ #include #include -#include "src/core/client_channel/client_channel_filter.h" +#include "src/core/client_channel/subchannel.h" #include "src/core/client_channel/subchannel_pool_interface.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/resolver/endpoint_addresses.h" @@ -33,20 +33,20 @@ namespace testing { namespace { TEST(MakeSubchannelArgs, UsesChannelDefaultAuthorityByDefault) { - ChannelArgs args = ClientChannelFilter::MakeSubchannelArgs( + ChannelArgs args = Subchannel::MakeSubchannelArgs( ChannelArgs(), ChannelArgs(), nullptr, "foo.example.com"); EXPECT_EQ(args.GetString(GRPC_ARG_DEFAULT_AUTHORITY), "foo.example.com"); } TEST(MakeSubchannelArgs, DefaultAuthorityFromChannelArgs) { - ChannelArgs args = ClientChannelFilter::MakeSubchannelArgs( + ChannelArgs args = Subchannel::MakeSubchannelArgs( ChannelArgs().Set(GRPC_ARG_DEFAULT_AUTHORITY, "bar.example.com"), ChannelArgs(), nullptr, "foo.example.com"); EXPECT_EQ(args.GetString(GRPC_ARG_DEFAULT_AUTHORITY), "bar.example.com"); } TEST(MakeSubchannelArgs, DefaultAuthorityFromResolver) { - ChannelArgs args = ClientChannelFilter::MakeSubchannelArgs( + ChannelArgs args = Subchannel::MakeSubchannelArgs( ChannelArgs(), ChannelArgs().Set(GRPC_ARG_DEFAULT_AUTHORITY, "bar.example.com"), nullptr, "foo.example.com"); @@ -55,7 +55,7 @@ TEST(MakeSubchannelArgs, DefaultAuthorityFromResolver) { TEST(MakeSubchannelArgs, DefaultAuthorityFromChannelArgsOverridesValueFromResolver) { - ChannelArgs args = ClientChannelFilter::MakeSubchannelArgs( + ChannelArgs args = Subchannel::MakeSubchannelArgs( ChannelArgs().Set(GRPC_ARG_DEFAULT_AUTHORITY, "bar.example.com"), ChannelArgs().Set(GRPC_ARG_DEFAULT_AUTHORITY, "baz.example.com"), nullptr, "foo.example.com"); @@ -63,14 +63,14 @@ TEST(MakeSubchannelArgs, } TEST(MakeSubchannelArgs, ArgsFromChannelTrumpPerAddressArgs) { - ChannelArgs args = ClientChannelFilter::MakeSubchannelArgs( - ChannelArgs().Set("foo", 1), ChannelArgs().Set("foo", 2), nullptr, - "foo.example.com"); + ChannelArgs args = Subchannel::MakeSubchannelArgs(ChannelArgs().Set("foo", 1), + ChannelArgs().Set("foo", 2), + nullptr, "foo.example.com"); EXPECT_EQ(args.GetInt("foo"), 1); } TEST(MakeSubchannelArgs, StripsOutNoSubchannelArgs) { - ChannelArgs args = ClientChannelFilter::MakeSubchannelArgs( + ChannelArgs args = Subchannel::MakeSubchannelArgs( ChannelArgs().Set(GRPC_ARG_NO_SUBCHANNEL_PREFIX "foo", 1), ChannelArgs().Set(GRPC_ARG_NO_SUBCHANNEL_PREFIX "bar", 1), nullptr, "foo.example.com"); diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index a6028ce7633..efb7dd26431 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -1091,6 +1091,8 @@ src/core/channelz/channelz_registry.cc \ src/core/channelz/channelz_registry.h \ src/core/client_channel/backup_poller.cc \ src/core/client_channel/backup_poller.h \ +src/core/client_channel/client_channel.cc \ +src/core/client_channel/client_channel.h \ src/core/client_channel/client_channel_factory.cc \ src/core/client_channel/client_channel_factory.h \ src/core/client_channel/client_channel_filter.cc \ @@ -2545,6 +2547,7 @@ src/core/lib/promise/interceptor_list.h \ src/core/lib/promise/latch.h \ src/core/lib/promise/loop.h \ src/core/lib/promise/map.h \ +src/core/lib/promise/observable.h \ src/core/lib/promise/party.cc \ src/core/lib/promise/party.h \ src/core/lib/promise/pipe.h \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 7db0d119296..32677b3bff9 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -895,6 +895,8 @@ src/core/channelz/channelz_registry.h \ src/core/client_channel/README.md \ src/core/client_channel/backup_poller.cc \ src/core/client_channel/backup_poller.h \ +src/core/client_channel/client_channel.cc \ +src/core/client_channel/client_channel.h \ src/core/client_channel/client_channel_factory.cc \ src/core/client_channel/client_channel_factory.h \ src/core/client_channel/client_channel_filter.cc \ @@ -2321,6 +2323,7 @@ src/core/lib/promise/interceptor_list.h \ src/core/lib/promise/latch.h \ src/core/lib/promise/loop.h \ src/core/lib/promise/map.h \ +src/core/lib/promise/observable.h \ src/core/lib/promise/party.cc \ src/core/lib/promise/party.h \ src/core/lib/promise/pipe.h \