@@ -25,13 +25,18 @@ folly::Future<Status> AdminClient::transLeader(GraphSpaceID spaceId,
25
25
storage::cpp2::TransLeaderReq req;
26
26
req.set_space_id (spaceId);
27
27
req.set_part_id (partId);
28
+ auto ret = getPeers (spaceId, partId);
29
+ if (!ret.ok ()) {
30
+ return ret.status ();
31
+ }
32
+ auto & peers = ret.value ();
33
+ auto it = std::find (peers.begin (), peers.end (), leader);
34
+ if (it == peers.end ()) {
35
+ LOG (WARNING) << " Can't find part " << partId << " on " << leader;
36
+ return Status::PartNotFound ();
37
+ }
28
38
auto target = dst;
29
39
if (dst == kRandomPeer ) {
30
- auto ret = getPeers (spaceId, partId);
31
- if (!ret.ok ()) {
32
- return ret.status ();
33
- }
34
- auto & peers = ret.value ();
35
40
for (auto & p : peers) {
36
41
if (p != leader && ActiveHostsMan::isLived (kv_, p)) {
37
42
target = p;
@@ -48,6 +53,9 @@ folly::Future<Status> AdminClient::transLeader(GraphSpaceID spaceId,
48
53
case storage::cpp2::ErrorCode::E_LEADER_CHANGED: {
49
54
return Status::OK ();
50
55
}
56
+ case storage::cpp2::ErrorCode::E_PART_NOT_FOUND: {
57
+ return Status::PartNotFound ();
58
+ }
51
59
default :
52
60
return Status::Error (" Unknown code %d" ,
53
61
static_cast <int32_t >(resp.get_code ()));
@@ -237,6 +245,60 @@ folly::Future<Status> AdminClient::removePart(GraphSpaceID spaceId,
237
245
});
238
246
}
239
247
248
+ folly::Future<Status> AdminClient::checkPeers (GraphSpaceID spaceId, PartitionID partId) {
249
+ if (injector_) {
250
+ return injector_->checkPeers ();
251
+ }
252
+ storage::cpp2::CheckPeersReq req;
253
+ req.set_space_id (spaceId);
254
+ req.set_part_id (partId);
255
+ auto ret = getPeers (spaceId, partId);
256
+ if (!ret.ok ()) {
257
+ return ret.status ();
258
+ }
259
+ auto peers = std::move (ret).value ();
260
+ std::vector<nebula::cpp2::HostAddr> thriftPeers;
261
+ thriftPeers.resize (peers.size ());
262
+ std::transform (peers.begin (), peers.end (), thriftPeers.begin (), [this ](const auto & h) {
263
+ return toThriftHost (h);
264
+ });
265
+ req.set_peers (std::move (thriftPeers));
266
+ folly::Promise<Status> pro;
267
+ auto fut = pro.getFuture ();
268
+ std::vector<folly::Future<Status>> futures;
269
+ for (auto & p : peers) {
270
+ auto f = getResponse (p, req, [] (auto client, auto request) {
271
+ return client->future_checkPeers (request);
272
+ }, [] (auto && resp) -> Status {
273
+ if (resp.get_code () == storage::cpp2::ErrorCode::SUCCEEDED) {
274
+ return Status::OK ();
275
+ } else {
276
+ return Status::Error (" Add part failed! code=%d" ,
277
+ static_cast <int32_t >(resp.get_code ()));
278
+ }
279
+ });
280
+ futures.emplace_back (std::move (f));
281
+ }
282
+ folly::collectAll (std::move (futures)).thenTry ([p = std::move (pro)] (auto && t) mutable {
283
+ if (t.hasException ()) {
284
+ p.setValue (Status::Error (" Check failed!" ));
285
+ } else {
286
+ auto v = std::move (t).value ();
287
+ for (auto & resp : v) {
288
+ // The exception has been catched inside getResponse.
289
+ CHECK (!resp.hasException ());
290
+ auto st = std::move (resp).value ();
291
+ if (!st.ok ()) {
292
+ p.setValue (st);
293
+ return ;
294
+ }
295
+ }
296
+ p.setValue (Status::OK ());
297
+ }
298
+ });
299
+ return fut;
300
+ }
301
+
240
302
template <typename Request,
241
303
typename RemoteFunc,
242
304
typename RespGenerator>
@@ -360,7 +422,6 @@ void AdminClient::getResponse(
360
422
// this task failed forever.
361
423
index = leaderIndex;
362
424
hosts.emplace_back (leader);
363
- return ;
364
425
}
365
426
LOG (INFO) << " Return leader change from " << hosts[index]
366
427
<< " , new leader is " << leader
@@ -499,6 +560,8 @@ folly::Future<Status> AdminClient::getLeaderDist(HostLeaderMap* result) {
499
560
}
500
561
501
562
p.setValue (Status::OK ());
563
+ }).thenError ([p = std::move (promise)] (auto && e) mutable {
564
+ p.setValue (Status::Error (" Get leader failed, %s" , e.what ().c_str ()));
502
565
});
503
566
504
567
return future;
0 commit comments