[英]grpc c++ async completion queue events
I am trying to understand the grpc c++ async model flow.我试图了解 grpc c++ 异步 model 流程。 This article ( link ) already explains many of my doubts.
这篇文章( 链接)已经解释了我的许多疑惑。 Here is the code for grpc_asycn_server .
这是grpc_asycn_server的代码。 To understand when CompletionQueue is getting requests, I added a few print statements as follows:
为了了解 CompletionQueue 何时收到请求,我添加了一些打印语句,如下所示:
First inside the HandleRpcs() function.首先在 HandleRpcs() function 中。
void HandleRpcs() {
// Spawn a new CallData instance to serve new clients.
new CallData(&service_, cq_.get());
void* tag; // uniquely identifies a request.
bool ok;
int i = 0;
while (true) {
std::cout << i << std::endl; ///////////////////////////////
// Block waiting to read the next event from the completion queue. The
// event is uniquely identified by its tag, which in this case is the
// memory address of a CallData instance.
// The return value of Next should always be checked. This return value
// tells us whether there is any kind of event or cq_ is shutting down.
GPR_ASSERT(cq_->Next(&tag, &ok));
GPR_ASSERT(ok);
static_cast<CallData*>(tag)->Proceed();
i++;
}
}
and inside the proceed() function:在proceed() function中:
void Proceed() {
if (status_ == CREATE) {
// Make this instance progress to the PROCESS state.
status_ = PROCESS;
// As part of the initial CREATE state, we *request* that the system
// start processing SayHello requests. In this request, "this" acts are
// the tag uniquely identifying the request (so that different CallData
// instances can serve different requests concurrently), in this case
// the memory address of this CallData instance.
std::cout<<"RequestSayHello called"<<std::endl; ////////////////////////////
service_->RequestSayHello(&ctx_, &request_, &responder_, cq_, cq_,
this);
} else if (status_ == PROCESS) {
// Spawn a new CallData instance to serve new clients while we process
// the one for this CallData. The instance will deallocate itself as
// part of its FINISH state.
new CallData(service_, cq_);
// The actual processing.
std::string prefix("Hello ");
reply_.set_message(prefix + request_.name());
// And we are done! Let the gRPC runtime know we've finished, using the
// memory address of this instance as the uniquely identifying tag for
// the event.
status_ = FINISH;
responder_.Finish(reply_, Status::OK, this);
} else {
std::cout<<"deallocated"<<std::endl; ////////////////////////////
GPR_ASSERT(status_ == FINISH);
// Once in the FINISH state, deallocate ourselves (CallData).
delete this;
}
}
Once I run the server and the one client ( client ) then the server prints the following:一旦我运行服务器和一个客户端( 客户端),服务器就会打印以下内容:
RequestSayHello called
i = 0
RequestSayHello called
i = 1
deallocated
i = 2
The second RequestSayHello called
makes sense because of the creation of new CallData
instance.由于创建了新的
CallData
实例,调用的第二个RequestSayHello called
是有意义的。 My question is how come proceed()
function executed the second time and deallocated
gets printed?我的问题是如何
proceed()
function 第二次执行并deallocated
被打印?
The completion queue ( cq_
) structure handles several types of events, including both request and response events.完成队列 (
cq_
) 结构处理多种类型的事件,包括请求和响应事件。 The first call to proceed()
enters the PROCESS
stage of the state machine for the CallData
object.对
proceed()
的第一次调用进入PROCESS
机器的处理阶段,用于CallData
object。
During this stage:在此阶段:
1. A new CallData
object is created; 1、新建
CallData
object; this inserts a request event into cq_
as you mentioned如您所述,这会将请求事件插入
cq_
2. The responder_
is called with the reply object; 2.
responder_
_被调用,回复为object; this inserts a response event into cq_
这会将响应事件插入
cq_
Upon receiving the response event from cq_
, proceed()
is called again on the first CallData
object, which is now in the FINISH
state, so clean up is performed and deallocated
is printed.在收到来自
cq_
的响应事件后,在第一个CallData
object 上再次调用proceed()
,它现在位于FINISH
state 中,因此执行清理并打印deallocated
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.