A major refactor to decouple replication state from storage. ATM it is still owned by storage but a following part should fix that.
112 lines
4.6 KiB
C++
112 lines
4.6 KiB
C++
// Copyright 2023 Memgraph Ltd.
|
|
//
|
|
// Use of this software is governed by the Business Source License
|
|
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
|
// License, and you may not use this file except in compliance with the Business Source License.
|
|
//
|
|
// As of the Change Date specified in that file, in accordance with
|
|
// the Business Source License, use of this software will be governed
|
|
// by the Apache License, Version 2.0, included in the file
|
|
// licenses/APL.txt.
|
|
|
|
#include "storage/v2/replication/replication_storage_state.hpp"
|
|
|
|
#include "storage/v2/replication/replication_client.hpp"
|
|
#include "storage/v2/replication/replication_server.hpp"
|
|
|
|
namespace memgraph::storage {
|
|
|
|
void ReplicationStorageState::InitializeTransaction(uint64_t seq_num) {
|
|
replication_clients_.WithLock([&](auto &clients) {
|
|
for (auto &client : clients) {
|
|
client->StartTransactionReplication(seq_num);
|
|
}
|
|
});
|
|
}
|
|
|
|
void ReplicationStorageState::AppendDelta(const Delta &delta, const Vertex &vertex, uint64_t timestamp) {
|
|
replication_clients_.WithLock([&](auto &clients) {
|
|
for (auto &client : clients) {
|
|
client->IfStreamingTransaction([&](auto &stream) { stream.AppendDelta(delta, vertex, timestamp); });
|
|
}
|
|
});
|
|
}
|
|
|
|
void ReplicationStorageState::AppendDelta(const Delta &delta, const Edge &edge, uint64_t timestamp) {
|
|
replication_clients_.WithLock([&](auto &clients) {
|
|
for (auto &client : clients) {
|
|
client->IfStreamingTransaction([&](auto &stream) { stream.AppendDelta(delta, edge, timestamp); });
|
|
}
|
|
});
|
|
}
|
|
void ReplicationStorageState::AppendOperation(durability::StorageMetadataOperation operation, LabelId label,
|
|
const std::set<PropertyId> &properties, const LabelIndexStats &stats,
|
|
const LabelPropertyIndexStats &property_stats,
|
|
uint64_t final_commit_timestamp) {
|
|
replication_clients_.WithLock([&](auto &clients) {
|
|
for (auto &client : clients) {
|
|
client->IfStreamingTransaction([&](auto &stream) {
|
|
stream.AppendOperation(operation, label, properties, stats, property_stats, final_commit_timestamp);
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
bool ReplicationStorageState::FinalizeTransaction(uint64_t timestamp) {
|
|
return replication_clients_.WithLock([=](auto &clients) {
|
|
bool finalized_on_all_replicas = true;
|
|
for (ReplicationClientPtr &client : clients) {
|
|
client->IfStreamingTransaction([&](auto &stream) { stream.AppendTransactionEnd(timestamp); });
|
|
const auto finalized = client->FinalizeTransactionReplication();
|
|
|
|
if (client->Mode() == memgraph::replication::ReplicationMode::SYNC) {
|
|
finalized_on_all_replicas = finalized && finalized_on_all_replicas;
|
|
}
|
|
}
|
|
return finalized_on_all_replicas;
|
|
});
|
|
}
|
|
|
|
std::optional<replication::ReplicaState> ReplicationStorageState::GetReplicaState(std::string_view name) const {
|
|
return replication_clients_.WithReadLock([&](auto const &clients) -> std::optional<replication::ReplicaState> {
|
|
auto const name_matches = [=](ReplicationClientPtr const &client) { return client->Name() == name; };
|
|
auto const client_it = std::find_if(clients.cbegin(), clients.cend(), name_matches);
|
|
if (client_it == clients.cend()) {
|
|
return std::nullopt;
|
|
}
|
|
return (*client_it)->State();
|
|
});
|
|
}
|
|
|
|
std::vector<ReplicaInfo> ReplicationStorageState::ReplicasInfo() const {
|
|
return replication_clients_.WithReadLock([](auto const &clients) {
|
|
std::vector<ReplicaInfo> replica_infos;
|
|
replica_infos.reserve(clients.size());
|
|
auto const asReplicaInfo = [](ReplicationClientPtr const &client) -> ReplicaInfo {
|
|
return {client->Name(), client->Mode(), client->Endpoint(), client->State(), client->GetTimestampInfo()};
|
|
};
|
|
std::transform(clients.begin(), clients.end(), std::back_inserter(replica_infos), asReplicaInfo);
|
|
return replica_infos;
|
|
});
|
|
}
|
|
|
|
void ReplicationStorageState::Reset() {
|
|
replication_server_.reset();
|
|
replication_clients_.WithLock([](auto &clients) { clients.clear(); });
|
|
}
|
|
|
|
void ReplicationStorageState::AddEpochToHistory(std::string prev_epoch) {
|
|
constexpr uint16_t kEpochHistoryRetention = 1000;
|
|
// Generate new epoch id and save the last one to the history.
|
|
if (history.size() == kEpochHistoryRetention) {
|
|
history.pop_front();
|
|
}
|
|
history.emplace_back(std::move(prev_epoch), last_commit_timestamp_);
|
|
}
|
|
|
|
void ReplicationStorageState::AddEpochToHistoryForce(std::string prev_epoch) {
|
|
history.emplace_back(std::move(prev_epoch), last_commit_timestamp_);
|
|
}
|
|
|
|
} // namespace memgraph::storage
|