From 7bc6b845c60b5d8f562809f0bcce37e9b1e5a849 Mon Sep 17 00:00:00 2001 From: Xiaoxi Chen Date: Fri, 19 Jan 2024 12:01:28 +0800 Subject: [PATCH] Exposing Leader to upper layer SM needs to return leader in both response of some API call as well as PGStat report. This helps client(of SM) to know up-to-date leader and send requests to leader. Signed-off-by: Xiaoxi Chen --- conanfile.py | 2 +- include/nuraft_mesg/mesg_state_mgr.hpp | 1 + src/lib/repl_service_ctx.cpp | 12 ++++++++++++ src/tests/data_service_tests.cpp | 1 + 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/conanfile.py b/conanfile.py index 227fe76..e2ce525 100644 --- a/conanfile.py +++ b/conanfile.py @@ -8,7 +8,7 @@ class NuRaftMesgConan(ConanFile): name = "nuraft_mesg" - version = "2.1.2" + version = "2.2.2" homepage = "https://github.com/eBay/nuraft_mesg" description = "A gRPC service for NuRAFT" diff --git a/include/nuraft_mesg/mesg_state_mgr.hpp b/include/nuraft_mesg/mesg_state_mgr.hpp index 8c3ca33..0ff94ee 100644 --- a/include/nuraft_mesg/mesg_state_mgr.hpp +++ b/include/nuraft_mesg/mesg_state_mgr.hpp @@ -36,6 +36,7 @@ class repl_service_ctx { // we do not own this pointer. Use this only if the life cycle of the pointer is well known nuraft::raft_server* _server; bool is_raft_leader() const; + const std::string& raft_leader_id() const; // return a list of replica configs for the peers of the raft group void get_cluster_config(std::list< replica_config >& cluster_config) const; diff --git a/src/lib/repl_service_ctx.cpp b/src/lib/repl_service_ctx.cpp index c972b38..5cd5022 100644 --- a/src/lib/repl_service_ctx.cpp +++ b/src/lib/repl_service_ctx.cpp @@ -64,6 +64,18 @@ repl_service_ctx::repl_service_ctx(nuraft::raft_server* server) : _server(server bool repl_service_ctx::is_raft_leader() const { return _server->is_leader(); } +const std::string& repl_service_ctx::raft_leader_id() const { + // when adding member to raft, the id recorded in raft is a hash + // of passed-in id (new_id in add_member()), the new_id was stored + // in endpoint field. + static std::string const empty; + if (!_server) return empty; + auto const leader = _server->get_leader(); + if (leader == -1) return empty; + auto const& srv_config = _server->get_srv_config(leader); + return (srv_config) ? srv_config->get_endpoint() : empty; +} + void repl_service_ctx::get_cluster_config(std::list< replica_config >& cluster_config) const { auto const& srv_configs = _server->get_config()->get_servers(); for (auto const& srv_config : srv_configs) { diff --git a/src/tests/data_service_tests.cpp b/src/tests/data_service_tests.cpp index dc609e6..7bc9530 100644 --- a/src/tests/data_service_tests.cpp +++ b/src/tests/data_service_tests.cpp @@ -125,6 +125,7 @@ TEST_F(DataServiceFixture, BasicTest2) { auto repl_ctx = sm1->get_repl_context(); EXPECT_TRUE(repl_ctx && repl_ctx->is_raft_leader()); + EXPECT_TRUE(repl_ctx && repl_ctx->raft_leader_id() == to_string(app_1_->id_)); std::list< nuraft_mesg::replica_config > cluster_config; repl_ctx->get_cluster_config(cluster_config); EXPECT_EQ(cluster_config.size(), 3u);