как использовать простой способ определить конец потоковой передачи клиента в асинхронном GRPC ++? - PullRequest
0 голосов
/ 21 июня 2020

Сейчас изучаю двунаправленную потоковую передачу в асинхронном GRPC ++. Спасибо мастеру: https://github.com/Mityuha/grpc_async. Я получил много полезной информации, чтобы узнать принцип реализации этого режима, но у меня есть вопрос по этому поводу: особо нечего сказать, код следующий: сервер:

if(!ok || mcounter >= greeting.size())//ctx_.IsCancelled() doesn't work
    {
        std::cout << "[ProceedMM]: Trying finish" << std::endl;
        status_ = FINISH;
        responder_.Finish(Status(), (void*)this);
    }

клиент:

void AsyncCompleteRpc()
    {
        void* got_tag;
        bool ok = false;
        while(cq_.Next(&got_tag, &ok))
        {
            AbstractAsyncClientCall* call = static_cast<AbstractAsyncClientCall*>(got_tag);
            call->Proceed(ok);
        }
        std::cout << "Completion queue is shutting down." << std::endl;
    }

на этом сервере конец ClientStream оценивается по логическому значению OK, которое отправляется клиентом. Это не похоже на способ синхронного GRP C, который оценивается как окончание обработки паром по возвращение bool Read(RequestType* request) в классе ServerReaderWriter много раз. Так странно найти такой же способ в классе ServerAsyncReaderWriter, который равен void Read(R* msg, void* tag). Хотя я знаю, что это из-за асинхронного способа. Но если я не знать, сколько раз асинхронная потоковая передача без оценки "ОК", как найти способ, как синхронная потоковая передача, чтобы судить об окончании потоковой передачи клиента. Потому что я тестирую производительность с помощью java, который представляет собой тот же код между синхронным и асинхронным способами , которые не имеют логического значения OK в асинхронном режиме. Так может ли кто-нибудь мне помочь? Или подскажите, как с этим справиться, или найдите способ протестировать тестирование производительности GRPC ++, выполненное Базелем, в другом моем вопросе.

Ответы [ 2 ]

0 голосов
/ 09 июля 2020

В случае получения потока в асинхронном клиенте gRP C вы будете использовать класс ClientAsyncReader<> для получения данных. Этот класс отличается, когда и отправка, и получение являются потоковыми, но logi c одно и то же.

Этот класс имеет метод Finish(), который необходимо вызвать после завершения отправки данных rp c на сервер. . Когда поток ответов с сервера закончится, будет добавлено сообщение на CompletionQueue, соответствующее этому методу. Этот Finish метод возвращает окончательный статус, когда его сообщение возвращается в CQ . Вы можете узнать, что ваш поток завершен. Ваш код будет похож на этот:

response_reader_ = stub->PrepareAsyncXYZ(ctx_, req, cq);
response_reader_->StartCall(&start_data_);
response_reader_->Finish(&status_, &finish_data_);

в этом примере сообщение в CQ будет иметь тег finish_data_, и вы можете использовать его для правильной обработки. Вам, вероятно, потребуется управлять сообщениями для Finish() и Read() путем подсчета ссылок, потому что вы, вероятно, также получите дополнительное сообщение об ошибке чтения. когда сообщение с finish_data_ получено в CQ, status_ будет иметь действительное значение status.

По крайней мере, так я его написал.

0 голосов
/ 09 июля 2020

Я не уверен на 100%, что получил вопрос, но ok говорит вам (когда ложно), что запрошенная вами операция не может быть завершена, и ничто другое никогда не будет успешно завершено на этой стороне поток. Поэтому, если вы выполняете операцию Read, а Next дает вам значение !ok, вы можете быть уверены, что больше данные от клиента никогда не вернутся. Более подробное объяснение приведено в комментариях к классу CompletionQueue.

Спасибо и удачи с gRP C.

...