Files
Rediska/rediska/frontend/RequestManager.hpp
Nikita Astafyev 35a6349071
Some checks failed
Code Analysis / analysis (push) Failing after 2m59s
chore: initial commit
2025-12-30 22:34:58 +07:00

53 lines
2.0 KiB
C++

#pragma once
#include <grpcpp/grpcpp.h>
#include <grpcpp/support/async_stream.h>
#include <memory>
#include <optional>
#include "rediska/common/QueueMessage.hpp"
// One global context kept alive as long as the server lives.
inline grpc::ServerContext& GlobalServerContext() {
static grpc::ServerContext ctx;
return ctx;
}
// The thing recieved from the completion queue in case of a request.
struct BaseRequestManager {
virtual void ListenForOne(grpc::ServerCompletionQueue& cq) = 0;
virtual std::optional<QueueMessage> ConsumeMessage() = 0;
virtual ~BaseRequestManager() = default;
};
// This is basically storage for an incoming request.
template <typename Derived, typename RequestT, typename ResponderT, typename ServiceT, auto RequestMethod>
class RequestManager : public BaseRequestManager {
protected:
RequestT request;
std::unique_ptr<ResponderT> responder;
ServiceT& service;
std::unique_ptr<grpc::internal::ServerAsyncStreamingInterface> TakeResponder() {
return std::unique_ptr<grpc::internal::ServerAsyncStreamingInterface>(std::move(responder));
}
public:
explicit RequestManager(ServiceT& svc) : service(svc) { }
// Sets up listening for a new request.
// You must ensure this object lives until the request is consumed, or grpc will be unhappy.
// The tag you recieve from the queue is a EventVariant* that you must take ownership of.
void ListenForOne(grpc::ServerCompletionQueue& cq) override {
request = RequestT{};
// FIXME: just leak this stupid shit for now idk how to fix I'm done with this stupid language
auto* ctx = new grpc::ServerContext();
responder = std::make_unique<ResponderT>(ctx);
(service.*RequestMethod)(ctx, &request, responder.get(), &cq, &cq, std::make_unique<EventVariant>(RequestEvent{*this}).release());
}
std::optional<QueueMessage> ConsumeMessage() override {
QueueMessage msg = static_cast<Derived*>(this)->BuildMessage();
return msg;
}
};