diff options
author | Alexander Rutkovsky <alexvru@mail.ru> | 2022-02-10 16:47:39 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:47:39 +0300 |
commit | f3646f91e0de459836a7800b9ce3e8dc57a2ab3a (patch) | |
tree | 25c1423200152570c1f8307e5b8304b9bc3840c5 /library/cpp/monlib/dynamic_counters | |
parent | fccc62e9bfdce9be2fe7e0f23479da3a5512211a (diff) | |
download | ydb-f3646f91e0de459836a7800b9ce3e8dc57a2ab3a.tar.gz |
Restoring authorship annotation for Alexander Rutkovsky <alexvru@mail.ru>. Commit 1 of 2.
Diffstat (limited to 'library/cpp/monlib/dynamic_counters')
-rw-r--r-- | library/cpp/monlib/dynamic_counters/contention_ut.cpp | 110 | ||||
-rw-r--r-- | library/cpp/monlib/dynamic_counters/counters.cpp | 152 | ||||
-rw-r--r-- | library/cpp/monlib/dynamic_counters/counters.h | 98 | ||||
-rw-r--r-- | library/cpp/monlib/dynamic_counters/ut/ya.make | 2 |
4 files changed, 181 insertions, 181 deletions
diff --git a/library/cpp/monlib/dynamic_counters/contention_ut.cpp b/library/cpp/monlib/dynamic_counters/contention_ut.cpp index 8798044ee3..eac30069a6 100644 --- a/library/cpp/monlib/dynamic_counters/contention_ut.cpp +++ b/library/cpp/monlib/dynamic_counters/contention_ut.cpp @@ -1,61 +1,61 @@ -#include "counters.h" +#include "counters.h" #include <library/cpp/testing/unittest/registar.h> -#include <util/system/event.h> -#include <util/system/thread.h> - -using namespace NMonitoring; - -Y_UNIT_TEST_SUITE(TDynamicCountersContentionTest) { - - Y_UNIT_TEST(EnsureNonlocking) { - TDynamicCounterPtr counters = MakeIntrusive<TDynamicCounters>(); - - class TConsumer : public ICountableConsumer { - TAutoEvent Ev; - TAutoEvent Response; - TDynamicCounterPtr Counters; - TThread Thread; - - public: - TConsumer(TDynamicCounterPtr counters) - : Counters(counters) - , Thread(std::bind(&TConsumer::ThreadFunc, this)) - { - Thread.Start(); - } - +#include <util/system/event.h> +#include <util/system/thread.h> + +using namespace NMonitoring; + +Y_UNIT_TEST_SUITE(TDynamicCountersContentionTest) { + + Y_UNIT_TEST(EnsureNonlocking) { + TDynamicCounterPtr counters = MakeIntrusive<TDynamicCounters>(); + + class TConsumer : public ICountableConsumer { + TAutoEvent Ev; + TAutoEvent Response; + TDynamicCounterPtr Counters; + TThread Thread; + + public: + TConsumer(TDynamicCounterPtr counters) + : Counters(counters) + , Thread(std::bind(&TConsumer::ThreadFunc, this)) + { + Thread.Start(); + } + ~TConsumer() override { - Thread.Join(); - } - + Thread.Join(); + } + void OnCounter(const TString& /*labelName*/, const TString& /*labelValue*/, const TCounterForPtr* /*counter*/) override { - Ev.Signal(); - Response.Wait(); - } - + Ev.Signal(); + Response.Wait(); + } + void OnHistogram(const TString& /*labelName*/, const TString& /*labelValue*/, IHistogramSnapshotPtr /*snapshot*/, bool /*derivative*/) override { - } - + } + void OnGroupBegin(const TString& /*labelName*/, const TString& /*labelValue*/, const TDynamicCounters* /*group*/) override { - } - + } + void OnGroupEnd(const TString& /*labelName*/, const TString& /*labelValue*/, const TDynamicCounters* /*group*/) override { - } - - private: - void ThreadFunc() { - // acts like a coroutine - Ev.Wait(); - auto ctr = Counters->GetSubgroup("label", "value")->GetCounter("name"); - Y_VERIFY(*ctr == 42); - Response.Signal(); - } - }; - - auto ctr = counters->GetSubgroup("label", "value")->GetCounter("name"); - *ctr = 42; - TConsumer consumer(counters); - counters->Accept({}, {}, consumer); - } - -} + } + + private: + void ThreadFunc() { + // acts like a coroutine + Ev.Wait(); + auto ctr = Counters->GetSubgroup("label", "value")->GetCounter("name"); + Y_VERIFY(*ctr == 42); + Response.Signal(); + } + }; + + auto ctr = counters->GetSubgroup("label", "value")->GetCounter("name"); + *ctr = 42; + TConsumer consumer(counters); + counters->Accept({}, {}, consumer); + } + +} diff --git a/library/cpp/monlib/dynamic_counters/counters.cpp b/library/cpp/monlib/dynamic_counters/counters.cpp index 3635d87d0d..04003d28a5 100644 --- a/library/cpp/monlib/dynamic_counters/counters.cpp +++ b/library/cpp/monlib/dynamic_counters/counters.cpp @@ -107,66 +107,66 @@ void TDynamicCounters::RemoveCounter(const TString &value) { } void TDynamicCounters::RemoveNamedCounter(const TString& name, const TString &value) { - auto g = LockForUpdate("RemoveNamedCounter", name, value); - if (const auto it = Counters.find({name, value}); it != Counters.end() && AsCounter(it->second)) { + auto g = LockForUpdate("RemoveNamedCounter", name, value); + if (const auto it = Counters.find({name, value}); it != Counters.end() && AsCounter(it->second)) { Counters.erase(it); } } TIntrusivePtr<TDynamicCounters> TDynamicCounters::GetSubgroup(const TString& name, const TString& value) { - auto res = FindSubgroup(name, value); - if (!res) { - auto g = LockForUpdate("GetSubgroup", name, value); - const TChildId key(name, value); - if (const auto it = Counters.lower_bound(key); it != Counters.end() && it->first == key) { - res = AsGroupRef(it->second); - } else { - res = MakeIntrusive<TDynamicCounters>(this); - Counters.emplace_hint(it, key, res); - } + auto res = FindSubgroup(name, value); + if (!res) { + auto g = LockForUpdate("GetSubgroup", name, value); + const TChildId key(name, value); + if (const auto it = Counters.lower_bound(key); it != Counters.end() && it->first == key) { + res = AsGroupRef(it->second); + } else { + res = MakeIntrusive<TDynamicCounters>(this); + Counters.emplace_hint(it, key, res); + } } - return res; + return res; } TIntrusivePtr<TDynamicCounters> TDynamicCounters::FindSubgroup(const TString& name, const TString& value) const { - TReadGuard g(Lock); - const auto it = Counters.find({name, value}); - return it != Counters.end() ? AsDynamicCounters(it->second) : nullptr; + TReadGuard g(Lock); + const auto it = Counters.find({name, value}); + return it != Counters.end() ? AsDynamicCounters(it->second) : nullptr; } void TDynamicCounters::RemoveSubgroup(const TString& name, const TString& value) { - auto g = LockForUpdate("RemoveSubgroup", name, value); - if (const auto it = Counters.find({name, value}); it != Counters.end() && AsDynamicCounters(it->second)) { + auto g = LockForUpdate("RemoveSubgroup", name, value); + if (const auto it = Counters.find({name, value}); it != Counters.end() && AsDynamicCounters(it->second)) { Counters.erase(it); } } -void TDynamicCounters::ReplaceSubgroup(const TString& name, const TString& value, TIntrusivePtr<TDynamicCounters> subgroup) { - auto g = LockForUpdate("ReplaceSubgroup", name, value); - const auto it = Counters.find({name, value}); - Y_VERIFY(it != Counters.end() && AsDynamicCounters(it->second)); - it->second = std::move(subgroup); +void TDynamicCounters::ReplaceSubgroup(const TString& name, const TString& value, TIntrusivePtr<TDynamicCounters> subgroup) { + auto g = LockForUpdate("ReplaceSubgroup", name, value); + const auto it = Counters.find({name, value}); + Y_VERIFY(it != Counters.end() && AsDynamicCounters(it->second)); + it->second = std::move(subgroup); } void TDynamicCounters::MergeWithSubgroup(const TString& name, const TString& value) { - auto g = LockForUpdate("MergeWithSubgroup", name, value); - auto it = Counters.find({name, value}); - Y_VERIFY(it != Counters.end()); - TIntrusivePtr<TDynamicCounters> subgroup = AsDynamicCounters(it->second); + auto g = LockForUpdate("MergeWithSubgroup", name, value); + auto it = Counters.find({name, value}); + Y_VERIFY(it != Counters.end()); + TIntrusivePtr<TDynamicCounters> subgroup = AsDynamicCounters(it->second); Y_VERIFY(subgroup); - Counters.erase(it); - Counters.merge(subgroup->Resign()); - AtomicAdd(ExpiringCount, AtomicSwap(&subgroup->ExpiringCount, 0)); + Counters.erase(it); + Counters.merge(subgroup->Resign()); + AtomicAdd(ExpiringCount, AtomicSwap(&subgroup->ExpiringCount, 0)); } void TDynamicCounters::ResetCounters(bool derivOnly) { - TReadGuard g(Lock); - for (auto& [key, value] : Counters) { - if (auto counter = AsCounter(value)) { - if (!derivOnly || counter->ForDerivative()) { + TReadGuard g(Lock); + for (auto& [key, value] : Counters) { + if (auto counter = AsCounter(value)) { + if (!derivOnly || counter->ForDerivative()) { *counter = 0; - } - } else if (auto subgroup = AsDynamicCounters(value)) { + } + } else if (auto subgroup = AsDynamicCounters(value)) { subgroup->ResetCounters(derivOnly); } } @@ -174,9 +174,9 @@ void TDynamicCounters::ResetCounters(bool derivOnly) { void TDynamicCounters::RegisterCountable(const TString& name, const TString& value, TCountablePtr countable) { Y_VERIFY(countable); - auto g = LockForUpdate("RegisterCountable", name, value); - const bool inserted = Counters.emplace(TChildId(name, value), std::move(countable)).second; - Y_VERIFY(inserted); + auto g = LockForUpdate("RegisterCountable", name, value); + const bool inserted = Counters.emplace(TChildId(name, value), std::move(countable)).second; + Y_VERIFY(inserted); } void TDynamicCounters::RegisterSubgroup(const TString& name, const TString& value, TIntrusivePtr<TDynamicCounters> subgroup) { @@ -192,31 +192,31 @@ void TDynamicCounters::OutputHtml(IOutputStream& os) const { } void TDynamicCounters::EnumerateSubgroups(const std::function<void(const TString& name, const TString& value)>& output) const { - TReadGuard g(Lock); - for (const auto& [key, value] : Counters) { - if (AsDynamicCounters(value)) { - output(key.LabelName, key.LabelValue); - } - } + TReadGuard g(Lock); + for (const auto& [key, value] : Counters) { + if (AsDynamicCounters(value)) { + output(key.LabelName, key.LabelValue); + } + } } void TDynamicCounters::OutputPlainText(IOutputStream& os, const TString& indent) const { - auto snap = ReadSnapshot(); + auto snap = ReadSnapshot(); // mark private records in plain text output auto outputVisibilityMarker = [] (EVisibility vis) { return vis == EVisibility::Private ? "\t[PRIVATE]" : ""; }; - for (const auto& [key, value] : snap) { - if (const auto counter = AsCounter(value)) { + for (const auto& [key, value] : snap) { + if (const auto counter = AsCounter(value)) { os << indent - << key.LabelName << '=' << key.LabelValue + << key.LabelName << '=' << key.LabelValue << ": " << counter->Val() << outputVisibilityMarker(counter->Visibility()) << '\n'; - } else if (const auto histogram = AsHistogram(value)) { + } else if (const auto histogram = AsHistogram(value)) { os << indent - << key.LabelName << '=' << key.LabelValue + << key.LabelName << '=' << key.LabelValue << ":" << outputVisibilityMarker(histogram->Visibility()) << "\n"; @@ -235,10 +235,10 @@ void TDynamicCounters::OutputPlainText(IOutputStream& os, const TString& indent) } } - for (const auto& [key, value] : snap) { - if (const auto subgroup = AsDynamicCounters(value)) { + for (const auto& [key, value] : snap) { + if (const auto subgroup = AsDynamicCounters(value)) { os << "\n"; - os << indent << key.LabelName << "=" << key.LabelValue << ":\n"; + os << indent << key.LabelName << "=" << key.LabelValue << ":\n"; subgroup->OutputPlainText(os, indent + INDENT); } } @@ -250,50 +250,50 @@ void TDynamicCounters::Accept(const TString& labelName, const TString& labelValu } consumer.OnGroupBegin(labelName, labelValue, this); - for (auto& [key, value] : ReadSnapshot()) { - value->Accept(key.LabelName, key.LabelValue, consumer); + for (auto& [key, value] : ReadSnapshot()) { + value->Accept(key.LabelName, key.LabelValue, consumer); } consumer.OnGroupEnd(labelName, labelValue, this); } void TDynamicCounters::RemoveExpired() const { - if (AtomicGet(ExpiringCount) == 0) { + if (AtomicGet(ExpiringCount) == 0) { return; } - TWriteGuard g(Lock); - TAtomicBase count = 0; - + TWriteGuard g(Lock); + TAtomicBase count = 0; + for (auto it = Counters.begin(); it != Counters.end();) { if (IsExpiringCounter(it->second) && it->second->RefCount() == 1) { it = Counters.erase(it); - ++count; + ++count; } else { ++it; } } - - AtomicSub(ExpiringCount, count); + + AtomicSub(ExpiringCount, count); } template <bool expiring, class TCounterType, class... TArgs> TDynamicCounters::TCountablePtr TDynamicCounters::GetNamedCounterImpl(const TString& name, const TString& value, TArgs&&... args) { - { - TReadGuard g(Lock); - auto it = Counters.find({name, value}); - if (it != Counters.end()) { - return it->second; - } + { + TReadGuard g(Lock); + auto it = Counters.find({name, value}); + if (it != Counters.end()) { + return it->second; + } } - auto g = LockForUpdate("GetNamedCounterImpl", name, value); - const TChildId key(name, value); - auto it = Counters.lower_bound(key); - if (it == Counters.end() || it->first != key) { - auto value = MakeIntrusive<TCounterType>(std::forward<TArgs>(args)...); - it = Counters.emplace_hint(it, key, value); + auto g = LockForUpdate("GetNamedCounterImpl", name, value); + const TChildId key(name, value); + auto it = Counters.lower_bound(key); + if (it == Counters.end() || it->first != key) { + auto value = MakeIntrusive<TCounterType>(std::forward<TArgs>(args)...); + it = Counters.emplace_hint(it, key, value); if constexpr (expiring) { - AtomicIncrement(ExpiringCount); + AtomicIncrement(ExpiringCount); } } return it->second; diff --git a/library/cpp/monlib/dynamic_counters/counters.h b/library/cpp/monlib/dynamic_counters/counters.h index dc178cfbe0..7f9b776645 100644 --- a/library/cpp/monlib/dynamic_counters/counters.h +++ b/library/cpp/monlib/dynamic_counters/counters.h @@ -5,12 +5,12 @@ #include <library/cpp/threading/light_rw_lock/lightrwlock.h> #include <library/cpp/containers/stack_vector/stack_vec.h> - + #include <util/generic/cast.h> #include <util/generic/map.h> #include <util/generic/ptr.h> #include <util/string/cast.h> -#include <util/system/rwlock.h> +#include <util/system/rwlock.h> #include <functional> @@ -194,7 +194,7 @@ namespace NMonitoring { using TOnLookupPtr = void (*)(const char *methodName, const TString &name, const TString &value); private: - TRWMutex Lock; + TRWMutex Lock; TCounterPtr LookupCounter; // Counts lookups by name TOnLookupPtr OnLookup = nullptr; // Called on each lookup if not nullptr, intended for lightweight tracing. @@ -210,66 +210,66 @@ namespace NMonitoring { , LabelValue(labelValue) { } - auto AsTuple() const { - return std::make_tuple(std::cref(LabelName), std::cref(LabelValue)); - } - friend bool operator <(const TChildId& x, const TChildId& y) { - return x.AsTuple() < y.AsTuple(); - } - friend bool operator ==(const TChildId& x, const TChildId& y) { - return x.AsTuple() == y.AsTuple(); - } - friend bool operator !=(const TChildId& x, const TChildId& y) { - return x.AsTuple() != y.AsTuple(); + auto AsTuple() const { + return std::make_tuple(std::cref(LabelName), std::cref(LabelValue)); } + friend bool operator <(const TChildId& x, const TChildId& y) { + return x.AsTuple() < y.AsTuple(); + } + friend bool operator ==(const TChildId& x, const TChildId& y) { + return x.AsTuple() == y.AsTuple(); + } + friend bool operator !=(const TChildId& x, const TChildId& y) { + return x.AsTuple() != y.AsTuple(); + } }; - using TCounters = TMap<TChildId, TCountablePtr>; + using TCounters = TMap<TChildId, TCountablePtr>; using TLabels = TVector<TChildId>; /// XXX: hack for deferred removal of expired counters. Remove once Output* functions are not used for serialization mutable TCounters Counters; - mutable TAtomic ExpiringCount = 0; + mutable TAtomic ExpiringCount = 0; public: TDynamicCounters(TCountableBase::EVisibility visibility = TCountableBase::EVisibility::Public); - - TDynamicCounters(const TDynamicCounters *origin) - : LookupCounter(origin->LookupCounter) - , OnLookup(origin->OnLookup) - {} - + + TDynamicCounters(const TDynamicCounters *origin) + : LookupCounter(origin->LookupCounter) + , OnLookup(origin->OnLookup) + {} + ~TDynamicCounters() override; // This counter allows to track lookups by name within the whole subtree void SetLookupCounter(TCounterPtr lookupCounter) { - TWriteGuard g(Lock); + TWriteGuard g(Lock); LookupCounter = lookupCounter; } void SetOnLookup(TOnLookupPtr onLookup) { - TWriteGuard g(Lock); + TWriteGuard g(Lock); OnLookup = onLookup; } - TWriteGuard LockForUpdate(const char *method, const TString& name, const TString& value) { - auto res = TWriteGuard(Lock); - if (LookupCounter) { - ++*LookupCounter; - } - if (OnLookup) { - OnLookup(method, name, value); - } - return res; - } - - TStackVec<TCounters::value_type, 256> ReadSnapshot() const { - RemoveExpired(); - TReadGuard g(Lock); - TStackVec<TCounters::value_type, 256> items(Counters.begin(), Counters.end()); - return items; - } - + TWriteGuard LockForUpdate(const char *method, const TString& name, const TString& value) { + auto res = TWriteGuard(Lock); + if (LookupCounter) { + ++*LookupCounter; + } + if (OnLookup) { + OnLookup(method, name, value); + } + return res; + } + + TStackVec<TCounters::value_type, 256> ReadSnapshot() const { + RemoveExpired(); + TReadGuard g(Lock); + TStackVec<TCounters::value_type, 256> items(Counters.begin(), Counters.end()); + return items; + } + TCounterPtr GetCounter( const TString& value, bool derivative = false, @@ -354,13 +354,13 @@ namespace NMonitoring { ICountableConsumer& consumer) const override; private: - TCounters Resign() { - TCounters counters; - TWriteGuard g(Lock); - Counters.swap(counters); - return counters; - } - + TCounters Resign() { + TCounters counters; + TWriteGuard g(Lock); + Counters.swap(counters); + return counters; + } + void RegisterCountable(const TString& name, const TString& value, TCountablePtr countable); void RemoveExpired() const; diff --git a/library/cpp/monlib/dynamic_counters/ut/ya.make b/library/cpp/monlib/dynamic_counters/ut/ya.make index 8242f2fe30..a334ef87dd 100644 --- a/library/cpp/monlib/dynamic_counters/ut/ya.make +++ b/library/cpp/monlib/dynamic_counters/ut/ya.make @@ -3,7 +3,7 @@ UNITTEST_FOR(library/cpp/monlib/dynamic_counters) OWNER(jamel) SRCS( - contention_ut.cpp + contention_ut.cpp counters_ut.cpp encode_ut.cpp ) |