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