No role when instance down
This commit is contained in:
parent
45def388c7
commit
a6483fc6a7
@ -112,31 +112,36 @@ auto CoordinatorData::DoFailover() -> DoFailoverStatus {
|
||||
return DoFailoverStatus::RPC_FAILED;
|
||||
}
|
||||
|
||||
auto old_main = std::ranges::find_if(registered_instances_, &CoordinatorInstance::IsMain);
|
||||
// TODO: (andi) For performing restoration we will have to improve this
|
||||
old_main->client_.PauseFrequentCheck();
|
||||
|
||||
chosen_replica_instance->PostFailover(main_succ_cb_, main_fail_cb_);
|
||||
|
||||
return DoFailoverStatus::SUCCESS;
|
||||
}
|
||||
|
||||
auto CoordinatorData::ShowMain() const -> std::optional<CoordinatorInstanceStatus> {
|
||||
auto lock = std::shared_lock{coord_data_lock_};
|
||||
auto main_instance = std::ranges::find_if(registered_instances_, &CoordinatorInstance::IsMain);
|
||||
if (main_instance == registered_instances_.end()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return CoordinatorInstanceStatus{.instance_name = main_instance->InstanceName(),
|
||||
.socket_address = main_instance->SocketAddress(),
|
||||
.is_alive = main_instance->IsAlive()};
|
||||
};
|
||||
|
||||
auto CoordinatorData::ShowReplicas() const -> std::vector<CoordinatorInstanceStatus> {
|
||||
auto lock = std::shared_lock{coord_data_lock_};
|
||||
auto CoordinatorData::ShowInstances() const -> std::vector<CoordinatorInstanceStatus> {
|
||||
std::vector<CoordinatorInstanceStatus> instances_status;
|
||||
instances_status.reserve(registered_instances_.size());
|
||||
|
||||
for (const auto &replica_instance : registered_instances_ | ranges::views::filter(&CoordinatorInstance::IsReplica)) {
|
||||
instances_status.emplace_back(CoordinatorInstanceStatus{.instance_name = replica_instance.InstanceName(),
|
||||
.socket_address = replica_instance.SocketAddress(),
|
||||
.is_alive = replica_instance.IsAlive()});
|
||||
auto const stringify_repl_role = [](const CoordinatorInstance &instance) -> std::string {
|
||||
if (!instance.IsAlive()) return "";
|
||||
if (instance.IsMain()) return "main";
|
||||
return "replica";
|
||||
};
|
||||
|
||||
auto const instance_to_status =
|
||||
[&stringify_repl_role](const CoordinatorInstance &instance) -> CoordinatorInstanceStatus {
|
||||
return {.instance_name = instance.InstanceName(),
|
||||
.socket_address = instance.SocketAddress(),
|
||||
.replication_role = stringify_repl_role(instance),
|
||||
.is_alive = instance.IsAlive()};
|
||||
};
|
||||
|
||||
{
|
||||
auto lock = std::shared_lock{coord_data_lock_};
|
||||
std::ranges::transform(registered_instances_, std::back_inserter(instances_status), instance_to_status);
|
||||
}
|
||||
|
||||
return instances_status;
|
||||
|
@ -13,8 +13,8 @@
|
||||
|
||||
#include "coordination/coordinator_state.hpp"
|
||||
|
||||
#include "coordination/register_main_replica_coordinator_status.hpp"
|
||||
#include "coordination/coordinator_config.hpp"
|
||||
#include "coordination/register_main_replica_coordinator_status.hpp"
|
||||
#include "flags/replication.hpp"
|
||||
#include "spdlog/spdlog.h"
|
||||
#include "utils/logging.hpp"
|
||||
@ -68,18 +68,12 @@ auto CoordinatorState::SetInstanceToMain(std::string instance_name) -> SetInstan
|
||||
data_);
|
||||
}
|
||||
|
||||
auto CoordinatorState::ShowReplicas() const -> std::vector<CoordinatorInstanceStatus> {
|
||||
auto CoordinatorState::ShowInstances() const -> std::vector<CoordinatorInstanceStatus> {
|
||||
MG_ASSERT(std::holds_alternative<CoordinatorData>(data_),
|
||||
"Can't call show replicas on data_, as variant holds wrong alternative");
|
||||
return std::get<CoordinatorData>(data_).ShowReplicas();
|
||||
"Can't call show instances on data_, as variant holds wrong alternative");
|
||||
return std::get<CoordinatorData>(data_).ShowInstances();
|
||||
}
|
||||
|
||||
auto CoordinatorState::ShowMain() const -> std::optional<CoordinatorInstanceStatus> {
|
||||
MG_ASSERT(std::holds_alternative<CoordinatorData>(data_),
|
||||
"Can't call show main on data_, as variant holds wrong alternative");
|
||||
return std::get<CoordinatorData>(data_).ShowMain();
|
||||
};
|
||||
|
||||
[[nodiscard]] auto CoordinatorState::DoFailover() -> DoFailoverStatus {
|
||||
MG_ASSERT(std::holds_alternative<CoordinatorData>(data_), "Cannot do failover since variant holds wrong alternative");
|
||||
auto &coord_state = std::get<CoordinatorData>(data_);
|
||||
|
@ -32,8 +32,7 @@ class CoordinatorData {
|
||||
[[nodiscard]] auto RegisterInstance(CoordinatorClientConfig config) -> RegisterInstanceCoordinatorStatus;
|
||||
[[nodiscard]] auto SetInstanceToMain(std::string instance_name) -> SetInstanceToMainCoordinatorStatus;
|
||||
|
||||
auto ShowReplicas() const -> std::vector<CoordinatorInstanceStatus>;
|
||||
auto ShowMain() const -> std::optional<CoordinatorInstanceStatus>;
|
||||
auto ShowInstances() const -> std::vector<CoordinatorInstanceStatus>;
|
||||
|
||||
private:
|
||||
mutable utils::RWLock coord_data_lock_{utils::RWLock::Priority::READ};
|
||||
|
@ -22,6 +22,7 @@ namespace memgraph::coordination {
|
||||
struct CoordinatorInstanceStatus {
|
||||
std::string instance_name;
|
||||
std::string socket_address;
|
||||
std::string replication_role;
|
||||
bool is_alive;
|
||||
};
|
||||
|
||||
|
@ -38,9 +38,7 @@ class CoordinatorState {
|
||||
|
||||
[[nodiscard]] auto SetInstanceToMain(std::string instance_name) -> SetInstanceToMainCoordinatorStatus;
|
||||
|
||||
auto ShowReplicas() const -> std::vector<CoordinatorInstanceStatus>;
|
||||
|
||||
auto ShowMain() const -> std::optional<CoordinatorInstanceStatus>;
|
||||
auto ShowInstances() const -> std::vector<CoordinatorInstanceStatus>;
|
||||
|
||||
// The client code must check that the server exists before calling this method.
|
||||
auto GetCoordinatorServer() const -> CoordinatorServer &;
|
||||
|
@ -30,14 +30,9 @@ auto CoordinatorHandler::SetInstanceToMain(std::string instance_name)
|
||||
return dbms_handler_.CoordinatorState().SetInstanceToMain(std::move(instance_name));
|
||||
}
|
||||
|
||||
auto CoordinatorHandler::ShowReplicasOnCoordinator() const -> std::vector<coordination::CoordinatorInstanceStatus> {
|
||||
return dbms_handler_.CoordinatorState().ShowReplicas();
|
||||
auto CoordinatorHandler::ShowInstances() const -> std::vector<coordination::CoordinatorInstanceStatus> {
|
||||
return dbms_handler_.CoordinatorState().ShowInstances();
|
||||
}
|
||||
|
||||
auto CoordinatorHandler::ShowMainOnCoordinator() const -> std::optional<coordination::CoordinatorInstanceStatus> {
|
||||
return dbms_handler_.CoordinatorState().ShowMain();
|
||||
}
|
||||
|
||||
} // namespace memgraph::dbms
|
||||
|
||||
#endif
|
||||
|
@ -37,9 +37,7 @@ class CoordinatorHandler {
|
||||
|
||||
auto SetInstanceToMain(std::string instance_name) -> coordination::SetInstanceToMainCoordinatorStatus;
|
||||
|
||||
auto ShowReplicasOnCoordinator() const -> std::vector<coordination::CoordinatorInstanceStatus>;
|
||||
|
||||
auto ShowMainOnCoordinator() const -> std::optional<coordination::CoordinatorInstanceStatus>;
|
||||
auto ShowInstances() const -> std::vector<coordination::CoordinatorInstanceStatus>;
|
||||
|
||||
private:
|
||||
DbmsHandler &dbms_handler_;
|
||||
|
@ -532,13 +532,10 @@ class CoordQueryHandler final : public query::CoordinatorQueryHandler {
|
||||
#endif
|
||||
|
||||
#ifdef MG_ENTERPRISE
|
||||
std::vector<coordination::CoordinatorInstanceStatus> ShowReplicasOnCoordinator() const override {
|
||||
return coordinator_handler_.ShowReplicasOnCoordinator();
|
||||
std::vector<coordination::CoordinatorInstanceStatus> ShowInstances() const override {
|
||||
return coordinator_handler_.ShowInstances();
|
||||
}
|
||||
|
||||
std::optional<coordination::CoordinatorInstanceStatus> ShowMainOnCoordinator() const override {
|
||||
return coordinator_handler_.ShowMainOnCoordinator();
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
@ -1079,19 +1076,16 @@ Callback HandleCoordinatorQuery(CoordinatorQuery *coordinator_query, const Param
|
||||
|
||||
callback.header = {"name", "socket_address", "alive", "role"};
|
||||
callback.fn = [handler = CoordQueryHandler{dbms_handler}, replica_nfields = callback.header.size()]() mutable {
|
||||
const auto replicas = handler.ShowReplicasOnCoordinator();
|
||||
const auto main = handler.ShowMainOnCoordinator();
|
||||
auto const instances = handler.ShowInstances();
|
||||
std::vector<std::vector<TypedValue>> result{};
|
||||
result.reserve(replicas.size() + 1);
|
||||
result.reserve(result.size());
|
||||
|
||||
std::ranges::transform(instances, std::back_inserter(result),
|
||||
[](const auto &status) -> std::vector<TypedValue> {
|
||||
return {TypedValue{status.instance_name}, TypedValue{status.socket_address},
|
||||
TypedValue{status.is_alive}, TypedValue{status.replication_role}};
|
||||
});
|
||||
|
||||
std::ranges::transform(replicas, std::back_inserter(result), [](const auto &status) -> std::vector<TypedValue> {
|
||||
return {TypedValue{status.instance_name}, TypedValue{status.socket_address}, TypedValue{status.is_alive},
|
||||
TypedValue{"replica"}};
|
||||
});
|
||||
if (main) {
|
||||
result.emplace_back(std::vector<TypedValue>{TypedValue{main->instance_name}, TypedValue{main->socket_address},
|
||||
TypedValue{main->is_alive}, TypedValue{"main"}});
|
||||
}
|
||||
return result;
|
||||
};
|
||||
return callback;
|
||||
|
@ -116,10 +116,7 @@ class CoordinatorQueryHandler {
|
||||
virtual void SetInstanceToMain(const std::string &instance_name) = 0;
|
||||
|
||||
/// @throw QueryRuntimeException if an error ocurred.
|
||||
virtual std::vector<coordination::CoordinatorInstanceStatus> ShowReplicasOnCoordinator() const = 0;
|
||||
|
||||
/// @throw QueryRuntimeException if an error ocurred.
|
||||
virtual std::optional<coordination::CoordinatorInstanceStatus> ShowMainOnCoordinator() const = 0;
|
||||
virtual std::vector<coordination::CoordinatorInstanceStatus> ShowInstances() const = 0;
|
||||
|
||||
#endif
|
||||
};
|
||||
|
@ -82,19 +82,19 @@ def test_show_replication_cluster(connection):
|
||||
interactive_mg_runner.kill(MEMGRAPH_INSTANCES_DESCRIPTION, "instance_1")
|
||||
|
||||
expected_data = [
|
||||
("instance_1", "127.0.0.1:10011", False, "replica"),
|
||||
("instance_1", "127.0.0.1:10011", False, ""),
|
||||
("instance_2", "127.0.0.1:10012", True, "replica"),
|
||||
("instance_3", "127.0.0.1:10013", True, "main"),
|
||||
]
|
||||
mg_sleep_and_assert(expected_data, retrieve_data)
|
||||
|
||||
# 4.
|
||||
interactive_mg_runner.kill(MEMGRAPH_INSTANCES_DESCRIPTION, "instance_3")
|
||||
interactive_mg_runner.kill(MEMGRAPH_INSTANCES_DESCRIPTION, "instance_2")
|
||||
|
||||
expected_data = [
|
||||
("instance_1", "127.0.0.1:10011", False, "replica"),
|
||||
("instance_2", "127.0.0.1:10012", True, "replica"),
|
||||
("instance_3", "127.0.0.1:10013", False, "main"),
|
||||
("instance_1", "127.0.0.1:10011", False, ""),
|
||||
("instance_2", "127.0.0.1:10012", False, ""),
|
||||
("instance_3", "127.0.0.1:10013", True, "main"),
|
||||
]
|
||||
mg_sleep_and_assert(expected_data, retrieve_data)
|
||||
|
||||
@ -120,7 +120,7 @@ def test_simple_automatic_failover(connection):
|
||||
expected_data_on_coord = [
|
||||
("instance_1", "127.0.0.1:10011", True, "main"),
|
||||
("instance_2", "127.0.0.1:10012", True, "replica"),
|
||||
("instance_3", "127.0.0.1:10013", False, "main"),
|
||||
("instance_3", "127.0.0.1:10013", False, ""),
|
||||
]
|
||||
mg_sleep_and_assert(expected_data_on_coord, retrieve_data_show_repl_cluster)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user