18
18
#include " gen_cpp/internal_service.pb.h"
19
19
#include " gen_cpp/lake_service.pb.h"
20
20
#include " util/failpoint/fail_point.h"
21
+ #include " util/misc.h"
21
22
#include " util/starrocks_metrics.h"
22
23
23
24
namespace starrocks {
@@ -28,12 +29,28 @@ BrpcStubCache::BrpcStubCache() {
28
29
std::lock_guard<SpinLock> l (_lock);
29
30
return _stub_map.size ();
30
31
});
32
+ _cleanup_thread = std::thread ([this ] {
33
+ #ifdef GOOGLE_PROFILER
34
+ ProfilerRegisterThread ();
35
+ #endif
36
+ while (!_stopped.load ()) {
37
+ LOG (INFO) << " Start to clean up expired brpc stubs" ;
38
+ check_and_cleanup_unhealthy_stubs ();
39
+ nap_sleep (config::brpc_stub_cleanup_interval_s, [this ] { return _stopped.load (); });
40
+ }
41
+ });
42
+ Thread::set_thread_name (_cleanup_thread, " brpc_cleanup_thread" );
31
43
}
32
44
33
45
BrpcStubCache::~BrpcStubCache () {
46
+ _stopped.store (true );
47
+ _cleanup_thread.join ();
48
+
34
49
for (auto & stub : _stub_map) {
35
50
delete stub.second ;
36
51
}
52
+
53
+ _stub_map.clear ();
37
54
}
38
55
39
56
std::shared_ptr<PInternalService_RecoverableStub> BrpcStubCache::get_stub (const butil::EndPoint& endpoint) {
@@ -71,10 +88,38 @@ std::shared_ptr<PInternalService_RecoverableStub> BrpcStubCache::get_stub(const
71
88
return get_stub (endpoint);
72
89
}
73
90
91
+ void BrpcStubCache::check_and_cleanup_unhealthy_stubs () {
92
+ std::vector<butil::EndPoint> snapshot;
93
+ {
94
+ std::lock_guard<SpinLock> l (_lock);
95
+
96
+ for (auto & entry : _stub_map) {
97
+ snapshot.push_back (entry.first );
98
+ }
99
+ }
100
+
101
+ for (const auto & endpoint : snapshot) {
102
+ auto stub_pool = get_stub_pool_readonly (endpoint);
103
+ if (stub_pool && stub_pool->is_unhealthy ()) {
104
+ {
105
+ std::lock_guard<SpinLock> l (_lock);
106
+
107
+ LOG (INFO) << " cleanup stubs from endpoint:" << endpoint;
108
+ _stub_map.erase (endpoint);
109
+ delete stub_pool;
110
+ }
111
+ }
112
+ }
113
+ }
114
+
74
115
BrpcStubCache::StubPool::StubPool () : _idx(-1 ) {
75
116
_stubs.reserve (config::brpc_max_connections_per_server);
76
117
}
77
118
119
+ BrpcStubCache::StubPool::~StubPool () {
120
+ _stubs.clear ();
121
+ }
122
+
78
123
std::shared_ptr<PInternalService_RecoverableStub> BrpcStubCache::StubPool::get_or_create (
79
124
const butil::EndPoint& endpoint) {
80
125
if (UNLIKELY (_stubs.size () < config::brpc_max_connections_per_server)) {
@@ -91,6 +136,27 @@ std::shared_ptr<PInternalService_RecoverableStub> BrpcStubCache::StubPool::get_o
91
136
return _stubs[_idx];
92
137
}
93
138
139
+ bool BrpcStubCache::StubPool::is_unhealthy () {
140
+ if (_stubs.size () == 0 ) {
141
+ // When the vector is empty do not need to clean
142
+ return false ;
143
+ }
144
+
145
+ auto & first_stub = _stubs[0 ];
146
+ if (!first_stub) {
147
+ return true ;
148
+ }
149
+
150
+ auto status = first_stub->check_health ();
151
+ return !status.ok ();
152
+ }
153
+
154
+ BrpcStubCache::StubPool* BrpcStubCache::get_stub_pool_readonly (const butil::EndPoint& endpoint) {
155
+ std::lock_guard<SpinLock> l (_lock);
156
+ auto stub_ptr = _stub_map.seek (endpoint);
157
+ return stub_ptr ? *stub_ptr : nullptr ;
158
+ }
159
+
94
160
HttpBrpcStubCache* HttpBrpcStubCache::getInstance () {
95
161
static HttpBrpcStubCache cache;
96
162
return &cache;
0 commit comments