Single (instance level) connection to a replica (messages from all databases get multiplexed through it) ReplicationClient split in two: ReplicationClient and ReplicationStorageClient New ReplicationClient, moved under replication, handles the raw connection, owned by MainRoleData ReplicationStorageClient handles the storage <-> replica state machine and holds to a stream Removed epoch and storage from *Clients rpc::Stream proactively aborts on error and sets itself to a defunct state Removed HandleRpcFailure, instead we simply log the error and let the FrequentCheck handle re-connection replica_state is now a synced variable ReplicaStorageClient state machine bugfixes Single FrequentCheck that goes through DBMS Moved ReplicationState under DbmsHandler Moved some replication startup logic under the DbmsHandler's constructor Removed InMemoryReplicationClient CreateReplicationClient has been removed from Storage Simplified GetRecoverySteps and made safer --------- Co-authored-by: Gareth Lloyd <gareth.lloyd@memgraph.io>
97 lines
2.9 KiB
C++
97 lines
2.9 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.
|
|
|
|
#pragma once
|
|
|
|
#ifdef MG_ENTERPRISE
|
|
|
|
#include <algorithm>
|
|
#include <filesystem>
|
|
#include <iterator>
|
|
#include <memory>
|
|
#include <optional>
|
|
#include <string_view>
|
|
#include <unordered_map>
|
|
|
|
#include "dbms/database.hpp"
|
|
|
|
#include "handler.hpp"
|
|
|
|
namespace memgraph::dbms {
|
|
|
|
/* NOTE
|
|
* The Database object is shared. All the higher-level function calls should be protected.
|
|
* Storage function calls should already be protected; add protection where needed.
|
|
*
|
|
* Current implementation uses a handler of Database objects. It owns them and gives
|
|
* Gatekeeper::Accessor to it. These guarantee that the object won't be
|
|
* destroyed unless no one is using it.
|
|
*/
|
|
|
|
/**Config
|
|
* @brief Multi-database storage handler
|
|
*
|
|
*/
|
|
class DatabaseHandler : public Handler<Database> {
|
|
public:
|
|
using HandlerT = Handler<Database>;
|
|
|
|
/**
|
|
* @brief Generate new storage associated with the passed name.
|
|
*
|
|
* @param name Name associating the new interpreter context
|
|
* @param config Storage configuration
|
|
* @return HandlerT::NewResult
|
|
*/
|
|
HandlerT::NewResult New(std::string_view name, storage::Config config, replication::ReplicationState &repl_state) {
|
|
// Control that no one is using the same data directory
|
|
if (std::any_of(begin(), end(), [&](auto &elem) {
|
|
auto db_acc = elem.second.access();
|
|
MG_ASSERT(db_acc.has_value(), "Gatekeeper in invalid state");
|
|
return db_acc->get()->config().durability.storage_directory == config.durability.storage_directory;
|
|
})) {
|
|
spdlog::info("Tried to generate new storage using a claimed directory.");
|
|
return NewError::EXISTS;
|
|
}
|
|
config.name = name; // Set storage id via config
|
|
return HandlerT::New(std::piecewise_construct, name, config, repl_state);
|
|
}
|
|
|
|
/**
|
|
* @brief All currently active storage.
|
|
*
|
|
* @return std::vector<std::string>
|
|
*/
|
|
std::vector<std::string> All() const {
|
|
std::vector<std::string> res;
|
|
res.reserve(std::distance(cbegin(), cend()));
|
|
std::for_each(cbegin(), cend(), [&](const auto &elem) { res.push_back(elem.first); });
|
|
return res;
|
|
}
|
|
|
|
/**
|
|
* @brief Get the associated storage's configuration
|
|
*
|
|
* @param name
|
|
* @return std::optional<storage::Config>
|
|
*/
|
|
std::optional<storage::Config> GetConfig(std::string_view name) {
|
|
auto db = Get(name);
|
|
if (db) {
|
|
return (*db)->config();
|
|
}
|
|
return std::nullopt;
|
|
}
|
|
};
|
|
|
|
} // namespace memgraph::dbms
|
|
#endif
|