Asynchronous model in grpc c ++

My team is developing a scalable solution with a microservice architecture and plans to use gRPC as a transport link between layers. And we decided to use the async grpc model. The design, an example ( greeter_async_server.cc ), does not seem viable if I scale the number of RPC methods, because then I will have to create a new class for each RPC method and create their objects in the HandleRpcs()following way. Pastebin (short example code).

   void HandleRpcs() {
            new CallDataForRPC1(&service_, cq_.get());
            new CallDataForRPC2(&service_, cq_.get());
            new CallDataForRPC3(&service, cq_.get());
            // so on...
    }

It will be hardcoded, all flexibility will be lost.

I have about 300-400RPC methods for implementation and the availability of 300-400 classes will be cumbersome and inefficient when I have to process more than 100 thousand RPC / sec requests, and this solution is very bad. I can not bear the overhead of creating objects in this way for each individual request. Can someone kindly provide me a workaround for this. Can async grpc c++not be as simple as its synchronizing companion?

Change . In order to improve the situation and for those who can try to understand the flow of this asynchronous example, I am writing what I have understood so far, please make me correct if something is wrong.

async grpc , , RPC , .

service_->RequestRPC2(&ctx_, &request_, &responder_, cq_, cq_,this); . RPC . HandleRpcs(), , RPC, cq_->Next(&tag, &OK) . :

while (true) {
          GPR_ASSERT(cq_->Next(&tag, &ok));
          GPR_ASSERT(ok);
          static_cast<CallData*>(tag)->Proceed();
        }

, , CallData, Proceed(). RPC Proceed(). RPC , CallData, Proceed(), () RPC1 ( postgres), RPC2 ( mongodb),.. . . , , GenericCallData virtual void Proceed() , RPC Proceed(). , .

, , RPC Proceed() std::map<long, std::function</*some params*/>>. , RPC , (, , ), . , &tag, . , , :

// pseudo code
void function(reply, responder, context, service)
{
    // register this RPC with another unique tag so to serve new incoming request of the same type on the completion queue
     service_->RequestRPC1(/*params*/, new_unique_id);
    // now again save this new_unique_id and current function into the map, so when tag will be returned we can do lookup
     map.emplace(new_unique_id, function);

    // now you're free to do your logic
    // do your logic
}

, , RPC. , . , - .

+4

Source: https://habr.com/ru/post/1694963/


All Articles