@@ -65,7 +65,7 @@ std::shared_ptr<PInternalService_RecoverableStub> BrpcStubCache::get_stub(const
65
65
timespec tm = butil::seconds_from_now (config::brpc_stub_expire_s);
66
66
auto status = _pipeline_timer->schedule ((*stub_pool)->_cleanup_task , tm);
67
67
if (!status.ok ()) {
68
- LOG (WARNING) << " Failed to schedule endpoint : " << endpoint;
68
+ LOG (WARNING) << " Failed to schedule brpc cleanup task : " << endpoint;
69
69
}
70
70
71
71
return (*stub_pool)->get_or_create (endpoint);
@@ -99,10 +99,7 @@ void BrpcStubCache::cleanup_expired(const butil::EndPoint& endpoint) {
99
99
std::lock_guard<SpinLock> l (_lock);
100
100
101
101
LOG (INFO) << " cleanup stubs from endpoint:" << endpoint;
102
- auto pool = _stub_map.seek (endpoint);
103
- if (pool != nullptr ) {
104
- _stub_map.erase (endpoint);
105
- }
102
+ _stub_map.erase (endpoint);
106
103
}
107
104
108
105
BrpcStubCache::StubPool::StubPool () : _idx(-1 ) {
@@ -137,6 +134,26 @@ HttpBrpcStubCache* HttpBrpcStubCache::getInstance() {
137
134
138
135
HttpBrpcStubCache::HttpBrpcStubCache () {
139
136
_stub_map.init (500 );
137
+ _task_map.init (500 );
138
+ _pipeline_timer = ExecEnv::GetInstance ()->pipeline_timer ();
139
+ }
140
+
141
+ HttpBrpcStubCache::~HttpBrpcStubCache () {
142
+ std::vector<std::shared_ptr<HttpEndpointCleanupTask>> task_to_cleanup;
143
+
144
+ {
145
+ std::lock_guard<SpinLock> l (_lock);
146
+ for (auto & stub : _task_map) {
147
+ task_to_cleanup.push_back (stub.second );
148
+ }
149
+ }
150
+
151
+ for (auto & task : task_to_cleanup) {
152
+ task->unschedule (_pipeline_timer);
153
+ }
154
+
155
+ _stub_map.clear ();
156
+ _task_map.clear ();
140
157
}
141
158
142
159
StatusOr<std::shared_ptr<PInternalService_RecoverableStub>> HttpBrpcStubCache::get_http_stub (
@@ -158,6 +175,21 @@ StatusOr<std::shared_ptr<PInternalService_RecoverableStub>> HttpBrpcStubCache::g
158
175
}
159
176
// get is exist
160
177
std::lock_guard<SpinLock> l (_lock);
178
+
179
+ // schedule clean up task
180
+ auto task = _task_map.seek (endpoint);
181
+ if (task == nullptr ) {
182
+ auto new_task = std::make_shared<HttpEndpointCleanupTask>(this , endpoint);
183
+ _task_map.insert (endpoint, new_task);
184
+ task = _task_map.seek (endpoint);
185
+ }
186
+ _pipeline_timer->unschedule ((*task).get ());
187
+ timespec tm = butil::seconds_from_now (config::brpc_stub_expire_s);
188
+ auto status = _pipeline_timer->schedule ((*task).get (), tm);
189
+ if (!status.ok ()) {
190
+ LOG (WARNING) << " Failed to schedule http brpc cleanup task: " << endpoint;
191
+ }
192
+
161
193
auto stub_ptr = _stub_map.seek (endpoint);
162
194
if (stub_ptr != nullptr ) {
163
195
return *stub_ptr;
@@ -172,13 +204,41 @@ StatusOr<std::shared_ptr<PInternalService_RecoverableStub>> HttpBrpcStubCache::g
172
204
return stub;
173
205
}
174
206
207
+ void HttpBrpcStubCache::cleanup_expired (const butil::EndPoint& endpoint) {
208
+ std::lock_guard<SpinLock> l (_lock);
209
+
210
+ LOG (INFO) << " cleanup http stubs from endpoint:" << endpoint;
211
+ _stub_map.erase (endpoint);
212
+ _task_map.erase (endpoint);
213
+ }
214
+
175
215
LakeServiceBrpcStubCache* LakeServiceBrpcStubCache::getInstance () {
176
216
static LakeServiceBrpcStubCache cache;
177
217
return &cache;
178
218
}
179
219
180
220
LakeServiceBrpcStubCache::LakeServiceBrpcStubCache () {
181
221
_stub_map.init (500 );
222
+ _task_map.init (500 );
223
+ _pipeline_timer = ExecEnv::GetInstance ()->pipeline_timer ();
224
+ }
225
+
226
+ LakeServiceBrpcStubCache::~LakeServiceBrpcStubCache () {
227
+ std::vector<std::shared_ptr<LakeEndpointCleanupTask>> task_to_cleanup;
228
+
229
+ {
230
+ std::lock_guard<SpinLock> l (_lock);
231
+ for (auto & stub : _task_map) {
232
+ task_to_cleanup.push_back (stub.second );
233
+ }
234
+ }
235
+
236
+ for (auto & task : task_to_cleanup) {
237
+ task->unschedule (_pipeline_timer);
238
+ }
239
+
240
+ _stub_map.clear ();
241
+ _task_map.clear ();
182
242
}
183
243
184
244
DEFINE_FAIL_POINT (get_stub_return_nullptr);
@@ -197,22 +257,54 @@ StatusOr<std::shared_ptr<starrocks::LakeService_RecoverableStub>> LakeServiceBrp
197
257
}
198
258
// get if exist
199
259
std::lock_guard<SpinLock> l (_lock);
260
+
261
+ // schedule clean up task
262
+ auto task = _task_map.seek (endpoint);
263
+ if (task == nullptr ) {
264
+ auto new_task = std::make_shared<LakeEndpointCleanupTask>(this , endpoint);
265
+ _task_map.insert (endpoint, new_task);
266
+ task = _task_map.seek (endpoint);
267
+ }
268
+ _pipeline_timer->unschedule ((*task).get ());
269
+ timespec tm = butil::seconds_from_now (config::brpc_stub_expire_s);
270
+ auto status = _pipeline_timer->schedule ((*task).get (), tm);
271
+ if (!status.ok ()) {
272
+ LOG (WARNING) << " Failed to schedule lake brpc cleanup task: " << endpoint;
273
+ }
274
+
200
275
auto stub_ptr = _stub_map.seek (endpoint);
201
276
FAIL_POINT_TRIGGER_EXECUTE (get_stub_return_nullptr, { stub_ptr = nullptr ; });
202
277
if (stub_ptr != nullptr ) {
203
278
return *stub_ptr;
204
279
}
205
280
// create
206
281
auto stub = std::make_shared<starrocks::LakeService_RecoverableStub>(endpoint, " " );
282
+
207
283
if (!stub->reset_channel ().ok ()) {
208
284
return Status::RuntimeError (" init brpc http channel error on " + host + " :" + std::to_string (port));
209
285
}
210
286
_stub_map.insert (endpoint, stub);
211
287
return stub;
212
288
}
213
289
290
+ void LakeServiceBrpcStubCache::cleanup_expired (const butil::EndPoint& endpoint) {
291
+ std::lock_guard<SpinLock> l (_lock);
292
+
293
+ LOG (INFO) << " cleanup lake service stubs from endpoint:" << endpoint;
294
+ _stub_map.erase (endpoint);
295
+ _task_map.erase (endpoint);
296
+ }
297
+
214
298
void EndpointCleanupTask::Run () {
215
299
_cache->cleanup_expired (_endpoint);
216
300
}
217
301
302
+ void HttpEndpointCleanupTask::Run () {
303
+ _cache->cleanup_expired (_endpoint);
304
+ }
305
+
306
+ void LakeEndpointCleanupTask::Run () {
307
+ _cache->cleanup_expired (_endpoint);
308
+ }
309
+
218
310
} // namespace starrocks
0 commit comments