From c2f3d9190c1328d3a593daafeb7a2c0934165bab Mon Sep 17 00:00:00 2001 From: kikimo Date: Mon, 22 Nov 2021 10:27:46 +0800 Subject: [PATCH 1/4] add rpc to query raft status --- src/interface/raftex.thrift | 32 ++++++++++++++++++++++++++++ src/kvstore/raftex/RaftPart.cpp | 13 +++++++++++ src/kvstore/raftex/RaftPart.h | 2 ++ src/kvstore/raftex/RaftexService.cpp | 10 +++++++++ src/kvstore/raftex/RaftexService.h | 2 ++ 5 files changed, 59 insertions(+) diff --git a/src/interface/raftex.thrift b/src/interface/raftex.thrift index 8f1a8ea4f47..b06821094db 100644 --- a/src/interface/raftex.thrift +++ b/src/interface/raftex.thrift @@ -7,6 +7,21 @@ namespace cpp nebula.raftex include "common.thrift" +enum Role { + LEADER = 1, // the leader + FOLLOWER = 2; // following a leader + CANDIDATE = 3; // Has sent AskForVote request + LEARNER = 4; // It is the same with FOLLOWER, + // except it does not participate in leader election +} + +enum Status { + STARTING = 0; // The part is starting, not ready for service + RUNNING = 1; // The part is running + STOPPED = 2; // The part has been stopped + WAITING_SNAPSHOT = 3; // Waiting for the snapshot. +} + enum ErrorCode { SUCCEEDED = 0; @@ -154,9 +169,26 @@ struct SendSnapshotResponse { 1: ErrorCode error_code; } +struct GetStateRequest { + 1: GraphSpaceID space; // Graphspace ID + 2: PartitionID part; // Partition ID +} + +struct GetStateResponse { + 1: ErrorCode error_code; + 2: Role role; + 3: TermID term; + 4: bool is_leader; + 5: LogID committed_log_id; + 6: LogID last_log_id; + 7: TermID last_log_term; + 8: Status status; +} + service RaftexService { AskForVoteResponse askForVote(1: AskForVoteRequest req); AppendLogResponse appendLog(1: AppendLogRequest req); SendSnapshotResponse sendSnapshot(1: SendSnapshotRequest req); HeartbeatResponse heartbeat(1: HeartbeatRequest req) (thread = 'eb'); + GetStateResponse getState(1: GetStateRequest req); } diff --git a/src/kvstore/raftex/RaftPart.cpp b/src/kvstore/raftex/RaftPart.cpp index 17b666488cb..c0644e608c9 100644 --- a/src/kvstore/raftex/RaftPart.cpp +++ b/src/kvstore/raftex/RaftPart.cpp @@ -998,10 +998,23 @@ bool RaftPart::prepareElectionRequest(cpp2::AskForVoteRequest& req, return true; } +void RaftPart::getState(cpp2::GetStateResponse& resp) { + std::lock_guard g(raftLock_); + resp.set_term(term_); + resp.set_role(nebula::raftex::cpp2::Role(role_)); + resp.set_is_leader(role_ == Role::LEADER); + resp.set_error_code(cpp2::ErrorCode::SUCCEEDED); + resp.set_committed_log_id(committedLogId_); + resp.set_last_log_id(lastLogId_); + resp.set_last_log_term(lastLogTerm_); + resp.set_status(nebula::raftex::cpp2::Status(status_)); +} + typename RaftPart::Role RaftPart::processElectionResponses( const RaftPart::ElectionResponses& results, std::vector> hosts, TermID proposedTerm) { + std::lock_guard g(raftLock_); if (UNLIKELY(status_ == Status::STOPPED)) { diff --git a/src/kvstore/raftex/RaftPart.h b/src/kvstore/raftex/RaftPart.h index a67fc0123c6..c056ba56570 100644 --- a/src/kvstore/raftex/RaftPart.h +++ b/src/kvstore/raftex/RaftPart.h @@ -196,6 +196,8 @@ class RaftPart : public std::enable_shared_from_this { * Methods to process incoming raft requests * ****************************************************/ + void getState(cpp2::GetStateResponse& resp); + // Process the incoming leader election request void processAskForVoteRequest(const cpp2::AskForVoteRequest& req, cpp2::AskForVoteResponse& resp); diff --git a/src/kvstore/raftex/RaftexService.cpp b/src/kvstore/raftex/RaftexService.cpp index 982b807c7e6..32e40d1340a 100644 --- a/src/kvstore/raftex/RaftexService.cpp +++ b/src/kvstore/raftex/RaftexService.cpp @@ -171,6 +171,16 @@ std::shared_ptr RaftexService::findPart(GraphSpaceID spaceId, Partitio return it->second; } +void RaftexService::getState(cpp2::GetStateResponse& resp, const cpp2::GetStateRequest& req) { + auto part = findPart(req.get_space(), req.get_part()); + if (part != nullptr) { + part->getState(resp); + } else { + resp.set_term(-1); + resp.set_error_code(cpp2::ErrorCode::E_UNKNOWN_PART); + } +} + void RaftexService::askForVote(cpp2::AskForVoteResponse& resp, const cpp2::AskForVoteRequest& req) { auto part = findPart(req.get_space(), req.get_part()); if (!part) { diff --git a/src/kvstore/raftex/RaftexService.h b/src/kvstore/raftex/RaftexService.h index c79c8a8b68c..664a11c3347 100644 --- a/src/kvstore/raftex/RaftexService.h +++ b/src/kvstore/raftex/RaftexService.h @@ -38,6 +38,8 @@ class RaftexService : public cpp2::RaftexServiceSvIf { void askForVote(cpp2::AskForVoteResponse& resp, const cpp2::AskForVoteRequest& req) override; + void getState(cpp2::GetStateResponse& resp, const cpp2::GetStateRequest& req) override; + void appendLog(cpp2::AppendLogResponse& resp, const cpp2::AppendLogRequest& req) override; void sendSnapshot(cpp2::SendSnapshotResponse& resp, From da5d406142e9f918da21437f797440562dcefed8 Mon Sep 17 00:00:00 2001 From: kikimo Date: Mon, 22 Nov 2021 10:42:41 +0800 Subject: [PATCH 2/4] correct format erroro --- src/kvstore/raftex/RaftPart.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/kvstore/raftex/RaftPart.cpp b/src/kvstore/raftex/RaftPart.cpp index c0644e608c9..01c97a5b9c2 100644 --- a/src/kvstore/raftex/RaftPart.cpp +++ b/src/kvstore/raftex/RaftPart.cpp @@ -1014,7 +1014,6 @@ typename RaftPart::Role RaftPart::processElectionResponses( const RaftPart::ElectionResponses& results, std::vector> hosts, TermID proposedTerm) { - std::lock_guard g(raftLock_); if (UNLIKELY(status_ == Status::STOPPED)) { From eb45dbf3f65f9f8e32a5b5436f8f5df4d3348735 Mon Sep 17 00:00:00 2001 From: kikimo Date: Thu, 25 Nov 2021 09:33:18 +0800 Subject: [PATCH 3/4] unify raft Role and Status --- src/interface/raftex.thrift | 4 ++-- src/kvstore/raftex/RaftPart.cpp | 4 ++-- src/kvstore/raftex/RaftPart.h | 16 ++-------------- 3 files changed, 6 insertions(+), 18 deletions(-) diff --git a/src/interface/raftex.thrift b/src/interface/raftex.thrift index b06821094db..a6bbcfae70c 100644 --- a/src/interface/raftex.thrift +++ b/src/interface/raftex.thrift @@ -11,8 +11,8 @@ enum Role { LEADER = 1, // the leader FOLLOWER = 2; // following a leader CANDIDATE = 3; // Has sent AskForVote request - LEARNER = 4; // It is the same with FOLLOWER, - // except it does not participate in leader election + LEARNER = 4; // same with FOLLOWER, except that it does + // not vote in leader election } enum Status { diff --git a/src/kvstore/raftex/RaftPart.cpp b/src/kvstore/raftex/RaftPart.cpp index 01c97a5b9c2..64a54eff2b4 100644 --- a/src/kvstore/raftex/RaftPart.cpp +++ b/src/kvstore/raftex/RaftPart.cpp @@ -1001,13 +1001,13 @@ bool RaftPart::prepareElectionRequest(cpp2::AskForVoteRequest& req, void RaftPart::getState(cpp2::GetStateResponse& resp) { std::lock_guard g(raftLock_); resp.set_term(term_); - resp.set_role(nebula::raftex::cpp2::Role(role_)); + resp.set_role(role_); resp.set_is_leader(role_ == Role::LEADER); resp.set_error_code(cpp2::ErrorCode::SUCCEEDED); resp.set_committed_log_id(committedLogId_); resp.set_last_log_id(lastLogId_); resp.set_last_log_term(lastLogTerm_); - resp.set_status(nebula::raftex::cpp2::Status(status_)); + resp.set_status(status_); } typename RaftPart::Role RaftPart::processElectionResponses( diff --git a/src/kvstore/raftex/RaftPart.h b/src/kvstore/raftex/RaftPart.h index c056ba56570..d593a2a10a7 100644 --- a/src/kvstore/raftex/RaftPart.h +++ b/src/kvstore/raftex/RaftPart.h @@ -238,20 +238,8 @@ class RaftPart : public std::enable_shared_from_this { std::shared_ptr> clientMan, std::shared_ptr diskMan); - enum class Status { - STARTING = 0, // The part is starting, not ready for service - RUNNING, // The part is running - STOPPED, // The part has been stopped - WAITING_SNAPSHOT // Waiting for the snapshot. - }; - - enum class Role { - LEADER = 1, // the leader - FOLLOWER, // following a leader - CANDIDATE, // Has sent AskForVote request - LEARNER // It is the same with FOLLOWER, - // except it does not participate in leader election - }; + using Status = cpp2::Status; + using Role = cpp2::Role; const char* idStr() const { return idStr_.c_str(); } From ae6adbd2204da20589c125aa04f13603d2cfd6cf Mon Sep 17 00:00:00 2001 From: kikimo Date: Thu, 25 Nov 2021 18:40:05 +0800 Subject: [PATCH 4/4] make raft role and status enum strict --- src/interface/raftex.thrift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/interface/raftex.thrift b/src/interface/raftex.thrift index 128d6bba892..51000f86af7 100644 --- a/src/interface/raftex.thrift +++ b/src/interface/raftex.thrift @@ -13,14 +13,14 @@ enum Role { CANDIDATE = 3; // Has sent AskForVote request LEARNER = 4; // same with FOLLOWER, except that it does // not vote in leader election -} +} (cpp.enum_strict) enum Status { STARTING = 0; // The part is starting, not ready for service RUNNING = 1; // The part is running STOPPED = 2; // The part has been stopped WAITING_SNAPSHOT = 3; // Waiting for the snapshot. -} +} (cpp.enum_strict) enum ErrorCode { SUCCEEDED = 0;