diff --git a/src/graph/ShowExecutor.cpp b/src/graph/ShowExecutor.cpp index 44d97635b1d..60c7e3884f7 100644 --- a/src/graph/ShowExecutor.cpp +++ b/src/graph/ShowExecutor.cpp @@ -74,13 +74,15 @@ void ShowExecutor::showHosts() { header.push_back("Ip"); header.push_back("Port"); + header.push_back("Status"); resp_->set_column_names(std::move(header)); - for (auto &host : retShowHosts) { + for (auto &status : retShowHosts) { std::vector row; - row.resize(2); - row[0].set_str(NetworkUtils::ipFromHostAddr(host)); - row[1].set_str(folly::to(NetworkUtils::portFromHostAddr(host))); + row.resize(3); + row[0].set_str(NetworkUtils::ipFromHostAddr(status.first)); + row[1].set_str(folly::to(NetworkUtils::portFromHostAddr(status.first))); + row[2].set_str(status.second); rows.emplace_back(); rows.back().set_columns(std::move(row)); } diff --git a/src/interface/meta.thrift b/src/interface/meta.thrift index 4ec08c21af7..69fcc30f0a0 100644 --- a/src/interface/meta.thrift +++ b/src/interface/meta.thrift @@ -89,6 +89,11 @@ struct EdgeItem { 4: common.Schema schema, } +struct HostItem { + 1: common.HostAddr hostAddr, + 2: string status, +} + struct ExecResp { 1: ErrorCode code, // For custom kv operations, it is useless. @@ -220,7 +225,7 @@ struct ListHostsResp { 1: ErrorCode code, // Valid if ret equals E_LEADER_CHANGED. 2: common.HostAddr leader, - 3: list hosts, + 3: list hosts, } struct RemoveHostsReq { diff --git a/src/meta/client/MetaClient.cpp b/src/meta/client/MetaClient.cpp index 6f668eaf585..3081d549c27 100644 --- a/src/meta/client/MetaClient.cpp +++ b/src/meta/client/MetaClient.cpp @@ -252,6 +252,15 @@ std::vector MetaClient::to(const std::vector& return hosts; } +std::vector MetaClient::toHostStatus(const std::vector& tHosts) { + std::vector hosts; + hosts.resize(tHosts.size()); + std::transform(tHosts.begin(), tHosts.end(), hosts.begin(), [](const auto& h) { + return HostStatus(HostAddr(h.hostAddr.get_ip(), h.hostAddr.get_port()), h.get_status()); + }); + return hosts; +} + std::vector MetaClient::toSpaceIdName(const std::vector& tIdNames) { std::vector idNames; idNames.resize(tIdNames.size()); @@ -438,12 +447,12 @@ folly::Future> MetaClient::addHosts(const std::vector& }, true); } -folly::Future>> MetaClient::listHosts() { +folly::Future>> MetaClient::listHosts() { cpp2::ListHostsReq req; return getResponse(std::move(req), [] (auto client, auto request) { return client->future_listHosts(request); }, [this] (cpp2::ListHostsResp&& resp) -> decltype(auto) { - return this->to(resp.hosts); + return this->toHostStatus(resp.hosts); }); } diff --git a/src/meta/client/MetaClient.h b/src/meta/client/MetaClient.h index caf788c6c53..7bc7d2890f2 100644 --- a/src/meta/client/MetaClient.h +++ b/src/meta/client/MetaClient.h @@ -22,6 +22,7 @@ namespace meta { using PartsAlloc = std::unordered_map>; using SpaceIdName = std::pair; +using HostStatus = std::pair; // struct for in cache using TagIDSchemas = std::unordered_map, @@ -90,7 +91,7 @@ class MetaClient { folly::Future> addHosts(const std::vector& hosts); - folly::Future>> + folly::Future>> listHosts(); folly::Future> @@ -228,6 +229,8 @@ class MetaClient { std::vector to(const std::vector& hosts); + std::vector toHostStatus(const std::vector& thosts); + std::vector toSpaceIdName(const std::vector& tIdNames); PartsMap doGetPartsMap(const HostAddr& host, diff --git a/src/meta/processors/BaseProcessor.h b/src/meta/processors/BaseProcessor.h index e54383ac21e..6fa7c2b7190 100644 --- a/src/meta/processors/BaseProcessor.h +++ b/src/meta/processors/BaseProcessor.h @@ -170,6 +170,11 @@ class BaseProcessor { * */ StatusOr> allHosts(); + /** + * Get all hosts + * */ + StatusOr> allHostsWithStatus(); + /** * Get one auto-increment Id. * */ diff --git a/src/meta/processors/BaseProcessor.inl b/src/meta/processors/BaseProcessor.inl index 069cf253d94..6bfa3869179 100644 --- a/src/meta/processors/BaseProcessor.inl +++ b/src/meta/processors/BaseProcessor.inl @@ -6,6 +6,7 @@ #include "meta/MetaServiceUtils.h" #include "meta/processors/BaseProcessor.h" +#include "meta/ActiveHostsMan.h" namespace nebula { namespace meta { @@ -126,6 +127,44 @@ StatusOr> BaseProcessor::allHosts() { return hosts; } +template +StatusOr> BaseProcessor::allHostsWithStatus() { + std::vector hostItems; + const auto& prefix = MetaServiceUtils::hostPrefix(); + std::unique_ptr iter; + auto ret = kvstore_->prefix(kDefaultSpaceId_, kDefaultPartId_, prefix, &iter); + if (ret != kvstore::ResultCode::SUCCEEDED) { + return Status::Error("Can't find any hosts"); + } + + auto hosts = ActiveHostsManHolder::hostsMan()->getActiveHosts(); + std::vector activeHosts; + activeHosts.resize(hosts.size()); + std::transform(hosts.begin(), hosts.end(), activeHosts.begin(), [](const auto& h) { + nebula::cpp2::HostAddr th; + th.set_ip(h.first); + th.set_port(h.second); + return th; + }); + + while (iter->valid()) { + cpp2::HostItem item; + nebula::cpp2::HostAddr host; + auto hostAddrPiece = iter->key().subpiece(prefix.size()); + memcpy(&host, hostAddrPiece.data(), hostAddrPiece.size()); + item.set_hostAddr(host); + if (std::find(activeHosts.begin(), activeHosts.end(), host) != activeHosts.end()) { + item.set_status("online"); + } else { + item.set_status("offline"); + } + hostItems.emplace_back(item); + iter->next(); + } + + return hostItems; +} + template int32_t BaseProcessor::autoIncrementId() { folly::SharedMutex::WriteHolder holder(LockUtils::idLock()); diff --git a/src/meta/processors/ListHostsProcessor.cpp b/src/meta/processors/ListHostsProcessor.cpp index 9502c384e21..b1bc1a2e12e 100644 --- a/src/meta/processors/ListHostsProcessor.cpp +++ b/src/meta/processors/ListHostsProcessor.cpp @@ -12,7 +12,7 @@ namespace meta { void ListHostsProcessor::process(const cpp2::ListHostsReq& req) { UNUSED(req); folly::SharedMutex::ReadHolder rHolder(LockUtils::spaceLock()); - auto ret = allHosts(); + auto ret = allHostsWithStatus(); if (!ret.ok()) { LOG(ERROR) << "List Hosts Failed : No hosts"; resp_.set_code(cpp2::ErrorCode::E_NO_HOSTS); diff --git a/src/meta/test/HBProcessorTest.cpp b/src/meta/test/HBProcessorTest.cpp index cf68b13b8cc..732df4ad1f3 100644 --- a/src/meta/test/HBProcessorTest.cpp +++ b/src/meta/test/HBProcessorTest.cpp @@ -46,8 +46,8 @@ TEST(HBProcessorTest, HBTest) { auto resp = std::move(f).get(); ASSERT_EQ(10, resp.hosts.size()); for (auto i = 0; i < 10; i++) { - ASSERT_EQ(i, resp.hosts[i].ip); - ASSERT_EQ(i, resp.hosts[i].port); + ASSERT_EQ(i, resp.hosts[i].hostAddr.ip); + ASSERT_EQ(i, resp.hosts[i].hostAddr.port); } } { diff --git a/src/meta/test/MetaClientTest.cpp b/src/meta/test/MetaClientTest.cpp index b0f221c26bb..73d68b39a2a 100644 --- a/src/meta/test/MetaClientTest.cpp +++ b/src/meta/test/MetaClientTest.cpp @@ -51,7 +51,9 @@ TEST(MetaClientTest, InterfacesTest) { TestUtils::registerHB(hosts); auto ret = client->listHosts().get(); ASSERT_TRUE(ret.ok()); - ASSERT_EQ(hosts, ret.value()); + for (auto i = 0u; i < hosts.size(); i++) { + ASSERT_EQ(hosts[i], ret.value()[i].first); + } } { // Test createSpace, listSpaces, getPartsAlloc. @@ -388,7 +390,9 @@ TEST(MetaClientTest, DiffTest) { TestUtils::registerHB(hosts); auto ret = client->listHosts().get(); ASSERT_TRUE(ret.ok()); - ASSERT_EQ(hosts, ret.value()); + for (auto i = 0u; i < hosts.size(); i++) { + ASSERT_EQ(hosts[i], ret.value()[i].first); + } } { // Test Create Space and List Spaces @@ -437,7 +441,9 @@ TEST(MetaClientTest, HeartbeatTest) { ASSERT_TRUE(r.ok()); auto ret = client->listHosts().get(); ASSERT_TRUE(ret.ok()); - ASSERT_EQ(hosts, ret.value()); + for (auto i = 0u; i < hosts.size(); i++) { + ASSERT_EQ(hosts[i], ret.value()[i].first); + } } sleep(FLAGS_heartbeat_interval_secs + 1); ASSERT_EQ(1, ActiveHostsManHolder::hostsMan()->getActiveHosts().size()); diff --git a/src/meta/test/ProcessorTest.cpp b/src/meta/test/ProcessorTest.cpp index 6dcd68c84fe..23b7d0eb968 100644 --- a/src/meta/test/ProcessorTest.cpp +++ b/src/meta/test/ProcessorTest.cpp @@ -64,8 +64,8 @@ TEST(ProcessorTest, AddHostsTest) { auto resp = std::move(f).get(); ASSERT_EQ(10, resp.hosts.size()); for (auto i = 0; i < 10; i++) { - ASSERT_EQ(i, resp.hosts[i].ip); - ASSERT_EQ(i, resp.hosts[i].port); + ASSERT_EQ(i, resp.hosts[i].hostAddr.ip); + ASSERT_EQ(i, resp.hosts[i].hostAddr.port); } } { @@ -89,8 +89,8 @@ TEST(ProcessorTest, AddHostsTest) { auto resp = std::move(f).get(); ASSERT_EQ(20, resp.hosts.size()); for (auto i = 0; i < 20; i++) { - ASSERT_EQ(i, resp.hosts[i].ip); - ASSERT_EQ(i, resp.hosts[i].port); + ASSERT_EQ(i, resp.hosts[i].hostAddr.ip); + ASSERT_EQ(i, resp.hosts[i].hostAddr.port); } } { diff --git a/src/meta/test/TestUtils.h b/src/meta/test/TestUtils.h index 148bdfc0192..ce45f9e793e 100644 --- a/src/meta/test/TestUtils.h +++ b/src/meta/test/TestUtils.h @@ -94,8 +94,8 @@ class TestUtils { auto resp = std::move(f).get(); EXPECT_EQ(hosts.size(), resp.hosts.size()); for (decltype(hosts.size()) i = 0; i < hosts.size(); i++) { - EXPECT_EQ(hosts[i].first, resp.hosts[i].ip); - EXPECT_EQ(hosts[i].second, resp.hosts[i].port); + EXPECT_EQ(hosts[i].first, resp.hosts[i].hostAddr.ip); + EXPECT_EQ(hosts[i].second, resp.hosts[i].hostAddr.port); } } return hosts.size();