Я пытаюсь понять поток асинхронной модели grpc c ++. Эта статья ( ссылка ) уже объясняет многие мои сомнения. Вот код для grpc_asycn_server . Чтобы понять, когда CompletionQueue получает запросы, я добавил несколько операторов print следующим образом:
Сначала внутри функции HandleRpcs ().
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++;
}
}
и внутри функции continue ():
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;
}
}
После запуска сервера и одного клиента ( client ) сервер выводит следующее:
RequestSayHello called
i = 0
RequestSayHello called
i = 1
deallocated
i = 2
Второй RequestSayHello called
имеет смысл из-засоздание нового CallData
экземпляра. Мой вопрос Почему функция proceed()
выполняется во второй раз, а deallocated
печатается?