Skip to content

Commit abccd55

Browse files
author
babenko
committed
Cache RCT statistics in monitoring
commit_hash:9b7142e7ddae81e75e12b9e50c9ada2041c82170
1 parent 54b3a7e commit abccd55

File tree

3 files changed

+98
-23
lines changed

3 files changed

+98
-23
lines changed

yt/yt/core/misc/ref_counted_tracker.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ namespace NYT {
1313

1414
////////////////////////////////////////////////////////////////////////////////
1515

16-
struct TRefCountedTrackerStatistics
16+
struct TRefCountedTrackerStatistics final
1717
{
1818
struct TStatistics
1919
{

yt/yt/core/misc/ref_counted_tracker_statistics_producer.cpp

Lines changed: 93 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,41 +2,112 @@
22

33
#include <yt/yt/core/ytree/fluent.h>
44

5+
#include <library/cpp/yt/memory/leaky_singleton.h>
6+
7+
#include <library/cpp/yt/threading/spin_lock.h>
8+
59
namespace NYT {
610

711
using namespace NYson;
812
using namespace NYTree;
913

1014
////////////////////////////////////////////////////////////////////////////////
1115

16+
namespace {
17+
18+
void Produce(IYsonConsumer* consumer, const TRefCountedTrackerStatistics& statistics)
19+
{
20+
BuildYsonFluently(consumer)
21+
.BeginMap()
22+
.Item("statistics")
23+
.DoListFor(statistics.NamedStatistics, [] (TFluentList fluent, const auto& namedSlotStatistics) {
24+
fluent
25+
.Item().BeginMap()
26+
.Item("name").Value(namedSlotStatistics.FullName)
27+
.Item("objects_alive").Value(namedSlotStatistics.ObjectsAlive)
28+
.Item("objects_allocated").Value(namedSlotStatistics.ObjectsAllocated)
29+
.Item("bytes_alive").Value(namedSlotStatistics.BytesAlive)
30+
.Item("bytes_allocated").Value(namedSlotStatistics.BytesAllocated)
31+
.EndMap();
32+
})
33+
.Item("total").BeginMap()
34+
.Item("objects_alive").Value(statistics.TotalStatistics.ObjectsAlive)
35+
.Item("objects_allocated").Value(statistics.TotalStatistics.ObjectsAllocated)
36+
.Item("bytes_alive").Value(statistics.TotalStatistics.BytesAlive)
37+
.Item("bytes_allocated").Value(statistics.TotalStatistics.BytesAllocated)
38+
.EndMap()
39+
.EndMap();
40+
}
41+
42+
} // namespace
43+
44+
////////////////////////////////////////////////////////////////////////////////
45+
1246
TYsonProducer CreateRefCountedTrackerStatisticsProducer()
1347
{
1448
return BIND([] (IYsonConsumer* consumer) {
15-
auto statistics = TRefCountedTracker::Get()->GetStatistics();
16-
17-
BuildYsonFluently(consumer)
18-
.BeginMap()
19-
.Item("statistics")
20-
.DoListFor(statistics.NamedStatistics, [] (TFluentList fluent, const auto& namedSlotStatistics) {
21-
fluent
22-
.Item().BeginMap()
23-
.Item("name").Value(namedSlotStatistics.FullName)
24-
.Item("objects_alive").Value(namedSlotStatistics.ObjectsAlive)
25-
.Item("objects_allocated").Value(namedSlotStatistics.ObjectsAllocated)
26-
.Item("bytes_alive").Value(namedSlotStatistics.BytesAlive)
27-
.Item("bytes_allocated").Value(namedSlotStatistics.BytesAllocated)
28-
.EndMap();
29-
})
30-
.Item("total").BeginMap()
31-
.Item("objects_alive").Value(statistics.TotalStatistics.ObjectsAlive)
32-
.Item("objects_allocated").Value(statistics.TotalStatistics.ObjectsAllocated)
33-
.Item("bytes_alive").Value(statistics.TotalStatistics.BytesAlive)
34-
.Item("bytes_allocated").Value(statistics.TotalStatistics.BytesAllocated)
35-
.EndMap()
36-
.EndMap();
49+
Produce(consumer, TRefCountedTracker::Get()->GetStatistics());
3750
});
3851
}
3952

4053
////////////////////////////////////////////////////////////////////////////////
4154

55+
class TCachingRefCountedTrackerStatisticsManager
56+
{
57+
public:
58+
TYsonProducer GetProducer()
59+
{
60+
return Producer_;
61+
}
62+
63+
private:
64+
TCachingRefCountedTrackerStatisticsManager()
65+
: Producer_(BIND([this] (IYsonConsumer* consumer) {
66+
Produce(consumer, *GetCachedStatistics());
67+
}))
68+
{ }
69+
70+
DECLARE_LEAKY_SINGLETON_FRIEND()
71+
72+
const TYsonProducer Producer_;
73+
74+
static constexpr auto CachedStatisticsTtl = TDuration::Seconds(10);
75+
76+
NThreading::TSpinLock CachedStatisticsLock_;
77+
TIntrusivePtr<TRefCountedTrackerStatistics> CachedStatistics_;
78+
TInstant CachedStatisticsUpdateTime_;
79+
80+
TIntrusivePtr<TRefCountedTrackerStatistics> GetCachedStatistics()
81+
{
82+
auto now = TInstant::Now();
83+
84+
// Fast path.
85+
{
86+
auto guard = Guard(CachedStatisticsLock_);
87+
if (CachedStatistics_ && now < CachedStatisticsUpdateTime_ + CachedStatisticsTtl) {
88+
return CachedStatistics_;
89+
}
90+
}
91+
92+
// Slow path.
93+
auto statistics = New<TRefCountedTrackerStatistics>(TRefCountedTracker::Get()->GetStatistics());
94+
{
95+
auto guard = Guard(CachedStatisticsLock_);
96+
if (!CachedStatistics_ || now > CachedStatisticsUpdateTime_ + CachedStatisticsTtl) {
97+
CachedStatistics_ = std::move(statistics);
98+
}
99+
return CachedStatistics_;
100+
}
101+
}
102+
};
103+
104+
////////////////////////////////////////////////////////////////////////////////
105+
106+
TYsonProducer GetCachingRefCountedTrackerStatisticsProducer()
107+
{
108+
return LeakySingleton<TCachingRefCountedTrackerStatisticsManager>()->GetProducer();
109+
}
110+
111+
////////////////////////////////////////////////////////////////////////////////
112+
42113
} // namespace NYT

yt/yt/core/misc/ref_counted_tracker_statistics_producer.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,12 @@ namespace NYT {
88

99
////////////////////////////////////////////////////////////////////////////////
1010

11+
//! Creates a producer for constructing the most up-to-date state of RCT.
1112
NYson::TYsonProducer CreateRefCountedTrackerStatisticsProducer();
1213

14+
//! Returns a producer that applies a (reasonable) caching to RCT data.
15+
NYson::TYsonProducer GetCachingRefCountedTrackerStatisticsProducer();
16+
1317
////////////////////////////////////////////////////////////////////////////////
1418

1519
} // namespace NYT

0 commit comments

Comments
 (0)