forked from mooncake-track/Mooncake
[Store] Refine Complicated Constructor Parameters (#748)
This commit is contained in:
parent
d6c1013891
commit
ec87bbd58b
|
|
@ -1,33 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
namespace mooncake {
|
||||
|
||||
struct MasterConfig {
|
||||
bool enable_gc;
|
||||
bool enable_metric_reporting;
|
||||
uint32_t metrics_port;
|
||||
uint32_t rpc_port;
|
||||
uint32_t rpc_thread_num;
|
||||
std::string rpc_address;
|
||||
int32_t rpc_conn_timeout_seconds;
|
||||
bool rpc_enable_tcp_no_delay;
|
||||
|
||||
uint64_t default_kv_lease_ttl;
|
||||
uint64_t default_kv_soft_pin_ttl;
|
||||
bool allow_evict_soft_pinned_objects;
|
||||
double eviction_ratio;
|
||||
double eviction_high_watermark_ratio;
|
||||
int64_t client_live_ttl_sec;
|
||||
|
||||
bool enable_ha;
|
||||
std::string etcd_endpoints;
|
||||
|
||||
std::string cluster_id;
|
||||
std::string root_fs_dir;
|
||||
std::string memory_allocator;
|
||||
};
|
||||
|
||||
} // namespace mooncake
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace mooncake {
|
||||
|
||||
/**
|
||||
* @brief A template class that wraps std::optional to provide configurable
|
||||
* variables with setter/getter functionality and exception handling for unset
|
||||
* values.
|
||||
* @tparam T The type of the configurable variable
|
||||
*/
|
||||
template <typename T>
|
||||
class RequiredParam {
|
||||
private:
|
||||
std::optional<T> value_;
|
||||
|
||||
public:
|
||||
RequiredParam() : name_(nullptr) {}
|
||||
RequiredParam(const char* name) : name_(name) {}
|
||||
|
||||
// Add copy constructor
|
||||
RequiredParam(const RequiredParam& other) { value_ = other.value_; }
|
||||
|
||||
// Add copy assignment operator
|
||||
RequiredParam& operator=(const RequiredParam& other) {
|
||||
value_ = other.value_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Assignment operator to set the value
|
||||
* @param value The value to set
|
||||
* @return Reference to this object
|
||||
*/
|
||||
RequiredParam& operator=(const T& value) {
|
||||
value_ = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the value of the config variable
|
||||
* @param value The value to set
|
||||
*/
|
||||
void Set(const T& value) { value_ = value; }
|
||||
|
||||
/**
|
||||
* @brief Get the value of the config variable
|
||||
* @return The stored value
|
||||
* @throws std::runtime_error if the value has not been set
|
||||
*/
|
||||
T Get() const {
|
||||
if (!value_.has_value()) {
|
||||
if (name_ == nullptr) {
|
||||
throw std::runtime_error("Required parameter has not been set");
|
||||
} else {
|
||||
throw std::runtime_error("Required parameter " +
|
||||
std::string(name_) +
|
||||
" has not been set");
|
||||
}
|
||||
}
|
||||
return value_.value();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Implicit conversion operator to type T
|
||||
* @return The stored value
|
||||
* @throws std::runtime_error if the value has not been set
|
||||
*/
|
||||
operator T() const { return Get(); }
|
||||
|
||||
/**
|
||||
* @brief Check if the value has been set
|
||||
* @return true if the value is set, false otherwise
|
||||
*/
|
||||
bool IsSet() const { return value_.has_value(); }
|
||||
|
||||
/**
|
||||
* @brief Get the value if set, otherwise return a default value
|
||||
* @param default_value The default value to return if not set
|
||||
* @return The stored value or the default value
|
||||
*/
|
||||
T GetOrDefault(const T& default_value) const {
|
||||
return value_.value_or(default_value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear the stored value
|
||||
*/
|
||||
void Clear() { value_.reset(); }
|
||||
|
||||
private:
|
||||
// The name of the parameter, used for error message
|
||||
const char* name_;
|
||||
};
|
||||
|
||||
} // namespace mooncake
|
||||
|
|
@ -3,16 +3,12 @@
|
|||
|
||||
#include <glog/logging.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <ylt/coro_rpc/coro_rpc_server.hpp>
|
||||
|
||||
#include "etcd_helper.h"
|
||||
#include "rpc_service.h"
|
||||
#include "config.h"
|
||||
#include "types.h"
|
||||
#include "master_config.h"
|
||||
|
||||
namespace mooncake {
|
||||
|
||||
|
|
@ -76,57 +72,15 @@ class MasterViewHelper {
|
|||
*/
|
||||
class MasterServiceSupervisor {
|
||||
public:
|
||||
MasterServiceSupervisor(
|
||||
int rpc_port, size_t rpc_thread_num, bool enable_gc,
|
||||
bool enable_metric_reporting, int metrics_port,
|
||||
int64_t default_kv_lease_ttl, int64_t default_kv_soft_pin_ttl,
|
||||
bool allow_evict_soft_pinned_objects, double eviction_ratio,
|
||||
double eviction_high_watermark_ratio, int64_t client_live_ttl_sec,
|
||||
const std::string& etcd_endpoints = "0.0.0.0:2379",
|
||||
const std::string& local_hostname = "0.0.0.0:50051",
|
||||
const std::string& rpc_address = "0.0.0.0",
|
||||
std::chrono::steady_clock::duration rpc_conn_timeout =
|
||||
std::chrono::seconds(
|
||||
0), // Client connection timeout. 0 = no timeout (infinite)
|
||||
bool rpc_enable_tcp_no_delay = true,
|
||||
const std::string& cluster_id = DEFAULT_CLUSTER_ID,
|
||||
const std::string& root_fs_dir = DEFAULT_ROOT_FS_DIR,
|
||||
BufferAllocatorType memory_allocator = BufferAllocatorType::CACHELIB);
|
||||
MasterServiceSupervisor(const MasterConfig& master_config);
|
||||
MasterServiceSupervisor(const MasterServiceSupervisorConfig& config);
|
||||
int Start();
|
||||
~MasterServiceSupervisor();
|
||||
|
||||
private:
|
||||
// Master service parameters
|
||||
bool enable_gc_;
|
||||
bool enable_metric_reporting_;
|
||||
int metrics_port_;
|
||||
int64_t default_kv_lease_ttl_;
|
||||
int64_t default_kv_soft_pin_ttl_;
|
||||
bool allow_evict_soft_pinned_objects_;
|
||||
double eviction_ratio_;
|
||||
double eviction_high_watermark_ratio_;
|
||||
int64_t client_live_ttl_sec_;
|
||||
|
||||
// RPC server configuration parameters
|
||||
const int rpc_port_;
|
||||
const size_t rpc_thread_num_;
|
||||
const std::string rpc_address_;
|
||||
const std::chrono::steady_clock::duration rpc_conn_timeout_;
|
||||
const bool rpc_enable_tcp_no_delay_;
|
||||
|
||||
// coro_rpc server thread
|
||||
std::thread server_thread_;
|
||||
|
||||
// ETCD parameters
|
||||
std::string etcd_endpoints_;
|
||||
|
||||
// Local hostname for leader election
|
||||
std::string local_hostname_;
|
||||
|
||||
std::string cluster_id_;
|
||||
std::string root_fs_dir_;
|
||||
BufferAllocatorType memory_allocator_;
|
||||
MasterServiceSupervisorConfig config_;
|
||||
};
|
||||
|
||||
} // namespace mooncake
|
||||
|
|
|
|||
|
|
@ -0,0 +1,377 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include "config_helper.h"
|
||||
#include "types.h"
|
||||
|
||||
namespace mooncake {
|
||||
|
||||
// The configuration for the master server
|
||||
struct MasterConfig {
|
||||
bool enable_gc;
|
||||
bool enable_metric_reporting;
|
||||
uint32_t metrics_port;
|
||||
uint32_t rpc_port;
|
||||
uint32_t rpc_thread_num;
|
||||
std::string rpc_address;
|
||||
int32_t rpc_conn_timeout_seconds;
|
||||
bool rpc_enable_tcp_no_delay;
|
||||
|
||||
uint64_t default_kv_lease_ttl;
|
||||
uint64_t default_kv_soft_pin_ttl;
|
||||
bool allow_evict_soft_pinned_objects;
|
||||
double eviction_ratio;
|
||||
double eviction_high_watermark_ratio;
|
||||
int64_t client_live_ttl_sec;
|
||||
|
||||
bool enable_ha;
|
||||
std::string etcd_endpoints;
|
||||
|
||||
std::string cluster_id;
|
||||
std::string root_fs_dir;
|
||||
std::string memory_allocator;
|
||||
};
|
||||
|
||||
class MasterServiceSupervisorConfig {
|
||||
public:
|
||||
// no default values (required parameters) - using RequiredParam
|
||||
RequiredParam<bool> enable_gc{"enable_gc"};
|
||||
RequiredParam<bool> enable_metric_reporting{"enable_metric_reporting"};
|
||||
RequiredParam<int> metrics_port{"metrics_port"};
|
||||
RequiredParam<int64_t> default_kv_lease_ttl{"default_kv_lease_ttl"};
|
||||
RequiredParam<int64_t> default_kv_soft_pin_ttl{"default_kv_soft_pin_ttl"};
|
||||
RequiredParam<bool> allow_evict_soft_pinned_objects{
|
||||
"allow_evict_soft_pinned_objects"};
|
||||
RequiredParam<double> eviction_ratio{"eviction_ratio"};
|
||||
RequiredParam<double> eviction_high_watermark_ratio{
|
||||
"eviction_high_watermark_ratio"};
|
||||
RequiredParam<int64_t> client_live_ttl_sec{"client_live_ttl_sec"};
|
||||
RequiredParam<int> rpc_port{"rpc_port"};
|
||||
RequiredParam<size_t> rpc_thread_num{"rpc_thread_num"};
|
||||
|
||||
// Parameters with default values (optional parameters)
|
||||
std::string rpc_address = "0.0.0.0";
|
||||
std::chrono::steady_clock::duration rpc_conn_timeout = std::chrono::seconds(
|
||||
0); // Client connection timeout. 0 = no timeout (infinite)
|
||||
bool rpc_enable_tcp_no_delay = true;
|
||||
std::string etcd_endpoints = "0.0.0.0:2379";
|
||||
std::string local_hostname = "0.0.0.0:50051";
|
||||
std::string cluster_id = DEFAULT_CLUSTER_ID;
|
||||
std::string root_fs_dir = DEFAULT_ROOT_FS_DIR;
|
||||
BufferAllocatorType memory_allocator = BufferAllocatorType::OFFSET;
|
||||
|
||||
MasterServiceSupervisorConfig() = default;
|
||||
|
||||
// From MasterConfig
|
||||
MasterServiceSupervisorConfig(const MasterConfig& config) {
|
||||
// Set required parameters using RequiredParam
|
||||
enable_gc = config.enable_gc;
|
||||
enable_metric_reporting = config.enable_metric_reporting;
|
||||
metrics_port = static_cast<int>(config.metrics_port);
|
||||
default_kv_lease_ttl = config.default_kv_lease_ttl;
|
||||
default_kv_soft_pin_ttl = config.default_kv_soft_pin_ttl;
|
||||
allow_evict_soft_pinned_objects =
|
||||
config.allow_evict_soft_pinned_objects;
|
||||
eviction_ratio = config.eviction_ratio;
|
||||
eviction_high_watermark_ratio = config.eviction_high_watermark_ratio;
|
||||
client_live_ttl_sec = config.client_live_ttl_sec;
|
||||
rpc_port = static_cast<int>(config.rpc_port);
|
||||
rpc_thread_num = static_cast<size_t>(config.rpc_thread_num);
|
||||
|
||||
// Set optional parameters (these have default values)
|
||||
rpc_address = config.rpc_address;
|
||||
rpc_conn_timeout =
|
||||
std::chrono::seconds(config.rpc_conn_timeout_seconds);
|
||||
rpc_enable_tcp_no_delay = config.rpc_enable_tcp_no_delay;
|
||||
etcd_endpoints = config.etcd_endpoints;
|
||||
local_hostname = rpc_address + ":" + std::to_string(rpc_port);
|
||||
cluster_id = config.cluster_id;
|
||||
root_fs_dir = config.root_fs_dir;
|
||||
|
||||
// Convert string memory_allocator to BufferAllocatorType enum
|
||||
if (config.memory_allocator == "cachelib") {
|
||||
memory_allocator = BufferAllocatorType::CACHELIB;
|
||||
} else {
|
||||
memory_allocator = BufferAllocatorType::OFFSET;
|
||||
}
|
||||
|
||||
validate();
|
||||
}
|
||||
|
||||
// Some of the parameters are not used in constructor but will be used in
|
||||
// the future. So we need to validate them at the beginning of the program
|
||||
// to avoid unexpected errors in the future.
|
||||
void validate() const {
|
||||
// Validate that all required parameters are set
|
||||
if (!enable_gc.IsSet()) {
|
||||
throw std::runtime_error("enable_gc is not set");
|
||||
}
|
||||
if (!enable_metric_reporting.IsSet()) {
|
||||
throw std::runtime_error("enable_metric_reporting is not set");
|
||||
}
|
||||
if (!metrics_port.IsSet()) {
|
||||
throw std::runtime_error("metrics_port is not set");
|
||||
}
|
||||
if (!default_kv_lease_ttl.IsSet()) {
|
||||
throw std::runtime_error("default_kv_lease_ttl is not set");
|
||||
}
|
||||
if (!default_kv_soft_pin_ttl.IsSet()) {
|
||||
throw std::runtime_error("default_kv_soft_pin_ttl is not set");
|
||||
}
|
||||
if (!allow_evict_soft_pinned_objects.IsSet()) {
|
||||
throw std::runtime_error(
|
||||
"allow_evict_soft_pinned_objects is not set");
|
||||
}
|
||||
if (!eviction_ratio.IsSet()) {
|
||||
throw std::runtime_error("eviction_ratio is not set");
|
||||
}
|
||||
if (!eviction_high_watermark_ratio.IsSet()) {
|
||||
throw std::runtime_error(
|
||||
"eviction_high_watermark_ratio is not set");
|
||||
}
|
||||
if (!client_live_ttl_sec.IsSet()) {
|
||||
throw std::runtime_error("client_live_ttl_sec is not set");
|
||||
}
|
||||
if (!rpc_port.IsSet()) {
|
||||
throw std::runtime_error("rpc_port is not set");
|
||||
}
|
||||
if (!rpc_thread_num.IsSet()) {
|
||||
throw std::runtime_error("rpc_thread_num is not set");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class WrappedMasterServiceConfig {
|
||||
public:
|
||||
// Required parameters (no default values) - using RequiredParam
|
||||
RequiredParam<bool> enable_gc{"enable_gc"};
|
||||
RequiredParam<uint64_t> default_kv_lease_ttl{"default_kv_lease_ttl"};
|
||||
|
||||
// Optional parameters (with default values)
|
||||
uint64_t default_kv_soft_pin_ttl = DEFAULT_KV_SOFT_PIN_TTL_MS;
|
||||
bool allow_evict_soft_pinned_objects =
|
||||
DEFAULT_ALLOW_EVICT_SOFT_PINNED_OBJECTS;
|
||||
bool enable_metric_reporting = true;
|
||||
uint16_t http_port = 9003;
|
||||
double eviction_ratio = DEFAULT_EVICTION_RATIO;
|
||||
double eviction_high_watermark_ratio =
|
||||
DEFAULT_EVICTION_HIGH_WATERMARK_RATIO;
|
||||
ViewVersionId view_version = 0;
|
||||
int64_t client_live_ttl_sec = DEFAULT_CLIENT_LIVE_TTL_SEC;
|
||||
bool enable_ha = false;
|
||||
std::string cluster_id = DEFAULT_CLUSTER_ID;
|
||||
std::string root_fs_dir = DEFAULT_ROOT_FS_DIR;
|
||||
BufferAllocatorType memory_allocator = BufferAllocatorType::OFFSET;
|
||||
|
||||
WrappedMasterServiceConfig() = default;
|
||||
|
||||
// From MasterConfig
|
||||
WrappedMasterServiceConfig(const MasterConfig& config,
|
||||
ViewVersionId view_version_param) {
|
||||
// Set required parameters using RequiredParam
|
||||
enable_gc = config.enable_gc;
|
||||
default_kv_lease_ttl = config.default_kv_lease_ttl;
|
||||
|
||||
// Set optional parameters (these have default values)
|
||||
default_kv_soft_pin_ttl = config.default_kv_soft_pin_ttl;
|
||||
allow_evict_soft_pinned_objects =
|
||||
config.allow_evict_soft_pinned_objects;
|
||||
enable_metric_reporting = config.enable_metric_reporting;
|
||||
http_port = static_cast<uint16_t>(config.metrics_port);
|
||||
eviction_ratio = config.eviction_ratio;
|
||||
eviction_high_watermark_ratio = config.eviction_high_watermark_ratio;
|
||||
view_version = view_version_param;
|
||||
client_live_ttl_sec = config.client_live_ttl_sec;
|
||||
enable_ha = config.enable_ha;
|
||||
cluster_id = config.cluster_id;
|
||||
root_fs_dir = config.root_fs_dir;
|
||||
|
||||
// Convert string memory_allocator to BufferAllocatorType enum
|
||||
if (config.memory_allocator == "cachelib") {
|
||||
memory_allocator = mooncake::BufferAllocatorType::CACHELIB;
|
||||
} else {
|
||||
memory_allocator = mooncake::BufferAllocatorType::OFFSET;
|
||||
}
|
||||
}
|
||||
|
||||
// From MasterServiceSupervisorConfig, enable_ha is set to true
|
||||
WrappedMasterServiceConfig(const MasterServiceSupervisorConfig& config,
|
||||
ViewVersionId view_version_param)
|
||||
: WrappedMasterServiceConfig() {
|
||||
// Set required parameters using assignment operator
|
||||
enable_gc = config.enable_gc;
|
||||
default_kv_lease_ttl = config.default_kv_lease_ttl;
|
||||
|
||||
// Set optional parameters (these have default values)
|
||||
default_kv_soft_pin_ttl = config.default_kv_soft_pin_ttl;
|
||||
allow_evict_soft_pinned_objects =
|
||||
config.allow_evict_soft_pinned_objects;
|
||||
enable_metric_reporting = config.enable_metric_reporting;
|
||||
http_port = static_cast<uint16_t>(config.metrics_port);
|
||||
eviction_ratio = config.eviction_ratio;
|
||||
eviction_high_watermark_ratio = config.eviction_high_watermark_ratio;
|
||||
view_version = view_version_param;
|
||||
client_live_ttl_sec = config.client_live_ttl_sec;
|
||||
enable_ha =
|
||||
true; // This is used in HA mode, so enable_ha should be true
|
||||
cluster_id = config.cluster_id;
|
||||
root_fs_dir = config.root_fs_dir;
|
||||
memory_allocator = config.memory_allocator;
|
||||
}
|
||||
};
|
||||
|
||||
// Forward declarations
|
||||
class MasterServiceConfig;
|
||||
|
||||
// Builder class for MasterServiceConfig
|
||||
class MasterServiceConfigBuilder {
|
||||
private:
|
||||
bool enable_gc_ = false;
|
||||
uint64_t default_kv_lease_ttl_ = DEFAULT_DEFAULT_KV_LEASE_TTL;
|
||||
uint64_t default_kv_soft_pin_ttl_ = DEFAULT_KV_SOFT_PIN_TTL_MS;
|
||||
bool allow_evict_soft_pinned_objects_ =
|
||||
DEFAULT_ALLOW_EVICT_SOFT_PINNED_OBJECTS;
|
||||
double eviction_ratio_ = DEFAULT_EVICTION_RATIO;
|
||||
double eviction_high_watermark_ratio_ =
|
||||
DEFAULT_EVICTION_HIGH_WATERMARK_RATIO;
|
||||
ViewVersionId view_version_ = 0;
|
||||
int64_t client_live_ttl_sec_ = DEFAULT_CLIENT_LIVE_TTL_SEC;
|
||||
bool enable_ha_ = false;
|
||||
std::string cluster_id_ = DEFAULT_CLUSTER_ID;
|
||||
std::string root_fs_dir_ = DEFAULT_ROOT_FS_DIR;
|
||||
BufferAllocatorType memory_allocator_ = BufferAllocatorType::OFFSET;
|
||||
|
||||
public:
|
||||
MasterServiceConfigBuilder() = default;
|
||||
|
||||
MasterServiceConfigBuilder& set_enable_gc(bool enable_gc) {
|
||||
enable_gc_ = enable_gc;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MasterServiceConfigBuilder& set_default_kv_lease_ttl(uint64_t ttl) {
|
||||
default_kv_lease_ttl_ = ttl;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MasterServiceConfigBuilder& set_default_kv_soft_pin_ttl(uint64_t ttl) {
|
||||
default_kv_soft_pin_ttl_ = ttl;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MasterServiceConfigBuilder& set_allow_evict_soft_pinned_objects(
|
||||
bool allow) {
|
||||
allow_evict_soft_pinned_objects_ = allow;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MasterServiceConfigBuilder& set_eviction_ratio(double ratio) {
|
||||
eviction_ratio_ = ratio;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MasterServiceConfigBuilder& set_eviction_high_watermark_ratio(
|
||||
double ratio) {
|
||||
eviction_high_watermark_ratio_ = ratio;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MasterServiceConfigBuilder& set_view_version(ViewVersionId version) {
|
||||
view_version_ = version;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MasterServiceConfigBuilder& set_client_live_ttl_sec(int64_t ttl) {
|
||||
client_live_ttl_sec_ = ttl;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MasterServiceConfigBuilder& set_enable_ha(bool enable) {
|
||||
enable_ha_ = enable;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MasterServiceConfigBuilder& set_cluster_id(const std::string& id) {
|
||||
cluster_id_ = id;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MasterServiceConfigBuilder& set_root_fs_dir(const std::string& dir) {
|
||||
root_fs_dir_ = dir;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MasterServiceConfigBuilder& set_memory_allocator(
|
||||
BufferAllocatorType allocator) {
|
||||
memory_allocator_ = allocator;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MasterServiceConfig build() const;
|
||||
};
|
||||
|
||||
class MasterServiceConfig {
|
||||
public:
|
||||
bool enable_gc = false;
|
||||
uint64_t default_kv_lease_ttl = DEFAULT_DEFAULT_KV_LEASE_TTL;
|
||||
uint64_t default_kv_soft_pin_ttl = DEFAULT_KV_SOFT_PIN_TTL_MS;
|
||||
bool allow_evict_soft_pinned_objects =
|
||||
DEFAULT_ALLOW_EVICT_SOFT_PINNED_OBJECTS;
|
||||
double eviction_ratio = DEFAULT_EVICTION_RATIO;
|
||||
double eviction_high_watermark_ratio =
|
||||
DEFAULT_EVICTION_HIGH_WATERMARK_RATIO;
|
||||
ViewVersionId view_version = 0;
|
||||
int64_t client_live_ttl_sec = DEFAULT_CLIENT_LIVE_TTL_SEC;
|
||||
bool enable_ha = false;
|
||||
std::string cluster_id = DEFAULT_CLUSTER_ID;
|
||||
std::string root_fs_dir = DEFAULT_ROOT_FS_DIR;
|
||||
BufferAllocatorType memory_allocator = BufferAllocatorType::OFFSET;
|
||||
|
||||
MasterServiceConfig() = default;
|
||||
|
||||
// From WrappedMasterServiceConfig
|
||||
MasterServiceConfig(const WrappedMasterServiceConfig& config) {
|
||||
enable_gc = config.enable_gc;
|
||||
default_kv_lease_ttl = config.default_kv_lease_ttl;
|
||||
default_kv_soft_pin_ttl = config.default_kv_soft_pin_ttl;
|
||||
allow_evict_soft_pinned_objects =
|
||||
config.allow_evict_soft_pinned_objects;
|
||||
eviction_ratio = config.eviction_ratio;
|
||||
eviction_high_watermark_ratio = config.eviction_high_watermark_ratio;
|
||||
view_version = config.view_version;
|
||||
client_live_ttl_sec = config.client_live_ttl_sec;
|
||||
enable_ha = config.enable_ha;
|
||||
cluster_id = config.cluster_id;
|
||||
root_fs_dir = config.root_fs_dir;
|
||||
memory_allocator = config.memory_allocator;
|
||||
}
|
||||
|
||||
// Static factory method to create a builder
|
||||
static MasterServiceConfigBuilder builder();
|
||||
};
|
||||
|
||||
// Implementation of MasterServiceConfigBuilder::build()
|
||||
inline MasterServiceConfig MasterServiceConfigBuilder::build() const {
|
||||
MasterServiceConfig config;
|
||||
config.enable_gc = enable_gc_;
|
||||
config.default_kv_lease_ttl = default_kv_lease_ttl_;
|
||||
config.default_kv_soft_pin_ttl = default_kv_soft_pin_ttl_;
|
||||
config.allow_evict_soft_pinned_objects = allow_evict_soft_pinned_objects_;
|
||||
config.eviction_ratio = eviction_ratio_;
|
||||
config.eviction_high_watermark_ratio = eviction_high_watermark_ratio_;
|
||||
config.view_version = view_version_;
|
||||
config.client_live_ttl_sec = client_live_ttl_sec_;
|
||||
config.enable_ha = enable_ha_;
|
||||
config.cluster_id = cluster_id_;
|
||||
config.root_fs_dir = root_fs_dir_;
|
||||
config.memory_allocator = memory_allocator_;
|
||||
return config;
|
||||
}
|
||||
|
||||
// Implementation of MasterServiceConfig::builder()
|
||||
inline MasterServiceConfigBuilder MasterServiceConfig::builder() {
|
||||
return MasterServiceConfigBuilder();
|
||||
}
|
||||
|
||||
} // namespace mooncake
|
||||
|
|
@ -15,13 +15,13 @@
|
|||
#include <vector>
|
||||
#include <ylt/util/expected.hpp>
|
||||
#include <ylt/util/tl/expected.hpp>
|
||||
#include <filesystem>
|
||||
|
||||
#include "allocation_strategy.h"
|
||||
#include "master_metric_manager.h"
|
||||
#include "mutex.h"
|
||||
#include "segment.h"
|
||||
#include "types.h"
|
||||
#include "master_config.h"
|
||||
|
||||
namespace mooncake {
|
||||
// Forward declarations
|
||||
|
|
@ -60,21 +60,8 @@ class MasterService {
|
|||
};
|
||||
|
||||
public:
|
||||
MasterService(
|
||||
bool enable_gc = true,
|
||||
uint64_t default_kv_lease_ttl = DEFAULT_DEFAULT_KV_LEASE_TTL,
|
||||
uint64_t default_kv_soft_pin_ttl = DEFAULT_KV_SOFT_PIN_TTL_MS,
|
||||
bool allow_evict_soft_pinned_objects =
|
||||
DEFAULT_ALLOW_EVICT_SOFT_PINNED_OBJECTS,
|
||||
double eviction_ratio = DEFAULT_EVICTION_RATIO,
|
||||
double eviction_high_watermark_ratio =
|
||||
DEFAULT_EVICTION_HIGH_WATERMARK_RATIO,
|
||||
ViewVersionId view_version = 0,
|
||||
int64_t client_live_ttl_sec = DEFAULT_CLIENT_LIVE_TTL_SEC,
|
||||
bool enable_ha = false,
|
||||
const std::string& cluster_id = DEFAULT_CLUSTER_ID,
|
||||
const std::string& root_fs_dir = DEFAULT_ROOT_FS_DIR,
|
||||
BufferAllocatorType memory_allocator = BufferAllocatorType::CACHELIB);
|
||||
MasterService();
|
||||
MasterService(const MasterServiceConfig& config);
|
||||
~MasterService();
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "master_service.h"
|
||||
#include "types.h"
|
||||
#include "master_config.h"
|
||||
|
||||
namespace mooncake {
|
||||
|
||||
|
|
@ -16,21 +17,7 @@ extern const uint64_t kMetricReportIntervalSeconds;
|
|||
|
||||
class WrappedMasterService {
|
||||
public:
|
||||
WrappedMasterService(
|
||||
bool enable_gc, uint64_t default_kv_lease_ttl,
|
||||
uint64_t default_kv_soft_pin_ttl = DEFAULT_KV_SOFT_PIN_TTL_MS,
|
||||
bool allow_evict_soft_pinned_objects =
|
||||
DEFAULT_ALLOW_EVICT_SOFT_PINNED_OBJECTS,
|
||||
bool enable_metric_reporting = true, uint16_t http_port = 9003,
|
||||
double eviction_ratio = DEFAULT_EVICTION_RATIO,
|
||||
double eviction_high_watermark_ratio =
|
||||
DEFAULT_EVICTION_HIGH_WATERMARK_RATIO,
|
||||
ViewVersionId view_version = 0,
|
||||
int64_t client_live_ttl_sec = DEFAULT_CLIENT_LIVE_TTL_SEC,
|
||||
bool enable_ha = false,
|
||||
const std::string& cluster_id = DEFAULT_CLUSTER_ID,
|
||||
const std::string& root_fs_dir = DEFAULT_ROOT_FS_DIR,
|
||||
BufferAllocatorType memory_allocator = BufferAllocatorType::CACHELIB);
|
||||
WrappedMasterService(const WrappedMasterServiceConfig& config);
|
||||
|
||||
~WrappedMasterService();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
#include "ha_helper.h"
|
||||
#include "etcd_helper.h"
|
||||
#include "rpc_service.h"
|
||||
|
||||
namespace mooncake {
|
||||
|
||||
|
|
@ -90,53 +92,28 @@ ErrorCode MasterViewHelper::GetMasterView(std::string& master_address,
|
|||
}
|
||||
|
||||
MasterServiceSupervisor::MasterServiceSupervisor(
|
||||
const MasterConfig& master_config)
|
||||
: enable_gc_(master_config.enable_gc),
|
||||
enable_metric_reporting_(master_config.enable_metric_reporting),
|
||||
metrics_port_(master_config.metrics_port),
|
||||
default_kv_lease_ttl_(master_config.default_kv_lease_ttl),
|
||||
default_kv_soft_pin_ttl_(master_config.default_kv_soft_pin_ttl),
|
||||
allow_evict_soft_pinned_objects_(
|
||||
master_config.allow_evict_soft_pinned_objects),
|
||||
eviction_ratio_(master_config.eviction_ratio),
|
||||
eviction_high_watermark_ratio_(
|
||||
master_config.eviction_high_watermark_ratio),
|
||||
client_live_ttl_sec_(master_config.client_live_ttl_sec),
|
||||
rpc_port_(master_config.rpc_port),
|
||||
rpc_thread_num_(master_config.rpc_thread_num),
|
||||
rpc_address_(master_config.rpc_address),
|
||||
rpc_conn_timeout_(
|
||||
std::chrono::seconds(master_config.rpc_conn_timeout_seconds)),
|
||||
rpc_enable_tcp_no_delay_(master_config.rpc_enable_tcp_no_delay),
|
||||
etcd_endpoints_(master_config.etcd_endpoints),
|
||||
local_hostname_(master_config.rpc_address + ":" +
|
||||
std::to_string(master_config.rpc_port)),
|
||||
cluster_id_(master_config.cluster_id),
|
||||
root_fs_dir_(master_config.root_fs_dir) {
|
||||
if (master_config.memory_allocator == "cachelib") {
|
||||
memory_allocator_ = BufferAllocatorType::CACHELIB;
|
||||
} else {
|
||||
memory_allocator_ = BufferAllocatorType::OFFSET;
|
||||
}
|
||||
}
|
||||
const MasterServiceSupervisorConfig& config)
|
||||
: config_(config) {}
|
||||
|
||||
int MasterServiceSupervisor::Start() {
|
||||
while (true) {
|
||||
LOG(INFO) << "Init master service...";
|
||||
coro_rpc::coro_rpc_server server(rpc_thread_num_, rpc_port_,
|
||||
rpc_address_, rpc_conn_timeout_,
|
||||
rpc_enable_tcp_no_delay_);
|
||||
coro_rpc::coro_rpc_server server(
|
||||
config_.rpc_thread_num, config_.rpc_port, config_.rpc_address,
|
||||
config_.rpc_conn_timeout, config_.rpc_enable_tcp_no_delay);
|
||||
LOG(INFO) << "Init leader election helper...";
|
||||
MasterViewHelper mv_helper;
|
||||
if (mv_helper.ConnectToEtcd(etcd_endpoints_) != ErrorCode::OK) {
|
||||
if (mv_helper.ConnectToEtcd(config_.etcd_endpoints) != ErrorCode::OK) {
|
||||
LOG(ERROR) << "Failed to connect to etcd endpoints: "
|
||||
<< etcd_endpoints_;
|
||||
<< config_.etcd_endpoints;
|
||||
return -1;
|
||||
}
|
||||
LOG(INFO) << "Trying to elect self as leader...";
|
||||
ViewVersionId version = 0;
|
||||
EtcdLeaseId lease_id = 0;
|
||||
mv_helper.ElectLeader(local_hostname_, version, lease_id);
|
||||
// view_version will be updated by ElectLeader and then used in
|
||||
// WrappedMasterService
|
||||
ViewVersionId view_version = 0;
|
||||
mv_helper.ElectLeader(config_.local_hostname, view_version, lease_id);
|
||||
|
||||
// Start a thread to keep the leader alive
|
||||
auto keep_leader_thread =
|
||||
|
|
@ -152,13 +129,8 @@ int MasterServiceSupervisor::Start() {
|
|||
std::this_thread::sleep_for(std::chrono::seconds(waiting_time));
|
||||
|
||||
LOG(INFO) << "Starting master service...";
|
||||
bool enable_ha = true;
|
||||
mooncake::WrappedMasterService wrapped_master_service(
|
||||
enable_gc_, default_kv_lease_ttl_, default_kv_soft_pin_ttl_,
|
||||
allow_evict_soft_pinned_objects_, enable_metric_reporting_,
|
||||
metrics_port_, eviction_ratio_, eviction_high_watermark_ratio_,
|
||||
version, client_live_ttl_sec_, enable_ha, cluster_id_, root_fs_dir_,
|
||||
memory_allocator_);
|
||||
mooncake::WrappedMasterServiceConfig(config_, view_version));
|
||||
mooncake::RegisterRpcService(server, wrapped_master_service);
|
||||
// Metric reporting is now handled by WrappedMasterService.
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@
|
|||
#include "rpc_service.h"
|
||||
#include "types.h"
|
||||
|
||||
#include "master_config.h"
|
||||
|
||||
using namespace coro_rpc;
|
||||
using namespace async_simple;
|
||||
using namespace async_simple::coro;
|
||||
|
|
@ -331,34 +333,19 @@ int main(int argc, char* argv[]) {
|
|||
<< ", memory_allocator=" << master_config.memory_allocator;
|
||||
|
||||
if (master_config.enable_ha) {
|
||||
// Construct local hostname from rpc_address and rpc_port
|
||||
mooncake::MasterServiceSupervisor supervisor(master_config);
|
||||
|
||||
mooncake::MasterServiceSupervisor supervisor(
|
||||
mooncake::MasterServiceSupervisorConfig{master_config});
|
||||
return supervisor.Start();
|
||||
} else {
|
||||
// version is not used in non-HA mode, just pass a dummy value
|
||||
mooncake::ViewVersionId version = 0;
|
||||
mooncake::BufferAllocatorType allocator_type;
|
||||
if (master_config.memory_allocator == "cachelib") {
|
||||
allocator_type = mooncake::BufferAllocatorType::CACHELIB;
|
||||
} else {
|
||||
allocator_type = mooncake::BufferAllocatorType::OFFSET;
|
||||
}
|
||||
coro_rpc::coro_rpc_server server(
|
||||
master_config.rpc_thread_num, master_config.rpc_port,
|
||||
master_config.rpc_address,
|
||||
std::chrono::seconds(master_config.rpc_conn_timeout_seconds),
|
||||
master_config.rpc_enable_tcp_no_delay);
|
||||
mooncake::WrappedMasterService wrapped_master_service(
|
||||
master_config.enable_gc, master_config.default_kv_lease_ttl,
|
||||
master_config.default_kv_soft_pin_ttl,
|
||||
master_config.allow_evict_soft_pinned_objects,
|
||||
master_config.enable_metric_reporting, master_config.metrics_port,
|
||||
master_config.eviction_ratio,
|
||||
master_config.eviction_high_watermark_ratio, version,
|
||||
master_config.client_live_ttl_sec, master_config.enable_ha,
|
||||
master_config.cluster_id, master_config.root_fs_dir,
|
||||
allocator_type);
|
||||
mooncake::WrappedMasterServiceConfig(master_config, version));
|
||||
|
||||
mooncake::RegisterRpcService(server, wrapped_master_service);
|
||||
return server.start();
|
||||
|
|
|
|||
|
|
@ -13,24 +13,20 @@
|
|||
|
||||
namespace mooncake {
|
||||
|
||||
MasterService::MasterService(
|
||||
bool enable_gc, uint64_t default_kv_lease_ttl,
|
||||
uint64_t default_kv_soft_pin_ttl, bool allow_evict_soft_pinned_objects,
|
||||
double eviction_ratio, double eviction_high_watermark_ratio,
|
||||
ViewVersionId view_version, int64_t client_live_ttl_sec, bool enable_ha,
|
||||
const std::string& cluster_id, const std::string& root_fs_dir,
|
||||
BufferAllocatorType memory_allocator)
|
||||
: enable_gc_(enable_gc),
|
||||
default_kv_lease_ttl_(default_kv_lease_ttl),
|
||||
default_kv_soft_pin_ttl_(default_kv_soft_pin_ttl),
|
||||
allow_evict_soft_pinned_objects_(allow_evict_soft_pinned_objects),
|
||||
eviction_ratio_(eviction_ratio),
|
||||
eviction_high_watermark_ratio_(eviction_high_watermark_ratio),
|
||||
client_live_ttl_sec_(client_live_ttl_sec),
|
||||
enable_ha_(enable_ha),
|
||||
cluster_id_(cluster_id),
|
||||
root_fs_dir_(root_fs_dir),
|
||||
segment_manager_(memory_allocator),
|
||||
MasterService::MasterService() : MasterService(MasterServiceConfig()) {}
|
||||
|
||||
MasterService::MasterService(const MasterServiceConfig& config)
|
||||
: enable_gc_(config.enable_gc),
|
||||
default_kv_lease_ttl_(config.default_kv_lease_ttl),
|
||||
default_kv_soft_pin_ttl_(config.default_kv_soft_pin_ttl),
|
||||
allow_evict_soft_pinned_objects_(config.allow_evict_soft_pinned_objects),
|
||||
eviction_ratio_(config.eviction_ratio),
|
||||
eviction_high_watermark_ratio_(config.eviction_high_watermark_ratio),
|
||||
client_live_ttl_sec_(config.client_live_ttl_sec),
|
||||
enable_ha_(config.enable_ha),
|
||||
cluster_id_(config.cluster_id),
|
||||
root_fs_dir_(config.root_fs_dir),
|
||||
segment_manager_(config.memory_allocator),
|
||||
allocation_strategy_(std::make_shared<RandomAllocationStrategy>()) {
|
||||
if (eviction_ratio_ < 0.0 || eviction_ratio_ > 1.0) {
|
||||
LOG(ERROR) << "Eviction ratio must be between 0.0 and 1.0, "
|
||||
|
|
@ -48,7 +44,7 @@ MasterService::MasterService(
|
|||
gc_thread_ = std::thread(&MasterService::GCThreadFunc, this);
|
||||
VLOG(1) << "action=start_gc_thread";
|
||||
|
||||
if (enable_ha) {
|
||||
if (enable_ha_) {
|
||||
client_monitor_running_ = true;
|
||||
client_monitor_thread_ =
|
||||
std::thread(&MasterService::ClientMonitorFunc, this);
|
||||
|
|
@ -1010,8 +1006,7 @@ void MasterService::BatchEvict(double evict_ratio_target,
|
|||
}
|
||||
MasterMetricManager::instance().inc_eviction_fail();
|
||||
}
|
||||
VLOG(1) << "action=evict_objects"
|
||||
<< ", evicted_count=" << evicted_count
|
||||
VLOG(1) << "action=evict_objects" << ", evicted_count=" << evicted_count
|
||||
<< ", total_freed_size=" << total_freed_size;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,25 +24,15 @@ namespace mooncake {
|
|||
const uint64_t kMetricReportIntervalSeconds = 10;
|
||||
|
||||
WrappedMasterService::WrappedMasterService(
|
||||
bool enable_gc, uint64_t default_kv_lease_ttl,
|
||||
uint64_t default_kv_soft_pin_ttl, bool allow_evict_soft_pinned_objects,
|
||||
bool enable_metric_reporting, uint16_t http_port, double eviction_ratio,
|
||||
double eviction_high_watermark_ratio, ViewVersionId view_version,
|
||||
int64_t client_live_ttl_sec, bool enable_ha, const std::string& cluster_id,
|
||||
const std::string& root_fs_dir, BufferAllocatorType memory_allocator)
|
||||
: master_service_(enable_gc, default_kv_lease_ttl, default_kv_soft_pin_ttl,
|
||||
allow_evict_soft_pinned_objects, eviction_ratio,
|
||||
eviction_high_watermark_ratio, view_version,
|
||||
client_live_ttl_sec, enable_ha, cluster_id, root_fs_dir,
|
||||
|
||||
memory_allocator),
|
||||
http_server_(4, http_port),
|
||||
metric_report_running_(enable_metric_reporting) {
|
||||
const WrappedMasterServiceConfig& config)
|
||||
: master_service_(MasterServiceConfig(config)),
|
||||
http_server_(4, config.http_port),
|
||||
metric_report_running_(config.enable_metric_reporting) {
|
||||
init_http_server();
|
||||
|
||||
MasterMetricManager::instance().set_enable_ha(enable_ha);
|
||||
MasterMetricManager::instance().set_enable_ha(config.enable_ha);
|
||||
|
||||
if (enable_metric_reporting) {
|
||||
if (config.enable_metric_reporting) {
|
||||
metric_report_thread_ = std::thread([this]() {
|
||||
while (metric_report_running_) {
|
||||
std::string metrics_summary =
|
||||
|
|
|
|||
|
|
@ -1,15 +1,12 @@
|
|||
#include <glog/logging.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
#include <random>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
#include "master_service.h"
|
||||
#include "rpc_service.h"
|
||||
#include "types.h"
|
||||
#include "master_config.h"
|
||||
|
||||
namespace mooncake::test {
|
||||
|
||||
|
|
@ -94,7 +91,11 @@ TEST_F(MasterMetricsTest, BasicRequestTest) {
|
|||
const uint64_t default_kv_lease_ttl = 100;
|
||||
auto& metrics = MasterMetricManager::instance();
|
||||
// Use a wrapped master service to test the metrics manager
|
||||
WrappedMasterService service_(false, default_kv_lease_ttl, true);
|
||||
WrappedMasterServiceConfig service_config;
|
||||
service_config.enable_gc = false;
|
||||
service_config.default_kv_lease_ttl = default_kv_lease_ttl;
|
||||
service_config.enable_metric_reporting = true;
|
||||
WrappedMasterService service_(service_config);
|
||||
|
||||
constexpr size_t kBufferAddress = 0x300000000;
|
||||
constexpr size_t kSegmentSize = 1024 * 1024 * 16;
|
||||
|
|
@ -202,7 +203,10 @@ TEST_F(MasterMetricsTest, BasicRequestTest) {
|
|||
TEST_F(MasterMetricsTest, BatchRequestTest) {
|
||||
const uint64_t default_kv_lease_ttl = 100;
|
||||
auto& metrics = MasterMetricManager::instance();
|
||||
WrappedMasterService service_(false, default_kv_lease_ttl, true);
|
||||
WrappedMasterServiceConfig service_config;
|
||||
service_config.enable_gc = false;
|
||||
service_config.default_kv_lease_ttl = default_kv_lease_ttl;
|
||||
WrappedMasterService service_(service_config);
|
||||
|
||||
constexpr size_t kBufferAddress = 0x300000000;
|
||||
constexpr size_t kSegmentSize = 1024 * 1024 * 64;
|
||||
|
|
|
|||
|
|
@ -3,9 +3,7 @@
|
|||
#include <glog/logging.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
#include <random>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
|
|
@ -16,15 +14,7 @@ namespace mooncake::test {
|
|||
std::unique_ptr<MasterService> CreateMasterServiceWithSSDFeat(
|
||||
const std::string& root_fs_dir) {
|
||||
return std::make_unique<MasterService>(
|
||||
false, // enable_gc
|
||||
DEFAULT_DEFAULT_KV_LEASE_TTL, // default_kv_lease_ttl
|
||||
DEFAULT_KV_SOFT_PIN_TTL_MS, // default_kv_soft_pin_ttl
|
||||
DEFAULT_ALLOW_EVICT_SOFT_PINNED_OBJECTS, DEFAULT_EVICTION_RATIO,
|
||||
DEFAULT_EVICTION_HIGH_WATERMARK_RATIO,
|
||||
0, // view_version
|
||||
DEFAULT_CLIENT_LIVE_TTL_SEC,
|
||||
false, // enable_ha
|
||||
DEFAULT_CLUSTER_ID, root_fs_dir, BufferAllocatorType::CACHELIB);
|
||||
MasterServiceConfig::builder().set_root_fs_dir(root_fs_dir).build());
|
||||
}
|
||||
|
||||
class MasterServiceSSDTest : public ::testing::Test {
|
||||
|
|
|
|||
|
|
@ -72,9 +72,13 @@ std::string GenerateKeyForSegment(const std::unique_ptr<MasterService>& service,
|
|||
}
|
||||
}
|
||||
|
||||
TEST_F(MasterServiceTest, MountUnmountSegment) {
|
||||
TEST_F(MasterServiceTest, MountUnmountSegmentWithCachelibAllocator) {
|
||||
// Create a MasterService instance for testing.
|
||||
std::unique_ptr<MasterService> service_(new MasterService());
|
||||
auto service_config =
|
||||
MasterServiceConfig::builder()
|
||||
.set_memory_allocator(BufferAllocatorType::CACHELIB)
|
||||
.build();
|
||||
std::unique_ptr<MasterService> service_(new MasterService(service_config));
|
||||
// Define a constant buffer address for the segment.
|
||||
constexpr size_t kBufferAddress = 0x300000000;
|
||||
// Define the size of the segment (16MB).
|
||||
|
|
@ -146,6 +150,69 @@ TEST_F(MasterServiceTest, MountUnmountSegment) {
|
|||
EXPECT_TRUE(unmount_result4.has_value());
|
||||
}
|
||||
|
||||
TEST_F(MasterServiceTest, MountUnmountSegmentWithOffsetAllocator) {
|
||||
// Create a MasterService instance for testing.
|
||||
auto service_config = MasterServiceConfig::builder()
|
||||
.set_memory_allocator(BufferAllocatorType::OFFSET)
|
||||
.build();
|
||||
std::unique_ptr<MasterService> service_(new MasterService(service_config));
|
||||
// Define a constant buffer address for the segment.
|
||||
constexpr size_t kBufferAddress = 0x300000000;
|
||||
// Define the size of the segment (16MB).
|
||||
constexpr size_t kSegmentSize = 1024 * 1024 * 16;
|
||||
// Define the name of the test segment.
|
||||
std::string segment_name = "test_segment";
|
||||
Segment segment(generate_uuid(), segment_name, kBufferAddress,
|
||||
kSegmentSize);
|
||||
UUID client_id = generate_uuid();
|
||||
|
||||
// Test invalid parameters.
|
||||
// Invalid buffer address (0).
|
||||
segment.base = 0;
|
||||
segment.size = kSegmentSize;
|
||||
auto mount_result1 = service_->MountSegment(segment, client_id);
|
||||
EXPECT_FALSE(mount_result1.has_value());
|
||||
EXPECT_EQ(ErrorCode::INVALID_PARAMS, mount_result1.error());
|
||||
|
||||
// Invalid segment size (0).
|
||||
segment.base = kBufferAddress;
|
||||
segment.size = 0;
|
||||
auto mount_result2 = service_->MountSegment(segment, client_id);
|
||||
EXPECT_FALSE(mount_result2.has_value());
|
||||
EXPECT_EQ(ErrorCode::INVALID_PARAMS, mount_result2.error());
|
||||
|
||||
// Test normal mount operation.
|
||||
segment.base = kBufferAddress;
|
||||
segment.size = kSegmentSize;
|
||||
auto mount_result5 = service_->MountSegment(segment, client_id);
|
||||
EXPECT_TRUE(mount_result5.has_value());
|
||||
|
||||
// Test mounting the same segment again (idempotent request should succeed).
|
||||
auto mount_result6 = service_->MountSegment(segment, client_id);
|
||||
EXPECT_TRUE(mount_result6.has_value());
|
||||
|
||||
// Test unmounting the segment.
|
||||
auto unmount_result1 = service_->UnmountSegment(segment.id, client_id);
|
||||
EXPECT_TRUE(unmount_result1.has_value());
|
||||
|
||||
// Test unmounting the same segment again (idempotent request should
|
||||
// succeed).
|
||||
auto unmount_result2 = service_->UnmountSegment(segment.id, client_id);
|
||||
EXPECT_TRUE(unmount_result2.has_value());
|
||||
|
||||
// Test unmounting a non-existent segment (idempotent request should
|
||||
// succeed).
|
||||
UUID non_existent_id = generate_uuid();
|
||||
auto unmount_result3 = service_->UnmountSegment(non_existent_id, client_id);
|
||||
EXPECT_TRUE(unmount_result3.has_value());
|
||||
|
||||
// Test remounting after unmount.
|
||||
auto mount_result7 = service_->MountSegment(segment, client_id);
|
||||
EXPECT_TRUE(mount_result7.has_value());
|
||||
auto unmount_result4 = service_->UnmountSegment(segment.id, client_id);
|
||||
EXPECT_TRUE(unmount_result4.has_value());
|
||||
}
|
||||
|
||||
TEST_F(MasterServiceTest, RandomMountUnmountSegment) {
|
||||
// Create a MasterService instance for testing.
|
||||
std::unique_ptr<MasterService> service_(new MasterService());
|
||||
|
|
@ -335,8 +402,10 @@ TEST_F(MasterServiceTest, RandomPutStartEndFlow) {
|
|||
|
||||
TEST_F(MasterServiceTest, GetReplicaListByRegex) {
|
||||
const uint64_t kv_lease_ttl = 50;
|
||||
std::unique_ptr<MasterService> service_(
|
||||
new MasterService(false, kv_lease_ttl));
|
||||
auto service_config = MasterServiceConfig::builder()
|
||||
.set_default_kv_lease_ttl(kv_lease_ttl)
|
||||
.build();
|
||||
std::unique_ptr<MasterService> service_(new MasterService(service_config));
|
||||
// Test getting non-existent key
|
||||
auto get_result = service_->GetReplicaList(".*non_existent.*");
|
||||
EXPECT_FALSE(get_result.has_value());
|
||||
|
|
@ -394,7 +463,10 @@ void put_object(MasterService& service, const std::string& key) {
|
|||
|
||||
TEST_F(MasterServiceTest, GetReplicaListByRegexComplex) {
|
||||
const uint64_t kv_lease_ttl = 100;
|
||||
auto service_ = std::make_unique<MasterService>(false, kv_lease_ttl);
|
||||
auto service_config = MasterServiceConfig::builder()
|
||||
.set_default_kv_lease_ttl(kv_lease_ttl)
|
||||
.build();
|
||||
auto service_ = std::make_unique<MasterService>(service_config);
|
||||
|
||||
// 1. Mount segment
|
||||
constexpr size_t buffer = 0x300000000;
|
||||
|
|
@ -623,8 +695,10 @@ TEST_F(MasterServiceTest, RandomRemoveObject) {
|
|||
|
||||
TEST_F(MasterServiceTest, RemoveByRegex) {
|
||||
const uint64_t kv_lease_ttl = 50;
|
||||
std::unique_ptr<MasterService> service_(
|
||||
new MasterService(false, kv_lease_ttl));
|
||||
auto service_config = MasterServiceConfig::builder()
|
||||
.set_default_kv_lease_ttl(kv_lease_ttl)
|
||||
.build();
|
||||
std::unique_ptr<MasterService> service_(new MasterService(service_config));
|
||||
// Mount segment and put 10 objects
|
||||
constexpr size_t buffer = 0x300000000;
|
||||
constexpr size_t size = 1024 * 1024 * 16;
|
||||
|
|
@ -664,7 +738,10 @@ TEST_F(MasterServiceTest, RemoveByRegex) {
|
|||
|
||||
TEST_F(MasterServiceTest, RemoveByRegexComplex) {
|
||||
const uint64_t kv_lease_ttl = 100;
|
||||
auto service_ = std::make_unique<MasterService>(false, kv_lease_ttl);
|
||||
auto service_config = MasterServiceConfig::builder()
|
||||
.set_default_kv_lease_ttl(kv_lease_ttl)
|
||||
.build();
|
||||
auto service_ = std::make_unique<MasterService>(service_config);
|
||||
|
||||
// 1. Mount segment
|
||||
constexpr size_t buffer = 0x300000000;
|
||||
|
|
@ -733,8 +810,10 @@ TEST_F(MasterServiceTest, RemoveByRegexComplex) {
|
|||
SCOPED_TRACE("Test Case 2: Removing all keys with '.*'");
|
||||
// Store is already populated from the previous (failed) test run, or we
|
||||
// can repopulate For isolation, let's assume we start fresh
|
||||
service_ = std::make_unique<MasterService>(
|
||||
false, kv_lease_ttl); // Reset the service for a clean slate
|
||||
auto service_config = MasterServiceConfig::builder()
|
||||
.set_default_kv_lease_ttl(kv_lease_ttl)
|
||||
.build();
|
||||
service_ = std::make_unique<MasterService>(service_config);
|
||||
service_->MountSegment(segment, client_id);
|
||||
populate_store();
|
||||
|
||||
|
|
@ -754,8 +833,11 @@ TEST_F(MasterServiceTest, RemoveByRegexComplex) {
|
|||
// --- Test Case 3: Attempt to remove with a non-matching pattern ---
|
||||
{
|
||||
SCOPED_TRACE("Test Case 3: Removing with a non-matching pattern");
|
||||
service_ =
|
||||
std::make_unique<MasterService>(false, kv_lease_ttl); // Reset
|
||||
auto service_config = MasterServiceConfig::builder()
|
||||
.set_default_kv_lease_ttl(kv_lease_ttl)
|
||||
.build();
|
||||
service_ = std::make_unique<MasterService>(
|
||||
service_config); // Reset the service
|
||||
service_->MountSegment(segment, client_id);
|
||||
populate_store();
|
||||
|
||||
|
|
@ -776,8 +858,10 @@ TEST_F(MasterServiceTest, RemoveByRegexComplex) {
|
|||
{
|
||||
SCOPED_TRACE(
|
||||
"Test Case 4: Removing based on file paths or containing digits");
|
||||
service_ =
|
||||
std::make_unique<MasterService>(false, kv_lease_ttl); // Reset
|
||||
auto service_config = MasterServiceConfig::builder()
|
||||
.set_default_kv_lease_ttl(kv_lease_ttl)
|
||||
.build();
|
||||
service_ = std::make_unique<MasterService>(service_config); // Reset
|
||||
service_->MountSegment(segment, client_id);
|
||||
populate_store();
|
||||
|
||||
|
|
@ -798,8 +882,10 @@ TEST_F(MasterServiceTest, RemoveByRegexComplex) {
|
|||
{
|
||||
SCOPED_TRACE(
|
||||
"Test Case 4 (Corrected): Removing based on complex pattern");
|
||||
service_ =
|
||||
std::make_unique<MasterService>(false, kv_lease_ttl); // Reset
|
||||
auto service_config = MasterServiceConfig::builder()
|
||||
.set_default_kv_lease_ttl(kv_lease_ttl)
|
||||
.build();
|
||||
service_ = std::make_unique<MasterService>(service_config); // Reset
|
||||
service_->MountSegment(segment, client_id);
|
||||
populate_store();
|
||||
|
||||
|
|
@ -828,8 +914,10 @@ TEST_F(MasterServiceTest, RemoveByRegexComplex) {
|
|||
|
||||
TEST_F(MasterServiceTest, RemoveAll) {
|
||||
const uint64_t kv_lease_ttl = 50;
|
||||
std::unique_ptr<MasterService> service_(
|
||||
new MasterService(false, kv_lease_ttl));
|
||||
auto service_config = MasterServiceConfig::builder()
|
||||
.set_default_kv_lease_ttl(kv_lease_ttl)
|
||||
.build();
|
||||
std::unique_ptr<MasterService> service_(new MasterService(service_config));
|
||||
// Mount segment and put 10 objects
|
||||
constexpr size_t buffer = 0x300000000;
|
||||
constexpr size_t size = 1024 * 1024 * 16;
|
||||
|
|
@ -866,7 +954,9 @@ TEST_F(MasterServiceTest, RemoveAll) {
|
|||
}
|
||||
|
||||
TEST_F(MasterServiceTest, MultiSliceMultiReplicaFlow) {
|
||||
std::unique_ptr<MasterService> service_(new MasterService());
|
||||
auto service_config =
|
||||
MasterServiceConfig::builder().set_enable_gc(true).build();
|
||||
std::unique_ptr<MasterService> service_(new MasterService(service_config));
|
||||
|
||||
// Mount a segment with sufficient size for multiple replicas
|
||||
constexpr size_t buffer = 0x300000000;
|
||||
|
|
@ -971,7 +1061,9 @@ TEST_F(MasterServiceTest, MultiSliceMultiReplicaFlow) {
|
|||
}
|
||||
|
||||
TEST_F(MasterServiceTest, ConcurrentGarbageCollectionTest) {
|
||||
std::unique_ptr<MasterService> service_(new MasterService());
|
||||
auto service_config =
|
||||
MasterServiceConfig::builder().set_enable_gc(true).build();
|
||||
std::unique_ptr<MasterService> service_(new MasterService(service_config));
|
||||
|
||||
// Mount segment for testing
|
||||
constexpr size_t buffer = 0x300000000;
|
||||
|
|
@ -1199,8 +1291,10 @@ TEST_F(MasterServiceTest, ConcurrentWriteAndRemoveAll) {
|
|||
TEST_F(MasterServiceTest, ConcurrentReadAndRemoveAll) {
|
||||
// set a large kv_lease_ttl so the granted lease will not quickly expire
|
||||
const uint64_t kv_lease_ttl = 200;
|
||||
std::unique_ptr<MasterService> service_(
|
||||
new MasterService(false, kv_lease_ttl));
|
||||
auto service_config = MasterServiceConfig::builder()
|
||||
.set_default_kv_lease_ttl(kv_lease_ttl)
|
||||
.build();
|
||||
std::unique_ptr<MasterService> service_(new MasterService(service_config));
|
||||
constexpr size_t buffer = 0x300000000;
|
||||
constexpr size_t size = 1024 * 1024 * 256; // 256MB for concurrent testing
|
||||
std::string segment_name = "concurrent_segment";
|
||||
|
|
@ -1387,7 +1481,7 @@ TEST_F(MasterServiceTest, UnmountSegmentImmediateCleanup) {
|
|||
}
|
||||
|
||||
TEST_F(MasterServiceTest, ReadableAfterPartialUnmountWithReplication) {
|
||||
std::unique_ptr<MasterService> service_(new MasterService(false));
|
||||
std::unique_ptr<MasterService> service_(new MasterService());
|
||||
|
||||
// TODO: mount two larger segments when replication affinity fixed
|
||||
// Mount two segments sized to fit exactly one replica each
|
||||
|
|
@ -1502,8 +1596,10 @@ TEST_F(MasterServiceTest, UnmountSegmentPerformance) {
|
|||
|
||||
TEST_F(MasterServiceTest, RemoveLeasedObject) {
|
||||
const uint64_t kv_lease_ttl = 50;
|
||||
std::unique_ptr<MasterService> service_(
|
||||
new MasterService(false, kv_lease_ttl));
|
||||
auto service_config = MasterServiceConfig::builder()
|
||||
.set_default_kv_lease_ttl(kv_lease_ttl)
|
||||
.build();
|
||||
std::unique_ptr<MasterService> service_(new MasterService(service_config));
|
||||
// Mount segment and put an object
|
||||
constexpr size_t buffer = 0x300000000;
|
||||
constexpr size_t size = 1024 * 1024 * 16;
|
||||
|
|
@ -1588,8 +1684,10 @@ TEST_F(MasterServiceTest, RemoveLeasedObject) {
|
|||
|
||||
TEST_F(MasterServiceTest, RemoveAllLeasedObject) {
|
||||
const uint64_t kv_lease_ttl = 50;
|
||||
std::unique_ptr<MasterService> service_(
|
||||
new MasterService(false, kv_lease_ttl));
|
||||
auto service_config = MasterServiceConfig::builder()
|
||||
.set_default_kv_lease_ttl(kv_lease_ttl)
|
||||
.build();
|
||||
std::unique_ptr<MasterService> service_(new MasterService(service_config));
|
||||
// Mount segment and put 10 objects, with 5 of them having lease
|
||||
constexpr size_t buffer = 0x300000000;
|
||||
constexpr size_t size = 1024 * 1024 * 16;
|
||||
|
|
@ -1631,8 +1729,10 @@ TEST_F(MasterServiceTest, RemoveAllLeasedObject) {
|
|||
TEST_F(MasterServiceTest, EvictObject) {
|
||||
// set a large kv_lease_ttl so the granted lease will not quickly expire
|
||||
const uint64_t kv_lease_ttl = 2000;
|
||||
std::unique_ptr<MasterService> service_(
|
||||
new MasterService(false, kv_lease_ttl));
|
||||
auto service_config = MasterServiceConfig::builder()
|
||||
.set_default_kv_lease_ttl(kv_lease_ttl)
|
||||
.build();
|
||||
std::unique_ptr<MasterService> service_(new MasterService(service_config));
|
||||
// Mount a segment that can hold about 1024 * 16 objects.
|
||||
// As the eviction is processed separately for each shard,
|
||||
// we need to fill each shard with enough objects to thoroughly
|
||||
|
|
@ -1671,8 +1771,10 @@ TEST_F(MasterServiceTest, EvictObject) {
|
|||
TEST_F(MasterServiceTest, TryEvictLeasedObject) {
|
||||
// set a large kv_lease_ttl so the granted lease will not quickly expire
|
||||
const uint64_t kv_lease_ttl = 500;
|
||||
std::unique_ptr<MasterService> service_(
|
||||
new MasterService(false, kv_lease_ttl));
|
||||
auto service_config = MasterServiceConfig::builder()
|
||||
.set_default_kv_lease_ttl(kv_lease_ttl)
|
||||
.build();
|
||||
std::unique_ptr<MasterService> service_(new MasterService(service_config));
|
||||
constexpr size_t buffer = 0x300000000;
|
||||
constexpr size_t size = 1024 * 1024 * 16;
|
||||
constexpr size_t object_size = 1024 * 1024;
|
||||
|
|
@ -1722,8 +1824,13 @@ TEST_F(MasterServiceTest, RemoveSoftPinObject) {
|
|||
// set a large soft_pin_ttl so the granted soft pin will not quickly expire
|
||||
const uint64_t kv_soft_pin_ttl = 10000;
|
||||
const bool allow_evict_soft_pinned_objects = true;
|
||||
std::unique_ptr<MasterService> service_(new MasterService(
|
||||
false, kv_lease_ttl, kv_soft_pin_ttl, allow_evict_soft_pinned_objects));
|
||||
auto service_config = MasterServiceConfig::builder()
|
||||
.set_default_kv_lease_ttl(kv_lease_ttl)
|
||||
.set_default_kv_soft_pin_ttl(kv_soft_pin_ttl)
|
||||
.set_allow_evict_soft_pinned_objects(
|
||||
allow_evict_soft_pinned_objects)
|
||||
.build();
|
||||
std::unique_ptr<MasterService> service_(new MasterService(service_config));
|
||||
// Mount segment and put an object
|
||||
constexpr size_t buffer = 0x300000000;
|
||||
constexpr size_t size = 1024 * 1024 * 16;
|
||||
|
|
@ -1755,9 +1862,14 @@ TEST_F(MasterServiceTest, SoftPinObjectsNotEvictedBeforeOtherObjects) {
|
|||
const uint64_t kv_soft_pin_ttl = 10000;
|
||||
const double eviction_ratio = 0.5;
|
||||
const bool allow_evict_soft_pinned_objects = true;
|
||||
std::unique_ptr<MasterService> service_(
|
||||
new MasterService(false, kv_lease_ttl, kv_soft_pin_ttl,
|
||||
allow_evict_soft_pinned_objects, eviction_ratio));
|
||||
auto service_config = MasterServiceConfig::builder()
|
||||
.set_default_kv_lease_ttl(kv_lease_ttl)
|
||||
.set_default_kv_soft_pin_ttl(kv_soft_pin_ttl)
|
||||
.set_allow_evict_soft_pinned_objects(
|
||||
allow_evict_soft_pinned_objects)
|
||||
.set_eviction_ratio(eviction_ratio)
|
||||
.build();
|
||||
std::unique_ptr<MasterService> service_(new MasterService(service_config));
|
||||
|
||||
// Mount segment and put an object
|
||||
constexpr size_t buffer = 0x300000000;
|
||||
|
|
@ -1821,8 +1933,13 @@ TEST_F(MasterServiceTest, SoftPinObjectsCanBeEvicted) {
|
|||
// set a large soft_pin_ttl so the granted soft pin will not quickly expire
|
||||
const uint64_t kv_soft_pin_ttl = 10000;
|
||||
const bool allow_evict_soft_pinned_objects = true;
|
||||
std::unique_ptr<MasterService> service_(new MasterService(
|
||||
false, kv_lease_ttl, kv_soft_pin_ttl, allow_evict_soft_pinned_objects));
|
||||
auto service_config = MasterServiceConfig::builder()
|
||||
.set_default_kv_lease_ttl(kv_lease_ttl)
|
||||
.set_default_kv_soft_pin_ttl(kv_soft_pin_ttl)
|
||||
.set_allow_evict_soft_pinned_objects(
|
||||
allow_evict_soft_pinned_objects)
|
||||
.build();
|
||||
std::unique_ptr<MasterService> service_(new MasterService(service_config));
|
||||
|
||||
// Mount segment and put an object
|
||||
constexpr size_t buffer = 0x300000000;
|
||||
|
|
@ -1864,9 +1981,14 @@ TEST_F(MasterServiceTest, SoftPinExtendedOnGet) {
|
|||
"kv_soft_pin_ttl must be larger than kv_lease_ttl in this test");
|
||||
const double eviction_ratio = 0.5;
|
||||
const bool allow_evict_soft_pinned_objects = true;
|
||||
std::unique_ptr<MasterService> service_(
|
||||
new MasterService(false, kv_lease_ttl, kv_soft_pin_ttl,
|
||||
allow_evict_soft_pinned_objects, eviction_ratio));
|
||||
auto service_config = MasterServiceConfig::builder()
|
||||
.set_default_kv_lease_ttl(kv_lease_ttl)
|
||||
.set_default_kv_soft_pin_ttl(kv_soft_pin_ttl)
|
||||
.set_allow_evict_soft_pinned_objects(
|
||||
allow_evict_soft_pinned_objects)
|
||||
.set_eviction_ratio(eviction_ratio)
|
||||
.build();
|
||||
std::unique_ptr<MasterService> service_(new MasterService(service_config));
|
||||
|
||||
// Mount segment and put an object
|
||||
constexpr size_t buffer = 0x300000000;
|
||||
|
|
@ -1941,8 +2063,13 @@ TEST_F(MasterServiceTest, SoftPinObjectsNotAllowEvict) {
|
|||
// set allow_evict_soft_pinned_objects to false to disable eviction of soft
|
||||
// pinned objects
|
||||
const bool allow_evict_soft_pinned_objects = false;
|
||||
std::unique_ptr<MasterService> service_(new MasterService(
|
||||
false, kv_lease_ttl, kv_soft_pin_ttl, allow_evict_soft_pinned_objects));
|
||||
auto service_config = MasterServiceConfig::builder()
|
||||
.set_default_kv_lease_ttl(kv_lease_ttl)
|
||||
.set_default_kv_soft_pin_ttl(kv_soft_pin_ttl)
|
||||
.set_allow_evict_soft_pinned_objects(
|
||||
allow_evict_soft_pinned_objects)
|
||||
.build();
|
||||
std::unique_ptr<MasterService> service_(new MasterService(service_config));
|
||||
|
||||
// Mount segment and put an object
|
||||
constexpr size_t buffer = 0x300000000;
|
||||
|
|
|
|||
Loading…
Reference in New Issue