From 2d1595c9af2590a46dbe332d5ec54825a238e0d7 Mon Sep 17 00:00:00 2001 From: h-vetinari Date: Wed, 13 Sep 2023 03:12:36 +1100 Subject: [PATCH 01/12] [Build] Shared builds on windows (#34103) Towards https://github.com/grpc/grpc/issues/33032, Reopen after botched force-push in #33175 that then got "merged" and cannot be reopened anymore. More context in that PR. --------- Co-authored-by: Isuru Fernando Co-authored-by: David Chamberlin --- CMakeLists.txt | 100 +++++++++++++++++- include/grpc/event_engine/event_engine.h | 4 +- include/grpc/support/port_platform.h | 57 +++++++++- include/grpcpp/impl/status.h | 2 +- .../security/tls_certificate_provider.h | 9 +- src/core/lib/config/config_vars.h | 2 +- src/core/lib/config/core_configuration.h | 2 +- src/core/lib/gprpp/fork.h | 2 +- src/core/lib/iomgr/exec_ctx.cc | 12 +++ src/core/lib/iomgr/exec_ctx.h | 39 +++++-- src/core/lib/slice/slice_refcount.h | 2 +- templates/CMakeLists.txt.template | 87 ++++++++++++++- tools/codegen/core/gen_config_vars.py | 2 +- 13 files changed, 294 insertions(+), 26 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 569cf60401baa..b4b076cc8bd39 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -421,8 +421,29 @@ endif() if(WIN32) set(_gRPC_ALLTARGETS_LIBRARIES ${_gRPC_ALLTARGETS_LIBRARIES} ws2_32 crypt32) + set(_gRPC_STATIC_WIN32 STATIC) endif() +if(BUILD_SHARED_LIBS AND WIN32) + +# Currently for shared lib on Windows (i.e. a DLL) certain bits of source code +# are generated from protobuf definitions by upbc. This source code does not include +# annotations needed to export these functions from gprc.lib so we have to +# re-include a small subset of these. +# +# This is not an ideal situation because these functions will be unavailable +# to clients of grpc and the libraries that need this (e.g. grpc++) will +# include redundant duplicate code. Hence, the duplication is only activated +# for DLL builds - and should be completely removed when source files are +# generated with the necessary __declspec annotations. +set(gRPC_UPB_GEN_DUPL_SRC + src/core/ext/upb-generated/src/proto/grpc/gcp/altscontext.upb.c + src/core/ext/upb-generated/src/proto/grpc/health/v1/health.upb.c + src/core/ext/upb-generated/src/proto/grpc/gcp/transport_security_common.upb.c +) + +endif() # BUILD_SHARED_LIBS AND WIN32 + # Create directory for proto source files set(_gRPC_PROTO_SRCS_DIR ${CMAKE_BINARY_DIR}/protos) file(MAKE_DIRECTORY ${_gRPC_PROTO_SRCS_DIR}) @@ -1481,6 +1502,7 @@ if(gRPC_BUILD_TESTS) endif() + add_library(address_sorting third_party/address_sorting/address_sorting.c third_party/address_sorting/address_sorting_posix.c @@ -1534,6 +1556,7 @@ if(gRPC_INSTALL) endif() + add_library(gpr src/core/lib/config/config_vars.cc src/core/lib/config/config_vars_non_generated.cc @@ -1594,6 +1617,10 @@ if(WIN32 AND MSVC) set_target_properties(gpr PROPERTIES COMPILE_PDB_NAME "gpr" COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" ) + set_target_properties(gpr PROPERTIES DEFINE_SYMBOL "GPR_DLL_EXPORTS") + if(BUILD_SHARED_LIBS) + target_compile_definitions(gpr INTERFACE GPR_DLL_IMPORTS) + endif() if(gRPC_INSTALL) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/gpr.pdb DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL @@ -1692,6 +1719,7 @@ if(gRPC_INSTALL) endif() + add_library(grpc src/core/ext/filters/backend_metrics/backend_metric_filter.cc src/core/ext/filters/census/grpc_context.cc @@ -2480,6 +2508,10 @@ if(WIN32 AND MSVC) set_target_properties(grpc PROPERTIES COMPILE_PDB_NAME "grpc" COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" ) + set_target_properties(grpc PROPERTIES DEFINE_SYMBOL "GRPC_DLL_EXPORTS") + if(BUILD_SHARED_LIBS) + target_compile_definitions(grpc INTERFACE GRPC_DLL_IMPORTS) + endif() if(gRPC_INSTALL) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/grpc.pdb DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL @@ -2618,6 +2650,7 @@ endif() if(gRPC_BUILD_TESTS) + add_library(grpc_test_util test/core/event_engine/test_init.cc test/core/util/build.cc @@ -2677,6 +2710,7 @@ endif() endif() if(gRPC_BUILD_TESTS) + add_library(grpc_test_util_unsecure test/core/event_engine/test_init.cc test/core/util/build.cc @@ -2734,6 +2768,7 @@ endif() endif() + add_library(grpc_unsecure src/core/ext/filters/backend_metrics/backend_metric_filter.cc src/core/ext/filters/census/grpc_context.cc @@ -3132,6 +3167,10 @@ if(WIN32 AND MSVC) set_target_properties(grpc_unsecure PROPERTIES COMPILE_PDB_NAME "grpc_unsecure" COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" ) + set_target_properties(grpc_unsecure PROPERTIES DEFINE_SYMBOL "GRPC_DLL_EXPORTS") + if(BUILD_SHARED_LIBS) + target_compile_definitions(grpc_unsecure INTERFACE GRPC_DLL_IMPORTS) + endif() if(gRPC_INSTALL) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/grpc_unsecure.pdb DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL @@ -3268,6 +3307,7 @@ endif() if(gRPC_BUILD_TESTS) + add_library(gtest third_party/googletest/googlemock/src/gmock-cardinalities.cc third_party/googletest/googlemock/src/gmock-internal-utils.cc @@ -3334,7 +3374,8 @@ target_link_libraries(gtest endif() -add_library(upb + +add_library(upb ${_gRPC_STATIC_WIN32} third_party/upb/upb/base/status.c third_party/upb/upb/collections/array.c third_party/upb/upb/collections/map.c @@ -3405,7 +3446,8 @@ if(gRPC_INSTALL) endif() -add_library(upb_collections_lib + +add_library(upb_collections_lib ${_gRPC_STATIC_WIN32} third_party/upb/upb/base/status.c third_party/upb/upb/collections/array.c third_party/upb/upb/collections/map.c @@ -3466,7 +3508,8 @@ if(gRPC_INSTALL) endif() -add_library(upb_json_lib + +add_library(upb_json_lib ${_gRPC_STATIC_WIN32} src/core/ext/upb-generated/google/protobuf/descriptor.upb.c third_party/upb/upb/json/decode.c third_party/upb/upb/json/encode.c @@ -3543,7 +3586,8 @@ if(gRPC_INSTALL) endif() -add_library(upb_textformat_lib + +add_library(upb_textformat_lib ${_gRPC_STATIC_WIN32} src/core/ext/upb-generated/google/protobuf/descriptor.upb.c third_party/upb/upb/message/accessors.c third_party/upb/upb/mini_descriptor/build_enum.c @@ -3619,6 +3663,7 @@ if(gRPC_INSTALL) endif() + add_library(utf8_range_lib third_party/utf8_range/naive.c third_party/utf8_range/range2-neon.c @@ -3674,6 +3719,7 @@ endif() if(gRPC_BUILD_TESTS) if(gRPC_BUILD_CODEGEN) + add_library(benchmark_helpers ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc @@ -3749,6 +3795,7 @@ endif() endif() + add_library(grpc++ src/core/ext/transport/binder/client/binder_connector.cc src/core/ext/transport/binder/client/channel_create.cc @@ -3815,6 +3862,7 @@ add_library(grpc++ src/cpp/util/status.cc src/cpp/util/string_ref.cc src/cpp/util/time_cc.cc + ${gRPC_UPB_GEN_DUPL_SRC} ) target_compile_features(grpc++ PUBLIC cxx_std_14) @@ -3828,6 +3876,10 @@ if(WIN32 AND MSVC) set_target_properties(grpc++ PROPERTIES COMPILE_PDB_NAME "grpc++" COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" ) + set_target_properties(grpc++ PROPERTIES DEFINE_SYMBOL "GRPCXX_DLL_EXPORTS") + if(BUILD_SHARED_LIBS) + target_compile_definitions(grpc++ INTERFACE GRPCXX_DLL_IMPORTS) + endif() if(gRPC_INSTALL) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/grpc++.pdb DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL @@ -4079,9 +4131,11 @@ if(gRPC_INSTALL) endif() + add_library(grpc++_alts src/cpp/common/alts_context.cc src/cpp/common/alts_util.cc + ${gRPC_UPB_GEN_DUPL_SRC} ) target_compile_features(grpc++_alts PUBLIC cxx_std_14) @@ -4143,6 +4197,7 @@ if(gRPC_INSTALL) endif() + add_library(grpc++_error_details src/cpp/util/error_details.cc ) @@ -4207,6 +4262,7 @@ endif() if(gRPC_BUILD_CODEGEN) + add_library(grpc++_reflection ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/reflection/v1alpha/reflection.pb.cc ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.cc @@ -4279,6 +4335,7 @@ endif() endif() if(gRPC_BUILD_TESTS) + add_library(grpc++_test src/cpp/client/channel_test_peer.cc ) @@ -4344,6 +4401,7 @@ endforeach() endif() if(gRPC_BUILD_TESTS) + add_library(grpc++_test_config test/cpp/util/test_config_cc.cc ) @@ -4390,6 +4448,7 @@ target_link_libraries(grpc++_test_config endif() if(gRPC_BUILD_TESTS) + add_library(grpc++_test_util src/core/lib/gpr/subprocess_posix.cc src/core/lib/gpr/subprocess_windows.cc @@ -4455,6 +4514,30 @@ target_link_libraries(grpc++_test_util endif() + +# for DLL build just compile a dummy grpc++_unsecure +# This is a temporary situation until some code restructuring +# obviates the need to exclude this library +if(BUILD_SHARED_LIBS AND MSVC) +add_library(grpc++_unsecure + src/cpp/common/version_cc.cc +) +target_include_directories(grpc++_unsecure + PUBLIC $ $ + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} +) + +foreach(_hdr + include/grpcpp/grpcpp.h +) + string(REPLACE "include/" "" _path ${_hdr}) + get_filename_component(_path ${_path} PATH) + install(FILES ${_hdr} + DESTINATION "${gRPC_INSTALL_INCLUDEDIR}/${_path}" + ) +endforeach() +else() add_library(grpc++_unsecure src/cpp/client/channel_cc.cc src/cpp/client/client_callback.cc @@ -4493,6 +4576,7 @@ add_library(grpc++_unsecure src/cpp/util/status.cc src/cpp/util/string_ref.cc src/cpp/util/time_cc.cc + ${gRPC_UPB_GEN_DUPL_SRC} ) target_compile_features(grpc++_unsecure PUBLIC cxx_std_14) @@ -4506,6 +4590,10 @@ if(WIN32 AND MSVC) set_target_properties(grpc++_unsecure PROPERTIES COMPILE_PDB_NAME "grpc++_unsecure" COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" ) + set_target_properties(grpc++_unsecure PROPERTIES DEFINE_SYMBOL "GRPCXX_DLL_EXPORTS") + if(BUILD_SHARED_LIBS) + target_compile_definitions(grpc++_unsecure INTERFACE GRPCXX_DLL_IMPORTS) + endif() if(gRPC_INSTALL) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/grpc++_unsecure.pdb DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL @@ -4741,6 +4829,7 @@ foreach(_hdr DESTINATION "${gRPC_INSTALL_INCLUDEDIR}/${_path}" ) endforeach() +endif() # BUILD_SHARED_LIBS AND MSVC if(gRPC_INSTALL) @@ -4753,6 +4842,7 @@ if(gRPC_INSTALL) endif() + add_library(grpc_authorization_provider src/core/ext/upb-generated/google/protobuf/any.upb.c src/core/ext/upb-generated/google/protobuf/descriptor.upb.c @@ -5161,6 +5251,7 @@ if(gRPC_INSTALL) endif() + add_library(grpc_plugin_support src/compiler/cpp_generator.cc src/compiler/csharp_generator.cc @@ -5235,6 +5326,7 @@ endif() # grpcpp_channelz doesn't build with protobuf-lite # See https://github.com/grpc/grpc/issues/19473 if(gRPC_BUILD_CODEGEN AND NOT gRPC_USE_PROTO_LITE) + add_library(grpcpp_channelz ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/channelz/channelz.pb.cc ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/channelz/channelz.grpc.pb.cc diff --git a/include/grpc/event_engine/event_engine.h b/include/grpc/event_engine/event_engine.h index 34804fd8c72fc..2130f7feb1a82 100644 --- a/include/grpc/event_engine/event_engine.h +++ b/include/grpc/event_engine/event_engine.h @@ -122,7 +122,7 @@ class EventEngine : public std::enable_shared_from_this { /// \a Cancel method. struct TaskHandle { intptr_t keys[2]; - static const TaskHandle kInvalid; + static const GRPC_DLL TaskHandle kInvalid; friend bool operator==(const TaskHandle& lhs, const TaskHandle& rhs); friend bool operator!=(const TaskHandle& lhs, const TaskHandle& rhs); }; @@ -131,7 +131,7 @@ class EventEngine : public std::enable_shared_from_this { /// Returned by \a Connect, and can be passed to \a CancelConnect. struct ConnectionHandle { intptr_t keys[2]; - static const ConnectionHandle kInvalid; + static const GRPC_DLL ConnectionHandle kInvalid; friend bool operator==(const ConnectionHandle& lhs, const ConnectionHandle& rhs); friend bool operator!=(const ConnectionHandle& lhs, diff --git a/include/grpc/support/port_platform.h b/include/grpc/support/port_platform.h index bb055465e5f27..f8a0ecb02d9b5 100644 --- a/include/grpc/support/port_platform.h +++ b/include/grpc/support/port_platform.h @@ -53,6 +53,57 @@ #define WIN32_LEAN_AND_MEAN #endif /* WIN32_LEAN_AND_MEAN */ +// GPRC_DLL +// inspired by +// https://github.com/abseil/abseil-cpp/blob/20220623.1/absl/base/config.h#L730-L747 +// +// When building gRPC as a DLL, this macro expands to `__declspec(dllexport)` +// so we can annotate symbols appropriately as being exported. When used in +// headers consuming a DLL, this macro expands to `__declspec(dllimport)` so +// that consumers know the symbol is defined inside the DLL. In all other cases, +// the macro expands to nothing. +// +// Warning: shared library support for Windows (i.e. producing DLL plus import +// library instead of a static library) is experimental. Some symbols that can +// be linked using the static library may not be available when using the +// dynamically linked library. +// +// Note: GRPC_DLL_EXPORTS is set in CMakeLists.txt when building shared +// grpc{,_unsecure} +// GRPC_DLL_IMPORTS is set by us as part of the interface for consumers of +// the DLL +#if !defined(GRPC_DLL) +#if defined(GRPC_DLL_EXPORTS) +#define GRPC_DLL __declspec(dllexport) +#elif defined(GRPC_DLL_IMPORTS) +#define GRPC_DLL __declspec(dllimport) +#else +#define GRPC_DLL +#endif // defined(GRPC_DLL_EXPORTS) +#endif + +// same for gRPC++ +#if !defined(GRPCXX_DLL) +#if defined(GRPCXX_DLL_EXPORTS) +#define GRPCXX_DLL __declspec(dllexport) +#elif defined(GRPCXX_DLL_IMPORTS) +#define GRPCXX_DLL __declspec(dllimport) +#else +#define GRPCXX_DLL +#endif // defined(GRPCXX_DLL_EXPORTS) +#endif + +// same for GPR +#if !defined(GPR_DLL) +#if defined(GPR_DLL_EXPORTS) +#define GPR_DLL __declspec(dllexport) +#elif defined(GPR_DLL_IMPORTS) +#define GPR_DLL __declspec(dllimport) +#else +#define GPR_DLL +#endif // defined(GPR_DLL_EXPORTS) +#endif + #ifndef NOMINMAX #define GRPC_NOMINMX_WAS_NOT_DEFINED #define NOMINMAX @@ -68,7 +119,6 @@ #error \ "Please compile grpc with _WIN32_WINNT of at least 0x600 (aka Windows Vista)" #endif /* _WIN32_WINNT < 0x0600 */ -#endif /* defined(_WIN32_WINNT) */ #ifdef GRPC_WIN32_LEAN_AND_MEAN_WAS_NOT_DEFINED #undef GRPC_WIN32_LEAN_AND_MEAN_WAS_NOT_DEFINED @@ -81,6 +131,11 @@ #endif /* GRPC_WIN32_LEAN_AND_MEAN_WAS_NOT_DEFINED */ #endif /* defined(_WIN64) || defined(WIN64) || defined(_WIN32) || \ defined(WIN32) */ +#else +#define GRPC_DLL +#define GRPCXX_DLL +#define GPR_DLL +#endif /* defined(_WIN32_WINNT) */ /* Override this file with one for your platform if you need to redefine things. */ diff --git a/include/grpcpp/impl/status.h b/include/grpcpp/impl/status.h index 95436ab8fbcd8..a068f9b0af289 100644 --- a/include/grpcpp/impl/status.h +++ b/include/grpcpp/impl/status.h @@ -32,7 +32,7 @@ namespace grpc { /// Did it work? If it didn't, why? /// /// See \a grpc::StatusCode for details on the available code and their meaning. -class GRPC_MUST_USE_RESULT_WHEN_USE_STRICT_WARNING Status { +class GRPC_MUST_USE_RESULT_WHEN_USE_STRICT_WARNING GRPCXX_DLL Status { public: /// Construct an OK instance. Status() : code_(StatusCode::OK) { diff --git a/include/grpcpp/security/tls_certificate_provider.h b/include/grpcpp/security/tls_certificate_provider.h index ce9df5aa9c3ca..d784292992e1b 100644 --- a/include/grpcpp/security/tls_certificate_provider.h +++ b/include/grpcpp/security/tls_certificate_provider.h @@ -32,7 +32,7 @@ namespace experimental { // Interface for a class that handles the process to fetch credential data. // Implementations should be a wrapper class of an internal provider // implementation. -class CertificateProviderInterface { +class GRPCXX_DLL CertificateProviderInterface { public: virtual ~CertificateProviderInterface() = default; virtual grpc_tls_certificate_provider* c_provider() = 0; @@ -41,7 +41,7 @@ class CertificateProviderInterface { // A struct that stores the credential data presented to the peer in handshake // to show local identity. The private_key and certificate_chain should always // match. -struct IdentityKeyCertPair { +struct GRPCXX_DLL IdentityKeyCertPair { std::string private_key; std::string certificate_chain; }; @@ -49,7 +49,8 @@ struct IdentityKeyCertPair { // A basic CertificateProviderInterface implementation that will load credential // data from static string during initialization. This provider will always // return the same cert data for all cert names, and reloading is not supported. -class StaticDataCertificateProvider : public CertificateProviderInterface { +class GRPCXX_DLL StaticDataCertificateProvider + : public CertificateProviderInterface { public: StaticDataCertificateProvider( const std::string& root_certificate, @@ -84,7 +85,7 @@ class StaticDataCertificateProvider : public CertificateProviderInterface { // then renaming the new directory to the original name of the old directory. // 2) using a symlink for the directory. When need to change, put new // credential data in a new directory, and change symlink. -class FileWatcherCertificateProvider final +class GRPCXX_DLL FileWatcherCertificateProvider final : public CertificateProviderInterface { public: // Constructor to get credential updates from root and identity file paths. diff --git a/src/core/lib/config/config_vars.h b/src/core/lib/config/config_vars.h index d465ad3204720..0ca8ad9f5300f 100644 --- a/src/core/lib/config/config_vars.h +++ b/src/core/lib/config/config_vars.h @@ -31,7 +31,7 @@ namespace grpc_core { -class ConfigVars { +class GPR_DLL ConfigVars { public: struct Overrides { absl::optional client_channel_backup_poll_interval_ms; diff --git a/src/core/lib/config/core_configuration.h b/src/core/lib/config/core_configuration.h index 740cc1fc8af47..88e190385575f 100644 --- a/src/core/lib/config/core_configuration.h +++ b/src/core/lib/config/core_configuration.h @@ -37,7 +37,7 @@ namespace grpc_core { // Global singleton that stores library configuration - factories, etc... // that plugins might choose to extend. -class CoreConfiguration { +class GRPC_DLL CoreConfiguration { public: CoreConfiguration(const CoreConfiguration&) = delete; CoreConfiguration& operator=(const CoreConfiguration&) = delete; diff --git a/src/core/lib/gprpp/fork.h b/src/core/lib/gprpp/fork.h index 9700d38fb7053..b12c94602bad8 100644 --- a/src/core/lib/gprpp/fork.h +++ b/src/core/lib/gprpp/fork.h @@ -31,7 +31,7 @@ namespace grpc_core { -class Fork { +class GPR_DLL Fork { public: typedef void (*child_postfork_func)(void); diff --git a/src/core/lib/iomgr/exec_ctx.cc b/src/core/lib/iomgr/exec_ctx.cc index 65cd319d20cb2..4b77738d9eb7f 100644 --- a/src/core/lib/iomgr/exec_ctx.cc +++ b/src/core/lib/iomgr/exec_ctx.cc @@ -56,9 +56,21 @@ static void exec_ctx_sched(grpc_closure* closure) { namespace grpc_core { +#if !defined(_WIN32) || !defined(_DLL) thread_local ExecCtx* ExecCtx::exec_ctx_; thread_local ApplicationCallbackExecCtx* ApplicationCallbackExecCtx::callback_exec_ctx_; +#else // _WIN32 +ExecCtx*& ExecCtx::exec_ctx() { + static thread_local ExecCtx* exec_ctx; + return exec_ctx; +} + +ApplicationCallbackExecCtx*& ApplicationCallbackExecCtx::callback_exec_ctx() { + static thread_local ApplicationCallbackExecCtx* callback_exec_ctx; + return callback_exec_ctx; +} +#endif // _WIN32 bool ExecCtx::Flush() { bool did_something = false; diff --git a/src/core/lib/iomgr/exec_ctx.h b/src/core/lib/iomgr/exec_ctx.h index 20d9ebe04e1c0..3e3227cb2cd2a 100644 --- a/src/core/lib/iomgr/exec_ctx.h +++ b/src/core/lib/iomgr/exec_ctx.h @@ -36,6 +36,14 @@ #include "src/core/lib/gprpp/time.h" #include "src/core/lib/iomgr/closure.h" +#if !defined(_WIN32) || !defined(_DLL) +#define EXEC_CTX exec_ctx_ +#define CALLBACK_EXEC_CTX callback_exec_ctx_ +#else +#define EXEC_CTX exec_ctx() +#define CALLBACK_EXEC_CTX callback_exec_ctx() +#endif + /// A combiner represents a list of work to be executed later. /// Forward declared here to avoid a circular dependency with combiner.h. typedef struct grpc_combiner grpc_combiner; @@ -94,7 +102,7 @@ class Combiner; /// since that implies a core re-entry outside of application /// callbacks. /// -class ExecCtx { +class GRPC_DLL ExecCtx { public: /// Default Constructor @@ -186,7 +194,7 @@ class ExecCtx { void TestOnlySetNow(Timestamp now) { time_cache_.TestOnlySetNow(now); } /// Gets pointer to current exec_ctx. - static ExecCtx* Get() { return exec_ctx_; } + static ExecCtx* Get() { return EXEC_CTX; } static void Run(const DebugLocation& location, grpc_closure* closure, grpc_error_handle error); @@ -201,8 +209,8 @@ class ExecCtx { static void operator delete(void* /* p */) { abort(); } private: - /// Set exec_ctx_ to exec_ctx. - static void Set(ExecCtx* exec_ctx) { exec_ctx_ = exec_ctx; } + /// Set EXEC_CTX to ctx. + static void Set(ExecCtx* ctx) { EXEC_CTX = ctx; } grpc_closure_list closure_list_ = GRPC_CLOSURE_LIST_INIT; CombinerData combiner_data_ = {nullptr, nullptr}; @@ -211,7 +219,13 @@ class ExecCtx { unsigned starting_cpu_ = std::numeric_limits::max(); ScopedTimeCache time_cache_; + +#if !defined(_WIN32) || !defined(_DLL) static thread_local ExecCtx* exec_ctx_; +#else + // cannot be thread_local data member (e.g. exec_ctx_) on windows + static ExecCtx*& exec_ctx(); +#endif ExecCtx* last_exec_ctx_ = Get(); }; @@ -262,7 +276,7 @@ class ExecCtx { /// /// -class ApplicationCallbackExecCtx { +class GRPC_DLL ApplicationCallbackExecCtx { public: /// Default Constructor ApplicationCallbackExecCtx() { Set(this, flags_); } @@ -282,7 +296,7 @@ class ApplicationCallbackExecCtx { } (*f->functor_run)(f, f->internal_success); } - callback_exec_ctx_ = nullptr; + CALLBACK_EXEC_CTX = nullptr; if (!(GRPC_APP_CALLBACK_EXEC_CTX_FLAG_IS_INTERNAL_THREAD & flags_)) { Fork::DecExecCtxCount(); } @@ -294,14 +308,14 @@ class ApplicationCallbackExecCtx { uintptr_t Flags() { return flags_; } - static ApplicationCallbackExecCtx* Get() { return callback_exec_ctx_; } + static ApplicationCallbackExecCtx* Get() { return CALLBACK_EXEC_CTX; } static void Set(ApplicationCallbackExecCtx* exec_ctx, uintptr_t flags) { if (Get() == nullptr) { if (!(GRPC_APP_CALLBACK_EXEC_CTX_FLAG_IS_INTERNAL_THREAD & flags)) { Fork::IncExecCtxCount(); } - callback_exec_ctx_ = exec_ctx; + CALLBACK_EXEC_CTX = exec_ctx; } } @@ -326,7 +340,13 @@ class ApplicationCallbackExecCtx { uintptr_t flags_{0u}; grpc_completion_queue_functor* head_{nullptr}; grpc_completion_queue_functor* tail_{nullptr}; + +#if !defined(_WIN32) || !defined(_DLL) static thread_local ApplicationCallbackExecCtx* callback_exec_ctx_; +#else + // cannot be thread_local data member (e.g. callback_exec_ctx_) on windows + static ApplicationCallbackExecCtx*& callback_exec_ctx(); +#endif }; template @@ -340,6 +360,9 @@ void EnsureRunInExecCtx(F f) { } } +#undef EXEC_CTX +#undef CALLBACK_EXEC_CTX + } // namespace grpc_core #endif // GRPC_SRC_CORE_LIB_IOMGR_EXEC_CTX_H diff --git a/src/core/lib/slice/slice_refcount.h b/src/core/lib/slice/slice_refcount.h index 50fdb6efd9ae2..fb39f0cbe3d73 100644 --- a/src/core/lib/slice/slice_refcount.h +++ b/src/core/lib/slice/slice_refcount.h @@ -27,7 +27,7 @@ #include "src/core/lib/debug/trace.h" #include "src/core/lib/gprpp/debug_location.h" -extern grpc_core::DebugOnlyTraceFlag grpc_slice_refcount_trace; +extern GRPC_DLL grpc_core::DebugOnlyTraceFlag grpc_slice_refcount_trace; // grpc_slice_refcount : A reference count for grpc_slice. struct grpc_slice_refcount { diff --git a/templates/CMakeLists.txt.template b/templates/CMakeLists.txt.template index f274da5442ac9..736476612553d 100644 --- a/templates/CMakeLists.txt.template +++ b/templates/CMakeLists.txt.template @@ -150,6 +150,20 @@ private_libs.append("-l" + lib_name) return private_libs + def lib_type_for_lib(lib_name): + """Returns STATIC/SHARED to force a static or shared lib build depending on the library.""" + # grpc_csharp_ext is loaded by C# runtime and it + # only makes sense as a shared lib. + if lib_name in ['grpc_csharp_ext']: + return ' SHARED' + + # upb always compiles as a static library on Windows + elif lib_name in ['upb','upb_collections_lib','upb_json_lib','upb_textformat_lib']: + return ' ${_gRPC_STATIC_WIN32}' + + else: + return '' + def get_deps(target_dict): # TODO(jtattermusch): remove special cases based on target names deps = [] @@ -235,6 +249,13 @@ return '\n'.join(lines) return _func + + def add_dll_annotation_macros(lib, prefix): + return """set_target_properties(%s PROPERTIES DEFINE_SYMBOL "%s_DLL_EXPORTS") + if(BUILD_SHARED_LIBS) + target_compile_definitions(%s INTERFACE %s_DLL_IMPORTS) + endif()""" % (lib, prefix, lib, prefix) + %> <% # These files are added to a set so that they are not duplicated if multiple @@ -486,8 +507,29 @@ if(WIN32) set(_gRPC_ALLTARGETS_LIBRARIES <%text>${_gRPC_ALLTARGETS_LIBRARIES} ws2_32 crypt32) + set(_gRPC_STATIC_WIN32 STATIC) endif() + if(BUILD_SHARED_LIBS AND WIN32) + + # Currently for shared lib on Windows (i.e. a DLL) certain bits of source code + # are generated from protobuf definitions by upbc. This source code does not include + # annotations needed to export these functions from gprc.lib so we have to + # re-include a small subset of these. + # + # This is not an ideal situation because these functions will be unavailable + # to clients of grpc and the libraries that need this (e.g. grpc++) will + # include redundant duplicate code. Hence, the duplication is only activated + # for DLL builds - and should be completely removed when source files are + # generated with the necessary __declspec annotations. + set(gRPC_UPB_GEN_DUPL_SRC + src/core/ext/upb-generated/src/proto/grpc/gcp/altscontext.upb.c + src/core/ext/upb-generated/src/proto/grpc/health/v1/health.upb.c + src/core/ext/upb-generated/src/proto/grpc/gcp/transport_security_common.upb.c + ) + + endif() # BUILD_SHARED_LIBS AND WIN32 + # Create directory for proto source files set(_gRPC_PROTO_SRCS_DIR <%text>${CMAKE_BINARY_DIR}/protos) file(MAKE_DIRECTORY <%text>${_gRPC_PROTO_SRCS_DIR}) @@ -727,7 +769,33 @@ if(gRPC_BUILD_CODEGEN) % endif % endif - add_library(${lib.name} + + % if lib.name == 'grpc++_unsecure': + # for DLL build just compile a dummy grpc++_unsecure + # This is a temporary situation until some code restructuring + # obviates the need to exclude this library + if(BUILD_SHARED_LIBS AND MSVC) + add_library(grpc++_unsecure + src/cpp/common/version_cc.cc + ) + target_include_directories(grpc++_unsecure + PUBLIC <%text>$ $ + PRIVATE + <%text>${CMAKE_CURRENT_SOURCE_DIR} + ) + + foreach(_hdr + include/grpcpp/grpcpp.h + ) + string(REPLACE "include/" "" _path <%text>${_hdr}) + get_filename_component(_path <%text>${_path} PATH) + install(FILES <%text>${_hdr} + DESTINATION <%text>"${gRPC_INSTALL_INCLUDEDIR}/${_path}" + ) + endforeach() + else() + % endif + add_library(${lib.name}${lib_type_for_lib(lib.name)} % for src in lib.src: % if not proto_re.match(src): ${src} @@ -741,6 +809,9 @@ % endif % endif % endfor + % if lib.name in ['grpc++_alts', 'grpc++_unsecure', 'grpc++']: + ${'${gRPC_UPB_GEN_DUPL_SRC}'} + % endif ) target_compile_features(${lib.name} PUBLIC cxx_std_14) @@ -759,6 +830,17 @@ set_target_properties(${lib.name} PROPERTIES COMPILE_PDB_NAME "${lib.name}" COMPILE_PDB_OUTPUT_DIRECTORY <%text>"${CMAKE_BINARY_DIR}" ) + % if lib.name == 'gpr': + ${add_dll_annotation_macros(lib.name, 'GPR')} + % elif lib.name == 'grpc': + ${add_dll_annotation_macros(lib.name, 'GRPC')} + % elif lib.name == 'grpc_unsecure': + ${add_dll_annotation_macros(lib.name, 'GRPC')} + % elif lib.name == 'grpc++': + ${add_dll_annotation_macros(lib.name, 'GRPCXX')} + % elif lib.name == 'grpc++_unsecure': + ${add_dll_annotation_macros(lib.name, 'GRPCXX')} + % endif if(gRPC_INSTALL) install(FILES <%text>${CMAKE_CURRENT_BINARY_DIR}/${lib.name}.pdb DESTINATION <%text>${gRPC_INSTALL_LIBDIR} OPTIONAL @@ -827,6 +909,9 @@ % if any(proto_re.match(src) for src in lib.src): endif() % endif + % if lib.name == 'grpc++_unsecure': + endif() # BUILD_SHARED_LIBS AND MSVC + % endif <%def name="cc_binary(tgt)"> diff --git a/tools/codegen/core/gen_config_vars.py b/tools/codegen/core/gen_config_vars.py index 62fa5e3ec1f6a..4739c3351d161 100755 --- a/tools/codegen/core/gen_config_vars.py +++ b/tools/codegen/core/gen_config_vars.py @@ -325,7 +325,7 @@ def string_default_value(x, name): print(file=H) print("namespace grpc_core {", file=H) print(file=H) - print("class ConfigVars {", file=H) + print("class GPR_DLL ConfigVars {", file=H) print(" public:", file=H) print(" struct Overrides {", file=H) for attr in attrs_in_packing_order: From e66cb7f2de9aecc9361c5979287a2fba7c96313c Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Tue, 12 Sep 2023 11:02:02 -0700 Subject: [PATCH 02/12] [GSM Observability] Update opentelemetry cpp bazel deps (#34290) This is needed for the upcoming work for GSM Observability integration testing. --- WORKSPACE | 8 ++++++++ bazel/grpc_deps.bzl | 8 ++++---- test/cpp/ext/otel/otel_test_library.cc | 1 + 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/WORKSPACE b/WORKSPACE index ce8023f530df1..118bae2aab595 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -102,6 +102,14 @@ load("@com_github_google_benchmark//:bazel/benchmark_deps.bzl", "benchmark_deps" benchmark_deps() +load("@io_opentelemetry_cpp//bazel:repository.bzl", "opentelemetry_cpp_deps") + +opentelemetry_cpp_deps() + +load("@io_opentelemetry_cpp//bazel:extra_deps.bzl", "opentelemetry_extra_deps") + +opentelemetry_extra_deps() + # TODO: Enable below once https://github.com/bazel-xcode/PodToBUILD/issues/232 is resolved # #http_archive( diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl index be2f566511fda..f64457d7b016d 100644 --- a/bazel/grpc_deps.bzl +++ b/bazel/grpc_deps.bzl @@ -492,11 +492,11 @@ def grpc_deps(): if "io_opentelemetry_cpp" not in native.existing_rules(): http_archive( name = "io_opentelemetry_cpp", - sha256 = "668de24f81c8d36d75092ad9dcb02a97cd41473adbe72485ece05e336db48249", - strip_prefix = "opentelemetry-cpp-1.9.1", + sha256 = "f30cd88bf898a5726d245eba882b8e81012021eb00df34109f4dfb203f005cea", + strip_prefix = "opentelemetry-cpp-1.11.0", urls = [ - "https://storage.googleapis.com/grpc-bazel-mirror/github.com/open-telemetry/opentelemetry-cpp/archive/refs/tags/v1.9.1.tar.gz", - "https://github.com/open-telemetry/opentelemetry-cpp/archive/refs/tags/v1.9.1.tar.gz", + "https://storage.googleapis.com/grpc-bazel-mirror/github.com/open-telemetry/opentelemetry-cpp/archive/refs/tags/v1.11.0.tar.gz", + "https://github.com/open-telemetry/opentelemetry-cpp/archive/refs/tags/v1.11.0.tar.gz", ], ) diff --git a/test/cpp/ext/otel/otel_test_library.cc b/test/cpp/ext/otel/otel_test_library.cc index 211aab26a3c8e..9e6d4ff79450a 100644 --- a/test/cpp/ext/otel/otel_test_library.cc +++ b/test/cpp/ext/otel/otel_test_library.cc @@ -22,6 +22,7 @@ #include "api/include/opentelemetry/metrics/provider.h" #include "gmock/gmock.h" #include "gtest/gtest.h" +#include "opentelemetry/sdk/metrics/export/metric_producer.h" #include "opentelemetry/sdk/metrics/meter_provider.h" #include "opentelemetry/sdk/metrics/metric_reader.h" From 91a7dbb44b959161d8473ec2f71c3ad7dabb7dcd Mon Sep 17 00:00:00 2001 From: Esun Kim Date: Tue, 12 Sep 2023 11:08:09 -0700 Subject: [PATCH 03/12] [Deps] Updated protobuf to 24.3 + layout fix (#34322) Updating Protobuf & upb to 24.3 (the latest at this point) and having https://github.com/protocolbuffers/protobuf/pull/14042 --- bazel/grpc_deps.bzl | 18 +++++++++--------- build_handwritten.yaml | 2 +- src/csharp/build/dependencies.props | 2 +- .../!ProtoCompiler-gRPCCppPlugin.podspec | 2 +- .../!ProtoCompiler-gRPCPlugin.podspec | 2 +- src/objective-c/!ProtoCompiler.podspec | 2 +- third_party/protobuf | 2 +- third_party/protobuf.patch | 2 +- third_party/upb | 2 +- tools/distrib/python/grpc_version.py | 2 +- .../python/grpcio_tools/grpc_version.py | 2 +- .../python/grpcio_tools/protoc_lib_deps.py | 2 +- .../distrib/python/xds_protos/grpc_version.py | 2 +- tools/run_tests/sanity/check_submodules.sh | 4 ++-- 14 files changed, 23 insertions(+), 23 deletions(-) diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl index f64457d7b016d..ee2a6ae8bc0ae 100644 --- a/bazel/grpc_deps.bzl +++ b/bazel/grpc_deps.bzl @@ -243,12 +243,12 @@ def grpc_deps(): if "com_google_protobuf" not in native.existing_rules(): http_archive( name = "com_google_protobuf", - sha256 = "1b46d45d9f5fff721a099bd6cd3be6717b8fa7ee3816a419f7d048ee55f9ae4c", - strip_prefix = "protobuf-54a2e5caa9d1a0a714fb2aa99753a1444414292a", + sha256 = "c580129f1db37f0ba8b80808b530593b89187b0d5573e9471396d0513aacfee4", + strip_prefix = "protobuf-0d22de520bf3fdb0978a962ae90b72db2f560cef", urls = [ - # https://github.com/protocolbuffers/protobuf/commits/v24.2 - "https://storage.googleapis.com/grpc-bazel-mirror/github.com/protocolbuffers/protobuf/archive/54a2e5caa9d1a0a714fb2aa99753a1444414292a.tar.gz", - "https://github.com/protocolbuffers/protobuf/archive/54a2e5caa9d1a0a714fb2aa99753a1444414292a.tar.gz", + # https://github.com/protocolbuffers/protobuf/commits/v24.3 + "https://storage.googleapis.com/grpc-bazel-mirror/github.com/protocolbuffers/protobuf/archive/0d22de520bf3fdb0978a962ae90b72db2f560cef.tar.gz", + "https://github.com/protocolbuffers/protobuf/archive/0d22de520bf3fdb0978a962ae90b72db2f560cef.tar.gz", ], patches = [ "@com_github_grpc_grpc//third_party:protobuf.patch", @@ -383,12 +383,12 @@ def grpc_deps(): if "upb" not in native.existing_rules(): http_archive( name = "upb", - sha256 = "af3f2651b8f27d92d086fc373af6194d4ba702e29e27cbc691fa8926561aa056", - strip_prefix = "upb-cc36926cffb00f0e8dd33bc9511c8e7354f09d0c", + sha256 = "5147e0ab6a28421d1e49004f4a205d84f06b924585e15eaa884cfe13289165b7", + strip_prefix = "upb-42cd08932e364a4cde35033b73f15c30250d7c2e", urls = [ # https://github.com/protocolbuffers/upb/commits/24.x - "https://storage.googleapis.com/grpc-bazel-mirror/github.com/protocolbuffers/upb/archive/cc36926cffb00f0e8dd33bc9511c8e7354f09d0c.tar.gz", - "https://github.com/protocolbuffers/upb/archive/cc36926cffb00f0e8dd33bc9511c8e7354f09d0c.tar.gz", + "https://storage.googleapis.com/grpc-bazel-mirror/github.com/protocolbuffers/upb/archive/42cd08932e364a4cde35033b73f15c30250d7c2e.tar.gz", + "https://github.com/protocolbuffers/upb/archive/42cd08932e364a4cde35033b73f15c30250d7c2e.tar.gz", ], ) diff --git a/build_handwritten.yaml b/build_handwritten.yaml index 6e25dca06db82..3d05d40fe1a44 100644 --- a/build_handwritten.yaml +++ b/build_handwritten.yaml @@ -15,7 +15,7 @@ settings: core_version: 35.0.0 csharp_major_version: 2 g_stands_for: generative - protobuf_version: 3.24.2 + protobuf_version: 3.24.3 version: 1.59.0-dev configs: asan: diff --git a/src/csharp/build/dependencies.props b/src/csharp/build/dependencies.props index 92af294c19169..3c96516f2b2b8 100644 --- a/src/csharp/build/dependencies.props +++ b/src/csharp/build/dependencies.props @@ -2,6 +2,6 @@ 2.59.0-dev - 3.24.2 + 3.24.3 diff --git a/src/objective-c/!ProtoCompiler-gRPCCppPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCCppPlugin.podspec index 4ab35f4912463..a603ec74f8d41 100644 --- a/src/objective-c/!ProtoCompiler-gRPCCppPlugin.podspec +++ b/src/objective-c/!ProtoCompiler-gRPCCppPlugin.podspec @@ -100,7 +100,7 @@ Pod::Spec.new do |s| s.preserve_paths = plugin # Restrict the protoc version to the one supported by this plugin. - s.dependency '!ProtoCompiler', '3.24.2' + s.dependency '!ProtoCompiler', '3.24.3' s.ios.deployment_target = '10.0' s.osx.deployment_target = '10.12' diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec index b19fddca166c7..6e5e305d0a136 100644 --- a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec +++ b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec @@ -102,7 +102,7 @@ Pod::Spec.new do |s| s.preserve_paths = plugin # Restrict the protoc version to the one supported by this plugin. - s.dependency '!ProtoCompiler', '3.24.2' + s.dependency '!ProtoCompiler', '3.24.3' s.ios.deployment_target = '10.0' s.osx.deployment_target = '10.12' diff --git a/src/objective-c/!ProtoCompiler.podspec b/src/objective-c/!ProtoCompiler.podspec index 609d125c7a988..3644ca6580e7a 100644 --- a/src/objective-c/!ProtoCompiler.podspec +++ b/src/objective-c/!ProtoCompiler.podspec @@ -36,7 +36,7 @@ Pod::Spec.new do |s| # exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed # before them. s.name = '!ProtoCompiler' - v = '3.24.2' + v = '3.24.3' s.version = v s.summary = 'The Protobuf Compiler (protoc) generates Objective-C files from .proto files' s.description = <<-DESC diff --git a/third_party/protobuf b/third_party/protobuf index 54a2e5caa9d1a..0d22de520bf3f 160000 --- a/third_party/protobuf +++ b/third_party/protobuf @@ -1 +1 @@ -Subproject commit 54a2e5caa9d1a0a714fb2aa99753a1444414292a +Subproject commit 0d22de520bf3fdb0978a962ae90b72db2f560cef diff --git a/third_party/protobuf.patch b/third_party/protobuf.patch index dfe4078a7aaba..1b870a305e90c 100644 --- a/third_party/protobuf.patch +++ b/third_party/protobuf.patch @@ -5,7 +5,7 @@ index 97ac28028..8b7585d9d 100644 @@ -31,3 +31,9 @@ # Copyright 2007 Google Inc. All Rights Reserved. - __version__ = '4.24.2' + __version__ = '4.24.3' + +if __name__ != '__main__': + try: diff --git a/third_party/upb b/third_party/upb index cc36926cffb00..42cd08932e364 160000 --- a/third_party/upb +++ b/third_party/upb @@ -1 +1 @@ -Subproject commit cc36926cffb00f0e8dd33bc9511c8e7354f09d0c +Subproject commit 42cd08932e364a4cde35033b73f15c30250d7c2e diff --git a/tools/distrib/python/grpc_version.py b/tools/distrib/python/grpc_version.py index cfdf5f71ccb8c..8466e04067079 100644 --- a/tools/distrib/python/grpc_version.py +++ b/tools/distrib/python/grpc_version.py @@ -15,4 +15,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/tools/distrib/python/grpcio_tools/grpc_version.py.template`!!! VERSION = '1.59.0.dev0' -PROTOBUF_VERSION = '3.24.2' +PROTOBUF_VERSION = '3.24.3' diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py index 0f7b5458b68b4..7f0b2a36d3017 100644 --- a/tools/distrib/python/grpcio_tools/grpc_version.py +++ b/tools/distrib/python/grpcio_tools/grpc_version.py @@ -15,4 +15,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/tools/distrib/python/grpcio_tools/grpc_version.py.template`!!! VERSION = '1.59.0.dev0' -PROTOBUF_VERSION = '3.24.2' +PROTOBUF_VERSION = '3.24.3' diff --git a/tools/distrib/python/grpcio_tools/protoc_lib_deps.py b/tools/distrib/python/grpcio_tools/protoc_lib_deps.py index e6d4e8849d110..d221cfb9734c3 100644 --- a/tools/distrib/python/grpcio_tools/protoc_lib_deps.py +++ b/tools/distrib/python/grpcio_tools/protoc_lib_deps.py @@ -315,4 +315,4 @@ ] PROTO_INCLUDE='third_party/protobuf/src' -PROTOBUF_SUBMODULE_VERSION="54a2e5caa9d1a0a714fb2aa99753a1444414292a" +PROTOBUF_SUBMODULE_VERSION="0d22de520bf3fdb0978a962ae90b72db2f560cef" diff --git a/tools/distrib/python/xds_protos/grpc_version.py b/tools/distrib/python/xds_protos/grpc_version.py index 10ffda07801ba..e20df66c44778 100644 --- a/tools/distrib/python/xds_protos/grpc_version.py +++ b/tools/distrib/python/xds_protos/grpc_version.py @@ -15,4 +15,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/tools/distrib/python/grpcio_tools/grpc_version.py.template`!!! VERSION = '1.59.0.dev0' -PROTOBUF_VERSION = '3.24.2' +PROTOBUF_VERSION = '3.24.3' diff --git a/tools/run_tests/sanity/check_submodules.sh b/tools/run_tests/sanity/check_submodules.sh index d21a2cac2f4c9..84e958181be34 100755 --- a/tools/run_tests/sanity/check_submodules.sh +++ b/tools/run_tests/sanity/check_submodules.sh @@ -35,10 +35,10 @@ third_party/googleapis 2f9af297c84c55c8b871ba4495e01ade42476c92 third_party/googletest 0e402173c97aea7a00749e825b194bfede4f2e45 third_party/opencensus-proto 4aa53e15cbf1a47bc9087e6cfdca214c1eea4e89 third_party/opentelemetry 60fa8754d890b5c55949a8c68dcfd7ab5c2395df -third_party/protobuf 54a2e5caa9d1a0a714fb2aa99753a1444414292a +third_party/protobuf 0d22de520bf3fdb0978a962ae90b72db2f560cef third_party/protoc-gen-validate fab737efbb4b4d03e7c771393708f75594b121e4 third_party/re2 0c5616df9c0aaa44c9440d87422012423d91c7d1 -third_party/upb cc36926cffb00f0e8dd33bc9511c8e7354f09d0c +third_party/upb 42cd08932e364a4cde35033b73f15c30250d7c2e third_party/xds e9ce68804cb4e64cab5a52e3c8baf840d4ff87b7 third_party/zlib 04f42ceca40f73e2978b50e93806c2a18c1281fc EOF From eb37b91072df99d58fb32a4d1ef59270c746885b Mon Sep 17 00:00:00 2001 From: Yijie Ma Date: Tue, 12 Sep 2023 11:08:32 -0700 Subject: [PATCH 04/12] [EventEngine] Make `AresResolver` build compatible with older c-ares versions (#34314) Tested by changing c-ares to `1.14.0` in Bazel dependency and verify that the `posix_event_engine_test` build. The test would fail though since c-ares versions < `1.16.0` does not come with address sorting capability so the relevant test cases will fail. But this is probably sufficient to make the Cloud C++ CI job pass and unblock the 1.58 release. --- Package.swift | 1 + build_autogenerated.yaml | 4 + gRPC-C++.podspec | 2 + gRPC-Core.podspec | 2 + grpc.gemspec | 1 + package.xml | 1 + src/core/BUILD | 1 + src/core/lib/event_engine/ares_resolver.cc | 10 ++ src/core/lib/event_engine/nameser.h | 102 +++++++++++++++++++++ tools/doxygen/Doxyfile.c++.internal | 1 + tools/doxygen/Doxyfile.core.internal | 1 + 11 files changed, 126 insertions(+) create mode 100644 src/core/lib/event_engine/nameser.h diff --git a/Package.swift b/Package.swift index c2cc9bfac6df5..386c3b36540c5 100644 --- a/Package.swift +++ b/Package.swift @@ -1085,6 +1085,7 @@ let package = Package( "src/core/lib/event_engine/handle_containers.h", "src/core/lib/event_engine/memory_allocator.cc", "src/core/lib/event_engine/memory_allocator_factory.h", + "src/core/lib/event_engine/nameser.h", "src/core/lib/event_engine/poller.h", "src/core/lib/event_engine/posix.h", "src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc", diff --git a/build_autogenerated.yaml b/build_autogenerated.yaml index 5ae25305e8115..f9c22f9c7b24d 100644 --- a/build_autogenerated.yaml +++ b/build_autogenerated.yaml @@ -696,6 +696,7 @@ libs: - src/core/lib/event_engine/grpc_polled_fd.h - src/core/lib/event_engine/handle_containers.h - src/core/lib/event_engine/memory_allocator_factory.h + - src/core/lib/event_engine/nameser.h - src/core/lib/event_engine/poller.h - src/core/lib/event_engine/posix.h - src/core/lib/event_engine/posix_engine/ev_epoll1_linux.h @@ -2106,6 +2107,7 @@ libs: - src/core/lib/event_engine/grpc_polled_fd.h - src/core/lib/event_engine/handle_containers.h - src/core/lib/event_engine/memory_allocator_factory.h + - src/core/lib/event_engine/nameser.h - src/core/lib/event_engine/poller.h - src/core/lib/event_engine/posix.h - src/core/lib/event_engine/posix_engine/ev_epoll1_linux.h @@ -4118,6 +4120,7 @@ libs: - src/core/lib/event_engine/grpc_polled_fd.h - src/core/lib/event_engine/handle_containers.h - src/core/lib/event_engine/memory_allocator_factory.h + - src/core/lib/event_engine/nameser.h - src/core/lib/event_engine/poller.h - src/core/lib/event_engine/posix.h - src/core/lib/event_engine/posix_engine/ev_epoll1_linux.h @@ -15633,6 +15636,7 @@ targets: - src/core/lib/event_engine/grpc_polled_fd.h - src/core/lib/event_engine/handle_containers.h - src/core/lib/event_engine/memory_allocator_factory.h + - src/core/lib/event_engine/nameser.h - src/core/lib/event_engine/poller.h - src/core/lib/event_engine/posix.h - src/core/lib/event_engine/posix_engine/ev_epoll1_linux.h diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 66701102fc046..a2c4378cc9d92 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -767,6 +767,7 @@ Pod::Spec.new do |s| 'src/core/lib/event_engine/grpc_polled_fd.h', 'src/core/lib/event_engine/handle_containers.h', 'src/core/lib/event_engine/memory_allocator_factory.h', + 'src/core/lib/event_engine/nameser.h', 'src/core/lib/event_engine/poller.h', 'src/core/lib/event_engine/posix.h', 'src/core/lib/event_engine/posix_engine/ev_epoll1_linux.h', @@ -1834,6 +1835,7 @@ Pod::Spec.new do |s| 'src/core/lib/event_engine/grpc_polled_fd.h', 'src/core/lib/event_engine/handle_containers.h', 'src/core/lib/event_engine/memory_allocator_factory.h', + 'src/core/lib/event_engine/nameser.h', 'src/core/lib/event_engine/poller.h', 'src/core/lib/event_engine/posix.h', 'src/core/lib/event_engine/posix_engine/ev_epoll1_linux.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index cb23b297197fc..10a71ac075113 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -1186,6 +1186,7 @@ Pod::Spec.new do |s| 'src/core/lib/event_engine/handle_containers.h', 'src/core/lib/event_engine/memory_allocator.cc', 'src/core/lib/event_engine/memory_allocator_factory.h', + 'src/core/lib/event_engine/nameser.h', 'src/core/lib/event_engine/poller.h', 'src/core/lib/event_engine/posix.h', 'src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc', @@ -2586,6 +2587,7 @@ Pod::Spec.new do |s| 'src/core/lib/event_engine/grpc_polled_fd.h', 'src/core/lib/event_engine/handle_containers.h', 'src/core/lib/event_engine/memory_allocator_factory.h', + 'src/core/lib/event_engine/nameser.h', 'src/core/lib/event_engine/poller.h', 'src/core/lib/event_engine/posix.h', 'src/core/lib/event_engine/posix_engine/ev_epoll1_linux.h', diff --git a/grpc.gemspec b/grpc.gemspec index 41ab905785a49..b37dbe8c127d7 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -1091,6 +1091,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/event_engine/handle_containers.h ) s.files += %w( src/core/lib/event_engine/memory_allocator.cc ) s.files += %w( src/core/lib/event_engine/memory_allocator_factory.h ) + s.files += %w( src/core/lib/event_engine/nameser.h ) s.files += %w( src/core/lib/event_engine/poller.h ) s.files += %w( src/core/lib/event_engine/posix.h ) s.files += %w( src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc ) diff --git a/package.xml b/package.xml index 654ff0c29cbd2..811227b94382d 100644 --- a/package.xml +++ b/package.xml @@ -1073,6 +1073,7 @@ + diff --git a/src/core/BUILD b/src/core/BUILD index 8e64a89e95af5..777eb1e1ea1da 100644 --- a/src/core/BUILD +++ b/src/core/BUILD @@ -2394,6 +2394,7 @@ grpc_cc_library( hdrs = [ "lib/event_engine/ares_resolver.h", "lib/event_engine/grpc_polled_fd.h", + "lib/event_engine/nameser.h", "lib/event_engine/posix_engine/grpc_polled_fd_posix.h", ], external_deps = [ diff --git a/src/core/lib/event_engine/ares_resolver.cc b/src/core/lib/event_engine/ares_resolver.cc index 2f26a9fcf1cc0..c137ef34f1e4e 100644 --- a/src/core/lib/event_engine/ares_resolver.cc +++ b/src/core/lib/event_engine/ares_resolver.cc @@ -33,7 +33,17 @@ #if GRPC_ARES == 1 +#include + +#include + +#if ARES_VERSION >= 0x011200 +// c-ares 1.18.0 or later starts to provide ares_nameser.h as a public header. #include +#else +#include "src/core/lib/event_engine/nameser.h" // IWYU pragma: keep +#endif + #include #include diff --git a/src/core/lib/event_engine/nameser.h b/src/core/lib/event_engine/nameser.h new file mode 100644 index 0000000000000..c73a91622d50f --- /dev/null +++ b/src/core/lib/event_engine/nameser.h @@ -0,0 +1,102 @@ +// Copyright 2023 The 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_LIB_EVENT_ENGINE_NAMESER_H +#define GRPC_SRC_CORE_LIB_EVENT_ENGINE_NAMESER_H + +#include + +#include "src/core/lib/iomgr/port.h" + +#ifdef GRPC_HAVE_ARPA_NAMESER + +#include // IWYU pragma: keep + +#else // GRPC_HAVE_ARPA_NAMESER + +typedef enum __ns_class { + ns_c_invalid = 0, // Cookie. + ns_c_in = 1, // Internet. + ns_c_2 = 2, // unallocated/unsupported. + ns_c_chaos = 3, // MIT Chaos-net. + ns_c_hs = 4, // MIT Hesiod. + // Query class values which do not appear in resource records + ns_c_none = 254, // for prereq. sections in update requests + ns_c_any = 255, // Wildcard match. + ns_c_max = 65536 +} ns_class; + +typedef enum __ns_type { + ns_t_invalid = 0, // Cookie. + ns_t_a = 1, // Host address. + ns_t_ns = 2, // Authoritative server. + ns_t_md = 3, // Mail destination. + ns_t_mf = 4, // Mail forwarder. + ns_t_cname = 5, // Canonical name. + ns_t_soa = 6, // Start of authority zone. + ns_t_mb = 7, // Mailbox domain name. + ns_t_mg = 8, // Mail group member. + ns_t_mr = 9, // Mail rename name. + ns_t_null = 10, // Null resource record. + ns_t_wks = 11, // Well known service. + ns_t_ptr = 12, // Domain name pointer. + ns_t_hinfo = 13, // Host information. + ns_t_minfo = 14, // Mailbox information. + ns_t_mx = 15, // Mail routing information. + ns_t_txt = 16, // Text strings. + ns_t_rp = 17, // Responsible person. + ns_t_afsdb = 18, // AFS cell database. + ns_t_x25 = 19, // X_25 calling address. + ns_t_isdn = 20, // ISDN calling address. + ns_t_rt = 21, // Router. + ns_t_nsap = 22, // NSAP address. + ns_t_nsap_ptr = 23, // Reverse NSAP lookup (deprecated). + ns_t_sig = 24, // Security signature. + ns_t_key = 25, // Security key. + ns_t_px = 26, // X.400 mail mapping. + ns_t_gpos = 27, // Geographical position (withdrawn). + ns_t_aaaa = 28, // Ip6 Address. + ns_t_loc = 29, // Location Information. + ns_t_nxt = 30, // Next domain (security). + ns_t_eid = 31, // Endpoint identifier. + ns_t_nimloc = 32, // Nimrod Locator. + ns_t_srv = 33, // Server Selection. + ns_t_atma = 34, // ATM Address + ns_t_naptr = 35, // Naming Authority PoinTeR + ns_t_kx = 36, // Key Exchange + ns_t_cert = 37, // Certification record + ns_t_a6 = 38, // IPv6 address (deprecates AAAA) + ns_t_dname = 39, // Non-terminal DNAME (for IPv6) + ns_t_sink = 40, // Kitchen sink (experimentatl) + ns_t_opt = 41, // EDNS0 option (meta-RR) + ns_t_apl = 42, // Address prefix list (RFC3123) + ns_t_ds = 43, // Delegation Signer (RFC4034) + ns_t_sshfp = 44, // SSH Key Fingerprint (RFC4255) + ns_t_rrsig = 46, // Resource Record Signature (RFC4034) + ns_t_nsec = 47, // Next Secure (RFC4034) + ns_t_dnskey = 48, // DNS Public Key (RFC4034) + ns_t_tkey = 249, // Transaction key + ns_t_tsig = 250, // Transaction signature. + ns_t_ixfr = 251, // Incremental zone transfer. + ns_t_axfr = 252, // Transfer zone of authority. + ns_t_mailb = 253, // Transfer mailbox records. + ns_t_maila = 254, // Transfer mail agent records. + ns_t_any = 255, // Wildcard match. + ns_t_zxfr = 256, // BIND-specific, nonstandard. + ns_t_max = 65536 +} ns_type; + +#endif // GRPC_HAVE_ARPA_NAMESER + +#endif // GRPC_SRC_CORE_LIB_EVENT_ENGINE_NAMESER_H diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index c27cf5780a00b..dd65e91e131a1 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -2088,6 +2088,7 @@ src/core/lib/event_engine/grpc_polled_fd.h \ src/core/lib/event_engine/handle_containers.h \ src/core/lib/event_engine/memory_allocator.cc \ src/core/lib/event_engine/memory_allocator_factory.h \ +src/core/lib/event_engine/nameser.h \ src/core/lib/event_engine/poller.h \ src/core/lib/event_engine/posix.h \ src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 76f0add5f7387..5a4c9d4f1c119 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -1866,6 +1866,7 @@ src/core/lib/event_engine/grpc_polled_fd.h \ src/core/lib/event_engine/handle_containers.h \ src/core/lib/event_engine/memory_allocator.cc \ src/core/lib/event_engine/memory_allocator_factory.h \ +src/core/lib/event_engine/nameser.h \ src/core/lib/event_engine/poller.h \ src/core/lib/event_engine/posix.h \ src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc \ From ab806f4219d3c2772846a4f247593f8a12a56204 Mon Sep 17 00:00:00 2001 From: yifeizhuang Date: Tue, 12 Sep 2023 11:27:13 -0700 Subject: [PATCH 05/12] [interop] Add grpc-java 1.58.0 to client_matrix.py (#34289) --- tools/interop_matrix/client_matrix.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index 095a6d970863a..11b8dd4c3a1f7 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -427,6 +427,7 @@ def __init__(self, patch=[], runtimes=[], testcases_file=None): ("v1.55.1", ReleaseInfo()), ("v1.56.0", ReleaseInfo()), ("v1.57.2", ReleaseInfo()), + ("v1.58.0", ReleaseInfo()), ] ), "python": OrderedDict( From d0d826750f3f5eeb8d37de9448341d462944ebf4 Mon Sep 17 00:00:00 2001 From: "Romain Geissler @ Amadeus" Date: Tue, 12 Sep 2023 21:46:41 +0200 Subject: [PATCH 06/12] [C++] Stop using std::aligned_storage. (#34110) Indeed this is now deprecated since C++23. Fix #32848. --- include/grpcpp/server_context.h | 3 +-- src/core/lib/gprpp/manual_constructor.h | 3 +-- src/core/lib/gprpp/no_destruct.h | 2 +- src/core/lib/iomgr/event_engine_shims/endpoint.cc | 6 ++---- src/core/lib/promise/arena_promise.h | 6 +++++- test/core/gprpp/ref_counted_test.cc | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/include/grpcpp/server_context.h b/include/grpcpp/server_context.h index 925316762fc92..243d1492054b2 100644 --- a/include/grpcpp/server_context.h +++ b/include/grpcpp/server_context.h @@ -545,8 +545,7 @@ class ServerContextBase { const std::function func_; }; - typename std::aligned_storage::type - default_reactor_; + alignas(Reactor) char default_reactor_[sizeof(Reactor)]; std::atomic_bool default_reactor_used_{false}; std::atomic_bool marked_cancelled_{false}; diff --git a/src/core/lib/gprpp/manual_constructor.h b/src/core/lib/gprpp/manual_constructor.h index 09740e29551e0..6a3db686a42eb 100644 --- a/src/core/lib/gprpp/manual_constructor.h +++ b/src/core/lib/gprpp/manual_constructor.h @@ -25,7 +25,6 @@ #include -#include #include #include "src/core/lib/gprpp/construct_destruct.h" @@ -139,7 +138,7 @@ class ManualConstructor { void Destroy() { Destruct(get()); } private: - typename std::aligned_storage::type space_; + alignas(Type) char space_[sizeof(Type)]; }; } // namespace grpc_core diff --git a/src/core/lib/gprpp/no_destruct.h b/src/core/lib/gprpp/no_destruct.h index daf8b757770e0..8899c87477b8a 100644 --- a/src/core/lib/gprpp/no_destruct.h +++ b/src/core/lib/gprpp/no_destruct.h @@ -68,7 +68,7 @@ class NoDestruct { const T* get() const { return reinterpret_cast(&space_); } private: - typename std::aligned_storage::type space_; + alignas(T) char space_[sizeof(T)]; }; // Helper for when a program desires a single *process wide* instance of a diff --git a/src/core/lib/iomgr/event_engine_shims/endpoint.cc b/src/core/lib/iomgr/event_engine_shims/endpoint.cc index 20b6a158494bb..864a48b0e7132 100644 --- a/src/core/lib/iomgr/event_engine_shims/endpoint.cc +++ b/src/core/lib/iomgr/event_engine_shims/endpoint.cc @@ -60,10 +60,8 @@ class EventEngineEndpointWrapper { struct grpc_event_engine_endpoint { grpc_endpoint base; EventEngineEndpointWrapper* wrapper; - std::aligned_storage::type - read_buffer; - std::aligned_storage::type - write_buffer; + alignas(SliceBuffer) char read_buffer[sizeof(SliceBuffer)]; + alignas(SliceBuffer) char write_buffer[sizeof(SliceBuffer)]; }; explicit EventEngineEndpointWrapper( diff --git a/src/core/lib/promise/arena_promise.h b/src/core/lib/promise/arena_promise.h index d6f0b288124a0..bdc5a484d8dde 100644 --- a/src/core/lib/promise/arena_promise.h +++ b/src/core/lib/promise/arena_promise.h @@ -19,6 +19,7 @@ #include +#include #include #include #include @@ -34,7 +35,10 @@ namespace grpc_core { namespace arena_promise_detail { -using ArgType = std::aligned_storage_t; +struct ArgType { + alignas(std::max_align_t) char buffer[sizeof(void*)]; +}; + template T*& ArgAsPtr(ArgType* arg) { static_assert(sizeof(ArgType) >= sizeof(T**), diff --git a/test/core/gprpp/ref_counted_test.cc b/test/core/gprpp/ref_counted_test.cc index 0d58d1338e90b..4d8761ecb1db0 100644 --- a/test/core/gprpp/ref_counted_test.cc +++ b/test/core/gprpp/ref_counted_test.cc @@ -119,8 +119,8 @@ class ValueInExternalAllocation }; TEST(RefCounted, CallDtorUponUnref) { - std::aligned_storage::type storage; + alignas(ValueInExternalAllocation) char + storage[sizeof(ValueInExternalAllocation)]; RefCountedPtr value( new (&storage) ValueInExternalAllocation(5)); EXPECT_EQ(value->value(), 5); From 0bc07c957e6dfec1969a6579742cbec235a44355 Mon Sep 17 00:00:00 2001 From: "Romain Geissler @ Amadeus" Date: Tue, 12 Sep 2023 21:47:55 +0200 Subject: [PATCH 07/12] [C++] Fix clang's -Winconsistent-missing-override in proto reader/writer. (#33646) The "override" is not added on purpose to remain compatible with Protobuf < 22.x, as already written in the comment on top of these two functions. CC @veblush as the author of this code. Note: I am personally not super enthousiastic about this change. As an alternative, I can propose to selectively add the `override` keyword, based on the value of the `PROTOBUF_VERSION` macro (comparing it to `4022000`). Tell me if you prefer this version instead. --- include/grpcpp/support/proto_buffer_reader.h | 8 ++++++-- include/grpcpp/support/proto_buffer_writer.h | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/include/grpcpp/support/proto_buffer_reader.h b/include/grpcpp/support/proto_buffer_reader.h index 04f060b015869..60a8c881af5ca 100644 --- a/include/grpcpp/support/proto_buffer_reader.h +++ b/include/grpcpp/support/proto_buffer_reader.h @@ -124,10 +124,14 @@ class ProtoBufferReader : public grpc::protobuf::io::ZeroCopyInputStream { #ifdef GRPC_PROTOBUF_CORD_SUPPORT_ENABLED /// Read the next `count` bytes and append it to the given Cord. - // (override is intentionally omitted here to support old Protobuf which + // (override is conditionally omitted here to support old Protobuf which // doesn't have ReadCord method) // NOLINTNEXTLINE(modernize-use-override) - virtual bool ReadCord(absl::Cord* cord, int count) { + virtual bool ReadCord(absl::Cord* cord, int count) +#if PROTOBUF_VERSION >= 4022000 + override +#endif + { if (!status().ok()) { return false; } diff --git a/include/grpcpp/support/proto_buffer_writer.h b/include/grpcpp/support/proto_buffer_writer.h index f4e3321ed2445..f7351ec2b76d9 100644 --- a/include/grpcpp/support/proto_buffer_writer.h +++ b/include/grpcpp/support/proto_buffer_writer.h @@ -154,10 +154,14 @@ class ProtoBufferWriter : public grpc::protobuf::io::ZeroCopyOutputStream { #ifdef GRPC_PROTOBUF_CORD_SUPPORT_ENABLED /// Writes cord to the backing byte_buffer, sharing the memory between the /// blocks of the cord, and the slices of the byte_buffer. - // (override is intentionally omitted here to support old Protobuf which + // (override is conditionally omitted here to support old Protobuf which // doesn't have ReadCord method) // NOLINTNEXTLINE(modernize-use-override) - virtual bool WriteCord(const absl::Cord& cord) { + virtual bool WriteCord(const absl::Cord& cord) +#if PROTOBUF_VERSION >= 4022000 + override +#endif + { grpc_slice_buffer* buffer = slice_buffer(); size_t cur = 0; for (absl::string_view chunk : cord.Chunks()) { From c9db4960006fd26740c17372afab17e3eca7db24 Mon Sep 17 00:00:00 2001 From: nanahpang <31627465+nanahpang@users.noreply.github.com> Date: Tue, 12 Sep 2023 13:42:20 -0700 Subject: [PATCH 08/12] =?UTF-8?q?Revert=20"[EventEngine]=20Make=20`AresRes?= =?UTF-8?q?olver`=20build=20compatible=20with=20older=E2=80=A6=20(#34325)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit … c-ares versions (#34314)" This reverts commit eb37b91072df99d58fb32a4d1ef59270c746885b. --- Package.swift | 1 - build_autogenerated.yaml | 4 - gRPC-C++.podspec | 2 - gRPC-Core.podspec | 2 - grpc.gemspec | 1 - package.xml | 1 - src/core/BUILD | 1 - src/core/lib/event_engine/ares_resolver.cc | 10 -- src/core/lib/event_engine/nameser.h | 102 --------------------- tools/doxygen/Doxyfile.c++.internal | 1 - tools/doxygen/Doxyfile.core.internal | 1 - 11 files changed, 126 deletions(-) delete mode 100644 src/core/lib/event_engine/nameser.h diff --git a/Package.swift b/Package.swift index 386c3b36540c5..c2cc9bfac6df5 100644 --- a/Package.swift +++ b/Package.swift @@ -1085,7 +1085,6 @@ let package = Package( "src/core/lib/event_engine/handle_containers.h", "src/core/lib/event_engine/memory_allocator.cc", "src/core/lib/event_engine/memory_allocator_factory.h", - "src/core/lib/event_engine/nameser.h", "src/core/lib/event_engine/poller.h", "src/core/lib/event_engine/posix.h", "src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc", diff --git a/build_autogenerated.yaml b/build_autogenerated.yaml index f9c22f9c7b24d..5ae25305e8115 100644 --- a/build_autogenerated.yaml +++ b/build_autogenerated.yaml @@ -696,7 +696,6 @@ libs: - src/core/lib/event_engine/grpc_polled_fd.h - src/core/lib/event_engine/handle_containers.h - src/core/lib/event_engine/memory_allocator_factory.h - - src/core/lib/event_engine/nameser.h - src/core/lib/event_engine/poller.h - src/core/lib/event_engine/posix.h - src/core/lib/event_engine/posix_engine/ev_epoll1_linux.h @@ -2107,7 +2106,6 @@ libs: - src/core/lib/event_engine/grpc_polled_fd.h - src/core/lib/event_engine/handle_containers.h - src/core/lib/event_engine/memory_allocator_factory.h - - src/core/lib/event_engine/nameser.h - src/core/lib/event_engine/poller.h - src/core/lib/event_engine/posix.h - src/core/lib/event_engine/posix_engine/ev_epoll1_linux.h @@ -4120,7 +4118,6 @@ libs: - src/core/lib/event_engine/grpc_polled_fd.h - src/core/lib/event_engine/handle_containers.h - src/core/lib/event_engine/memory_allocator_factory.h - - src/core/lib/event_engine/nameser.h - src/core/lib/event_engine/poller.h - src/core/lib/event_engine/posix.h - src/core/lib/event_engine/posix_engine/ev_epoll1_linux.h @@ -15636,7 +15633,6 @@ targets: - src/core/lib/event_engine/grpc_polled_fd.h - src/core/lib/event_engine/handle_containers.h - src/core/lib/event_engine/memory_allocator_factory.h - - src/core/lib/event_engine/nameser.h - src/core/lib/event_engine/poller.h - src/core/lib/event_engine/posix.h - src/core/lib/event_engine/posix_engine/ev_epoll1_linux.h diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index a2c4378cc9d92..66701102fc046 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -767,7 +767,6 @@ Pod::Spec.new do |s| 'src/core/lib/event_engine/grpc_polled_fd.h', 'src/core/lib/event_engine/handle_containers.h', 'src/core/lib/event_engine/memory_allocator_factory.h', - 'src/core/lib/event_engine/nameser.h', 'src/core/lib/event_engine/poller.h', 'src/core/lib/event_engine/posix.h', 'src/core/lib/event_engine/posix_engine/ev_epoll1_linux.h', @@ -1835,7 +1834,6 @@ Pod::Spec.new do |s| 'src/core/lib/event_engine/grpc_polled_fd.h', 'src/core/lib/event_engine/handle_containers.h', 'src/core/lib/event_engine/memory_allocator_factory.h', - 'src/core/lib/event_engine/nameser.h', 'src/core/lib/event_engine/poller.h', 'src/core/lib/event_engine/posix.h', 'src/core/lib/event_engine/posix_engine/ev_epoll1_linux.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 10a71ac075113..cb23b297197fc 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -1186,7 +1186,6 @@ Pod::Spec.new do |s| 'src/core/lib/event_engine/handle_containers.h', 'src/core/lib/event_engine/memory_allocator.cc', 'src/core/lib/event_engine/memory_allocator_factory.h', - 'src/core/lib/event_engine/nameser.h', 'src/core/lib/event_engine/poller.h', 'src/core/lib/event_engine/posix.h', 'src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc', @@ -2587,7 +2586,6 @@ Pod::Spec.new do |s| 'src/core/lib/event_engine/grpc_polled_fd.h', 'src/core/lib/event_engine/handle_containers.h', 'src/core/lib/event_engine/memory_allocator_factory.h', - 'src/core/lib/event_engine/nameser.h', 'src/core/lib/event_engine/poller.h', 'src/core/lib/event_engine/posix.h', 'src/core/lib/event_engine/posix_engine/ev_epoll1_linux.h', diff --git a/grpc.gemspec b/grpc.gemspec index b37dbe8c127d7..41ab905785a49 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -1091,7 +1091,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/event_engine/handle_containers.h ) s.files += %w( src/core/lib/event_engine/memory_allocator.cc ) s.files += %w( src/core/lib/event_engine/memory_allocator_factory.h ) - s.files += %w( src/core/lib/event_engine/nameser.h ) s.files += %w( src/core/lib/event_engine/poller.h ) s.files += %w( src/core/lib/event_engine/posix.h ) s.files += %w( src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc ) diff --git a/package.xml b/package.xml index 811227b94382d..654ff0c29cbd2 100644 --- a/package.xml +++ b/package.xml @@ -1073,7 +1073,6 @@ - diff --git a/src/core/BUILD b/src/core/BUILD index 777eb1e1ea1da..8e64a89e95af5 100644 --- a/src/core/BUILD +++ b/src/core/BUILD @@ -2394,7 +2394,6 @@ grpc_cc_library( hdrs = [ "lib/event_engine/ares_resolver.h", "lib/event_engine/grpc_polled_fd.h", - "lib/event_engine/nameser.h", "lib/event_engine/posix_engine/grpc_polled_fd_posix.h", ], external_deps = [ diff --git a/src/core/lib/event_engine/ares_resolver.cc b/src/core/lib/event_engine/ares_resolver.cc index c137ef34f1e4e..2f26a9fcf1cc0 100644 --- a/src/core/lib/event_engine/ares_resolver.cc +++ b/src/core/lib/event_engine/ares_resolver.cc @@ -33,17 +33,7 @@ #if GRPC_ARES == 1 -#include - -#include - -#if ARES_VERSION >= 0x011200 -// c-ares 1.18.0 or later starts to provide ares_nameser.h as a public header. #include -#else -#include "src/core/lib/event_engine/nameser.h" // IWYU pragma: keep -#endif - #include #include diff --git a/src/core/lib/event_engine/nameser.h b/src/core/lib/event_engine/nameser.h deleted file mode 100644 index c73a91622d50f..0000000000000 --- a/src/core/lib/event_engine/nameser.h +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright 2023 The 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_LIB_EVENT_ENGINE_NAMESER_H -#define GRPC_SRC_CORE_LIB_EVENT_ENGINE_NAMESER_H - -#include - -#include "src/core/lib/iomgr/port.h" - -#ifdef GRPC_HAVE_ARPA_NAMESER - -#include // IWYU pragma: keep - -#else // GRPC_HAVE_ARPA_NAMESER - -typedef enum __ns_class { - ns_c_invalid = 0, // Cookie. - ns_c_in = 1, // Internet. - ns_c_2 = 2, // unallocated/unsupported. - ns_c_chaos = 3, // MIT Chaos-net. - ns_c_hs = 4, // MIT Hesiod. - // Query class values which do not appear in resource records - ns_c_none = 254, // for prereq. sections in update requests - ns_c_any = 255, // Wildcard match. - ns_c_max = 65536 -} ns_class; - -typedef enum __ns_type { - ns_t_invalid = 0, // Cookie. - ns_t_a = 1, // Host address. - ns_t_ns = 2, // Authoritative server. - ns_t_md = 3, // Mail destination. - ns_t_mf = 4, // Mail forwarder. - ns_t_cname = 5, // Canonical name. - ns_t_soa = 6, // Start of authority zone. - ns_t_mb = 7, // Mailbox domain name. - ns_t_mg = 8, // Mail group member. - ns_t_mr = 9, // Mail rename name. - ns_t_null = 10, // Null resource record. - ns_t_wks = 11, // Well known service. - ns_t_ptr = 12, // Domain name pointer. - ns_t_hinfo = 13, // Host information. - ns_t_minfo = 14, // Mailbox information. - ns_t_mx = 15, // Mail routing information. - ns_t_txt = 16, // Text strings. - ns_t_rp = 17, // Responsible person. - ns_t_afsdb = 18, // AFS cell database. - ns_t_x25 = 19, // X_25 calling address. - ns_t_isdn = 20, // ISDN calling address. - ns_t_rt = 21, // Router. - ns_t_nsap = 22, // NSAP address. - ns_t_nsap_ptr = 23, // Reverse NSAP lookup (deprecated). - ns_t_sig = 24, // Security signature. - ns_t_key = 25, // Security key. - ns_t_px = 26, // X.400 mail mapping. - ns_t_gpos = 27, // Geographical position (withdrawn). - ns_t_aaaa = 28, // Ip6 Address. - ns_t_loc = 29, // Location Information. - ns_t_nxt = 30, // Next domain (security). - ns_t_eid = 31, // Endpoint identifier. - ns_t_nimloc = 32, // Nimrod Locator. - ns_t_srv = 33, // Server Selection. - ns_t_atma = 34, // ATM Address - ns_t_naptr = 35, // Naming Authority PoinTeR - ns_t_kx = 36, // Key Exchange - ns_t_cert = 37, // Certification record - ns_t_a6 = 38, // IPv6 address (deprecates AAAA) - ns_t_dname = 39, // Non-terminal DNAME (for IPv6) - ns_t_sink = 40, // Kitchen sink (experimentatl) - ns_t_opt = 41, // EDNS0 option (meta-RR) - ns_t_apl = 42, // Address prefix list (RFC3123) - ns_t_ds = 43, // Delegation Signer (RFC4034) - ns_t_sshfp = 44, // SSH Key Fingerprint (RFC4255) - ns_t_rrsig = 46, // Resource Record Signature (RFC4034) - ns_t_nsec = 47, // Next Secure (RFC4034) - ns_t_dnskey = 48, // DNS Public Key (RFC4034) - ns_t_tkey = 249, // Transaction key - ns_t_tsig = 250, // Transaction signature. - ns_t_ixfr = 251, // Incremental zone transfer. - ns_t_axfr = 252, // Transfer zone of authority. - ns_t_mailb = 253, // Transfer mailbox records. - ns_t_maila = 254, // Transfer mail agent records. - ns_t_any = 255, // Wildcard match. - ns_t_zxfr = 256, // BIND-specific, nonstandard. - ns_t_max = 65536 -} ns_type; - -#endif // GRPC_HAVE_ARPA_NAMESER - -#endif // GRPC_SRC_CORE_LIB_EVENT_ENGINE_NAMESER_H diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index dd65e91e131a1..c27cf5780a00b 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -2088,7 +2088,6 @@ src/core/lib/event_engine/grpc_polled_fd.h \ src/core/lib/event_engine/handle_containers.h \ src/core/lib/event_engine/memory_allocator.cc \ src/core/lib/event_engine/memory_allocator_factory.h \ -src/core/lib/event_engine/nameser.h \ src/core/lib/event_engine/poller.h \ src/core/lib/event_engine/posix.h \ src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 5a4c9d4f1c119..76f0add5f7387 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -1866,7 +1866,6 @@ src/core/lib/event_engine/grpc_polled_fd.h \ src/core/lib/event_engine/handle_containers.h \ src/core/lib/event_engine/memory_allocator.cc \ src/core/lib/event_engine/memory_allocator_factory.h \ -src/core/lib/event_engine/nameser.h \ src/core/lib/event_engine/poller.h \ src/core/lib/event_engine/posix.h \ src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc \ From a9bf741735f5749b49f58b47c29c0ff887754d9f Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 12 Sep 2023 13:43:14 -0700 Subject: [PATCH 09/12] [fuzzing] Make it easier for fuzzers to find experiments (#34296) The previous approach of generating strings was not converging well. Instead, load a bitfield from the protobuf and use the bits to select experiments. The fuzzers can explore this space swiftly. Downside is that as experiments rotate in/out the corpus gets a bit messed up, but I'm reasonably confident we'll recover quickly. --------- Co-authored-by: ctiller --- src/core/lib/config/config_vars.yaml | 1 + test/core/end2end/end2end_test_fuzzer.cc | 8 -------- test/core/util/fuzz_config_vars.proto | 2 +- test/core/util/fuzz_config_vars_helpers.cc | 20 +++++++++----------- test/core/util/fuzz_config_vars_helpers.h | 6 +++--- tools/codegen/core/gen_config_vars.py | 4 ++-- 6 files changed, 16 insertions(+), 25 deletions(-) diff --git a/src/core/lib/config/config_vars.yaml b/src/core/lib/config/config_vars.yaml index 1f300ab9640e4..8ccd41c2d41c6 100644 --- a/src/core/lib/config/config_vars.yaml +++ b/src/core/lib/config/config_vars.yaml @@ -35,6 +35,7 @@ A comma separated list of currently active experiments. Experiments may be prefixed with a '-' to disable them. default: + fuzz_type: uint64 fuzz: ValidateExperimentsStringForFuzzing - name: client_channel_backup_poll_interval_ms type: int diff --git a/test/core/end2end/end2end_test_fuzzer.cc b/test/core/end2end/end2end_test_fuzzer.cc index 5c14b898702e6..094f765e8149d 100644 --- a/test/core/end2end/end2end_test_fuzzer.cc +++ b/test/core/end2end/end2end_test_fuzzer.cc @@ -46,7 +46,6 @@ #include "test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.h" #include "test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.pb.h" #include "test/core/util/fuzz_config_vars.h" -#include "test/core/util/fuzz_config_vars.pb.h" using ::grpc_event_engine::experimental::FuzzingEventEngine; using ::grpc_event_engine::experimental::GetDefaultEventEngine; @@ -100,8 +99,6 @@ DEFINE_PROTO_FUZZER(const core_end2end_test_fuzzer::Msg& msg) { return tests; }(); if (tests.empty()) return; - static const auto only_experiment = - grpc_core::GetEnv("GRPC_TEST_FUZZER_EXPERIMENT"); const int test_id = msg.test_id() % tests.size(); @@ -109,11 +106,6 @@ DEFINE_PROTO_FUZZER(const core_end2end_test_fuzzer::Msg& msg) { gpr_set_log_function(dont_log); } - if (only_experiment.has_value() && - msg.config_vars().experiments() != only_experiment.value()) { - return; - } - // TODO(ctiller): make this per fixture? grpc_core::ConfigVars::Overrides overrides = grpc_core::OverridesFromFuzzConfigVars(msg.config_vars()); diff --git a/test/core/util/fuzz_config_vars.proto b/test/core/util/fuzz_config_vars.proto index df71f6540f923..5c30dca2de8a8 100644 --- a/test/core/util/fuzz_config_vars.proto +++ b/test/core/util/fuzz_config_vars.proto @@ -25,6 +25,6 @@ message FuzzConfigVars { optional string dns_resolver = 76817901; optional string verbosity = 68420950; optional string stacktrace_minloglevel = 273035715; - optional string experiments = 510817011; + optional uint64 experiments = 510817011; optional string trace = 291231137; }; diff --git a/test/core/util/fuzz_config_vars_helpers.cc b/test/core/util/fuzz_config_vars_helpers.cc index e1b46a9d0c0e3..9029fdfd665aa 100644 --- a/test/core/util/fuzz_config_vars_helpers.cc +++ b/test/core/util/fuzz_config_vars_helpers.cc @@ -13,27 +13,25 @@ // limitations under the License. #include +#include -#include +#include #include +#include #include "absl/strings/str_join.h" -#include "absl/strings/str_split.h" -#include "absl/strings/string_view.h" #include "src/core/lib/experiments/config.h" #include "src/core/lib/experiments/experiments.h" namespace grpc_core { -std::string ValidateExperimentsStringForFuzzing(absl::string_view input) { - std::set experiments; - for (absl::string_view experiment : absl::StrSplit(input, ',')) { - for (size_t i = 0; i < kNumExperiments; i++) { - const auto& metadata = g_experiment_metadata[i]; - if (metadata.name == experiment && metadata.allow_in_fuzzing_config) { - experiments.insert(experiment); - } +std::string ValidateExperimentsStringForFuzzing(uint64_t input) { + std::vector experiments; + for (size_t i = 0; i < std::min(kNumExperiments, 64); i++) { + const auto& metadata = g_experiment_metadata[i]; + if ((input & (1ull << i)) && metadata.allow_in_fuzzing_config) { + experiments.push_back(metadata.name); } } return absl::StrJoin(experiments, ","); diff --git a/test/core/util/fuzz_config_vars_helpers.h b/test/core/util/fuzz_config_vars_helpers.h index 7024f083d207b..9550b75bd7dd8 100644 --- a/test/core/util/fuzz_config_vars_helpers.h +++ b/test/core/util/fuzz_config_vars_helpers.h @@ -17,13 +17,13 @@ #include -#include +#include -#include "absl/strings/string_view.h" +#include namespace grpc_core { -std::string ValidateExperimentsStringForFuzzing(absl::string_view experiments); +std::string ValidateExperimentsStringForFuzzing(uint64_t experiments); } // namespace grpc_core diff --git a/tools/codegen/core/gen_config_vars.py b/tools/codegen/core/gen_config_vars.py index 4739c3351d161..0beae5d73e2f5 100755 --- a/tools/codegen/core/gen_config_vars.py +++ b/tools/codegen/core/gen_config_vars.py @@ -29,7 +29,7 @@ import yaml with open("src/core/lib/config/config_vars.yaml") as f: - attrs = yaml.safe_load(f.read(), Loader=yaml.FullLoader) + attrs = yaml.safe_load(f.read()) error = False today = datetime.date.today() @@ -199,7 +199,7 @@ def string_default_value(x, name): print( " optional %s %s = %d;" % ( - PROTO_TYPE[attr["type"]], + attr.get("fuzz_type", PROTO_TYPE[attr["type"]]), attr["name"], binascii.crc32(attr["name"].encode("ascii")) & 0x1FFFFFFF, ), From ce8838f05cb8d0374aba9edd06c7d38b0d5453a6 Mon Sep 17 00:00:00 2001 From: Esun Kim Date: Tue, 12 Sep 2023 15:30:38 -0700 Subject: [PATCH 10/12] [Release] Added 1.58 to interop (#34323) --- tools/interop_matrix/client_matrix.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index 11b8dd4c3a1f7..88995b4b0fe72 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -128,6 +128,7 @@ def __init__(self, patch=[], runtimes=[], testcases_file=None): ("v1.55.0", ReleaseInfo()), ("v1.56.0", ReleaseInfo()), ("v1.57.0", ReleaseInfo()), + ("v1.58.0", ReleaseInfo()), ] ), "go": OrderedDict( @@ -744,6 +745,12 @@ def __init__(self, patch=[], runtimes=[], testcases_file=None): runtimes=["python"], testcases_file="python__master" ), ), + ( + "v1.58.0", + ReleaseInfo( + runtimes=["python"], testcases_file="python__master" + ), + ), ] ), "node": OrderedDict( @@ -836,6 +843,7 @@ def __init__(self, patch=[], runtimes=[], testcases_file=None): ("v1.55.0", ReleaseInfo()), ("v1.56.0", ReleaseInfo()), ("v1.57.0", ReleaseInfo()), + ("v1.58.0", ReleaseInfo()), ] ), "php": OrderedDict( @@ -892,6 +900,7 @@ def __init__(self, patch=[], runtimes=[], testcases_file=None): ("v1.55.0", ReleaseInfo()), ("v1.56.0", ReleaseInfo()), ("v1.57.0", ReleaseInfo()), + ("v1.58.0", ReleaseInfo()), ] ), "csharp": OrderedDict( From 82c39092ff3767e4d284b25b5858bcfe54c4e2c6 Mon Sep 17 00:00:00 2001 From: Esun Kim Date: Tue, 12 Sep 2023 17:05:18 -0700 Subject: [PATCH 11/12] [Deps] Bumped the protobuf commit to b2b7a511 (#34330) This is to have https://github.com/protocolbuffers/protobuf/pull/14054 which is required to make abseil-at-head test pass. --- bazel/grpc_deps.bzl | 8 ++++---- third_party/protobuf | 2 +- tools/distrib/python/grpcio_tools/protoc_lib_deps.py | 2 +- tools/run_tests/sanity/check_submodules.sh | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl index ee2a6ae8bc0ae..5268b090ac3ba 100644 --- a/bazel/grpc_deps.bzl +++ b/bazel/grpc_deps.bzl @@ -243,12 +243,12 @@ def grpc_deps(): if "com_google_protobuf" not in native.existing_rules(): http_archive( name = "com_google_protobuf", - sha256 = "c580129f1db37f0ba8b80808b530593b89187b0d5573e9471396d0513aacfee4", - strip_prefix = "protobuf-0d22de520bf3fdb0978a962ae90b72db2f560cef", + sha256 = "660ce016f987550bc1ccec4a6ee4199afb871799b696227098e3641476a7d566", + strip_prefix = "protobuf-b2b7a51158418f41cff0520894836c15b1738721", urls = [ # https://github.com/protocolbuffers/protobuf/commits/v24.3 - "https://storage.googleapis.com/grpc-bazel-mirror/github.com/protocolbuffers/protobuf/archive/0d22de520bf3fdb0978a962ae90b72db2f560cef.tar.gz", - "https://github.com/protocolbuffers/protobuf/archive/0d22de520bf3fdb0978a962ae90b72db2f560cef.tar.gz", + "https://storage.googleapis.com/grpc-bazel-mirror/github.com/protocolbuffers/protobuf/archive/b2b7a51158418f41cff0520894836c15b1738721.tar.gz", + "https://github.com/protocolbuffers/protobuf/archive/b2b7a51158418f41cff0520894836c15b1738721.tar.gz", ], patches = [ "@com_github_grpc_grpc//third_party:protobuf.patch", diff --git a/third_party/protobuf b/third_party/protobuf index 0d22de520bf3f..b2b7a51158418 160000 --- a/third_party/protobuf +++ b/third_party/protobuf @@ -1 +1 @@ -Subproject commit 0d22de520bf3fdb0978a962ae90b72db2f560cef +Subproject commit b2b7a51158418f41cff0520894836c15b1738721 diff --git a/tools/distrib/python/grpcio_tools/protoc_lib_deps.py b/tools/distrib/python/grpcio_tools/protoc_lib_deps.py index d221cfb9734c3..c0fedbb958ab5 100644 --- a/tools/distrib/python/grpcio_tools/protoc_lib_deps.py +++ b/tools/distrib/python/grpcio_tools/protoc_lib_deps.py @@ -315,4 +315,4 @@ ] PROTO_INCLUDE='third_party/protobuf/src' -PROTOBUF_SUBMODULE_VERSION="0d22de520bf3fdb0978a962ae90b72db2f560cef" +PROTOBUF_SUBMODULE_VERSION="b2b7a51158418f41cff0520894836c15b1738721" diff --git a/tools/run_tests/sanity/check_submodules.sh b/tools/run_tests/sanity/check_submodules.sh index 84e958181be34..46d916fa04358 100755 --- a/tools/run_tests/sanity/check_submodules.sh +++ b/tools/run_tests/sanity/check_submodules.sh @@ -35,7 +35,7 @@ third_party/googleapis 2f9af297c84c55c8b871ba4495e01ade42476c92 third_party/googletest 0e402173c97aea7a00749e825b194bfede4f2e45 third_party/opencensus-proto 4aa53e15cbf1a47bc9087e6cfdca214c1eea4e89 third_party/opentelemetry 60fa8754d890b5c55949a8c68dcfd7ab5c2395df -third_party/protobuf 0d22de520bf3fdb0978a962ae90b72db2f560cef +third_party/protobuf b2b7a51158418f41cff0520894836c15b1738721 third_party/protoc-gen-validate fab737efbb4b4d03e7c771393708f75594b121e4 third_party/re2 0c5616df9c0aaa44c9440d87422012423d91c7d1 third_party/upb 42cd08932e364a4cde35033b73f15c30250d7c2e From d713427cec544b45682546937e955e27515d7126 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 12 Sep 2023 17:46:31 -0700 Subject: [PATCH 12/12] [round_robin] third attempt: delegate to pick_first as per dualstack design (#34320) Previous attempt was #34241, reverted in #34317. The second commit here makes the experiment disablable, so that we can roll it out slowly internally. --- CMakeLists.txt | 2 + Makefile | 2 + Package.swift | 2 + bazel/experiments.bzl | 18 + build_autogenerated.yaml | 4 + config.m4 | 1 + config.w32 | 1 + gRPC-C++.podspec | 2 + gRPC-Core.podspec | 3 + grpc.gemspec | 2 + grpc.gyp | 2 + package.xml | 2 + src/core/BUILD | 37 ++ .../client_channel/lb_policy/endpoint_list.cc | 188 ++++++++ .../client_channel/lb_policy/endpoint_list.h | 214 +++++++++ .../lb_policy/round_robin/round_robin.cc | 436 ++++++++++++++++-- src/core/lib/experiments/experiments.cc | 24 + src/core/lib/experiments/experiments.h | 12 +- src/core/lib/experiments/experiments.yaml | 7 + src/core/lib/experiments/rollouts.yaml | 2 + src/python/grpcio/grpc_core_dependencies.py | 1 + .../lb_policy/outlier_detection_test.cc | 2 - .../lb_policy/round_robin_test.cc | 4 +- test/cpp/end2end/BUILD | 2 + test/cpp/end2end/client_lb_end2end_test.cc | 40 +- tools/doxygen/Doxyfile.c++.internal | 2 + tools/doxygen/Doxyfile.core.internal | 2 + 27 files changed, 971 insertions(+), 43 deletions(-) create mode 100644 src/core/ext/filters/client_channel/lb_policy/endpoint_list.cc create mode 100644 src/core/ext/filters/client_channel/lb_policy/endpoint_list.h diff --git a/CMakeLists.txt b/CMakeLists.txt index b4b076cc8bd39..6ef5e5faed651 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1739,6 +1739,7 @@ add_library(grpc src/core/ext/filters/client_channel/http_proxy_mapper.cc src/core/ext/filters/client_channel/lb_policy/address_filtering.cc src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc + src/core/ext/filters/client_channel/lb_policy/endpoint_list.cc src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc @@ -2788,6 +2789,7 @@ add_library(grpc_unsecure src/core/ext/filters/client_channel/http_proxy_mapper.cc src/core/ext/filters/client_channel/lb_policy/address_filtering.cc src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc + src/core/ext/filters/client_channel/lb_policy/endpoint_list.cc src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc diff --git a/Makefile b/Makefile index e9353eb334c0a..c4eda72e5bd52 100644 --- a/Makefile +++ b/Makefile @@ -972,6 +972,7 @@ LIBGRPC_SRC = \ src/core/ext/filters/client_channel/http_proxy_mapper.cc \ src/core/ext/filters/client_channel/lb_policy/address_filtering.cc \ src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc \ + src/core/ext/filters/client_channel/lb_policy/endpoint_list.cc \ src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc \ src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc \ src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc \ @@ -1875,6 +1876,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/ext/filters/client_channel/http_proxy_mapper.cc \ src/core/ext/filters/client_channel/lb_policy/address_filtering.cc \ src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc \ + src/core/ext/filters/client_channel/lb_policy/endpoint_list.cc \ src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc \ src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc \ src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc \ diff --git a/Package.swift b/Package.swift index c2cc9bfac6df5..05576ebc0dc93 100644 --- a/Package.swift +++ b/Package.swift @@ -149,6 +149,8 @@ let package = Package( "src/core/ext/filters/client_channel/lb_policy/backend_metric_data.h", "src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc", "src/core/ext/filters/client_channel/lb_policy/child_policy_handler.h", + "src/core/ext/filters/client_channel/lb_policy/endpoint_list.cc", + "src/core/ext/filters/client_channel/lb_policy/endpoint_list.h", "src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc", "src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h", "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc", diff --git a/bazel/experiments.bzl b/bazel/experiments.bzl index 4285419f54d27..9ed9bd2c48111 100644 --- a/bazel/experiments.bzl +++ b/bazel/experiments.bzl @@ -60,9 +60,15 @@ EXPERIMENTS = { "core_end2end_test": [ "work_stealing", ], + "cpp_lb_end2end_test": [ + "round_robin_delegate_to_pick_first", + ], "flow_control_test": [ "lazier_stream_updates", ], + "xds_end2end_test": [ + "round_robin_delegate_to_pick_first", + ], }, }, "ios": { @@ -108,9 +114,15 @@ EXPERIMENTS = { "core_end2end_test": [ "work_stealing", ], + "cpp_lb_end2end_test": [ + "round_robin_delegate_to_pick_first", + ], "flow_control_test": [ "lazier_stream_updates", ], + "xds_end2end_test": [ + "round_robin_delegate_to_pick_first", + ], }, }, "posix": { @@ -166,9 +178,15 @@ EXPERIMENTS = { "core_end2end_test": [ "work_stealing", ], + "cpp_lb_end2end_test": [ + "round_robin_delegate_to_pick_first", + ], "flow_control_test": [ "lazier_stream_updates", ], + "xds_end2end_test": [ + "round_robin_delegate_to_pick_first", + ], }, }, } diff --git a/build_autogenerated.yaml b/build_autogenerated.yaml index 5ae25305e8115..3615cc468964f 100644 --- a/build_autogenerated.yaml +++ b/build_autogenerated.yaml @@ -232,6 +232,7 @@ libs: - src/core/ext/filters/client_channel/lb_policy/address_filtering.h - src/core/ext/filters/client_channel/lb_policy/backend_metric_data.h - src/core/ext/filters/client_channel/lb_policy/child_policy_handler.h + - src/core/ext/filters/client_channel/lb_policy/endpoint_list.h - src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.h @@ -1047,6 +1048,7 @@ libs: - src/core/ext/filters/client_channel/http_proxy_mapper.cc - src/core/ext/filters/client_channel/lb_policy/address_filtering.cc - src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc + - src/core/ext/filters/client_channel/lb_policy/endpoint_list.cc - src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc @@ -1978,6 +1980,7 @@ libs: - src/core/ext/filters/client_channel/lb_policy/address_filtering.h - src/core/ext/filters/client_channel/lb_policy/backend_metric_data.h - src/core/ext/filters/client_channel/lb_policy/child_policy_handler.h + - src/core/ext/filters/client_channel/lb_policy/endpoint_list.h - src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.h @@ -2409,6 +2412,7 @@ libs: - src/core/ext/filters/client_channel/http_proxy_mapper.cc - src/core/ext/filters/client_channel/lb_policy/address_filtering.cc - src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc + - src/core/ext/filters/client_channel/lb_policy/endpoint_list.cc - src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc diff --git a/config.m4 b/config.m4 index 50cfef0e9ce8c..275f65b14012b 100644 --- a/config.m4 +++ b/config.m4 @@ -59,6 +59,7 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/filters/client_channel/http_proxy_mapper.cc \ src/core/ext/filters/client_channel/lb_policy/address_filtering.cc \ src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc \ + src/core/ext/filters/client_channel/lb_policy/endpoint_list.cc \ src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc \ src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc \ src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc \ diff --git a/config.w32 b/config.w32 index 9b891dabde135..32504b958a3cd 100644 --- a/config.w32 +++ b/config.w32 @@ -24,6 +24,7 @@ if (PHP_GRPC != "no") { "src\\core\\ext\\filters\\client_channel\\http_proxy_mapper.cc " + "src\\core\\ext\\filters\\client_channel\\lb_policy\\address_filtering.cc " + "src\\core\\ext\\filters\\client_channel\\lb_policy\\child_policy_handler.cc " + + "src\\core\\ext\\filters\\client_channel\\lb_policy\\endpoint_list.cc " + "src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\client_load_reporting_filter.cc " + "src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\grpclb.cc " + "src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\grpclb_balancer_addresses.cc " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 66701102fc046..ca7d8ae57c1b0 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -263,6 +263,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/lb_policy/address_filtering.h', 'src/core/ext/filters/client_channel/lb_policy/backend_metric_data.h', 'src/core/ext/filters/client_channel/lb_policy/child_policy_handler.h', + 'src/core/ext/filters/client_channel/lb_policy/endpoint_list.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.h', @@ -1348,6 +1349,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/lb_policy/address_filtering.h', 'src/core/ext/filters/client_channel/lb_policy/backend_metric_data.h', 'src/core/ext/filters/client_channel/lb_policy/child_policy_handler.h', + 'src/core/ext/filters/client_channel/lb_policy/endpoint_list.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index cb23b297197fc..b1b5ac2c4e594 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -250,6 +250,8 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/lb_policy/backend_metric_data.h', 'src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc', 'src/core/ext/filters/client_channel/lb_policy/child_policy_handler.h', + 'src/core/ext/filters/client_channel/lb_policy/endpoint_list.cc', + 'src/core/ext/filters/client_channel/lb_policy/endpoint_list.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc', 'src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc', @@ -2120,6 +2122,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/lb_policy/address_filtering.h', 'src/core/ext/filters/client_channel/lb_policy/backend_metric_data.h', 'src/core/ext/filters/client_channel/lb_policy/child_policy_handler.h', + 'src/core/ext/filters/client_channel/lb_policy/endpoint_list.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.h', diff --git a/grpc.gemspec b/grpc.gemspec index 41ab905785a49..9d0846479a725 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -155,6 +155,8 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/lb_policy/backend_metric_data.h ) s.files += %w( src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc ) s.files += %w( src/core/ext/filters/client_channel/lb_policy/child_policy_handler.h ) + s.files += %w( src/core/ext/filters/client_channel/lb_policy/endpoint_list.cc ) + s.files += %w( src/core/ext/filters/client_channel/lb_policy/endpoint_list.h ) s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc ) s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h ) s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc ) diff --git a/grpc.gyp b/grpc.gyp index 617cb48302ec4..2b418e262216f 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -288,6 +288,7 @@ 'src/core/ext/filters/client_channel/http_proxy_mapper.cc', 'src/core/ext/filters/client_channel/lb_policy/address_filtering.cc', 'src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc', + 'src/core/ext/filters/client_channel/lb_policy/endpoint_list.cc', 'src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc', @@ -1131,6 +1132,7 @@ 'src/core/ext/filters/client_channel/http_proxy_mapper.cc', 'src/core/ext/filters/client_channel/lb_policy/address_filtering.cc', 'src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc', + 'src/core/ext/filters/client_channel/lb_policy/endpoint_list.cc', 'src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc', diff --git a/package.xml b/package.xml index 654ff0c29cbd2..ceda0c4b8f7cc 100644 --- a/package.xml +++ b/package.xml @@ -137,6 +137,8 @@ + + diff --git a/src/core/BUILD b/src/core/BUILD index 8e64a89e95af5..a8474c2d84e58 100644 --- a/src/core/BUILD +++ b/src/core/BUILD @@ -4775,6 +4775,41 @@ grpc_cc_library( ], ) +grpc_cc_library( + name = "lb_endpoint_list", + srcs = [ + "ext/filters/client_channel/lb_policy/endpoint_list.cc", + ], + hdrs = [ + "ext/filters/client_channel/lb_policy/endpoint_list.h", + ], + external_deps = [ + "absl/functional:any_invocable", + "absl/status", + "absl/status:statusor", + "absl/types:optional", + ], + language = "c++", + deps = [ + "channel_args", + "delegating_helper", + "grpc_lb_policy_pick_first", + "json", + "lb_policy", + "lb_policy_registry", + "pollset_set", + "subchannel_interface", + "//:config", + "//:debug_location", + "//:gpr", + "//:grpc_base", + "//:orphanable", + "//:ref_counted_ptr", + "//:server_address", + "//:work_serializer", + ], +) + grpc_cc_library( name = "grpc_lb_policy_pick_first", srcs = [ @@ -4879,8 +4914,10 @@ grpc_cc_library( language = "c++", deps = [ "channel_args", + "experiments", "grpc_lb_subchannel_list", "json", + "lb_endpoint_list", "lb_policy", "lb_policy_factory", "subchannel_interface", diff --git a/src/core/ext/filters/client_channel/lb_policy/endpoint_list.cc b/src/core/ext/filters/client_channel/lb_policy/endpoint_list.cc new file mode 100644 index 0000000000000..9269359d74848 --- /dev/null +++ b/src/core/ext/filters/client_channel/lb_policy/endpoint_list.cc @@ -0,0 +1,188 @@ +// +// 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/ext/filters/client_channel/lb_policy/endpoint_list.h" + +#include + +#include +#include +#include +#include + +#include "absl/status/status.h" +#include "absl/status/statusor.h" +#include "absl/types/optional.h" + +#include +#include +#include + +#include "src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/config/core_configuration.h" +#include "src/core/lib/gprpp/debug_location.h" +#include "src/core/lib/gprpp/orphanable.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/iomgr/pollset_set.h" +#include "src/core/lib/json/json.h" +#include "src/core/lib/load_balancing/delegating_helper.h" +#include "src/core/lib/load_balancing/lb_policy.h" +#include "src/core/lib/load_balancing/lb_policy_registry.h" +#include "src/core/lib/resolver/server_address.h" + +namespace grpc_core { + +// +// EndpointList::Endpoint::Helper +// + +class EndpointList::Endpoint::Helper + : public LoadBalancingPolicy::DelegatingChannelControlHelper { + public: + explicit Helper(RefCountedPtr endpoint) + : endpoint_(std::move(endpoint)) {} + + ~Helper() override { endpoint_.reset(DEBUG_LOCATION, "Helper"); } + + RefCountedPtr CreateSubchannel( + ServerAddress address, const ChannelArgs& args) override { + return endpoint_->CreateSubchannel(std::move(address), args); + } + + void UpdateState( + grpc_connectivity_state state, const absl::Status& status, + RefCountedPtr picker) override { + auto old_state = std::exchange(endpoint_->connectivity_state_, state); + endpoint_->picker_ = std::move(picker); + endpoint_->OnStateUpdate(old_state, state, status); + } + + private: + LoadBalancingPolicy::ChannelControlHelper* parent_helper() const override { + return endpoint_->endpoint_list_->channel_control_helper(); + } + + RefCountedPtr endpoint_; +}; + +// +// EndpointList::Endpoint +// + +void EndpointList::Endpoint::Init( + const ServerAddress& address, const ChannelArgs& args, + std::shared_ptr work_serializer) { + ChannelArgs child_args = + args.Set(GRPC_ARG_INTERNAL_PICK_FIRST_ENABLE_HEALTH_CHECKING, true) + .Set(GRPC_ARG_INTERNAL_PICK_FIRST_OMIT_STATUS_MESSAGE_PREFIX, true); + LoadBalancingPolicy::Args lb_policy_args; + lb_policy_args.work_serializer = std::move(work_serializer); + lb_policy_args.args = child_args; + lb_policy_args.channel_control_helper = + std::make_unique(Ref(DEBUG_LOCATION, "Helper")); + child_policy_ = + CoreConfiguration::Get().lb_policy_registry().CreateLoadBalancingPolicy( + "pick_first", std::move(lb_policy_args)); + if (GPR_UNLIKELY(endpoint_list_->tracer_ != nullptr)) { + gpr_log(GPR_INFO, "[%s %p] endpoint %p: created child policy %p", + endpoint_list_->tracer_, endpoint_list_->policy_.get(), this, + child_policy_.get()); + } + // Add our interested_parties pollset_set to that of the newly created + // child policy. This will make the child policy progress upon activity on + // this policy, which in turn is tied to the application's call. + grpc_pollset_set_add_pollset_set( + child_policy_->interested_parties(), + endpoint_list_->policy_->interested_parties()); + // Construct pick_first config. + auto config = + CoreConfiguration::Get().lb_policy_registry().ParseLoadBalancingConfig( + Json::FromArray( + {Json::FromObject({{"pick_first", Json::FromObject({})}})})); + GPR_ASSERT(config.ok()); + // Update child policy. + LoadBalancingPolicy::UpdateArgs update_args; + update_args.addresses.emplace().emplace_back(address); + update_args.args = child_args; + update_args.config = std::move(*config); + // TODO(roth): If the child reports a non-OK status with the update, + // we need to propagate that back to the resolver somehow. + (void)child_policy_->UpdateLocked(std::move(update_args)); +} + +void EndpointList::Endpoint::Orphan() { + // Remove pollset_set linkage. + grpc_pollset_set_del_pollset_set( + child_policy_->interested_parties(), + endpoint_list_->policy_->interested_parties()); + child_policy_.reset(); + picker_.reset(); + Unref(); +} + +void EndpointList::Endpoint::ResetBackoffLocked() { + if (child_policy_ != nullptr) child_policy_->ResetBackoffLocked(); +} + +void EndpointList::Endpoint::ExitIdleLocked() { + if (child_policy_ != nullptr) child_policy_->ExitIdleLocked(); +} + +size_t EndpointList::Endpoint::Index() const { + for (size_t i = 0; i < endpoint_list_->endpoints_.size(); ++i) { + if (endpoint_list_->endpoints_[i].get() == this) return i; + } + return -1; +} + +RefCountedPtr EndpointList::Endpoint::CreateSubchannel( + ServerAddress address, const ChannelArgs& args) { + return endpoint_list_->channel_control_helper()->CreateSubchannel( + std::move(address), args); +} + +// +// EndpointList +// + +void EndpointList::Init( + const ServerAddressList& addresses, const ChannelArgs& args, + absl::AnyInvocable( + RefCountedPtr, const ServerAddress&, const ChannelArgs&)> + create_endpoint) { + for (const ServerAddress& address : addresses) { + endpoints_.push_back( + create_endpoint(Ref(DEBUG_LOCATION, "Endpoint"), address, args)); + } +} + +void EndpointList::ResetBackoffLocked() { + for (const auto& endpoint : endpoints_) { + endpoint->ResetBackoffLocked(); + } +} + +bool EndpointList::AllEndpointsSeenInitialState() const { + for (const auto& endpoint : endpoints_) { + if (!endpoint->connectivity_state().has_value()) return false; + } + return true; +} + +} // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/lb_policy/endpoint_list.h b/src/core/ext/filters/client_channel/lb_policy/endpoint_list.h new file mode 100644 index 0000000000000..66fce2871e4bf --- /dev/null +++ b/src/core/ext/filters/client_channel/lb_policy/endpoint_list.h @@ -0,0 +1,214 @@ +// +// 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_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_ENDPOINT_LIST_H +#define GRPC_SRC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_ENDPOINT_LIST_H + +#include + +#include + +#include +#include +#include + +#include "absl/functional/any_invocable.h" +#include "absl/status/status.h" +#include "absl/types/optional.h" + +#include + +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gprpp/debug_location.h" +#include "src/core/lib/gprpp/orphanable.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/gprpp/work_serializer.h" +#include "src/core/lib/load_balancing/lb_policy.h" +#include "src/core/lib/load_balancing/subchannel_interface.h" +#include "src/core/lib/resolver/server_address.h" + +namespace grpc_core { + +// A list of endpoints for use in a petiole LB policy. Each endpoint may +// have one or more addresses, which will be passed down to a pick_first +// child policy. +// +// To use this, a petiole policy must define its own subclass of both +// EndpointList and EndpointList::Endpoint, like so: +/* +class MyEndpointList : public EndpointList { + public: + MyEndpointList(RefCountedPtr lb_policy, + const ServerAddressList& addresses, const ChannelArgs& args) + : EndpointList(std::move(lb_policy), + GRPC_TRACE_FLAG_ENABLED(grpc_my_tracer) + ? "MyEndpointList" + : nullptr) { + Init(addresses, args, + [&](RefCountedPtr endpoint_list, + const ServerAddress& address, const ChannelArgs& args) { + return MakeOrphanable( + std::move(endpoint_list), address, args, + policy()->work_serializer()); + }); + } + + private: + class MyEndpoint : public Endpoint { + public: + MyEndpoint(RefCountedPtr endpoint_list, + const ServerAddress& address, const ChannelArgs& args, + std::shared_ptr work_serializer) + : Endpoint(std::move(endpoint_list)) { + Init(address, args, std::move(work_serializer)); + } + + private: + void OnStateUpdate( + absl::optional old_state, + grpc_connectivity_state new_state, + const absl::Status& status) override { + // ...handle connectivity state change... + } + }; + + LoadBalancingPolicy::ChannelControlHelper* channel_control_helper() + const override { + return policy()->channel_control_helper(); + } +}; +*/ +// TODO(roth): Consider wrapping this in an LB policy subclass for petiole +// policies to inherit from. +class EndpointList : public InternallyRefCounted { + public: + // An individual endpoint. + class Endpoint : public InternallyRefCounted { + public: + ~Endpoint() override { endpoint_list_.reset(DEBUG_LOCATION, "Endpoint"); } + + void Orphan() override; + + void ResetBackoffLocked(); + void ExitIdleLocked(); + + absl::optional connectivity_state() const { + return connectivity_state_; + } + RefCountedPtr picker() const { + return picker_; + } + + protected: + // We use two-phase initialization here to ensure that the vtable is + // initialized before we need to use it. Subclass must invoke Init() + // from inside its ctor. + explicit Endpoint(RefCountedPtr endpoint_list) + : endpoint_list_(std::move(endpoint_list)) {} + + void Init(const ServerAddress& address, const ChannelArgs& args, + std::shared_ptr work_serializer); + + // Templated for convenience, to provide a short-hand for + // down-casting in the caller. + template + T* endpoint_list() const { + return static_cast(endpoint_list_.get()); + } + + // Templated for convenience, to provide a short-hand for down-casting + // in the caller. + template + T* policy() const { + return endpoint_list_->policy(); + } + + // Returns the index of this endpoint within the EndpointList. + // Intended for trace logging. + size_t Index() const; + + private: + class Helper; + + // Called when the child policy reports a connectivity state update. + virtual void OnStateUpdate( + absl::optional old_state, + grpc_connectivity_state new_state, const absl::Status& status) = 0; + + // Called to create a subchannel. Subclasses may override. + virtual RefCountedPtr CreateSubchannel( + ServerAddress address, const ChannelArgs& args); + + RefCountedPtr endpoint_list_; + + OrphanablePtr child_policy_; + absl::optional connectivity_state_; + RefCountedPtr picker_; + }; + + ~EndpointList() override { policy_.reset(DEBUG_LOCATION, "EndpointList"); } + + void Orphan() override { + endpoints_.clear(); + Unref(); + } + + size_t size() const { return endpoints_.size(); } + + const std::vector>& endpoints() const { + return endpoints_; + } + + void ResetBackoffLocked(); + + protected: + // We use two-phase initialization here to ensure that the vtable is + // initialized before we need to use it. Subclass must invoke Init() + // from inside its ctor. + EndpointList(RefCountedPtr policy, const char* tracer) + : policy_(std::move(policy)), tracer_(tracer) {} + + void Init(const ServerAddressList& addresses, const ChannelArgs& args, + absl::AnyInvocable( + RefCountedPtr, const ServerAddress&, + const ChannelArgs&)> + create_endpoint); + + // Templated for convenience, to provide a short-hand for down-casting + // in the caller. + template + T* policy() const { + return static_cast(policy_.get()); + } + + // Returns true if all endpoints have seen their initial connectivity + // state notification. + bool AllEndpointsSeenInitialState() const; + + private: + // Returns the parent policy's helper. Needed because the accessor + // method is protected on LoadBalancingPolicy. + virtual LoadBalancingPolicy::ChannelControlHelper* channel_control_helper() + const = 0; + + RefCountedPtr policy_; + const char* tracer_; + std::vector> endpoints_; +}; + +} // namespace grpc_core + +#endif // GRPC_SRC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_ENDPOINT_LIST_H diff --git a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc index 4cf71c9c951a8..2a556d6448903 100644 --- a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +++ b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc @@ -37,10 +37,12 @@ #include #include +#include "src/core/ext/filters/client_channel/lb_policy/endpoint_list.h" #include "src/core/ext/filters/client_channel/lb_policy/subchannel_list.h" #include "src/core/lib/channel/channel_args.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/orphanable.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" @@ -59,14 +61,14 @@ TraceFlag grpc_lb_round_robin_trace(false, "round_robin"); namespace { // -// round_robin LB policy +// legacy round_robin LB policy (before dualstack support) // constexpr absl::string_view kRoundRobin = "round_robin"; -class RoundRobin : public LoadBalancingPolicy { +class OldRoundRobin : public LoadBalancingPolicy { public: - explicit RoundRobin(Args args); + explicit OldRoundRobin(Args args); absl::string_view name() const override { return kRoundRobin; } @@ -74,7 +76,7 @@ class RoundRobin : public LoadBalancingPolicy { void ResetBackoffLocked() override; private: - ~RoundRobin() override; + ~OldRoundRobin() override; // Forward declaration. class RoundRobinSubchannelList; @@ -122,7 +124,7 @@ class RoundRobin : public LoadBalancingPolicy { : public SubchannelList { public: - RoundRobinSubchannelList(RoundRobin* policy, ServerAddressList addresses, + RoundRobinSubchannelList(OldRoundRobin* policy, ServerAddressList addresses, const ChannelArgs& args) : SubchannelList(policy, (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace) @@ -137,7 +139,7 @@ class RoundRobin : public LoadBalancingPolicy { } ~RoundRobinSubchannelList() override { - RoundRobin* p = static_cast(policy()); + OldRoundRobin* p = static_cast(policy()); p->Unref(DEBUG_LOCATION, "subchannel_list"); } @@ -155,7 +157,7 @@ class RoundRobin : public LoadBalancingPolicy { private: std::shared_ptr work_serializer() const override { - return static_cast(policy())->work_serializer(); + return static_cast(policy())->work_serializer(); } std::string CountersString() const { @@ -174,13 +176,13 @@ class RoundRobin : public LoadBalancingPolicy { class Picker : public SubchannelPicker { public: - Picker(RoundRobin* parent, RoundRobinSubchannelList* subchannel_list); + Picker(OldRoundRobin* parent, RoundRobinSubchannelList* subchannel_list); PickResult Pick(PickArgs args) override; private: // Using pointer value only, no ref held -- do not dereference! - RoundRobin* parent_; + OldRoundRobin* parent_; std::atomic last_picked_index_; std::vector> subchannels_; @@ -202,11 +204,11 @@ class RoundRobin : public LoadBalancingPolicy { }; // -// RoundRobin::Picker +// OldRoundRobin::Picker // -RoundRobin::Picker::Picker(RoundRobin* parent, - RoundRobinSubchannelList* subchannel_list) +OldRoundRobin::Picker::Picker(OldRoundRobin* parent, + RoundRobinSubchannelList* subchannel_list) : parent_(parent) { for (size_t i = 0; i < subchannel_list->num_subchannels(); ++i) { RoundRobinSubchannelData* sd = subchannel_list->subchannel(i); @@ -228,7 +230,7 @@ RoundRobin::Picker::Picker(RoundRobin* parent, } } -RoundRobin::PickResult RoundRobin::Picker::Pick(PickArgs /*args*/) { +OldRoundRobin::PickResult OldRoundRobin::Picker::Pick(PickArgs /*args*/) { size_t index = last_picked_index_.fetch_add(1, std::memory_order_relaxed) % subchannels_.size(); if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) { @@ -243,13 +245,13 @@ RoundRobin::PickResult RoundRobin::Picker::Pick(PickArgs /*args*/) { // RoundRobin // -RoundRobin::RoundRobin(Args args) : LoadBalancingPolicy(std::move(args)) { +OldRoundRobin::OldRoundRobin(Args args) : LoadBalancingPolicy(std::move(args)) { if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) { gpr_log(GPR_INFO, "[RR %p] Created", this); } } -RoundRobin::~RoundRobin() { +OldRoundRobin::~OldRoundRobin() { if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) { gpr_log(GPR_INFO, "[RR %p] Destroying Round Robin policy", this); } @@ -257,7 +259,7 @@ RoundRobin::~RoundRobin() { GPR_ASSERT(latest_pending_subchannel_list_ == nullptr); } -void RoundRobin::ShutdownLocked() { +void OldRoundRobin::ShutdownLocked() { if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) { gpr_log(GPR_INFO, "[RR %p] Shutting down", this); } @@ -266,14 +268,14 @@ void RoundRobin::ShutdownLocked() { latest_pending_subchannel_list_.reset(); } -void RoundRobin::ResetBackoffLocked() { +void OldRoundRobin::ResetBackoffLocked() { subchannel_list_->ResetBackoffLocked(); if (latest_pending_subchannel_list_ != nullptr) { latest_pending_subchannel_list_->ResetBackoffLocked(); } } -absl::Status RoundRobin::UpdateLocked(UpdateArgs args) { +absl::Status OldRoundRobin::UpdateLocked(UpdateArgs args) { ServerAddressList addresses; if (args.addresses.ok()) { if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) { @@ -329,7 +331,7 @@ absl::Status RoundRobin::UpdateLocked(UpdateArgs args) { // RoundRobinSubchannelList // -void RoundRobin::RoundRobinSubchannelList::UpdateStateCountersLocked( +void OldRoundRobin::RoundRobinSubchannelList::UpdateStateCountersLocked( absl::optional old_state, grpc_connectivity_state new_state) { if (old_state.has_value()) { @@ -355,9 +357,9 @@ void RoundRobin::RoundRobinSubchannelList::UpdateStateCountersLocked( } } -void RoundRobin::RoundRobinSubchannelList:: +void OldRoundRobin::RoundRobinSubchannelList:: MaybeUpdateRoundRobinConnectivityStateLocked(absl::Status status_for_tf) { - RoundRobin* p = static_cast(policy()); + OldRoundRobin* p = static_cast(policy()); // If this is latest_pending_subchannel_list_, then swap it into // subchannel_list_ in the following cases: // - subchannel_list_ has no READY subchannels. @@ -424,10 +426,10 @@ void RoundRobin::RoundRobinSubchannelList:: // RoundRobinSubchannelData // -void RoundRobin::RoundRobinSubchannelData::ProcessConnectivityChangeLocked( +void OldRoundRobin::RoundRobinSubchannelData::ProcessConnectivityChangeLocked( absl::optional old_state, grpc_connectivity_state new_state) { - RoundRobin* p = static_cast(subchannel_list()->policy()); + OldRoundRobin* p = static_cast(subchannel_list()->policy()); GPR_ASSERT(subchannel() != nullptr); // If this is not the initial state notification and the new state is // TRANSIENT_FAILURE or IDLE, re-resolve. @@ -457,9 +459,10 @@ void RoundRobin::RoundRobinSubchannelData::ProcessConnectivityChangeLocked( connectivity_status()); } -void RoundRobin::RoundRobinSubchannelData::UpdateLogicalConnectivityStateLocked( - grpc_connectivity_state connectivity_state) { - RoundRobin* p = static_cast(subchannel_list()->policy()); +void OldRoundRobin::RoundRobinSubchannelData:: + UpdateLogicalConnectivityStateLocked( + grpc_connectivity_state connectivity_state) { + OldRoundRobin* p = static_cast(subchannel_list()->policy()); if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) { gpr_log( GPR_INFO, @@ -503,6 +506,384 @@ void RoundRobin::RoundRobinSubchannelData::UpdateLogicalConnectivityStateLocked( logical_connectivity_state_ = connectivity_state; } +// +// round_robin LB policy (with dualstack changes) +// + +class RoundRobin : public LoadBalancingPolicy { + public: + explicit RoundRobin(Args args); + + absl::string_view name() const override { return kRoundRobin; } + + absl::Status UpdateLocked(UpdateArgs args) override; + void ResetBackoffLocked() override; + + private: + class RoundRobinEndpointList : public EndpointList { + public: + RoundRobinEndpointList(RefCountedPtr round_robin, + const ServerAddressList& addresses, + const ChannelArgs& args) + : EndpointList(std::move(round_robin), + GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace) + ? "RoundRobinEndpointList" + : nullptr) { + Init(addresses, args, + [&](RefCountedPtr endpoint_list, + const ServerAddress& address, const ChannelArgs& args) { + return MakeOrphanable( + std::move(endpoint_list), address, args, + policy()->work_serializer()); + }); + } + + private: + class RoundRobinEndpoint : public Endpoint { + public: + RoundRobinEndpoint(RefCountedPtr endpoint_list, + const ServerAddress& address, const ChannelArgs& args, + std::shared_ptr work_serializer) + : Endpoint(std::move(endpoint_list)) { + Init(address, args, std::move(work_serializer)); + } + + private: + // Called when the child policy reports a connectivity state update. + void OnStateUpdate(absl::optional old_state, + grpc_connectivity_state new_state, + const absl::Status& status) override; + }; + + LoadBalancingPolicy::ChannelControlHelper* channel_control_helper() + const override { + return policy()->channel_control_helper(); + } + + // Updates the counters of children in each state when a + // child transitions from old_state to new_state. + void UpdateStateCountersLocked( + absl::optional old_state, + grpc_connectivity_state new_state); + + // Ensures that the right child list is used and then updates + // the RR policy's connectivity state based on the child list's + // state counters. + void MaybeUpdateRoundRobinConnectivityStateLocked( + absl::Status status_for_tf); + + std::string CountersString() const { + return absl::StrCat("num_children=", size(), " num_ready=", num_ready_, + " num_connecting=", num_connecting_, + " num_transient_failure=", num_transient_failure_); + } + + size_t num_ready_ = 0; + size_t num_connecting_ = 0; + size_t num_transient_failure_ = 0; + + absl::Status last_failure_; + }; + + class Picker : public SubchannelPicker { + public: + Picker(RoundRobin* parent, + std::vector> + pickers); + + PickResult Pick(PickArgs args) override; + + private: + // Using pointer value only, no ref held -- do not dereference! + RoundRobin* parent_; + + std::atomic last_picked_index_; + std::vector> pickers_; + }; + + ~RoundRobin() override; + + void ShutdownLocked() override; + + // Current child list. + OrphanablePtr endpoint_list_; + // Latest pending child list. + // When we get an updated address list, we create a new child list + // for it here, and we wait to swap it into endpoint_list_ until the new + // list becomes READY. + OrphanablePtr latest_pending_endpoint_list_; + + bool shutdown_ = false; + + absl::BitGen bit_gen_; +}; + +// +// RoundRobin::Picker +// + +RoundRobin::Picker::Picker( + RoundRobin* parent, + std::vector> pickers) + : parent_(parent), pickers_(std::move(pickers)) { + // For discussion on why we generate a random starting index for + // the picker, see https://github.com/grpc/grpc-go/issues/2580. + size_t index = absl::Uniform(parent->bit_gen_, 0, pickers_.size()); + last_picked_index_.store(index, std::memory_order_relaxed); + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) { + gpr_log(GPR_INFO, + "[RR %p picker %p] created picker from endpoint_list=%p " + "with %" PRIuPTR " READY children; last_picked_index_=%" PRIuPTR, + parent_, this, parent_->endpoint_list_.get(), pickers_.size(), + index); + } +} + +RoundRobin::PickResult RoundRobin::Picker::Pick(PickArgs args) { + size_t index = last_picked_index_.fetch_add(1, std::memory_order_relaxed) % + pickers_.size(); + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) { + gpr_log(GPR_INFO, + "[RR %p picker %p] using picker index %" PRIuPTR ", picker=%p", + parent_, this, index, pickers_[index].get()); + } + return pickers_[index]->Pick(args); +} + +// +// RoundRobin +// + +RoundRobin::RoundRobin(Args args) : LoadBalancingPolicy(std::move(args)) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) { + gpr_log(GPR_INFO, "[RR %p] Created", this); + } +} + +RoundRobin::~RoundRobin() { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) { + gpr_log(GPR_INFO, "[RR %p] Destroying Round Robin policy", this); + } + GPR_ASSERT(endpoint_list_ == nullptr); + GPR_ASSERT(latest_pending_endpoint_list_ == nullptr); +} + +void RoundRobin::ShutdownLocked() { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) { + gpr_log(GPR_INFO, "[RR %p] Shutting down", this); + } + shutdown_ = true; + endpoint_list_.reset(); + latest_pending_endpoint_list_.reset(); +} + +void RoundRobin::ResetBackoffLocked() { + endpoint_list_->ResetBackoffLocked(); + if (latest_pending_endpoint_list_ != nullptr) { + latest_pending_endpoint_list_->ResetBackoffLocked(); + } +} + +absl::Status RoundRobin::UpdateLocked(UpdateArgs args) { + ServerAddressList addresses; + if (args.addresses.ok()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) { + gpr_log(GPR_INFO, "[RR %p] received update with %" PRIuPTR " addresses", + this, args.addresses->size()); + } + addresses = std::move(*args.addresses); + } else { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) { + gpr_log(GPR_INFO, "[RR %p] received update with address error: %s", this, + args.addresses.status().ToString().c_str()); + } + // If we already have a child list, then keep using the existing + // list, but still report back that the update was not accepted. + if (endpoint_list_ != nullptr) return args.addresses.status(); + } + // Create new child list, replacing the previous pending list, if any. + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace) && + latest_pending_endpoint_list_ != nullptr) { + gpr_log(GPR_INFO, "[RR %p] replacing previous pending child list %p", this, + latest_pending_endpoint_list_.get()); + } + latest_pending_endpoint_list_ = MakeOrphanable( + Ref(DEBUG_LOCATION, "RoundRobinEndpointList"), std::move(addresses), + args.args); + // If the new list is empty, immediately promote it to + // endpoint_list_ and report TRANSIENT_FAILURE. + // TODO(roth): As part of adding dualstack backend support, we need to + // also handle the case where the list of addresses for a given + // endpoint is empty. + if (latest_pending_endpoint_list_->size() == 0) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace) && + endpoint_list_ != nullptr) { + gpr_log(GPR_INFO, "[RR %p] replacing previous child list %p", this, + endpoint_list_.get()); + } + endpoint_list_ = std::move(latest_pending_endpoint_list_); + absl::Status status = + args.addresses.ok() ? absl::UnavailableError(absl::StrCat( + "empty address list: ", args.resolution_note)) + : args.addresses.status(); + channel_control_helper()->UpdateState( + GRPC_CHANNEL_TRANSIENT_FAILURE, status, + MakeRefCounted(status)); + return status; + } + // Otherwise, if this is the initial update, immediately promote it to + // endpoint_list_. + if (endpoint_list_ == nullptr) { + endpoint_list_ = std::move(latest_pending_endpoint_list_); + } + return absl::OkStatus(); +} + +// +// RoundRobin::RoundRobinEndpointList::RoundRobinEndpoint +// + +void RoundRobin::RoundRobinEndpointList::RoundRobinEndpoint::OnStateUpdate( + absl::optional old_state, + grpc_connectivity_state new_state, const absl::Status& status) { + auto* rr_endpoint_list = endpoint_list(); + auto* round_robin = policy(); + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) { + gpr_log(GPR_INFO, + "[RR %p] connectivity changed for child %p, endpoint_list %p " + "(index %" PRIuPTR " of %" PRIuPTR + "): prev_state=%s new_state=%s " + "(%s)", + round_robin, this, rr_endpoint_list, Index(), + rr_endpoint_list->size(), + (old_state.has_value() ? ConnectivityStateName(*old_state) : "N/A"), + ConnectivityStateName(new_state), status.ToString().c_str()); + } + if (new_state == GRPC_CHANNEL_IDLE) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) { + gpr_log(GPR_INFO, "[RR %p] child %p reported IDLE; requesting connection", + round_robin, this); + } + ExitIdleLocked(); + } + // If state changed, update state counters. + if (!old_state.has_value() || *old_state != new_state) { + rr_endpoint_list->UpdateStateCountersLocked(old_state, new_state); + } + // Update the policy state. + rr_endpoint_list->MaybeUpdateRoundRobinConnectivityStateLocked(status); +} + +// +// RoundRobin::RoundRobinEndpointList +// + +void RoundRobin::RoundRobinEndpointList::UpdateStateCountersLocked( + absl::optional old_state, + grpc_connectivity_state new_state) { + // We treat IDLE the same as CONNECTING, since it will immediately + // transition into that state anyway. + if (old_state.has_value()) { + GPR_ASSERT(*old_state != GRPC_CHANNEL_SHUTDOWN); + if (*old_state == GRPC_CHANNEL_READY) { + GPR_ASSERT(num_ready_ > 0); + --num_ready_; + } else if (*old_state == GRPC_CHANNEL_CONNECTING || + *old_state == GRPC_CHANNEL_IDLE) { + GPR_ASSERT(num_connecting_ > 0); + --num_connecting_; + } else if (*old_state == GRPC_CHANNEL_TRANSIENT_FAILURE) { + GPR_ASSERT(num_transient_failure_ > 0); + --num_transient_failure_; + } + } + GPR_ASSERT(new_state != GRPC_CHANNEL_SHUTDOWN); + if (new_state == GRPC_CHANNEL_READY) { + ++num_ready_; + } else if (new_state == GRPC_CHANNEL_CONNECTING || + new_state == GRPC_CHANNEL_IDLE) { + ++num_connecting_; + } else if (new_state == GRPC_CHANNEL_TRANSIENT_FAILURE) { + ++num_transient_failure_; + } +} + +void RoundRobin::RoundRobinEndpointList:: + MaybeUpdateRoundRobinConnectivityStateLocked(absl::Status status_for_tf) { + auto* round_robin = policy(); + // If this is latest_pending_endpoint_list_, then swap it into + // endpoint_list_ in the following cases: + // - endpoint_list_ has no READY children. + // - This list has at least one READY child and we have seen the + // initial connectivity state notification for all children. + // - All of the children in this list are in TRANSIENT_FAILURE. + // (This may cause the channel to go from READY to TRANSIENT_FAILURE, + // but we're doing what the control plane told us to do.) + if (round_robin->latest_pending_endpoint_list_.get() == this && + (round_robin->endpoint_list_->num_ready_ == 0 || + (num_ready_ > 0 && AllEndpointsSeenInitialState()) || + num_transient_failure_ == size())) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) { + const std::string old_counters_string = + round_robin->endpoint_list_ != nullptr + ? round_robin->endpoint_list_->CountersString() + : ""; + gpr_log(GPR_INFO, + "[RR %p] swapping out child list %p (%s) in favor of %p (%s)", + round_robin, round_robin->endpoint_list_.get(), + old_counters_string.c_str(), this, CountersString().c_str()); + } + round_robin->endpoint_list_ = + std::move(round_robin->latest_pending_endpoint_list_); + } + // Only set connectivity state if this is the current child list. + if (round_robin->endpoint_list_.get() != this) return; + // FIXME: scan children each time instead of keeping counters? + // First matching rule wins: + // 1) ANY child is READY => policy is READY. + // 2) ANY child is CONNECTING => policy is CONNECTING. + // 3) ALL children are TRANSIENT_FAILURE => policy is TRANSIENT_FAILURE. + if (num_ready_ > 0) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) { + gpr_log(GPR_INFO, "[RR %p] reporting READY with child list %p", + round_robin, this); + } + std::vector> pickers; + for (const auto& endpoint : endpoints()) { + auto state = endpoint->connectivity_state(); + if (state.has_value() && *state == GRPC_CHANNEL_READY) { + pickers.push_back(endpoint->picker()); + } + } + GPR_ASSERT(!pickers.empty()); + round_robin->channel_control_helper()->UpdateState( + GRPC_CHANNEL_READY, absl::OkStatus(), + MakeRefCounted(round_robin, std::move(pickers))); + } else if (num_connecting_ > 0) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) { + gpr_log(GPR_INFO, "[RR %p] reporting CONNECTING with child list %p", + round_robin, this); + } + round_robin->channel_control_helper()->UpdateState( + GRPC_CHANNEL_CONNECTING, absl::Status(), + MakeRefCounted(nullptr)); + } else if (num_transient_failure_ == size()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) { + gpr_log(GPR_INFO, + "[RR %p] reporting TRANSIENT_FAILURE with child list %p: %s", + round_robin, this, status_for_tf.ToString().c_str()); + } + if (!status_for_tf.ok()) { + last_failure_ = absl::UnavailableError( + absl::StrCat("connections to all backends failing; last error: ", + status_for_tf.message())); + } + round_robin->channel_control_helper()->UpdateState( + GRPC_CHANNEL_TRANSIENT_FAILURE, last_failure_, + MakeRefCounted(last_failure_)); + } +} + // // factory // @@ -516,6 +897,9 @@ class RoundRobinFactory : public LoadBalancingPolicyFactory { public: OrphanablePtr CreateLoadBalancingPolicy( LoadBalancingPolicy::Args args) const override { + if (!IsRoundRobinDelegateToPickFirstEnabled()) { + return MakeOrphanable(std::move(args)); + } return MakeOrphanable(std::move(args)); } diff --git a/src/core/lib/experiments/experiments.cc b/src/core/lib/experiments/experiments.cc index cad482774fe42..61d87841c08fa 100644 --- a/src/core/lib/experiments/experiments.cc +++ b/src/core/lib/experiments/experiments.cc @@ -105,6 +105,11 @@ const char* const description_jitter_max_idle = "only on max connection age, but it seems like this could smooth out some " "herding problems."; const char* const additional_constraints_jitter_max_idle = "{}"; +const char* const description_round_robin_delegate_to_pick_first = + "Change round_robin code to delegate to pick_first as per dualstack " + "backend design."; +const char* const additional_constraints_round_robin_delegate_to_pick_first = + "{}"; } // namespace namespace grpc_core { @@ -158,6 +163,9 @@ const ExperimentMetadata g_experiment_metadata[] = { additional_constraints_lazier_stream_updates, true, true}, {"jitter_max_idle", description_jitter_max_idle, additional_constraints_jitter_max_idle, true, true}, + {"round_robin_delegate_to_pick_first", + description_round_robin_delegate_to_pick_first, + additional_constraints_round_robin_delegate_to_pick_first, true, true}, }; } // namespace grpc_core @@ -247,6 +255,11 @@ const char* const description_jitter_max_idle = "only on max connection age, but it seems like this could smooth out some " "herding problems."; const char* const additional_constraints_jitter_max_idle = "{}"; +const char* const description_round_robin_delegate_to_pick_first = + "Change round_robin code to delegate to pick_first as per dualstack " + "backend design."; +const char* const additional_constraints_round_robin_delegate_to_pick_first = + "{}"; } // namespace namespace grpc_core { @@ -300,6 +313,9 @@ const ExperimentMetadata g_experiment_metadata[] = { additional_constraints_lazier_stream_updates, true, true}, {"jitter_max_idle", description_jitter_max_idle, additional_constraints_jitter_max_idle, true, true}, + {"round_robin_delegate_to_pick_first", + description_round_robin_delegate_to_pick_first, + additional_constraints_round_robin_delegate_to_pick_first, true, true}, }; } // namespace grpc_core @@ -389,6 +405,11 @@ const char* const description_jitter_max_idle = "only on max connection age, but it seems like this could smooth out some " "herding problems."; const char* const additional_constraints_jitter_max_idle = "{}"; +const char* const description_round_robin_delegate_to_pick_first = + "Change round_robin code to delegate to pick_first as per dualstack " + "backend design."; +const char* const additional_constraints_round_robin_delegate_to_pick_first = + "{}"; } // namespace namespace grpc_core { @@ -442,6 +463,9 @@ const ExperimentMetadata g_experiment_metadata[] = { additional_constraints_lazier_stream_updates, true, true}, {"jitter_max_idle", description_jitter_max_idle, additional_constraints_jitter_max_idle, true, true}, + {"round_robin_delegate_to_pick_first", + description_round_robin_delegate_to_pick_first, + additional_constraints_round_robin_delegate_to_pick_first, true, true}, }; } // namespace grpc_core diff --git a/src/core/lib/experiments/experiments.h b/src/core/lib/experiments/experiments.h index 56251427db95a..f241376d9ec57 100644 --- a/src/core/lib/experiments/experiments.h +++ b/src/core/lib/experiments/experiments.h @@ -87,6 +87,8 @@ inline bool IsKeepaliveServerFixEnabled() { return false; } inline bool IsLazierStreamUpdatesEnabled() { return true; } #define GRPC_EXPERIMENT_IS_INCLUDED_JITTER_MAX_IDLE inline bool IsJitterMaxIdleEnabled() { return true; } +#define GRPC_EXPERIMENT_IS_INCLUDED_ROUND_ROBIN_DELEGATE_TO_PICK_FIRST +inline bool IsRoundRobinDelegateToPickFirstEnabled() { return true; } #elif defined(GPR_WINDOWS) inline bool IsTcpFrameSizeTuningEnabled() { return false; } @@ -117,6 +119,8 @@ inline bool IsKeepaliveServerFixEnabled() { return false; } inline bool IsLazierStreamUpdatesEnabled() { return true; } #define GRPC_EXPERIMENT_IS_INCLUDED_JITTER_MAX_IDLE inline bool IsJitterMaxIdleEnabled() { return true; } +#define GRPC_EXPERIMENT_IS_INCLUDED_ROUND_ROBIN_DELEGATE_TO_PICK_FIRST +inline bool IsRoundRobinDelegateToPickFirstEnabled() { return true; } #else inline bool IsTcpFrameSizeTuningEnabled() { return false; } @@ -147,6 +151,8 @@ inline bool IsKeepaliveServerFixEnabled() { return false; } inline bool IsLazierStreamUpdatesEnabled() { return true; } #define GRPC_EXPERIMENT_IS_INCLUDED_JITTER_MAX_IDLE inline bool IsJitterMaxIdleEnabled() { return true; } +#define GRPC_EXPERIMENT_IS_INCLUDED_ROUND_ROBIN_DELEGATE_TO_PICK_FIRST +inline bool IsRoundRobinDelegateToPickFirstEnabled() { return true; } #endif #else @@ -202,8 +208,12 @@ inline bool IsKeepaliveServerFixEnabled() { return IsExperimentEnabled(20); } inline bool IsLazierStreamUpdatesEnabled() { return IsExperimentEnabled(21); } #define GRPC_EXPERIMENT_IS_INCLUDED_JITTER_MAX_IDLE inline bool IsJitterMaxIdleEnabled() { return IsExperimentEnabled(22); } +#define GRPC_EXPERIMENT_IS_INCLUDED_ROUND_ROBIN_DELEGATE_TO_PICK_FIRST +inline bool IsRoundRobinDelegateToPickFirstEnabled() { + return IsExperimentEnabled(23); +} -constexpr const size_t kNumExperiments = 23; +constexpr const size_t kNumExperiments = 24; extern const ExperimentMetadata g_experiment_metadata[kNumExperiments]; #endif diff --git a/src/core/lib/experiments/experiments.yaml b/src/core/lib/experiments/experiments.yaml index af6e4b4a6db9c..992a3e99415ee 100644 --- a/src/core/lib/experiments/experiments.yaml +++ b/src/core/lib/experiments/experiments.yaml @@ -185,3 +185,10 @@ owner: ctiller@google.com test_tags: [] allow_in_fuzzing_config: true +- name: round_robin_delegate_to_pick_first + description: + Change round_robin code to delegate to pick_first as per dualstack + backend design. + expiry: 2023/11/15 + owner: roth@google.com + test_tags: ["cpp_lb_end2end_test", "xds_end2end_test"] diff --git a/src/core/lib/experiments/rollouts.yaml b/src/core/lib/experiments/rollouts.yaml index 77df5ad282e24..f1770b22fae88 100644 --- a/src/core/lib/experiments/rollouts.yaml +++ b/src/core/lib/experiments/rollouts.yaml @@ -94,3 +94,5 @@ default: true - name: jitter_max_idle default: true +- name: round_robin_delegate_to_pick_first + default: true diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 59259c5885022..80f1628e13e86 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -33,6 +33,7 @@ 'src/core/ext/filters/client_channel/http_proxy_mapper.cc', 'src/core/ext/filters/client_channel/lb_policy/address_filtering.cc', 'src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc', + 'src/core/ext/filters/client_channel/lb_policy/endpoint_list.cc', 'src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc', diff --git a/test/core/client_channel/lb_policy/outlier_detection_test.cc b/test/core/client_channel/lb_policy/outlier_detection_test.cc index ea3c0a477c2cf..597bfabb8e62f 100644 --- a/test/core/client_channel/lb_policy/outlier_detection_test.cc +++ b/test/core/client_channel/lb_policy/outlier_detection_test.cc @@ -229,8 +229,6 @@ TEST_F(OutlierDetectionTest, FailurePercentage) { time_cache_.IncrementBy(Duration::Seconds(10)); RunTimerCallback(); gpr_log(GPR_INFO, "### ejection complete"); - // Expect a re-resolution request. - ExpectReresolutionRequest(); // Expect a picker update. std::vector remaining_addresses; for (const auto& addr : kAddresses) { diff --git a/test/core/client_channel/lb_policy/round_robin_test.cc b/test/core/client_channel/lb_policy/round_robin_test.cc index ef82ceadebfaa..092242e66f3d3 100644 --- a/test/core/client_channel/lb_policy/round_robin_test.cc +++ b/test/core/client_channel/lb_policy/round_robin_test.cc @@ -42,8 +42,6 @@ class RoundRobinTest : public LoadBalancingPolicyTest { void ExpectStartup(absl::Span addresses) { EXPECT_EQ(ApplyUpdate(BuildUpdate(addresses, nullptr), lb_policy_.get()), absl::OkStatus()); - // Expect the initial CONNECTNG update with a picker that queues. - ExpectConnectingUpdate(); // RR should have created a subchannel for each address. for (size_t i = 0; i < addresses.size(); ++i) { auto* subchannel = FindSubchannel(addresses[i]); @@ -52,6 +50,8 @@ class RoundRobinTest : public LoadBalancingPolicyTest { EXPECT_TRUE(subchannel->ConnectionRequested()); // The subchannel will connect successfully. subchannel->SetConnectivityState(GRPC_CHANNEL_CONNECTING); + // Expect the initial CONNECTNG update with a picker that queues. + if (i == 0) ExpectConnectingUpdate(); subchannel->SetConnectivityState(GRPC_CHANNEL_READY); // As each subchannel becomes READY, we should get a new picker that // includes the behavior. Note that there may be any number of diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD index 69b01b60d64b4..197f5126b55e1 100644 --- a/test/cpp/end2end/BUILD +++ b/test/cpp/end2end/BUILD @@ -513,6 +513,7 @@ grpc_cc_test( flaky = True, # TODO(b/151315347) tags = [ "cpp_end2end_test", + "cpp_lb_end2end_test", "no_windows", ], # TODO(jtattermusch): fix test on windows deps = [ @@ -597,6 +598,7 @@ grpc_cc_test( flaky = True, # TODO(b/150567713) tags = [ "cpp_end2end_test", + "cpp_lb_end2end_test", "no_windows", ], # TODO(jtattermusch): fix test on windows deps = [ diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index 3dd450b673c5a..1674757118b98 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -56,6 +56,7 @@ #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/config/config_vars.h" +#include "src/core/lib/experiments/experiments.h" #include "src/core/lib/gprpp/crash.h" #include "src/core/lib/gprpp/debug_location.h" #include "src/core/lib/gprpp/env.h" @@ -2055,10 +2056,15 @@ TEST_F(RoundRobinTest, HealthChecking) { servers_[1]->SetServingStatus("health_check_service_name", false); servers_[2]->SetServingStatus("health_check_service_name", false); EXPECT_TRUE(WaitForChannelNotReady(channel.get())); - CheckRpcSendFailure(DEBUG_LOCATION, stub, StatusCode::UNAVAILABLE, - "connections to all backends failing; last error: " - "UNAVAILABLE: (ipv6:%5B::1%5D|ipv4:127.0.0.1):[0-9]+: " - "backend unhealthy"); + CheckRpcSendFailure( + DEBUG_LOCATION, stub, StatusCode::UNAVAILABLE, + grpc_core::IsRoundRobinDelegateToPickFirstEnabled() + ? "connections to all backends failing; last error: " + "(ipv6:%5B::1%5D|ipv4:127.0.0.1):[0-9]+: " + "backend unhealthy" + : "connections to all backends failing; last error: " + "UNAVAILABLE: (ipv6:%5B::1%5D|ipv4:127.0.0.1):[0-9]+: " + "backend unhealthy"); // Clean up. EnableDefaultHealthCheckService(false); } @@ -2114,10 +2120,15 @@ TEST_F(RoundRobinTest, WithHealthCheckingInhibitPerChannel) { // First channel should not become READY, because health checks should be // failing. EXPECT_FALSE(WaitForChannelReady(channel1.get(), 1)); - CheckRpcSendFailure(DEBUG_LOCATION, stub1, StatusCode::UNAVAILABLE, - "connections to all backends failing; last error: " - "UNAVAILABLE: (ipv6:%5B::1%5D|ipv4:127.0.0.1):[0-9]+: " - "backend unhealthy"); + CheckRpcSendFailure( + DEBUG_LOCATION, stub1, StatusCode::UNAVAILABLE, + grpc_core::IsRoundRobinDelegateToPickFirstEnabled() + ? "connections to all backends failing; last error: " + "(ipv6:%5B::1%5D|ipv4:127.0.0.1):[0-9]+: " + "backend unhealthy" + : "connections to all backends failing; last error: " + "UNAVAILABLE: (ipv6:%5B::1%5D|ipv4:127.0.0.1):[0-9]+: " + "backend unhealthy"); // Second channel should be READY. EXPECT_TRUE(WaitForChannelReady(channel2.get(), 1)); CheckRpcSendOk(DEBUG_LOCATION, stub2); @@ -2160,10 +2171,15 @@ TEST_F(RoundRobinTest, HealthCheckingServiceNamePerChannel) { // First channel should not become READY, because health checks should be // failing. EXPECT_FALSE(WaitForChannelReady(channel1.get(), 1)); - CheckRpcSendFailure(DEBUG_LOCATION, stub1, StatusCode::UNAVAILABLE, - "connections to all backends failing; last error: " - "UNAVAILABLE: (ipv6:%5B::1%5D|ipv4:127.0.0.1):[0-9]+: " - "backend unhealthy"); + CheckRpcSendFailure( + DEBUG_LOCATION, stub1, StatusCode::UNAVAILABLE, + grpc_core::IsRoundRobinDelegateToPickFirstEnabled() + ? "connections to all backends failing; last error: " + "(ipv6:%5B::1%5D|ipv4:127.0.0.1):[0-9]+: " + "backend unhealthy" + : "connections to all backends failing; last error: " + "UNAVAILABLE: (ipv6:%5B::1%5D|ipv4:127.0.0.1):[0-9]+: " + "backend unhealthy"); // Second channel should be READY. EXPECT_TRUE(WaitForChannelReady(channel2.get(), 1)); CheckRpcSendOk(DEBUG_LOCATION, stub2); diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index c27cf5780a00b..771a3471091a6 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -1114,6 +1114,8 @@ src/core/ext/filters/client_channel/lb_policy/address_filtering.h \ src/core/ext/filters/client_channel/lb_policy/backend_metric_data.h \ src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc \ src/core/ext/filters/client_channel/lb_policy/child_policy_handler.h \ +src/core/ext/filters/client_channel/lb_policy/endpoint_list.cc \ +src/core/ext/filters/client_channel/lb_policy/endpoint_list.h \ src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc \ src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h \ src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 76f0add5f7387..038c92baf2bf4 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -920,6 +920,8 @@ src/core/ext/filters/client_channel/lb_policy/address_filtering.h \ src/core/ext/filters/client_channel/lb_policy/backend_metric_data.h \ src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc \ src/core/ext/filters/client_channel/lb_policy/child_policy_handler.h \ +src/core/ext/filters/client_channel/lb_policy/endpoint_list.cc \ +src/core/ext/filters/client_channel/lb_policy/endpoint_list.h \ src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc \ src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h \ src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc \