Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix. stats manager may cause crash when stats with new labels. #5933

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 45 additions & 23 deletions src/common/stats/StatsManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,18 +177,24 @@ CounterId StatsManager::counterWithLabels(const CounterId& id,
}
newIndex.back() = '}';

auto it = sm.nameMap_.find(newIndex);
// Get the counter if it already exists
if (it != sm.nameMap_.end()) {
return it->second.id_;
}

// Register a new counter if it doesn't exist
auto it2 = sm.nameMap_.find(index);
DCHECK(it2 != sm.nameMap_.end());
auto& methods = it2->second.methods_;

return registerStats(newIndex, methods);
std::vector<StatsMethod> methods;
{
folly::RWSpinLock::ReadHolder rh(sm.nameMapLock_);
// Check if the counter already exists
auto it = sm.nameMap_.find(newIndex);
if (it != sm.nameMap_.end()) {
// fast path if the counter already exists
return it->second.id_;
}

// Register a new counter if it doesn't exist
// Fetch the counter indexed by the parent index and get the methods
auto it2 = sm.nameMap_.find(index);
DCHECK(it2 != sm.nameMap_.end());
methods = it2->second.methods_;
}

return registerStats(newIndex, *methods);
}

// static
Expand All @@ -205,19 +211,35 @@ CounterId StatsManager::histoWithLabels(const CounterId& id, const std::vector<L
newIndex.append(k).append("=").append(v).append(",");
}
newIndex.back() = '}';
auto it = sm.nameMap_.find(newIndex);
// Get the counter if it already exists
if (it != sm.nameMap_.end()) {
return it->second.id_;
}

auto it2 = sm.nameMap_.find(index);
DCHECK(it2 != sm.nameMap_.end());
auto& methods = it2->second.methods_;
auto& percentiles = it2->second.percentiles_;
std::vector<StatsMethod> methods;
std::vector<std::pair<std::string, double>> percentiles;
StatsManager::VT bucketSize, min, max;
{
folly::RWSpinLock::ReadHolder rh(sm.nameMapLock_);
// Check if the counter already exists
auto it = sm.nameMap_.find(newIndex);
if (it != sm.nameMap_.end()) {
// fast path if the counter already exists
return it->second.id_;
}
// Register a new counter if it doesn't exist
// Fetch the counter indexed by the parent index and get the methods
auto it2 = sm.nameMap_.find(index);
DCHECK(it2 != sm.nameMap_.end());
methods = it2->second.methods_;
percentiles = it2->second.percentiles_;
bucketSize = it2->second.bucketSize_;
min = it2->second.min_;
max = it2->second.max_;
}

return registerHisto(
newIndex, it2->second.bucketSize_, it2->second.min_, it2->second.max_, methods, percentiles);
return registerHisto(/* counterName */ newIndex,
/* bucketSize */ bucketSize,
/* min */ min,
/* max */ max,
/* methods */ *methods,
/* percentiles */ *percentiles);
}

// static
Expand Down
30 changes: 30 additions & 0 deletions src/common/stats/test/StatsManagerTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,36 @@ TEST(StatsManager, ReadAllTest) {
EXPECT_FALSE(counterExists(stats2, "stat04{space=test}.p95.5", val));
}

TEST(StatsManager, ConcurrentCountWithLabelTest) {
auto statId = StatsManager::registerStats("stat06", "RATE, sum");
std::vector<std::thread> threads;
for (int i = 0; i < 257; i++) {
std::string spaceName = folly::stringPrintf("space%d", i);
threads.emplace_back([&statId, &spaceName]() {
auto counterId = StatsManager::counterWithLabels(statId, {{"space", spaceName}});
});
}

for (auto& t : threads) {
t.join();
}
}

TEST(StatsManager, ConcurrentHistoWithLabelTest) {
auto statId = StatsManager::registerHisto("stat07", 1, 1, 100, "sum, p95, p99");
std::vector<std::thread> threads;
for (int i = 0; i < 257; i++) {
std::string spaceName = folly::stringPrintf("space%d", i);
threads.emplace_back([&statId, &spaceName]() {
auto histoId = StatsManager::histoWithLabels(statId, {{"space", spaceName}});
});
}

for (auto& t : threads) {
t.join();
}
}

} // namespace stats
} // namespace nebula

Expand Down