chore: initial commit
Some checks failed
Code Analysis / analysis (push) Failing after 2m59s

This commit is contained in:
2025-12-30 22:34:58 +07:00
commit 35a6349071
63 changed files with 2675 additions and 0 deletions

View File

@@ -0,0 +1,157 @@
#include "rediska/worker/AsyncWorker.hpp"
#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"
namespace rediska::worker {
AsyncWorker::AsyncWorker(size_t num_workers, size_t cache_capacity)
: num_workers_(num_workers) {
cache_config_.maxCapacity = cache_capacity;
cache_config_.ttl = 0;
cache_config_.resetTTLOnAccess = true;
InitializeCache();
}
AsyncWorker::~AsyncWorker() {
Stop();
}
void AsyncWorker::Start() {
if (running_) return;
running_ = true;
workers_.reserve(num_workers_);
for (size_t i = 0; i < num_workers_; ++i) {
workers_.emplace_back(&AsyncWorker::WorkerLoop, this);
}
}
void AsyncWorker::Stop() {
if (!running_) return;
running_ = false;
queue_cv_.notify_all();
for (auto& worker : workers_) {
if (worker.joinable()) {
worker.join();
}
}
workers_.clear();
}
void AsyncWorker::Enqueue(QueueMessage msg) {
{
std::lock_guard<std::mutex> lock(queue_mutex_);
message_queue_.push(std::move(msg));
}
queue_cv_.notify_one();
}
void AsyncWorker::WorkerLoop() {
while (running_) {
QueueMessage msg;
{
std::unique_lock<std::mutex> lock(queue_mutex_);
queue_cv_.wait(lock, [this] { return !message_queue_.empty() || !running_; });
if (!running_) break;
msg = std::move(message_queue_.front());
message_queue_.pop();
}
ProcessMessage(msg);
}
}
void AsyncWorker::ProcessMessage(QueueMessage& msg) {
if (!msg.responder) return;
try {
switch (msg.operation) {
case OperationId::SET: {
if (msg.type == CacheValueId::ARRAY) {
v1::collections::list::ListSetResponse response;
msg.respond<v1::collections::list::ListSetResponse>(response);
} else {
google::protobuf::Empty response;
msg.respond<google::protobuf::Empty>(response);
}
break;
}
case OperationId::GET: {
cache_->get(std::string(msg.key));
// заглушка, пока кэш не интегрирован полностью TODO
if (msg.type == CacheValueId::BOOLEAN) {
v1::primitives::boolean::BoolGetResponse response;
response.set_value(false);
msg.respond<v1::primitives::boolean::BoolGetResponse>(response);
} else if (msg.type == CacheValueId::INT) {
v1::primitives::integer::IntGetResponse response;
response.set_value(0);
msg.respond<v1::primitives::integer::IntGetResponse>(response);
} else if (msg.type == CacheValueId::STRING) {
v1::primitives::str::StringGetResponse response;
response.set_value("cached_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: {
if (msg.type == CacheValueId::BOOLEAN) {
v1::primitives::boolean::BoolDeleteResponse response;
response.set_removed_value(false);
msg.respond<v1::primitives::boolean::BoolDeleteResponse>(response);
} else if (msg.type == CacheValueId::INT) {
v1::primitives::integer::IntDeleteResponse response;
response.set_removed_value(0);
msg.respond<v1::primitives::integer::IntDeleteResponse>(response);
} else if (msg.type == CacheValueId::STRING) {
v1::primitives::str::StringDeleteResponse response;
response.set_removed_value("");
msg.respond<v1::primitives::str::StringDeleteResponse>(response);
} else if (msg.type == CacheValueId::ARRAY) {
google::protobuf::Empty response;
msg.respond<google::protobuf::Empty>(response);
}
break;
}
case OperationId::LIST_PUSH_BACK:
case OperationId::LIST_POP_BACK:
case OperationId::LIST_INSERT:
case OperationId::LIST_ERASE: {
google::protobuf::Empty response;
msg.respond<google::protobuf::Empty>(response);
break;
}
default:
break;
}
} catch (const std::exception& e) {
std::cout << "Error processing message: " << e.what() << std::endl;
}
}
void AsyncWorker::InitializeCache() {
auto callback = [this](auto result) {
// TODO
};
cache_ = std::make_unique<cache::LRU>(cache_config_, callback);
}
} // namespace rediska::worker

View File

@@ -0,0 +1,42 @@
#pragma once
#include <condition_variable>
#include <functional>
#include <memory>
#include <mutex>
#include <queue>
#include <thread>
#include <vector>
#include <grpcpp/grpcpp.h>
#include "rediska/cache/lru/LRU.hpp"
#include "rediska/common/QueueMessage.hpp"
#include "rediska/common/types.hpp"
namespace rediska::worker {
class AsyncWorker {
public:
explicit AsyncWorker(size_t num_workers = 4, size_t cache_capacity = 1000);
~AsyncWorker();
void Start();
void Stop();
void Enqueue(QueueMessage msg);
bool IsRunning() const { return running_; }
private:
void WorkerLoop();
void ProcessMessage(QueueMessage& msg);
void InitializeCache();
std::vector<std::thread> workers_;
std::queue<QueueMessage> message_queue_;
std::mutex queue_mutex_;
std::condition_variable queue_cv_;
std::atomic<bool> running_{false};
size_t num_workers_;
std::unique_ptr<cache::LRU> cache_;
cache::LRUConfig cache_config_;
};
} // namespace rediska::worker

View File

@@ -0,0 +1,14 @@
#include "rediska/worker/AsyncWorker.hpp"
#include "rediska/frontend/server.hpp"
#include <iostream>
int run_async_server() {
rediska::worker::AsyncWorker worker(4, 1000);
worker.Start();
RunFrontendServer("0.0.0.0:50051", [&worker](QueueMessage msg) {
worker.Enqueue(std::move(msg));
});
return 0;
}

View File

@@ -0,0 +1,15 @@
add_library(worker STATIC
tmp.cpp
AsyncWorker.cpp
AsyncWorker.hpp
AsyncWorkerMain.cpp
FrontendWorker.cpp
CacheWorker.cpp
)
target_link_libraries(worker PUBLIC
common
frontend
cache
data-structures
)

View 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;
}

View File

@@ -0,0 +1,123 @@
#include <condition_variable>
#include <iostream>
#include <mutex>
#include <queue>
#include <thread>
#include <grpcpp/grpcpp.h>
#include "google/protobuf/empty.pb.h"
#include "v1/primitives/bool.grpc.pb.h"
#include "v1/primitives/int.grpc.pb.h"
#include "v1/primitives/string.grpc.pb.h"
#include "v1/collections/list.grpc.pb.h"
#include "rediska/common/QueueMessage.hpp"
#include "rediska/frontend/RequestManager.hpp"
#include "rediska/frontend/server.hpp"
#include "rediska/cache/lru/LRU.hpp"
namespace {
class FrontendWorker {
public:
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 << "[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) {
v1::collections::list::ListSetResponse response;
msg.respond<v1::collections::list::ListSetResponse>(response);
} else {
msg.respond<google::protobuf::Empty>(google::protobuf::Empty{});
}
break;
}
case OperationId::GET: {
if (msg.type == CacheValueId::BOOLEAN) {
v1::primitives::boolean::BoolGetResponse response;
response.set_value(false);
msg.respond<v1::primitives::boolean::BoolGetResponse>(response);
} else if (msg.type == CacheValueId::INT) {
v1::primitives::integer::IntGetResponse response;
response.set_value(0);
msg.respond<v1::primitives::integer::IntGetResponse>(response);
} else if (msg.type == CacheValueId::STRING) {
v1::primitives::str::StringGetResponse response;
response.set_value("cached_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: {
if (msg.type == CacheValueId::BOOLEAN) {
v1::primitives::boolean::BoolDeleteResponse response;
response.set_removed_value(false);
msg.respond<v1::primitives::boolean::BoolDeleteResponse>(response);
} else if (msg.type == CacheValueId::INT) {
v1::primitives::integer::IntDeleteResponse response;
response.set_removed_value(0);
msg.respond<v1::primitives::integer::IntDeleteResponse>(response);
} else if (msg.type == CacheValueId::STRING) {
v1::primitives::str::StringDeleteResponse response;
response.set_removed_value("");
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:
case OperationId::LIST_POP_BACK:
case OperationId::LIST_INSERT:
case OperationId::LIST_ERASE: {
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_;
};
} // namespace
int run_frontend_server() {
FrontendWorker worker;
std::thread t([&] { worker.Run(); });
RunFrontendServer("0.0.0.0:50051", [&](QueueMessage msg) {
worker.Enqueue(std::move(msg));
});
t.join();
return 0;
}

86
rediska/worker/tmp.cpp Normal file
View File

@@ -0,0 +1,86 @@
#include <condition_variable>
#include <iostream>
#include <mutex>
#include <queue>
#include <thread>
#include <grpcpp/grpcpp.h>
#include "google/protobuf/empty.pb.h"
#include "v1/primitives/bool.grpc.pb.h"
#include "v1/primitives/int.grpc.pb.h"
#include "v1/primitives/string.grpc.pb.h"
#include "v1/collections/list.grpc.pb.h"
#include "rediska/common/QueueMessage.hpp"
#include "rediska/frontend/RequestManager.hpp"
#include "rediska/frontend/server.hpp"
namespace {
class PrintWorker {
public:
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 << "[worker] key=" << msg.key
<< " type=" << static_cast<int>(msg.type)
<< " op=" << static_cast<int>(msg.operation) << std::endl;
if (!msg.responder) continue;
switch (msg.operation) {
case OperationId::SET:
case OperationId::DELETE: {
msg.respond<google::protobuf::Empty>(google::protobuf::Empty{});
break;
}
case OperationId::GET: {
if (msg.type == CacheValueId::BOOLEAN) {
v1::primitives::boolean::BoolGetResponse r; r.set_value(false);
msg.respond<v1::primitives::boolean::BoolGetResponse>(r);
} else if (msg.type == CacheValueId::INT) {
v1::primitives::integer::IntGetResponse r; r.set_value(0);
msg.respond<v1::primitives::integer::IntGetResponse>(r);
} else if (msg.type == CacheValueId::STRING) {
v1::primitives::str::StringGetResponse r; r.set_value("test");
msg.respond<v1::primitives::str::StringGetResponse>(r);
} else if (msg.type == CacheValueId::ARRAY) {
v1::collections::list::ListGetResponse r;
msg.respond<v1::collections::list::ListGetResponse>(r);
}
break;
}
default:
break;
}
}
}
private:
std::queue<QueueMessage> queue_;
std::mutex mtx_;
std::condition_variable cv_;
};
} // namespace
int run_print_server() {
PrintWorker worker;
std::thread t([&] { worker.Run(); });
RunFrontendServer("0.0.0.0:50051", [&](QueueMessage msg) {
worker.Enqueue(std::move(msg));
});
t.join();
return 0;
}