17
17
#include " common/config.h"
18
18
#include " gen_cpp/internal_service.pb.h"
19
19
#include " gen_cpp/lake_service.pb.h"
20
+ #include " util/misc.h"
20
21
#include " util/failpoint/fail_point.h"
21
22
#include " util/starrocks_metrics.h"
22
23
@@ -28,6 +29,17 @@ 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 () {
@@ -71,6 +83,30 @@ std::shared_ptr<PInternalService_RecoverableStub> BrpcStubCache::get_stub(const
71
83
return get_stub (endpoint);
72
84
}
73
85
86
+ void BrpcStubCache::check_and_cleanup_unhealthy_stubs () {
87
+ std::vector<butil::EndPoint> snapshot;
88
+ {
89
+ std::lock_guard<SpinLock> l (_lock);
90
+
91
+ for (auto & entry : _stub_map) {
92
+ snapshot.push_back (entry.first );
93
+ }
94
+ }
95
+
96
+ for (auto endpoint : snapshot) {
97
+ auto stub_pool = get_stub_pool_readonly (endpoint);
98
+ if (stub_pool && stub_pool->is_unhealthy ()) {
99
+ {
100
+ std::lock_guard<SpinLock> l (_lock);
101
+
102
+ LOG (INFO) << " cleanup stubs from endpoint:" << endpoint;
103
+ _stub_map.erase (endpoint);
104
+ delete stub_pool;
105
+ }
106
+ }
107
+ }
108
+ }
109
+
74
110
BrpcStubCache::StubPool::StubPool () : _idx(-1 ) {
75
111
_stubs.reserve (config::brpc_max_connections_per_server);
76
112
}
@@ -91,6 +127,28 @@ std::shared_ptr<PInternalService_RecoverableStub> BrpcStubCache::StubPool::get_o
91
127
return _stubs[_idx];
92
128
}
93
129
130
+ bool BrpcStubCache::StubPool::is_unhealthy () {
131
+ if (_stubs.size () == 0 ) {
132
+ // When the vector is empty do not need to clean
133
+ return false ;
134
+ }
135
+
136
+ auto & first_stub = _stubs[0 ];
137
+ if (!first_stub) {
138
+ return true ;
139
+ }
140
+
141
+ auto status = first_stub->check_health ();
142
+ return !status.ok ();
143
+ }
144
+
145
+ BrpcStubCache::StubPool* BrpcStubCache::get_stub_pool_readonly (
146
+ const butil::EndPoint& endpoint) {
147
+ std::lock_guard<SpinLock> l (_lock);
148
+ auto stub_ptr = _stub_map.seek (endpoint);
149
+ return stub_ptr ? *stub_ptr : nullptr ;
150
+ }
151
+
94
152
HttpBrpcStubCache* HttpBrpcStubCache::getInstance () {
95
153
static HttpBrpcStubCache cache;
96
154
return &cache;
0 commit comments