Асинхронный сервер не обрабатывает запросы, пока запрос застрял - PullRequest
0 голосов
/ 25 октября 2019

Я новичок в GRPC, поэтому, пожалуйста, дайте мне знать, если я что-то не так делаю здесь. Я смотрю на пример кода greeter_async_server.cc. Похоже, что это нормально работает для обычных запросов, но я хотел смоделировать запрос, застревающий на сервере, поэтому я добавил режим ожидания в цикл обработки. Я добавил это прямо перед вызовом Finish для респондента, чтобы это было в реальной логике обработки запроса. Пока поток сервера спит, он не будет принимать новые запросы, пока поток не освободится. Я попытался создать еще один клиентский запрос, пока исходный запрос на сервере спит, но сервер grpc не обработает запрос. Клиент, казалось, застрял, пока сервер не вышел из сна.

Я также разбил этот процесс на отладчик, но единственный запрос, который я видел, был тот, который спал. Другие потоки ожидали в очереди завершения.

Я новичок в grpc, поэтому, если я делаю это неправильно, пожалуйста, дайте мне знать, что мне нужно сделать, чтобы обработать запрос, пока другой запрос застрял.

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.
        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());

        Sleep((DWORD)-1);

        // 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 {
        GPR_ASSERT(status_ == FINISH);
        // Once in the FINISH state, deallocate ourselves (CallData).
        delete this;
      }
    }
...