This commit is contained in:
183
rediska/worker/CacheWorker.cpp
Normal file
183
rediska/worker/CacheWorker.cpp
Normal file
@@ -0,0 +1,183 @@
|
||||
#include <condition_variable>
|
||||
#include <iostream>
|
||||
#include <mutex>
|
||||
#include <queue>
|
||||
#include <thread>
|
||||
#include <unordered_map>
|
||||
#include <shared_mutex>
|
||||
#include <chrono>
|
||||
#include <grpcpp/grpcpp.h>
|
||||
#include "google/protobuf/empty.pb.h"
|
||||
#include "v1/primitives/bool.grpc.pb.h"
|
||||
#include "v1/primitives/bool.pb.h"
|
||||
#include "v1/primitives/int.grpc.pb.h"
|
||||
#include "v1/primitives/int.pb.h"
|
||||
#include "v1/primitives/string.grpc.pb.h"
|
||||
#include "v1/primitives/string.pb.h"
|
||||
#include "v1/collections/list.grpc.pb.h"
|
||||
#include "v1/collections/list.pb.h"
|
||||
#include "rediska/common/QueueMessage.hpp"
|
||||
#include "rediska/frontend/RequestManager.hpp"
|
||||
#include "rediska/frontend/server.hpp"
|
||||
#include "rediska/cache/lru/LRU.hpp"
|
||||
#include "rediska/data-structures/impl/ListDataStructure.hpp"
|
||||
|
||||
namespace {
|
||||
class CacheWorker {
|
||||
public:
|
||||
CacheWorker(size_t cache_capacity = 1000) {
|
||||
cache_config_.maxCapacity = cache_capacity;
|
||||
cache_config_.ttl = 0;
|
||||
cache_config_.resetTTLOnAccess = true;
|
||||
|
||||
auto callback = [this](auto result) {
|
||||
};
|
||||
|
||||
cache_ = std::make_unique<cache::LRU>(cache_config_, callback);
|
||||
}
|
||||
|
||||
void Enqueue(QueueMessage msg) {
|
||||
std::lock_guard<std::mutex> lock(mtx_);
|
||||
queue_.push(std::move(msg));
|
||||
cv_.notify_one();
|
||||
}
|
||||
|
||||
void Run() {
|
||||
for (;;) {
|
||||
QueueMessage msg;
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mtx_);
|
||||
cv_.wait(lock, [&] { return !queue_.empty(); });
|
||||
msg = std::move(queue_.front());
|
||||
queue_.pop();
|
||||
}
|
||||
|
||||
std::cout << "[cache-worker] key=" << msg.key
|
||||
<< " type=" << static_cast<int>(msg.type)
|
||||
<< " op=" << static_cast<int>(msg.operation) << std::endl;
|
||||
|
||||
if (!msg.responder) continue;
|
||||
|
||||
try {
|
||||
switch (msg.operation) {
|
||||
case OperationId::SET: {
|
||||
if (msg.type == CacheValueId::ARRAY) {
|
||||
auto list = std::make_shared<ListDataStructure>();
|
||||
|
||||
if (std::holds_alternative<ListPushManyArgs>(msg.arguments)) {
|
||||
auto& args = std::get<ListPushManyArgs>(msg.arguments);
|
||||
for (auto& value : args.values) {
|
||||
list->handle(OperationId::LIST_PUSH_BACK, DSValue{});
|
||||
}
|
||||
}
|
||||
|
||||
cache_->set(std::string(msg.key), CacheValue{list}, 0);
|
||||
|
||||
v1::collections::list::ListSetResponse response;
|
||||
msg.respond<v1::collections::list::ListSetResponse>(response);
|
||||
} else {
|
||||
|
||||
CacheValue value;
|
||||
if (msg.arguments.index() != 0) {
|
||||
auto& args = std::get<PrimitiveSetArgs>(msg.arguments);
|
||||
value = args.value;
|
||||
}
|
||||
|
||||
cache_->set(std::string(msg.key), std::move(value), 0);
|
||||
msg.respond<google::protobuf::Empty>(google::protobuf::Empty{});
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OperationId::GET: {
|
||||
cache_->get(std::string(msg.key));
|
||||
|
||||
// я не нашел пока полный callback, тут заглушки (TODO)
|
||||
if (msg.type == CacheValueId::BOOLEAN) {
|
||||
v1::primitives::boolean::BoolGetResponse response;
|
||||
response.set_value(true);
|
||||
msg.respond<v1::primitives::boolean::BoolGetResponse>(response);
|
||||
} else if (msg.type == CacheValueId::INT) {
|
||||
v1::primitives::integer::IntGetResponse response;
|
||||
response.set_value(42);
|
||||
msg.respond<v1::primitives::integer::IntGetResponse>(response);
|
||||
} else if (msg.type == CacheValueId::STRING) {
|
||||
v1::primitives::str::StringGetResponse response;
|
||||
response.set_value("cached_string_value");
|
||||
msg.respond<v1::primitives::str::StringGetResponse>(response);
|
||||
} else if (msg.type == CacheValueId::ARRAY) {
|
||||
v1::collections::list::ListGetResponse response;
|
||||
msg.respond<v1::collections::list::ListGetResponse>(response);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OperationId::DELETE: {
|
||||
cache_->applyTo(std::string(msg.key), OperationId::DELETE, std::move(msg.arguments));
|
||||
|
||||
if (msg.type == CacheValueId::BOOLEAN) {
|
||||
v1::primitives::boolean::BoolDeleteResponse response;
|
||||
response.set_removed_value(true);
|
||||
msg.respond<v1::primitives::boolean::BoolDeleteResponse>(response);
|
||||
} else if (msg.type == CacheValueId::INT) {
|
||||
v1::primitives::integer::IntDeleteResponse response;
|
||||
response.set_removed_value(42);
|
||||
msg.respond<v1::primitives::integer::IntDeleteResponse>(response);
|
||||
} else if (msg.type == CacheValueId::STRING) {
|
||||
v1::primitives::str::StringDeleteResponse response;
|
||||
response.set_removed_value("deleted_string");
|
||||
msg.respond<v1::primitives::str::StringDeleteResponse>(response);
|
||||
} else if (msg.type == CacheValueId::ARRAY) {
|
||||
msg.respond<google::protobuf::Empty>(google::protobuf::Empty{});
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OperationId::LIST_PUSH_BACK: {
|
||||
cache_->applyTo(std::string(msg.key), OperationId::LIST_PUSH_BACK, std::move(msg.arguments));
|
||||
msg.respond<google::protobuf::Empty>(google::protobuf::Empty{});
|
||||
break;
|
||||
}
|
||||
case OperationId::LIST_POP_BACK: {
|
||||
cache_->applyTo(std::string(msg.key), OperationId::LIST_POP_BACK, std::move(msg.arguments));
|
||||
|
||||
v1::collections::list::PopBackResponse response;
|
||||
msg.respond<v1::collections::list::PopBackResponse>(response);
|
||||
break;
|
||||
}
|
||||
case OperationId::LIST_INSERT: {
|
||||
cache_->applyTo(std::string(msg.key), OperationId::LIST_INSERT, std::move(msg.arguments));
|
||||
msg.respond<google::protobuf::Empty>(google::protobuf::Empty{});
|
||||
break;
|
||||
}
|
||||
case OperationId::LIST_ERASE: {
|
||||
cache_->applyTo(std::string(msg.key), OperationId::LIST_ERASE, std::move(msg.arguments));
|
||||
msg.respond<google::protobuf::Empty>(google::protobuf::Empty{});
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
std::cout << "Error processing message: " << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::queue<QueueMessage> queue_;
|
||||
std::mutex mtx_;
|
||||
std::condition_variable cv_;
|
||||
std::unique_ptr<cache::LRU> cache_;
|
||||
cache::LRUConfig cache_config_;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
int run_cache_server() {
|
||||
CacheWorker worker(1000);
|
||||
std::thread t([&] { worker.Run(); });
|
||||
|
||||
RunFrontendServer("0.0.0.0:50051", [&](QueueMessage msg) {
|
||||
worker.Enqueue(std::move(msg));
|
||||
});
|
||||
|
||||
t.join();
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user