[CCF Archive] Store object type eviction policy submission #3
|
|
@ -1919,7 +1919,8 @@ PYBIND11_MODULE(store, m) {
|
|||
const std::string &master_server_addr = "127.0.0.1:50051",
|
||||
const py::object &engine = py::none(),
|
||||
bool enable_ssd_offload = false,
|
||||
const std::string &ssd_offload_path = "") {
|
||||
const std::string &ssd_offload_path = "",
|
||||
const std::string &tenant_id = "default") {
|
||||
auto real_client = self.init_real_client();
|
||||
std::shared_ptr<mooncake::TransferEngine> transfer_engine =
|
||||
nullptr;
|
||||
|
|
@ -1931,14 +1932,14 @@ PYBIND11_MODULE(store, m) {
|
|||
local_hostname, metadata_server, global_segment_size,
|
||||
local_buffer_size, protocol, rdma_devices,
|
||||
master_server_addr, transfer_engine, "", enable_ssd_offload,
|
||||
ssd_offload_path);
|
||||
ssd_offload_path, tenant_id);
|
||||
},
|
||||
py::arg("local_hostname"), py::arg("metadata_server"),
|
||||
py::arg("global_segment_size"), py::arg("local_buffer_size"),
|
||||
py::arg("protocol"), py::arg("rdma_devices"),
|
||||
py::arg("master_server_addr"), py::arg("engine") = py::none(),
|
||||
py::arg("enable_ssd_offload") = false,
|
||||
py::arg("ssd_offload_path") = "")
|
||||
py::arg("ssd_offload_path") = "", py::arg("tenant_id") = "default")
|
||||
.def(
|
||||
"setup",
|
||||
[](MooncakeStorePyWrapper &self, const py::dict &config_dict) {
|
||||
|
|
|
|||
|
|
@ -86,7 +86,8 @@ class Client {
|
|||
const std::optional<std::string>& device_names = std::nullopt,
|
||||
const std::string& master_server_entry = kDefaultMasterAddress,
|
||||
const std::shared_ptr<TransferEngine>& transfer_engine = nullptr,
|
||||
std::map<std::string, std::string> labels = {});
|
||||
std::map<std::string, std::string> labels = {},
|
||||
const std::string& tenant_id = "default");
|
||||
|
||||
/**
|
||||
* @brief Retrieves data for a given key
|
||||
|
|
@ -627,7 +628,8 @@ class Client {
|
|||
*/
|
||||
Client(const std::string& local_hostname,
|
||||
const std::string& metadata_connstring, const std::string& protocol,
|
||||
const std::map<std::string, std::string>& labels = {});
|
||||
const std::map<std::string, std::string>& labels = {},
|
||||
const std::string& tenant_id = "default");
|
||||
|
||||
private:
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -29,7 +29,8 @@ class DummyClient : public PyClient {
|
|||
const std::shared_ptr<TransferEngine> &transfer_engine,
|
||||
const std::string &ipc_socket_path,
|
||||
bool enable_ssd_offload = false,
|
||||
const std::string &ssd_offload_path = "") {
|
||||
const std::string &ssd_offload_path = "",
|
||||
const std::string &tenant_id = "default") {
|
||||
// Dummy client does not support real setup
|
||||
return -1;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -52,8 +52,11 @@ inline void MaybeEnableRdmaSocketConfig(SocketConfigVariant& socket_config) {
|
|||
*/
|
||||
class MasterClient {
|
||||
public:
|
||||
MasterClient(const UUID& client_id, MasterClientMetric* metrics = nullptr)
|
||||
: client_id_(client_id), metrics_(metrics) {
|
||||
MasterClient(const UUID& client_id, MasterClientMetric* metrics = nullptr,
|
||||
std::string tenant_id = "default")
|
||||
: client_id_(client_id),
|
||||
tenant_id_(NormalizeTenantId(std::move(tenant_id))),
|
||||
metrics_(metrics) {
|
||||
coro_io::client_pool<coro_rpc::coro_rpc_client>::pool_config
|
||||
pool_conf{};
|
||||
|
||||
|
|
@ -635,6 +638,9 @@ class MasterClient {
|
|||
// The client identification.
|
||||
const UUID client_id_;
|
||||
|
||||
// Tenant identity for this client instance.
|
||||
const std::string tenant_id_;
|
||||
|
||||
// Metrics for tracking RPC operations
|
||||
MasterClientMetric* metrics_;
|
||||
std::shared_ptr<coro_io::client_pools<coro_rpc::coro_rpc_client>>
|
||||
|
|
|
|||
|
|
@ -318,6 +318,9 @@ class MasterService {
|
|||
*/
|
||||
auto PutRevoke(const UUID& client_id, const std::string& key,
|
||||
ReplicaType replica_type) -> tl::expected<void, ErrorCode>;
|
||||
auto PutRevoke(const UUID& client_id, const std::string& key,
|
||||
const std::string& tenant_id, ReplicaType replica_type)
|
||||
-> tl::expected<void, ErrorCode>;
|
||||
|
||||
/**
|
||||
* @brief Complete a batch of put operations
|
||||
|
|
@ -327,6 +330,10 @@ class MasterService {
|
|||
std::vector<tl::expected<void, ErrorCode>> BatchPutEnd(
|
||||
const UUID& client_id, const std::vector<std::string>& keys,
|
||||
ReplicaType replica_type = ReplicaType::ALL);
|
||||
std::vector<tl::expected<void, ErrorCode>> BatchPutEnd(
|
||||
const UUID& client_id, const std::vector<std::string>& keys,
|
||||
const std::string& tenant_id,
|
||||
ReplicaType replica_type = ReplicaType::ALL);
|
||||
|
||||
/**
|
||||
* @brief Revoke a batch of put operations
|
||||
|
|
@ -336,6 +343,10 @@ class MasterService {
|
|||
std::vector<tl::expected<void, ErrorCode>> BatchPutRevoke(
|
||||
const UUID& client_id, const std::vector<std::string>& keys,
|
||||
ReplicaType replica_type = ReplicaType::ALL);
|
||||
std::vector<tl::expected<void, ErrorCode>> BatchPutRevoke(
|
||||
const UUID& client_id, const std::vector<std::string>& keys,
|
||||
const std::string& tenant_id,
|
||||
ReplicaType replica_type = ReplicaType::ALL);
|
||||
|
||||
/**
|
||||
* @brief Start an upsert operation. If the key does not exist, behaves
|
||||
|
|
@ -359,6 +370,9 @@ class MasterService {
|
|||
*/
|
||||
auto UpsertEnd(const UUID& client_id, const std::string& key,
|
||||
ReplicaType replica_type) -> tl::expected<void, ErrorCode>;
|
||||
auto UpsertEnd(const UUID& client_id, const std::string& key,
|
||||
const std::string& tenant_id, ReplicaType replica_type)
|
||||
-> tl::expected<void, ErrorCode>;
|
||||
|
||||
/**
|
||||
* @brief Revoke an upsert operation. Delegates to PutRevoke.
|
||||
|
|
@ -366,6 +380,9 @@ class MasterService {
|
|||
auto UpsertRevoke(const UUID& client_id, const std::string& key,
|
||||
ReplicaType replica_type)
|
||||
-> tl::expected<void, ErrorCode>;
|
||||
auto UpsertRevoke(const UUID& client_id, const std::string& key,
|
||||
const std::string& tenant_id, ReplicaType replica_type)
|
||||
-> tl::expected<void, ErrorCode>;
|
||||
|
||||
/**
|
||||
* @brief Start a batch of upsert operations.
|
||||
|
|
@ -375,18 +392,30 @@ class MasterService {
|
|||
const std::vector<std::string>& keys,
|
||||
const std::vector<uint64_t>& slice_lengths,
|
||||
const ReplicateConfig& config);
|
||||
std::vector<tl::expected<std::vector<Replica::Descriptor>, ErrorCode>>
|
||||
BatchUpsertStart(const UUID& client_id,
|
||||
const std::vector<std::string>& keys,
|
||||
const std::string& tenant_id,
|
||||
const std::vector<uint64_t>& slice_lengths,
|
||||
const ReplicateConfig& config);
|
||||
|
||||
/**
|
||||
* @brief Complete a batch of upsert operations. Delegates to BatchPutEnd.
|
||||
*/
|
||||
std::vector<tl::expected<void, ErrorCode>> BatchUpsertEnd(
|
||||
const UUID& client_id, const std::vector<std::string>& keys);
|
||||
std::vector<tl::expected<void, ErrorCode>> BatchUpsertEnd(
|
||||
const UUID& client_id, const std::vector<std::string>& keys,
|
||||
const std::string& tenant_id);
|
||||
|
||||
/**
|
||||
* @brief Revoke a batch of upsert operations. Delegates to BatchPutRevoke.
|
||||
*/
|
||||
std::vector<tl::expected<void, ErrorCode>> BatchUpsertRevoke(
|
||||
const UUID& client_id, const std::vector<std::string>& keys);
|
||||
std::vector<tl::expected<void, ErrorCode>> BatchUpsertRevoke(
|
||||
const UUID& client_id, const std::vector<std::string>& keys,
|
||||
const std::string& tenant_id);
|
||||
|
||||
/**
|
||||
* @brief Evict a disk replica for a key (triggered by client-side disk
|
||||
|
|
@ -483,12 +512,20 @@ class MasterService {
|
|||
bool force = false) -> tl::expected<long, ErrorCode>;
|
||||
|
||||
/**
|
||||
* @brief Remove all objects and their replicas
|
||||
* @brief Remove all objects and their replicas across all tenants.
|
||||
* @param force If true, skip lease and replication task checks.
|
||||
* @return return the number of objects removed
|
||||
*/
|
||||
long RemoveAll(bool force = false);
|
||||
|
||||
/**
|
||||
* @brief Remove all objects and their replicas for a single tenant.
|
||||
* @param tenant_id The tenant whose objects should be removed.
|
||||
* @param force If true, skip lease and replication task checks.
|
||||
* @return return the number of objects removed
|
||||
*/
|
||||
long RemoveAll(const std::string& tenant_id, bool force = false);
|
||||
|
||||
/**
|
||||
* @brief Batch remove objects and their replicas
|
||||
* @param keys The list of keys to remove.
|
||||
|
|
@ -497,6 +534,9 @@ class MasterService {
|
|||
*/
|
||||
auto BatchRemove(const std::vector<std::string>& keys, bool force = false)
|
||||
-> std::vector<tl::expected<void, ErrorCode>>;
|
||||
auto BatchRemove(const std::vector<std::string>& keys,
|
||||
const std::string& tenant_id, bool force = false)
|
||||
-> std::vector<tl::expected<void, ErrorCode>>;
|
||||
|
||||
/**
|
||||
* @brief Get the count of keys
|
||||
|
|
|
|||
|
|
@ -215,7 +215,8 @@ class PyClient {
|
|||
const std::string &master_server_addr,
|
||||
const std::shared_ptr<TransferEngine> &transfer_engine,
|
||||
const std::string &ipc_socket_path, bool enable_ssd_offload = false,
|
||||
const std::string &ssd_offload_path = "") = 0;
|
||||
const std::string &ssd_offload_path = "",
|
||||
const std::string &tenant_id = "default") = 0;
|
||||
|
||||
virtual int setup_dummy(size_t mem_pool_size, size_t local_buffer_size,
|
||||
const std::string &server_address,
|
||||
|
|
|
|||
|
|
@ -82,7 +82,8 @@ class RealClient : public PyClient {
|
|||
const std::shared_ptr<TransferEngine> &transfer_engine = nullptr,
|
||||
const std::string &ipc_socket_path = "",
|
||||
bool enable_ssd_offload = false,
|
||||
const std::string &ssd_offload_path = "");
|
||||
const std::string &ssd_offload_path = "",
|
||||
const std::string &tenant_id = "default");
|
||||
|
||||
int setup_dummy(size_t mem_pool_size, size_t local_buffer_size,
|
||||
const std::string &server_address,
|
||||
|
|
@ -503,7 +504,8 @@ class RealClient : public PyClient {
|
|||
const std::shared_ptr<TransferEngine> &transfer_engine = nullptr,
|
||||
const std::string &ipc_socket_path = "", int local_rpc_port = 50052,
|
||||
bool enable_ssd_offload = false, bool start_offload_rpc_server = false,
|
||||
const std::string &ssd_offload_path = "");
|
||||
const std::string &ssd_offload_path = "",
|
||||
const std::string &tenant_id = "default");
|
||||
|
||||
// Overload that accepts a configuration dictionary
|
||||
tl::expected<void, ErrorCode> setup_internal(const ConfigDict &config);
|
||||
|
|
|
|||
|
|
@ -30,13 +30,15 @@ class WrappedMasterService {
|
|||
|
||||
~WrappedMasterService();
|
||||
|
||||
tl::expected<bool, ErrorCode> ExistKey(const std::string& key);
|
||||
tl::expected<bool, ErrorCode> ExistKey(
|
||||
const std::string& key, const std::string& tenant_id = "default");
|
||||
|
||||
tl::expected<MasterMetricManager::CacheHitStatDict, ErrorCode>
|
||||
CalcCacheStats();
|
||||
|
||||
std::vector<tl::expected<bool, ErrorCode>> BatchExistKey(
|
||||
const std::vector<std::string>& keys);
|
||||
const std::vector<std::string>& keys,
|
||||
const std::string& tenant_id = "default");
|
||||
|
||||
tl::expected<
|
||||
std::unordered_map<UUID, std::vector<std::string>, boost::hash<UUID>>,
|
||||
|
|
@ -50,73 +52,91 @@ class WrappedMasterService {
|
|||
tl::expected<
|
||||
std::unordered_map<std::string, std::vector<Replica::Descriptor>>,
|
||||
ErrorCode>
|
||||
GetReplicaListByRegex(const std::string& str);
|
||||
GetReplicaListByRegex(const std::string& str,
|
||||
const std::string& tenant_id = "default");
|
||||
|
||||
tl::expected<GetReplicaListResponse, ErrorCode> GetReplicaList(
|
||||
const std::string& key);
|
||||
const std::string& key, const std::string& tenant_id = "default");
|
||||
|
||||
std::vector<tl::expected<GetReplicaListResponse, ErrorCode>>
|
||||
BatchGetReplicaList(const std::vector<std::string>& keys);
|
||||
BatchGetReplicaList(const std::vector<std::string>& keys,
|
||||
const std::string& tenant_id = "default");
|
||||
|
||||
tl::expected<std::vector<Replica::Descriptor>, ErrorCode> PutStart(
|
||||
const UUID& client_id, const std::string& key,
|
||||
const uint64_t slice_length, const ReplicateConfig& config);
|
||||
const uint64_t slice_length, const ReplicateConfig& config,
|
||||
const std::string& tenant_id = "default");
|
||||
|
||||
tl::expected<void, ErrorCode> PutEnd(
|
||||
const UUID& client_id, const std::string& key,
|
||||
ReplicaType replica_type = ReplicaType::ALL);
|
||||
ReplicaType replica_type = ReplicaType::ALL,
|
||||
const std::string& tenant_id = "default");
|
||||
|
||||
tl::expected<void, ErrorCode> PutRevoke(
|
||||
const UUID& client_id, const std::string& key,
|
||||
ReplicaType replica_type = ReplicaType::ALL);
|
||||
ReplicaType replica_type = ReplicaType::ALL,
|
||||
const std::string& tenant_id = "default");
|
||||
|
||||
std::vector<tl::expected<std::vector<Replica::Descriptor>, ErrorCode>>
|
||||
BatchPutStart(const UUID& client_id, const std::vector<std::string>& keys,
|
||||
const std::vector<uint64_t>& slice_lengths,
|
||||
const ReplicateConfig& config);
|
||||
const ReplicateConfig& config,
|
||||
const std::string& tenant_id = "default");
|
||||
|
||||
std::vector<tl::expected<void, ErrorCode>> BatchPutEnd(
|
||||
const UUID& client_id, const std::vector<std::string>& keys,
|
||||
ReplicaType replica_type = ReplicaType::ALL);
|
||||
ReplicaType replica_type = ReplicaType::ALL,
|
||||
const std::string& tenant_id = "default");
|
||||
|
||||
std::vector<tl::expected<void, ErrorCode>> BatchPutRevoke(
|
||||
const UUID& client_id, const std::vector<std::string>& keys,
|
||||
ReplicaType replica_type = ReplicaType::ALL);
|
||||
ReplicaType replica_type = ReplicaType::ALL,
|
||||
const std::string& tenant_id = "default");
|
||||
|
||||
tl::expected<std::vector<Replica::Descriptor>, ErrorCode> UpsertStart(
|
||||
const UUID& client_id, const std::string& key,
|
||||
const uint64_t slice_length, const ReplicateConfig& config);
|
||||
const uint64_t slice_length, const ReplicateConfig& config,
|
||||
const std::string& tenant_id = "default");
|
||||
|
||||
tl::expected<void, ErrorCode> UpsertEnd(const UUID& client_id,
|
||||
const std::string& key,
|
||||
ReplicaType replica_type);
|
||||
tl::expected<void, ErrorCode> UpsertEnd(
|
||||
const UUID& client_id, const std::string& key,
|
||||
ReplicaType replica_type = ReplicaType::ALL,
|
||||
const std::string& tenant_id = "default");
|
||||
|
||||
tl::expected<void, ErrorCode> UpsertRevoke(const UUID& client_id,
|
||||
const std::string& key,
|
||||
ReplicaType replica_type);
|
||||
tl::expected<void, ErrorCode> UpsertRevoke(
|
||||
const UUID& client_id, const std::string& key,
|
||||
ReplicaType replica_type = ReplicaType::ALL,
|
||||
const std::string& tenant_id = "default");
|
||||
|
||||
std::vector<tl::expected<std::vector<Replica::Descriptor>, ErrorCode>>
|
||||
BatchUpsertStart(const UUID& client_id,
|
||||
const std::vector<std::string>& keys,
|
||||
const std::vector<uint64_t>& slice_lengths,
|
||||
const ReplicateConfig& config);
|
||||
const ReplicateConfig& config,
|
||||
const std::string& tenant_id = "default");
|
||||
|
||||
std::vector<tl::expected<void, ErrorCode>> BatchUpsertEnd(
|
||||
const UUID& client_id, const std::vector<std::string>& keys);
|
||||
const UUID& client_id, const std::vector<std::string>& keys,
|
||||
const std::string& tenant_id = "default");
|
||||
|
||||
std::vector<tl::expected<void, ErrorCode>> BatchUpsertRevoke(
|
||||
const UUID& client_id, const std::vector<std::string>& keys);
|
||||
const UUID& client_id, const std::vector<std::string>& keys,
|
||||
const std::string& tenant_id = "default");
|
||||
|
||||
tl::expected<void, ErrorCode> Remove(const std::string& key,
|
||||
bool force = false);
|
||||
tl::expected<void, ErrorCode> Remove(
|
||||
const std::string& key, bool force = false,
|
||||
const std::string& tenant_id = "default");
|
||||
|
||||
tl::expected<long, ErrorCode> RemoveByRegex(const std::string& str,
|
||||
bool force = false);
|
||||
tl::expected<long, ErrorCode> RemoveByRegex(
|
||||
const std::string& str, bool force = false,
|
||||
const std::string& tenant_id = "default");
|
||||
|
||||
long RemoveAll(bool force = false);
|
||||
long RemoveAll(bool force = false,
|
||||
const std::string& tenant_id = "default");
|
||||
|
||||
std::vector<tl::expected<void, ErrorCode>> BatchRemove(
|
||||
const std::vector<std::string>& keys, bool force = false);
|
||||
const std::vector<std::string>& keys, bool force = false,
|
||||
const std::string& tenant_id = "default");
|
||||
|
||||
tl::expected<void, ErrorCode> MountSegment(const Segment& segment,
|
||||
const UUID& client_id);
|
||||
|
|
|
|||
|
|
@ -215,6 +215,7 @@ constexpr const char* CONFIG_KEY_PROTOCOL = "protocol";
|
|||
constexpr const char* CONFIG_KEY_RDMA_DEVICES = "rdma_devices";
|
||||
constexpr const char* CONFIG_KEY_MASTER_SERVER_ADDR = "master_server_addr";
|
||||
constexpr const char* CONFIG_KEY_IPC_SOCKET_PATH = "ipc_socket_path";
|
||||
constexpr const char* CONFIG_KEY_TENANT_ID = "tenant_id";
|
||||
|
||||
// Store client configuration defaults
|
||||
static constexpr size_t DEFAULT_GLOBAL_SEGMENT_SIZE = 1024 * 1024 * 16; // 16MB
|
||||
|
|
|
|||
|
|
@ -272,11 +272,13 @@ FinalizeDecision DetermineFinalizeDecision(
|
|||
Client::Client(const std::string& local_hostname,
|
||||
const std::string& metadata_connstring,
|
||||
const std::string& protocol,
|
||||
const std::map<std::string, std::string>& labels)
|
||||
const std::map<std::string, std::string>& labels,
|
||||
const std::string& tenant_id)
|
||||
: client_id_(generate_uuid()),
|
||||
metrics_(ClientMetric::Create(merge_labels(labels))),
|
||||
master_client_(client_id_,
|
||||
metrics_ ? &metrics_->master_client_metric : nullptr),
|
||||
metrics_ ? &metrics_->master_client_metric : nullptr,
|
||||
tenant_id),
|
||||
local_hostname_(local_hostname),
|
||||
metadata_connstring_(metadata_connstring),
|
||||
protocol_(protocol),
|
||||
|
|
@ -832,9 +834,9 @@ std::optional<std::shared_ptr<Client>> Client::Create(
|
|||
const std::string& protocol, const std::optional<std::string>& device_names,
|
||||
const std::string& master_server_entry,
|
||||
const std::shared_ptr<TransferEngine>& transfer_engine,
|
||||
std::map<std::string, std::string> labels) {
|
||||
auto client = std::shared_ptr<Client>(
|
||||
new Client(local_hostname, metadata_connstring, protocol, labels));
|
||||
std::map<std::string, std::string> labels, const std::string& tenant_id) {
|
||||
auto client = std::shared_ptr<Client>(new Client(
|
||||
local_hostname, metadata_connstring, protocol, labels, tenant_id));
|
||||
|
||||
ErrorCode err = client->ConnectToMaster(master_server_entry);
|
||||
if (err != ErrorCode::OK) {
|
||||
|
|
|
|||
|
|
@ -445,7 +445,8 @@ tl::expected<bool, ErrorCode> MasterClient::ExistKey(
|
|||
ScopedVLogTimer timer(1, "MasterClient::ExistKey");
|
||||
timer.LogRequest("object_key=", object_key);
|
||||
|
||||
auto result = invoke_rpc<&WrappedMasterService::ExistKey, bool>(object_key);
|
||||
auto result = invoke_rpc<&WrappedMasterService::ExistKey, bool>(object_key,
|
||||
tenant_id_);
|
||||
timer.LogResponseExpected(result);
|
||||
return result;
|
||||
}
|
||||
|
|
@ -456,7 +457,7 @@ std::vector<tl::expected<bool, ErrorCode>> MasterClient::BatchExistKey(
|
|||
timer.LogRequest("keys_count=", object_keys.size());
|
||||
|
||||
auto result = invoke_batch_rpc<&WrappedMasterService::BatchExistKey, bool>(
|
||||
object_keys.size(), object_keys);
|
||||
object_keys.size(), object_keys, tenant_id_);
|
||||
timer.LogResponse("result=", result.size(), " keys");
|
||||
return result;
|
||||
}
|
||||
|
|
@ -506,7 +507,8 @@ MasterClient::GetReplicaListByRegex(const std::string& str) {
|
|||
|
||||
auto result = invoke_rpc<
|
||||
&WrappedMasterService::GetReplicaListByRegex,
|
||||
std::unordered_map<std::string, std::vector<Replica::Descriptor>>>(str);
|
||||
std::unordered_map<std::string, std::vector<Replica::Descriptor>>>(
|
||||
str, tenant_id_);
|
||||
|
||||
timer.LogResponseExpected(result);
|
||||
return result;
|
||||
|
|
@ -518,7 +520,7 @@ tl::expected<GetReplicaListResponse, ErrorCode> MasterClient::GetReplicaList(
|
|||
timer.LogRequest("object_key=", object_key);
|
||||
|
||||
auto result = invoke_rpc<&WrappedMasterService::GetReplicaList,
|
||||
GetReplicaListResponse>(object_key);
|
||||
GetReplicaListResponse>(object_key, tenant_id_);
|
||||
timer.LogResponseExpected(result);
|
||||
return result;
|
||||
}
|
||||
|
|
@ -529,8 +531,8 @@ MasterClient::BatchGetReplicaList(const std::vector<std::string>& object_keys) {
|
|||
timer.LogRequest("keys_count=", object_keys.size());
|
||||
|
||||
auto result = invoke_batch_rpc<&WrappedMasterService::BatchGetReplicaList,
|
||||
GetReplicaListResponse>(object_keys.size(),
|
||||
object_keys);
|
||||
GetReplicaListResponse>(
|
||||
object_keys.size(), object_keys, tenant_id_);
|
||||
timer.LogResponse("result=", result.size(), " operations");
|
||||
return result;
|
||||
}
|
||||
|
|
@ -549,7 +551,7 @@ MasterClient::PutStart(const std::string& key,
|
|||
|
||||
auto result = invoke_rpc<&WrappedMasterService::PutStart,
|
||||
std::vector<Replica::Descriptor>>(
|
||||
client_id_, key, total_slice_length, config);
|
||||
client_id_, key, total_slice_length, config, tenant_id_);
|
||||
timer.LogResponseExpected(result);
|
||||
return result;
|
||||
}
|
||||
|
|
@ -574,7 +576,7 @@ MasterClient::BatchPutStart(
|
|||
|
||||
auto result = invoke_batch_rpc<&WrappedMasterService::BatchPutStart,
|
||||
std::vector<Replica::Descriptor>>(
|
||||
keys.size(), client_id_, keys, total_slice_lengths, config);
|
||||
keys.size(), client_id_, keys, total_slice_lengths, config, tenant_id_);
|
||||
timer.LogResponse("result=", result.size(), " operations");
|
||||
return result;
|
||||
}
|
||||
|
|
@ -585,7 +587,7 @@ tl::expected<void, ErrorCode> MasterClient::PutEnd(const std::string& key,
|
|||
timer.LogRequest("key=", key);
|
||||
|
||||
auto result = invoke_rpc<&WrappedMasterService::PutEnd, void>(
|
||||
client_id_, key, replica_type);
|
||||
client_id_, key, replica_type, tenant_id_);
|
||||
timer.LogResponseExpected(result);
|
||||
return result;
|
||||
}
|
||||
|
|
@ -596,7 +598,7 @@ std::vector<tl::expected<void, ErrorCode>> MasterClient::BatchPutEnd(
|
|||
timer.LogRequest("keys_count=", keys.size());
|
||||
|
||||
auto result = invoke_batch_rpc<&WrappedMasterService::BatchPutEnd, void>(
|
||||
keys.size(), client_id_, keys, replica_type);
|
||||
keys.size(), client_id_, keys, replica_type, tenant_id_);
|
||||
timer.LogResponse("result=", result.size(), " operations");
|
||||
return result;
|
||||
}
|
||||
|
|
@ -607,7 +609,7 @@ tl::expected<void, ErrorCode> MasterClient::PutRevoke(
|
|||
timer.LogRequest("key=", key);
|
||||
|
||||
auto result = invoke_rpc<&WrappedMasterService::PutRevoke, void>(
|
||||
client_id_, key, replica_type);
|
||||
client_id_, key, replica_type, tenant_id_);
|
||||
timer.LogResponseExpected(result);
|
||||
return result;
|
||||
}
|
||||
|
|
@ -618,7 +620,7 @@ std::vector<tl::expected<void, ErrorCode>> MasterClient::BatchPutRevoke(
|
|||
timer.LogRequest("keys_count=", keys.size());
|
||||
|
||||
auto result = invoke_batch_rpc<&WrappedMasterService::BatchPutRevoke, void>(
|
||||
keys.size(), client_id_, keys, replica_type);
|
||||
keys.size(), client_id_, keys, replica_type, tenant_id_);
|
||||
timer.LogResponse("result=", result.size(), " operations");
|
||||
return result;
|
||||
}
|
||||
|
|
@ -637,7 +639,7 @@ MasterClient::UpsertStart(const std::string& key,
|
|||
|
||||
auto result = invoke_rpc<&WrappedMasterService::UpsertStart,
|
||||
std::vector<Replica::Descriptor>>(
|
||||
client_id_, key, total_slice_length, config);
|
||||
client_id_, key, total_slice_length, config, tenant_id_);
|
||||
timer.LogResponseExpected(result);
|
||||
return result;
|
||||
}
|
||||
|
|
@ -662,7 +664,7 @@ MasterClient::BatchUpsertStart(
|
|||
|
||||
auto result = invoke_batch_rpc<&WrappedMasterService::BatchUpsertStart,
|
||||
std::vector<Replica::Descriptor>>(
|
||||
keys.size(), client_id_, keys, total_slice_lengths, config);
|
||||
keys.size(), client_id_, keys, total_slice_lengths, config, tenant_id_);
|
||||
timer.LogResponse("result=", result.size(), " operations");
|
||||
return result;
|
||||
}
|
||||
|
|
@ -673,7 +675,7 @@ tl::expected<void, ErrorCode> MasterClient::UpsertEnd(
|
|||
timer.LogRequest("key=", key);
|
||||
|
||||
auto result = invoke_rpc<&WrappedMasterService::UpsertEnd, void>(
|
||||
client_id_, key, replica_type);
|
||||
client_id_, key, replica_type, tenant_id_);
|
||||
timer.LogResponseExpected(result);
|
||||
return result;
|
||||
}
|
||||
|
|
@ -684,7 +686,7 @@ std::vector<tl::expected<void, ErrorCode>> MasterClient::BatchUpsertEnd(
|
|||
timer.LogRequest("keys_count=", keys.size());
|
||||
|
||||
auto result = invoke_batch_rpc<&WrappedMasterService::BatchUpsertEnd, void>(
|
||||
keys.size(), client_id_, keys);
|
||||
keys.size(), client_id_, keys, tenant_id_);
|
||||
timer.LogResponse("result=", result.size(), " operations");
|
||||
return result;
|
||||
}
|
||||
|
|
@ -695,7 +697,7 @@ tl::expected<void, ErrorCode> MasterClient::UpsertRevoke(
|
|||
timer.LogRequest("key=", key);
|
||||
|
||||
auto result = invoke_rpc<&WrappedMasterService::UpsertRevoke, void>(
|
||||
client_id_, key, replica_type);
|
||||
client_id_, key, replica_type, tenant_id_);
|
||||
timer.LogResponseExpected(result);
|
||||
return result;
|
||||
}
|
||||
|
|
@ -707,7 +709,7 @@ std::vector<tl::expected<void, ErrorCode>> MasterClient::BatchUpsertRevoke(
|
|||
|
||||
auto result =
|
||||
invoke_batch_rpc<&WrappedMasterService::BatchUpsertRevoke, void>(
|
||||
keys.size(), client_id_, keys);
|
||||
keys.size(), client_id_, keys, tenant_id_);
|
||||
timer.LogResponse("result=", result.size(), " operations");
|
||||
return result;
|
||||
}
|
||||
|
|
@ -717,7 +719,8 @@ tl::expected<void, ErrorCode> MasterClient::Remove(const std::string& key,
|
|||
ScopedVLogTimer timer(1, "MasterClient::Remove");
|
||||
timer.LogRequest("key=", key, ", force=", force);
|
||||
|
||||
auto result = invoke_rpc<&WrappedMasterService::Remove, void>(key, force);
|
||||
auto result =
|
||||
invoke_rpc<&WrappedMasterService::Remove, void>(key, force, tenant_id_);
|
||||
timer.LogResponseExpected(result);
|
||||
return result;
|
||||
}
|
||||
|
|
@ -727,8 +730,8 @@ tl::expected<long, ErrorCode> MasterClient::RemoveByRegex(
|
|||
ScopedVLogTimer timer(1, "MasterClient::RemoveByRegex");
|
||||
timer.LogRequest("key=", str, ", force=", force);
|
||||
|
||||
auto result =
|
||||
invoke_rpc<&WrappedMasterService::RemoveByRegex, long>(str, force);
|
||||
auto result = invoke_rpc<&WrappedMasterService::RemoveByRegex, long>(
|
||||
str, force, tenant_id_);
|
||||
timer.LogResponseExpected(result);
|
||||
return result;
|
||||
}
|
||||
|
|
@ -737,7 +740,8 @@ tl::expected<long, ErrorCode> MasterClient::RemoveAll(bool force) {
|
|||
ScopedVLogTimer timer(1, "MasterClient::RemoveAll");
|
||||
timer.LogRequest("action=remove_all_objects, force=", force);
|
||||
|
||||
auto result = invoke_rpc<&WrappedMasterService::RemoveAll, long>(force);
|
||||
auto result =
|
||||
invoke_rpc<&WrappedMasterService::RemoveAll, long>(force, tenant_id_);
|
||||
timer.LogResponseExpected(result);
|
||||
return result;
|
||||
}
|
||||
|
|
@ -748,7 +752,7 @@ std::vector<tl::expected<void, ErrorCode>> MasterClient::BatchRemove(
|
|||
timer.LogRequest("keys_count=", keys.size(), ", force=", force);
|
||||
|
||||
auto result = invoke_batch_rpc<&WrappedMasterService::BatchRemove, void>(
|
||||
keys.size(), keys, force);
|
||||
keys.size(), keys, force, tenant_id_);
|
||||
timer.LogResponse("result=", result.size(), " operations");
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1773,8 +1773,15 @@ auto MasterService::AddReplica(const UUID& client_id, const std::string& key,
|
|||
auto MasterService::PutRevoke(const UUID& client_id, const std::string& key,
|
||||
ReplicaType replica_type)
|
||||
-> tl::expected<void, ErrorCode> {
|
||||
return PutRevoke(client_id, key, "default", replica_type);
|
||||
}
|
||||
|
||||
auto MasterService::PutRevoke(const UUID& client_id, const std::string& key,
|
||||
const std::string& tenant_id,
|
||||
ReplicaType replica_type)
|
||||
-> tl::expected<void, ErrorCode> {
|
||||
std::shared_lock<std::shared_mutex> shared_lock(snapshot_mutex_);
|
||||
MetadataAccessorRW accessor(this, key);
|
||||
MetadataAccessorRW accessor(this, MakeObjectIdentity(key, tenant_id));
|
||||
if (!accessor.Exists()) {
|
||||
LOG(INFO) << "key=" << key << ", info=object_not_found";
|
||||
return tl::make_unexpected(ErrorCode::OBJECT_NOT_FOUND);
|
||||
|
|
@ -1830,10 +1837,16 @@ auto MasterService::PutRevoke(const UUID& client_id, const std::string& key,
|
|||
std::vector<tl::expected<void, ErrorCode>> MasterService::BatchPutEnd(
|
||||
const UUID& client_id, const std::vector<std::string>& keys,
|
||||
ReplicaType replica_type) {
|
||||
return BatchPutEnd(client_id, keys, "default", replica_type);
|
||||
}
|
||||
|
||||
std::vector<tl::expected<void, ErrorCode>> MasterService::BatchPutEnd(
|
||||
const UUID& client_id, const std::vector<std::string>& keys,
|
||||
const std::string& tenant_id, ReplicaType replica_type) {
|
||||
std::vector<tl::expected<void, ErrorCode>> results;
|
||||
results.reserve(keys.size());
|
||||
for (const auto& key : keys) {
|
||||
results.emplace_back(PutEnd(client_id, key, replica_type));
|
||||
results.emplace_back(PutEnd(client_id, key, tenant_id, replica_type));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
|
@ -1841,10 +1854,17 @@ std::vector<tl::expected<void, ErrorCode>> MasterService::BatchPutEnd(
|
|||
std::vector<tl::expected<void, ErrorCode>> MasterService::BatchPutRevoke(
|
||||
const UUID& client_id, const std::vector<std::string>& keys,
|
||||
ReplicaType replica_type) {
|
||||
return BatchPutRevoke(client_id, keys, "default", replica_type);
|
||||
}
|
||||
|
||||
std::vector<tl::expected<void, ErrorCode>> MasterService::BatchPutRevoke(
|
||||
const UUID& client_id, const std::vector<std::string>& keys,
|
||||
const std::string& tenant_id, ReplicaType replica_type) {
|
||||
std::vector<tl::expected<void, ErrorCode>> results;
|
||||
results.reserve(keys.size());
|
||||
for (const auto& key : keys) {
|
||||
results.emplace_back(PutRevoke(client_id, key, replica_type));
|
||||
results.emplace_back(
|
||||
PutRevoke(client_id, key, tenant_id, replica_type));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
|
@ -2128,13 +2148,27 @@ auto MasterService::UpsertStart(const UUID& client_id, const std::string& key,
|
|||
auto MasterService::UpsertEnd(const UUID& client_id, const std::string& key,
|
||||
ReplicaType replica_type)
|
||||
-> tl::expected<void, ErrorCode> {
|
||||
return PutEnd(client_id, key, replica_type);
|
||||
return UpsertEnd(client_id, key, "default", replica_type);
|
||||
}
|
||||
|
||||
auto MasterService::UpsertEnd(const UUID& client_id, const std::string& key,
|
||||
const std::string& tenant_id,
|
||||
ReplicaType replica_type)
|
||||
-> tl::expected<void, ErrorCode> {
|
||||
return PutEnd(client_id, key, tenant_id, replica_type);
|
||||
}
|
||||
|
||||
auto MasterService::UpsertRevoke(const UUID& client_id, const std::string& key,
|
||||
ReplicaType replica_type)
|
||||
-> tl::expected<void, ErrorCode> {
|
||||
return PutRevoke(client_id, key, replica_type);
|
||||
return UpsertRevoke(client_id, key, "default", replica_type);
|
||||
}
|
||||
|
||||
auto MasterService::UpsertRevoke(const UUID& client_id, const std::string& key,
|
||||
const std::string& tenant_id,
|
||||
ReplicaType replica_type)
|
||||
-> tl::expected<void, ErrorCode> {
|
||||
return PutRevoke(client_id, key, tenant_id, replica_type);
|
||||
}
|
||||
|
||||
std::vector<tl::expected<std::vector<Replica::Descriptor>, ErrorCode>>
|
||||
|
|
@ -2142,6 +2176,15 @@ MasterService::BatchUpsertStart(const UUID& client_id,
|
|||
const std::vector<std::string>& keys,
|
||||
const std::vector<uint64_t>& slice_lengths,
|
||||
const ReplicateConfig& config) {
|
||||
return BatchUpsertStart(client_id, keys, "default", slice_lengths, config);
|
||||
}
|
||||
|
||||
std::vector<tl::expected<std::vector<Replica::Descriptor>, ErrorCode>>
|
||||
MasterService::BatchUpsertStart(const UUID& client_id,
|
||||
const std::vector<std::string>& keys,
|
||||
const std::string& tenant_id,
|
||||
const std::vector<uint64_t>& slice_lengths,
|
||||
const ReplicateConfig& config) {
|
||||
if (keys.size() != slice_lengths.size()) {
|
||||
LOG(ERROR) << "BatchUpsertStart: keys.size()=" << keys.size()
|
||||
<< " != slice_lengths.size()=" << slice_lengths.size();
|
||||
|
|
@ -2163,20 +2206,32 @@ MasterService::BatchUpsertStart(const UUID& client_id,
|
|||
results.reserve(keys.size());
|
||||
for (size_t i = 0; i < keys.size(); ++i) {
|
||||
auto key_config = config.ForSingleKey(i);
|
||||
results.emplace_back(
|
||||
UpsertStart(client_id, keys[i], slice_lengths[i], key_config));
|
||||
results.emplace_back(UpsertStart(client_id, keys[i], tenant_id,
|
||||
slice_lengths[i], key_config));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
std::vector<tl::expected<void, ErrorCode>> MasterService::BatchUpsertEnd(
|
||||
const UUID& client_id, const std::vector<std::string>& keys) {
|
||||
return BatchPutEnd(client_id, keys);
|
||||
return BatchUpsertEnd(client_id, keys, "default");
|
||||
}
|
||||
|
||||
std::vector<tl::expected<void, ErrorCode>> MasterService::BatchUpsertEnd(
|
||||
const UUID& client_id, const std::vector<std::string>& keys,
|
||||
const std::string& tenant_id) {
|
||||
return BatchPutEnd(client_id, keys, tenant_id);
|
||||
}
|
||||
|
||||
std::vector<tl::expected<void, ErrorCode>> MasterService::BatchUpsertRevoke(
|
||||
const UUID& client_id, const std::vector<std::string>& keys) {
|
||||
return BatchPutRevoke(client_id, keys);
|
||||
return BatchUpsertRevoke(client_id, keys, "default");
|
||||
}
|
||||
|
||||
std::vector<tl::expected<void, ErrorCode>> MasterService::BatchUpsertRevoke(
|
||||
const UUID& client_id, const std::vector<std::string>& keys,
|
||||
const std::string& tenant_id) {
|
||||
return BatchPutRevoke(client_id, keys, tenant_id);
|
||||
}
|
||||
|
||||
auto MasterService::EvictDiskReplica(const UUID& client_id,
|
||||
|
|
@ -2802,8 +2857,6 @@ auto MasterService::RemoveByRegex(const std::string& regex_pattern,
|
|||
long MasterService::RemoveAll(bool force) {
|
||||
long removed_count = 0;
|
||||
uint64_t total_freed_size = 0;
|
||||
// Store the current time to avoid repeatedly
|
||||
// calling std::chrono::steady_clock::now()
|
||||
std::shared_lock<std::shared_mutex> shared_lock(snapshot_mutex_);
|
||||
auto now = std::chrono::system_clock::now();
|
||||
|
||||
|
|
@ -2841,10 +2894,60 @@ long MasterService::RemoveAll(bool force) {
|
|||
return removed_count;
|
||||
}
|
||||
|
||||
long MasterService::RemoveAll(const std::string& tenant_id, bool force) {
|
||||
long removed_count = 0;
|
||||
uint64_t total_freed_size = 0;
|
||||
// Store the current time to avoid repeatedly
|
||||
// calling std::chrono::steady_clock::now()
|
||||
std::shared_lock<std::shared_mutex> shared_lock(snapshot_mutex_);
|
||||
auto now = std::chrono::system_clock::now();
|
||||
const auto normalized_tenant = NormalizeTenantId(tenant_id);
|
||||
|
||||
for (size_t i = 0; i < kNumShards; i++) {
|
||||
MetadataShardAccessorRW shard(this, i);
|
||||
auto tenant_it = shard->tenants.find(normalized_tenant);
|
||||
if (tenant_it == shard->tenants.end()) {
|
||||
continue;
|
||||
}
|
||||
auto& tenant_state = tenant_it->second;
|
||||
auto it = tenant_state.metadata.begin();
|
||||
while (it != tenant_state.metadata.end()) {
|
||||
if ((force || it->second.IsLeaseExpired(now)) &&
|
||||
it->second.AllReplicas(&Replica::fn_is_completed) &&
|
||||
!tenant_state.replication_tasks.contains(it->first)) {
|
||||
auto mem_rep_count =
|
||||
it->second.CountReplicas(&Replica::fn_is_memory_replica);
|
||||
total_freed_size += it->second.size * mem_rep_count;
|
||||
ErasePromotionTaskIfPresent(tenant_state, it->first);
|
||||
it = EraseMetadata(tenant_state, it, normalized_tenant);
|
||||
removed_count++;
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
if (tenant_state.Empty()) {
|
||||
shard->tenants.erase(tenant_it);
|
||||
}
|
||||
}
|
||||
|
||||
VLOG(1) << "action=remove_all_objects"
|
||||
<< ", tenant_id=" << normalized_tenant
|
||||
<< ", removed_count=" << removed_count
|
||||
<< ", total_freed_size=" << total_freed_size;
|
||||
return removed_count;
|
||||
}
|
||||
|
||||
auto MasterService::BatchRemove(const std::vector<std::string>& keys,
|
||||
bool force)
|
||||
-> std::vector<tl::expected<void, ErrorCode>> {
|
||||
return BatchRemove(keys, "default", force);
|
||||
}
|
||||
|
||||
auto MasterService::BatchRemove(const std::vector<std::string>& keys,
|
||||
const std::string& tenant_id, bool force)
|
||||
-> std::vector<tl::expected<void, ErrorCode>> {
|
||||
std::vector<tl::expected<void, ErrorCode>> results(keys.size());
|
||||
const auto normalized_tenant = NormalizeTenantId(tenant_id);
|
||||
|
||||
// Group keys by shard to reduce lock contention
|
||||
std::unordered_map<size_t,
|
||||
|
|
@ -2854,7 +2957,7 @@ auto MasterService::BatchRemove(const std::vector<std::string>& keys,
|
|||
std::min(keys.size(), static_cast<size_t>(kNumShards)));
|
||||
|
||||
for (size_t i = 0; i < keys.size(); ++i) {
|
||||
size_t shard_idx = getMetadataShardIndex(keys[i]);
|
||||
size_t shard_idx = getMetadataShardIndex(normalized_tenant, keys[i]);
|
||||
keys_by_shard[shard_idx].emplace_back(i, &keys[i]);
|
||||
}
|
||||
|
||||
|
|
@ -2869,7 +2972,7 @@ auto MasterService::BatchRemove(const std::vector<std::string>& keys,
|
|||
|
||||
for (const auto& [original_idx, key_ptr] : key_group) {
|
||||
const std::string& key = *key_ptr;
|
||||
auto tenant_it = shard->tenants.find("default");
|
||||
auto tenant_it = shard->tenants.find(normalized_tenant);
|
||||
if (tenant_it == shard->tenants.end()) {
|
||||
VLOG(1) << "key=" << key << ", error=object_not_found";
|
||||
results[original_idx] =
|
||||
|
|
@ -2892,7 +2995,10 @@ auto MasterService::BatchRemove(const std::vector<std::string>& keys,
|
|||
tenant_state.replication_tasks.erase(key);
|
||||
tenant_state.offloading_tasks.erase(key);
|
||||
ErasePromotionTaskIfPresent(tenant_state, key);
|
||||
EraseMetadata(tenant_state, it, "default");
|
||||
EraseMetadata(tenant_state, it, normalized_tenant);
|
||||
if (tenant_state.Empty()) {
|
||||
shard->tenants.erase(tenant_it);
|
||||
}
|
||||
results[original_idx] =
|
||||
tl::make_unexpected(ErrorCode::OBJECT_NOT_FOUND);
|
||||
continue;
|
||||
|
|
@ -2929,7 +3035,7 @@ auto MasterService::BatchRemove(const std::vector<std::string>& keys,
|
|||
|
||||
// Remove object metadata
|
||||
ErasePromotionTaskIfPresent(tenant_state, key);
|
||||
EraseMetadata(tenant_state, it, "default");
|
||||
EraseMetadata(tenant_state, it, normalized_tenant);
|
||||
if (tenant_state.Empty()) {
|
||||
shard->tenants.erase(tenant_it);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -633,7 +633,7 @@ tl::expected<void, ErrorCode> RealClient::setup_internal(
|
|||
const std::shared_ptr<TransferEngine> &transfer_engine,
|
||||
const std::string &ipc_socket_path, int local_rpc_port,
|
||||
bool enable_ssd_offload, bool start_offload_rpc_server,
|
||||
const std::string &ssd_offload_path) {
|
||||
const std::string &ssd_offload_path, const std::string &tenant_id) {
|
||||
this->protocol = protocol;
|
||||
this->ipc_socket_path_ = ipc_socket_path;
|
||||
const bool should_use_hugepage =
|
||||
|
|
@ -677,7 +677,8 @@ tl::expected<void, ErrorCode> RealClient::setup_internal(
|
|||
getHostNameWithoutPort(hostname), local_rpc_port);
|
||||
auto client_opt = mooncake::Client::Create(
|
||||
this->local_hostname, metadata_server, protocol, device_name,
|
||||
master_server_addr, transfer_engine, {{"client_mode", "real"}});
|
||||
master_server_addr, transfer_engine, {{"client_mode", "real"}},
|
||||
tenant_id);
|
||||
if (!client_opt) {
|
||||
LOG(ERROR) << "Failed to create client";
|
||||
return tl::unexpected(ErrorCode::INVALID_PARAMS);
|
||||
|
|
@ -712,7 +713,8 @@ tl::expected<void, ErrorCode> RealClient::setup_internal(
|
|||
buildHostNameWithPort(hostname, local_rpc_port);
|
||||
auto client_opt = mooncake::Client::Create(
|
||||
this->local_hostname, metadata_server, protocol, device_name,
|
||||
master_server_addr, transfer_engine, {{"client_mode", "real"}});
|
||||
master_server_addr, transfer_engine, {{"client_mode", "real"}},
|
||||
tenant_id);
|
||||
if (client_opt) {
|
||||
client_ = *client_opt;
|
||||
success = true;
|
||||
|
|
@ -939,11 +941,12 @@ int RealClient::setup_real(
|
|||
const std::string &master_server_addr,
|
||||
const std::shared_ptr<TransferEngine> &transfer_engine,
|
||||
const std::string &ipc_socket_path, bool enable_ssd_offload,
|
||||
const std::string &ssd_offload_path) {
|
||||
const std::string &ssd_offload_path, const std::string &tenant_id) {
|
||||
return to_py_ret(setup_internal(
|
||||
local_hostname, metadata_server, global_segment_size, local_buffer_size,
|
||||
protocol, rdma_devices, master_server_addr, transfer_engine,
|
||||
ipc_socket_path, 50052, enable_ssd_offload, true, ssd_offload_path));
|
||||
ipc_socket_path, 50052, enable_ssd_offload, true, ssd_offload_path,
|
||||
tenant_id));
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
|
@ -1034,6 +1037,7 @@ tl::expected<void, ErrorCode> RealClient::setup_internal(
|
|||
}
|
||||
|
||||
std::string ssd_offload_path = get_config(config, "ssd_offload_path");
|
||||
std::string tenant_id = get_config(config, CONFIG_KEY_TENANT_ID, "default");
|
||||
|
||||
std::string enable_ssd_offload_str =
|
||||
get_config(config, "enable_ssd_offload", "false");
|
||||
|
|
@ -1043,10 +1047,10 @@ tl::expected<void, ErrorCode> RealClient::setup_internal(
|
|||
bool enable_ssd_offload =
|
||||
(enable_ssd_offload_str == "true" || enable_ssd_offload_str == "1");
|
||||
|
||||
return setup_internal(local_hostname, metadata_server, global_segment_size,
|
||||
local_buffer_size, protocol, rdma_devices,
|
||||
master_server_addr, nullptr, ipc_socket_path, 50052,
|
||||
enable_ssd_offload, true, ssd_offload_path);
|
||||
return setup_internal(
|
||||
local_hostname, metadata_server, global_segment_size, local_buffer_size,
|
||||
protocol, rdma_devices, master_server_addr, nullptr, ipc_socket_path,
|
||||
50052, enable_ssd_offload, true, ssd_offload_path, tenant_id);
|
||||
}
|
||||
|
||||
tl::expected<void, ErrorCode> RealClient::initAll_internal(
|
||||
|
|
|
|||
|
|
@ -434,7 +434,8 @@ void MasterAdminServer::InitHttpServer() {
|
|||
}
|
||||
|
||||
auto key = req.get_query_value("key");
|
||||
auto get_result = service->GetReplicaList(std::string(key));
|
||||
auto get_result =
|
||||
service->GetReplicaList(std::string(key), "default");
|
||||
resp.add_header("Content-Type", "text/plain; version=0.0.4");
|
||||
if (get_result) {
|
||||
std::string ss;
|
||||
|
|
@ -696,7 +697,7 @@ void MasterAdminServer::InitHttpServer() {
|
|||
return;
|
||||
}
|
||||
|
||||
auto results = service->BatchGetReplicaList(keys);
|
||||
auto results = service->BatchGetReplicaList(keys, "default");
|
||||
const size_t n = std::min(keys.size(), results.size());
|
||||
std::string body;
|
||||
body.reserve(n * 512);
|
||||
|
|
@ -754,22 +755,26 @@ WrappedMasterService::CalcCacheStats() {
|
|||
}
|
||||
|
||||
tl::expected<bool, ErrorCode> WrappedMasterService::ExistKey(
|
||||
const std::string& key) {
|
||||
const std::string& key, const std::string& tenant_id) {
|
||||
return execute_rpc(
|
||||
"ExistKey", [&] { return master_service_.ExistKey(key); },
|
||||
"ExistKey", [&] { return master_service_.ExistKey(key, tenant_id); },
|
||||
[&](auto& timer) { timer.LogRequest("key=", key); },
|
||||
[] { MasterMetricManager::instance().inc_exist_key_requests(); },
|
||||
[] { MasterMetricManager::instance().inc_exist_key_failures(); });
|
||||
}
|
||||
|
||||
std::vector<tl::expected<bool, ErrorCode>> WrappedMasterService::BatchExistKey(
|
||||
const std::vector<std::string>& keys) {
|
||||
const std::vector<std::string>& keys, const std::string& tenant_id) {
|
||||
ScopedVLogTimer timer(1, "BatchExistKey");
|
||||
const size_t total_keys = keys.size();
|
||||
timer.LogRequest("keys_count=", total_keys);
|
||||
MasterMetricManager::instance().inc_batch_exist_key_requests(total_keys);
|
||||
|
||||
auto result = master_service_.BatchExistKey(keys);
|
||||
std::vector<tl::expected<bool, ErrorCode>> result;
|
||||
result.reserve(keys.size());
|
||||
for (const auto& key : keys) {
|
||||
result.emplace_back(master_service_.ExistKey(key, tenant_id));
|
||||
}
|
||||
|
||||
size_t failure_count = 0;
|
||||
for (size_t i = 0; i < result.size(); ++i) {
|
||||
|
|
@ -876,10 +881,11 @@ WrappedMasterService::BatchReplicaClear(
|
|||
|
||||
tl::expected<std::unordered_map<std::string, std::vector<Replica::Descriptor>>,
|
||||
ErrorCode>
|
||||
WrappedMasterService::GetReplicaListByRegex(const std::string& str) {
|
||||
WrappedMasterService::GetReplicaListByRegex(const std::string& str,
|
||||
const std::string& tenant_id) {
|
||||
return execute_rpc(
|
||||
"GetReplicaListByRegex",
|
||||
[&] { return master_service_.GetReplicaListByRegex(str); },
|
||||
[&] { return master_service_.GetReplicaListByRegex(str, tenant_id); },
|
||||
[&](auto& timer) { timer.LogRequest("Regex=", str); },
|
||||
[] {
|
||||
MasterMetricManager::instance()
|
||||
|
|
@ -892,9 +898,11 @@ WrappedMasterService::GetReplicaListByRegex(const std::string& str) {
|
|||
}
|
||||
|
||||
tl::expected<GetReplicaListResponse, ErrorCode>
|
||||
WrappedMasterService::GetReplicaList(const std::string& key) {
|
||||
WrappedMasterService::GetReplicaList(const std::string& key,
|
||||
const std::string& tenant_id) {
|
||||
return execute_rpc(
|
||||
"GetReplicaList", [&] { return master_service_.GetReplicaList(key); },
|
||||
"GetReplicaList",
|
||||
[&] { return master_service_.GetReplicaList(key, tenant_id); },
|
||||
[&](auto& timer) { timer.LogRequest("key=", key); },
|
||||
[] { MasterMetricManager::instance().inc_get_replica_list_requests(); },
|
||||
[] {
|
||||
|
|
@ -903,8 +911,8 @@ WrappedMasterService::GetReplicaList(const std::string& key) {
|
|||
}
|
||||
|
||||
std::vector<tl::expected<GetReplicaListResponse, ErrorCode>>
|
||||
WrappedMasterService::BatchGetReplicaList(
|
||||
const std::vector<std::string>& keys) {
|
||||
WrappedMasterService::BatchGetReplicaList(const std::vector<std::string>& keys,
|
||||
const std::string& tenant_id) {
|
||||
ScopedVLogTimer timer(1, "BatchGetReplicaList");
|
||||
const size_t total_keys = keys.size();
|
||||
timer.LogRequest("keys_count=", total_keys);
|
||||
|
|
@ -915,7 +923,7 @@ WrappedMasterService::BatchGetReplicaList(
|
|||
results.reserve(keys.size());
|
||||
|
||||
for (const auto& key : keys) {
|
||||
results.emplace_back(master_service_.GetReplicaList(key));
|
||||
results.emplace_back(master_service_.GetReplicaList(key, tenant_id));
|
||||
}
|
||||
|
||||
size_t failure_count = 0;
|
||||
|
|
@ -951,12 +959,13 @@ WrappedMasterService::BatchGetReplicaList(
|
|||
tl::expected<std::vector<Replica::Descriptor>, ErrorCode>
|
||||
WrappedMasterService::PutStart(const UUID& client_id, const std::string& key,
|
||||
const uint64_t slice_length,
|
||||
const ReplicateConfig& config) {
|
||||
const ReplicateConfig& config,
|
||||
const std::string& tenant_id) {
|
||||
return execute_rpc(
|
||||
"PutStart",
|
||||
[&] {
|
||||
return master_service_.PutStart(client_id, key, slice_length,
|
||||
config);
|
||||
return master_service_.PutStart(client_id, key, tenant_id,
|
||||
slice_length, config);
|
||||
},
|
||||
[&](auto& timer) {
|
||||
timer.LogRequest("client_id=", client_id, ", key=", key,
|
||||
|
|
@ -967,10 +976,14 @@ WrappedMasterService::PutStart(const UUID& client_id, const std::string& key,
|
|||
}
|
||||
|
||||
tl::expected<void, ErrorCode> WrappedMasterService::PutEnd(
|
||||
const UUID& client_id, const std::string& key, ReplicaType replica_type) {
|
||||
const UUID& client_id, const std::string& key, ReplicaType replica_type,
|
||||
const std::string& tenant_id) {
|
||||
return execute_rpc(
|
||||
"PutEnd",
|
||||
[&] { return master_service_.PutEnd(client_id, key, replica_type); },
|
||||
[&] {
|
||||
return master_service_.PutEnd(client_id, key, tenant_id,
|
||||
replica_type);
|
||||
},
|
||||
[&](auto& timer) {
|
||||
timer.LogRequest("client_id=", client_id, ", key=", key,
|
||||
", replica_type=", replica_type);
|
||||
|
|
@ -980,10 +993,14 @@ tl::expected<void, ErrorCode> WrappedMasterService::PutEnd(
|
|||
}
|
||||
|
||||
tl::expected<void, ErrorCode> WrappedMasterService::PutRevoke(
|
||||
const UUID& client_id, const std::string& key, ReplicaType replica_type) {
|
||||
const UUID& client_id, const std::string& key, ReplicaType replica_type,
|
||||
const std::string& tenant_id) {
|
||||
return execute_rpc(
|
||||
"PutRevoke",
|
||||
[&] { return master_service_.PutRevoke(client_id, key, replica_type); },
|
||||
[&] {
|
||||
return master_service_.PutRevoke(client_id, key, tenant_id,
|
||||
replica_type);
|
||||
},
|
||||
[&](auto& timer) {
|
||||
timer.LogRequest("client_id=", client_id, ", key=", key,
|
||||
", replica_type=", replica_type);
|
||||
|
|
@ -996,7 +1013,8 @@ std::vector<tl::expected<std::vector<Replica::Descriptor>, ErrorCode>>
|
|||
WrappedMasterService::BatchPutStart(const UUID& client_id,
|
||||
const std::vector<std::string>& keys,
|
||||
const std::vector<uint64_t>& slice_lengths,
|
||||
const ReplicateConfig& config) {
|
||||
const ReplicateConfig& config,
|
||||
const std::string& tenant_id) {
|
||||
ScopedVLogTimer timer(1, "BatchPutStart");
|
||||
const size_t total_keys = keys.size();
|
||||
timer.LogRequest("client_id=", client_id, ", keys_count=", total_keys);
|
||||
|
|
@ -1023,7 +1041,7 @@ WrappedMasterService::BatchPutStart(const UUID& client_id,
|
|||
for (size_t i = 0; i < keys.size(); ++i) {
|
||||
auto key_config = new_config.ForSingleKey(i);
|
||||
auto result = master_service_.PutStart(
|
||||
client_id, keys[i], slice_lengths[i], key_config);
|
||||
client_id, keys[i], tenant_id, slice_lengths[i], key_config);
|
||||
results.emplace_back(result);
|
||||
if ((i == 0) && result.has_value()) {
|
||||
std::string preferred_segment;
|
||||
|
|
@ -1045,7 +1063,7 @@ WrappedMasterService::BatchPutStart(const UUID& client_id,
|
|||
for (size_t i = 0; i < keys.size(); ++i) {
|
||||
auto key_config = config.ForSingleKey(i);
|
||||
results.emplace_back(master_service_.PutStart(
|
||||
client_id, keys[i], slice_lengths[i], key_config));
|
||||
client_id, keys[i], tenant_id, slice_lengths[i], key_config));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1088,7 +1106,7 @@ WrappedMasterService::BatchPutStart(const UUID& client_id,
|
|||
|
||||
std::vector<tl::expected<void, ErrorCode>> WrappedMasterService::BatchPutEnd(
|
||||
const UUID& client_id, const std::vector<std::string>& keys,
|
||||
ReplicaType replica_type) {
|
||||
ReplicaType replica_type, const std::string& tenant_id) {
|
||||
ScopedVLogTimer timer(1, "BatchPutEnd");
|
||||
const size_t total_keys = keys.size();
|
||||
timer.LogRequest("client_id=", client_id, ", keys_count=", total_keys);
|
||||
|
|
@ -1099,7 +1117,7 @@ std::vector<tl::expected<void, ErrorCode>> WrappedMasterService::BatchPutEnd(
|
|||
|
||||
for (const auto& key : keys) {
|
||||
results.emplace_back(
|
||||
master_service_.PutEnd(client_id, key, replica_type));
|
||||
master_service_.PutEnd(client_id, key, tenant_id, replica_type));
|
||||
}
|
||||
|
||||
size_t failure_count = 0;
|
||||
|
|
@ -1128,7 +1146,7 @@ std::vector<tl::expected<void, ErrorCode>> WrappedMasterService::BatchPutEnd(
|
|||
|
||||
std::vector<tl::expected<void, ErrorCode>> WrappedMasterService::BatchPutRevoke(
|
||||
const UUID& client_id, const std::vector<std::string>& keys,
|
||||
ReplicaType replica_type) {
|
||||
ReplicaType replica_type, const std::string& tenant_id) {
|
||||
ScopedVLogTimer timer(1, "BatchPutRevoke");
|
||||
const size_t total_keys = keys.size();
|
||||
timer.LogRequest("client_id=", client_id, ", keys_count=", total_keys);
|
||||
|
|
@ -1139,7 +1157,7 @@ std::vector<tl::expected<void, ErrorCode>> WrappedMasterService::BatchPutRevoke(
|
|||
|
||||
for (const auto& key : keys) {
|
||||
results.emplace_back(
|
||||
master_service_.PutRevoke(client_id, key, replica_type));
|
||||
master_service_.PutRevoke(client_id, key, tenant_id, replica_type));
|
||||
}
|
||||
|
||||
size_t failure_count = 0;
|
||||
|
|
@ -1169,12 +1187,13 @@ std::vector<tl::expected<void, ErrorCode>> WrappedMasterService::BatchPutRevoke(
|
|||
tl::expected<std::vector<Replica::Descriptor>, ErrorCode>
|
||||
WrappedMasterService::UpsertStart(const UUID& client_id, const std::string& key,
|
||||
const uint64_t slice_length,
|
||||
const ReplicateConfig& config) {
|
||||
const ReplicateConfig& config,
|
||||
const std::string& tenant_id) {
|
||||
return execute_rpc(
|
||||
"UpsertStart",
|
||||
[&] {
|
||||
return master_service_.UpsertStart(client_id, key, slice_length,
|
||||
config);
|
||||
return master_service_.UpsertStart(client_id, key, tenant_id,
|
||||
slice_length, config);
|
||||
},
|
||||
[&](auto& timer) {
|
||||
timer.LogRequest("client_id=", client_id, ", key=", key,
|
||||
|
|
@ -1185,10 +1204,14 @@ WrappedMasterService::UpsertStart(const UUID& client_id, const std::string& key,
|
|||
}
|
||||
|
||||
tl::expected<void, ErrorCode> WrappedMasterService::UpsertEnd(
|
||||
const UUID& client_id, const std::string& key, ReplicaType replica_type) {
|
||||
const UUID& client_id, const std::string& key, ReplicaType replica_type,
|
||||
const std::string& tenant_id) {
|
||||
return execute_rpc(
|
||||
"UpsertEnd",
|
||||
[&] { return master_service_.UpsertEnd(client_id, key, replica_type); },
|
||||
[&] {
|
||||
return master_service_.UpsertEnd(client_id, key, tenant_id,
|
||||
replica_type);
|
||||
},
|
||||
[&](auto& timer) {
|
||||
timer.LogRequest("client_id=", client_id, ", key=", key,
|
||||
", replica_type=", replica_type);
|
||||
|
|
@ -1198,11 +1221,13 @@ tl::expected<void, ErrorCode> WrappedMasterService::UpsertEnd(
|
|||
}
|
||||
|
||||
tl::expected<void, ErrorCode> WrappedMasterService::UpsertRevoke(
|
||||
const UUID& client_id, const std::string& key, ReplicaType replica_type) {
|
||||
const UUID& client_id, const std::string& key, ReplicaType replica_type,
|
||||
const std::string& tenant_id) {
|
||||
return execute_rpc(
|
||||
"UpsertRevoke",
|
||||
[&] {
|
||||
return master_service_.UpsertRevoke(client_id, key, replica_type);
|
||||
return master_service_.UpsertRevoke(client_id, key, tenant_id,
|
||||
replica_type);
|
||||
},
|
||||
[&](auto& timer) {
|
||||
timer.LogRequest("client_id=", client_id, ", key=", key,
|
||||
|
|
@ -1215,13 +1240,14 @@ tl::expected<void, ErrorCode> WrappedMasterService::UpsertRevoke(
|
|||
std::vector<tl::expected<std::vector<Replica::Descriptor>, ErrorCode>>
|
||||
WrappedMasterService::BatchUpsertStart(
|
||||
const UUID& client_id, const std::vector<std::string>& keys,
|
||||
const std::vector<uint64_t>& slice_lengths, const ReplicateConfig& config) {
|
||||
const std::vector<uint64_t>& slice_lengths, const ReplicateConfig& config,
|
||||
const std::string& tenant_id) {
|
||||
ScopedVLogTimer timer(1, "BatchUpsertStart");
|
||||
const size_t total_keys = keys.size();
|
||||
timer.LogRequest("client_id=", client_id, ", keys_count=", total_keys);
|
||||
MasterMetricManager::instance().inc_batch_put_start_requests(total_keys);
|
||||
|
||||
auto results = master_service_.BatchUpsertStart(client_id, keys,
|
||||
auto results = master_service_.BatchUpsertStart(client_id, keys, tenant_id,
|
||||
slice_lengths, config);
|
||||
|
||||
size_t failure_count = 0;
|
||||
|
|
@ -1249,13 +1275,14 @@ WrappedMasterService::BatchUpsertStart(
|
|||
}
|
||||
|
||||
std::vector<tl::expected<void, ErrorCode>> WrappedMasterService::BatchUpsertEnd(
|
||||
const UUID& client_id, const std::vector<std::string>& keys) {
|
||||
const UUID& client_id, const std::vector<std::string>& keys,
|
||||
const std::string& tenant_id) {
|
||||
ScopedVLogTimer timer(1, "BatchUpsertEnd");
|
||||
const size_t total_keys = keys.size();
|
||||
timer.LogRequest("client_id=", client_id, ", keys_count=", total_keys);
|
||||
MasterMetricManager::instance().inc_batch_put_end_requests(total_keys);
|
||||
|
||||
auto results = master_service_.BatchUpsertEnd(client_id, keys);
|
||||
auto results = master_service_.BatchUpsertEnd(client_id, keys, tenant_id);
|
||||
|
||||
size_t failure_count = 0;
|
||||
for (size_t i = 0; i < results.size(); ++i) {
|
||||
|
|
@ -1283,13 +1310,15 @@ std::vector<tl::expected<void, ErrorCode>> WrappedMasterService::BatchUpsertEnd(
|
|||
|
||||
std::vector<tl::expected<void, ErrorCode>>
|
||||
WrappedMasterService::BatchUpsertRevoke(const UUID& client_id,
|
||||
const std::vector<std::string>& keys) {
|
||||
const std::vector<std::string>& keys,
|
||||
const std::string& tenant_id) {
|
||||
ScopedVLogTimer timer(1, "BatchUpsertRevoke");
|
||||
const size_t total_keys = keys.size();
|
||||
timer.LogRequest("client_id=", client_id, ", keys_count=", total_keys);
|
||||
MasterMetricManager::instance().inc_batch_put_revoke_requests(total_keys);
|
||||
|
||||
auto results = master_service_.BatchUpsertRevoke(client_id, keys);
|
||||
auto results =
|
||||
master_service_.BatchUpsertRevoke(client_id, keys, tenant_id);
|
||||
|
||||
size_t failure_count = 0;
|
||||
for (size_t i = 0; i < results.size(); ++i) {
|
||||
|
|
@ -1316,19 +1345,19 @@ WrappedMasterService::BatchUpsertRevoke(const UUID& client_id,
|
|||
}
|
||||
|
||||
tl::expected<void, ErrorCode> WrappedMasterService::Remove(
|
||||
const std::string& key, bool force) {
|
||||
const std::string& key, bool force, const std::string& tenant_id) {
|
||||
return execute_rpc(
|
||||
"Remove", [&] { return master_service_.Remove(key, force); },
|
||||
"Remove", [&] { return master_service_.Remove(key, tenant_id, force); },
|
||||
[&](auto& timer) { timer.LogRequest("key=", key, ", force=", force); },
|
||||
[] { MasterMetricManager::instance().inc_remove_requests(); },
|
||||
[] { MasterMetricManager::instance().inc_remove_failures(); });
|
||||
}
|
||||
|
||||
tl::expected<long, ErrorCode> WrappedMasterService::RemoveByRegex(
|
||||
const std::string& str, bool force) {
|
||||
const std::string& str, bool force, const std::string& tenant_id) {
|
||||
return execute_rpc(
|
||||
"RemoveByRegex",
|
||||
[&] { return master_service_.RemoveByRegex(str, force); },
|
||||
[&] { return master_service_.RemoveByRegex(str, tenant_id, force); },
|
||||
[&](auto& timer) {
|
||||
timer.LogRequest("regex=", str, ", force=", force);
|
||||
},
|
||||
|
|
@ -1336,23 +1365,24 @@ tl::expected<long, ErrorCode> WrappedMasterService::RemoveByRegex(
|
|||
[] { MasterMetricManager::instance().inc_remove_by_regex_failures(); });
|
||||
}
|
||||
|
||||
long WrappedMasterService::RemoveAll(bool force) {
|
||||
long WrappedMasterService::RemoveAll(bool force, const std::string& tenant_id) {
|
||||
ScopedVLogTimer timer(1, "RemoveAll");
|
||||
timer.LogRequest("action=remove_all_objects, force=", force);
|
||||
MasterMetricManager::instance().inc_remove_all_requests();
|
||||
long result = master_service_.RemoveAll(force);
|
||||
long result = master_service_.RemoveAll(tenant_id, force);
|
||||
timer.LogResponse("items_removed=", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<tl::expected<void, ErrorCode>> WrappedMasterService::BatchRemove(
|
||||
const std::vector<std::string>& keys, bool force) {
|
||||
const std::vector<std::string>& keys, bool force,
|
||||
const std::string& tenant_id) {
|
||||
ScopedVLogTimer timer(1, "BatchRemove");
|
||||
const size_t total_keys = keys.size();
|
||||
timer.LogRequest("keys_count=", total_keys, ", force=", force);
|
||||
MasterMetricManager::instance().inc_remove_requests(total_keys);
|
||||
|
||||
auto results = master_service_.BatchRemove(keys, force);
|
||||
auto results = master_service_.BatchRemove(keys, tenant_id, force);
|
||||
|
||||
size_t failure_count = 0;
|
||||
for (const auto& result : results) {
|
||||
|
|
|
|||
|
|
@ -1404,6 +1404,131 @@ TEST_F(MasterServiceTest, RegexOperationsAreTenantScoped) {
|
|||
EXPECT_TRUE(service_->GetReplicaList(key, tenant_b).has_value());
|
||||
}
|
||||
|
||||
TEST_F(MasterServiceTest, TenantBatchUpsertAndRevokeAreScoped) {
|
||||
auto svc = std::make_unique<MasterService>();
|
||||
[[maybe_unused]] const auto context = PrepareSimpleSegment(*svc);
|
||||
const UUID client_id = generate_uuid();
|
||||
|
||||
const std::vector<std::string> keys = {"tenant_batch_upsert_key_a",
|
||||
"tenant_batch_upsert_key_b"};
|
||||
const std::vector<uint64_t> sizes = {1024, 2048};
|
||||
const std::string tenant_a = "tenant_batch_upsert_a";
|
||||
const std::string tenant_b = "tenant_batch_upsert_b";
|
||||
|
||||
ReplicateConfig config;
|
||||
config.replica_num = 1;
|
||||
|
||||
auto tenant_a_results =
|
||||
svc->BatchUpsertStart(client_id, keys, tenant_a, sizes, config);
|
||||
ASSERT_EQ(tenant_a_results.size(), keys.size());
|
||||
for (const auto& result : tenant_a_results) {
|
||||
ASSERT_TRUE(result.has_value());
|
||||
}
|
||||
auto tenant_a_end = svc->BatchUpsertEnd(client_id, keys, tenant_a);
|
||||
ASSERT_EQ(tenant_a_end.size(), keys.size());
|
||||
for (const auto& result : tenant_a_end) {
|
||||
ASSERT_TRUE(result.has_value());
|
||||
}
|
||||
|
||||
auto tenant_b_results =
|
||||
svc->BatchUpsertStart(client_id, keys, tenant_b, sizes, config);
|
||||
ASSERT_EQ(tenant_b_results.size(), keys.size());
|
||||
for (const auto& result : tenant_b_results) {
|
||||
ASSERT_TRUE(result.has_value());
|
||||
}
|
||||
auto tenant_b_end = svc->BatchUpsertEnd(client_id, keys, tenant_b);
|
||||
ASSERT_EQ(tenant_b_end.size(), keys.size());
|
||||
for (const auto& result : tenant_b_end) {
|
||||
ASSERT_TRUE(result.has_value());
|
||||
}
|
||||
|
||||
for (const auto& key : keys) {
|
||||
EXPECT_FALSE(svc->GetReplicaList(key).has_value());
|
||||
EXPECT_TRUE(svc->GetReplicaList(key, tenant_a).has_value());
|
||||
EXPECT_TRUE(svc->GetReplicaList(key, tenant_b).has_value());
|
||||
}
|
||||
|
||||
const std::string revoke_key = "tenant_batch_upsert_revoke_key";
|
||||
auto revoke_start =
|
||||
svc->UpsertStart(client_id, revoke_key, tenant_a, 1024, config);
|
||||
ASSERT_TRUE(revoke_start.has_value());
|
||||
ASSERT_TRUE(
|
||||
svc->UpsertRevoke(client_id, revoke_key, tenant_a, ReplicaType::MEMORY)
|
||||
.has_value());
|
||||
EXPECT_FALSE(svc->GetReplicaList(revoke_key, tenant_a).has_value());
|
||||
}
|
||||
|
||||
TEST_F(MasterServiceTest, TenantBatchRemoveAndRemoveAllAreScoped) {
|
||||
auto svc = std::make_unique<MasterService>();
|
||||
[[maybe_unused]] const auto context = PrepareSimpleSegment(*svc);
|
||||
const UUID client_id = generate_uuid();
|
||||
|
||||
const std::string shared_key = "tenant_batch_remove_shared_key";
|
||||
const std::string tenant_a = "tenant_batch_remove_a";
|
||||
const std::string tenant_b = "tenant_batch_remove_b";
|
||||
|
||||
ReplicateConfig config;
|
||||
config.replica_num = 1;
|
||||
|
||||
ASSERT_TRUE(svc->PutStart(client_id, shared_key, 1024, config).has_value());
|
||||
ASSERT_TRUE(
|
||||
svc->PutEnd(client_id, shared_key, ReplicaType::MEMORY).has_value());
|
||||
ASSERT_TRUE(svc->PutStart(client_id, shared_key, tenant_a, 1024, config)
|
||||
.has_value());
|
||||
ASSERT_TRUE(
|
||||
svc->PutEnd(client_id, shared_key, tenant_a, ReplicaType::MEMORY)
|
||||
.has_value());
|
||||
ASSERT_TRUE(svc->PutStart(client_id, shared_key, tenant_b, 1024, config)
|
||||
.has_value());
|
||||
ASSERT_TRUE(
|
||||
svc->PutEnd(client_id, shared_key, tenant_b, ReplicaType::MEMORY)
|
||||
.has_value());
|
||||
|
||||
auto remove_a = svc->BatchRemove({shared_key}, tenant_a, /*force=*/true);
|
||||
ASSERT_EQ(remove_a.size(), 1u);
|
||||
ASSERT_TRUE(remove_a[0].has_value());
|
||||
EXPECT_FALSE(svc->GetReplicaList(shared_key, tenant_a).has_value());
|
||||
EXPECT_TRUE(svc->GetReplicaList(shared_key).has_value());
|
||||
EXPECT_TRUE(svc->GetReplicaList(shared_key, tenant_b).has_value());
|
||||
|
||||
EXPECT_EQ(svc->RemoveAll(tenant_b, /*force=*/true), 1);
|
||||
EXPECT_FALSE(svc->GetReplicaList(shared_key, tenant_b).has_value());
|
||||
EXPECT_TRUE(svc->GetReplicaList(shared_key).has_value());
|
||||
|
||||
EXPECT_EQ(svc->RemoveAll(/*force=*/true), 1);
|
||||
EXPECT_FALSE(svc->GetReplicaList(shared_key).has_value());
|
||||
}
|
||||
|
||||
TEST_F(MasterServiceTest, LegacyRemoveAllRemovesAllTenants) {
|
||||
auto svc = std::make_unique<MasterService>();
|
||||
[[maybe_unused]] const auto context = PrepareSimpleSegment(*svc);
|
||||
const UUID client_id = generate_uuid();
|
||||
|
||||
const std::string key = "legacy_remove_all_shared_key";
|
||||
const std::string tenant_a = "legacy_remove_all_a";
|
||||
const std::string tenant_b = "legacy_remove_all_b";
|
||||
|
||||
ReplicateConfig config;
|
||||
config.replica_num = 1;
|
||||
|
||||
ASSERT_TRUE(svc->PutStart(client_id, key, 1024, config).has_value());
|
||||
ASSERT_TRUE(svc->PutEnd(client_id, key, ReplicaType::MEMORY).has_value());
|
||||
ASSERT_TRUE(
|
||||
svc->PutStart(client_id, key, tenant_a, 1024, config).has_value());
|
||||
ASSERT_TRUE(
|
||||
svc->PutEnd(client_id, key, tenant_a, ReplicaType::MEMORY).has_value());
|
||||
ASSERT_TRUE(
|
||||
svc->PutStart(client_id, key, tenant_b, 1024, config).has_value());
|
||||
ASSERT_TRUE(
|
||||
svc->PutEnd(client_id, key, tenant_b, ReplicaType::MEMORY).has_value());
|
||||
|
||||
EXPECT_EQ(svc->RemoveAll(/*force=*/true), 3);
|
||||
EXPECT_FALSE(svc->GetReplicaList(key).has_value());
|
||||
EXPECT_FALSE(svc->GetReplicaList(key, tenant_a).has_value());
|
||||
EXPECT_FALSE(svc->GetReplicaList(key, tenant_b).has_value());
|
||||
EXPECT_EQ(svc->RemoveAll(/*force=*/true), 0);
|
||||
}
|
||||
|
||||
TEST_F(MasterServiceTest, PutWithPreferredSegment) {
|
||||
// For backward compatibility, test the deprecated single preferred_segment
|
||||
std::unique_ptr<MasterService> service_(new MasterService());
|
||||
|
|
|
|||
Loading…
Reference in New Issue