diff --git a/src/core/telemetry/metrics.h b/src/core/telemetry/metrics.h index 7cbd7fc55c2c7..06132b00009cc 100644 --- a/src/core/telemetry/metrics.h +++ b/src/core/telemetry/metrics.h @@ -446,6 +446,8 @@ class GlobalStatsPluginRegistry { return false; } + size_t size() const { return plugins_state_.size(); } + // Registers a callback to be used to populate callback metrics. // The callback will update the specified metrics. The callback // will be invoked no more often than min_interval. Multiple callbacks may diff --git a/test/core/telemetry/metrics_test.cc b/test/core/telemetry/metrics_test.cc index ad139096e14de..106205a118021 100644 --- a/test/core/telemetry/metrics_test.cc +++ b/test/core/telemetry/metrics_test.cc @@ -15,6 +15,7 @@ #include "src/core/telemetry/metrics.h" #include +#include #include "absl/log/log.h" #include "gmock/gmock.h" @@ -648,6 +649,38 @@ TEST_F(MetricsTest, FindInstrumentByName) { ::testing::Eq(uint64_counter_handle.index)))); } +TEST_F(MetricsTest, ParallelStatsPluginRegistrationAndLookup) { + std::vector register_threads; + std::vector lookup_threads; + register_threads.reserve(100); + lookup_threads.reserve(100); + // 100 threads that register 100 stats plugins each + for (int i = 0; i < 100; ++i) { + register_threads.emplace_back([] { + for (int j = 0; j < 100; ++j) { + grpc_core::FakeStatsPluginBuilder().BuildAndRegister(); + } + }); + } + // 100 threads that keep looking up stats plugins till they see 10000 stats + // plugins + for (int i = 0; i < 100; ++i) { + lookup_threads.emplace_back([this] { + while (GlobalStatsPluginRegistry::GetStatsPluginsForChannel( + StatsPluginChannelScope("", "", endpoint_config_)) + .size() < 10000) { + }; + }); + } + for (int i = 0; i < 100; ++i) { + register_threads[i].join(); + lookup_threads[i].join(); + } + EXPECT_THAT(GlobalStatsPluginRegistry::GetStatsPluginsForChannel( + StatsPluginChannelScope("", "", endpoint_config_)), + ::testing::SizeIs(10000)); +} + using MetricsDeathTest = MetricsTest; TEST_F(MetricsDeathTest, RegisterTheSameMetricNameWouldCrash) {