Как правильно использовать grpc асинхронно (ClientAsyncReaderWriter)

Я не могу найти пример grpc, показывающий, как использовать ClientAsyncReaderWriter (есть один?). Я попробовал что-то самостоятельно, но у меня проблемы с количеством ссылок. Мой вопрос связан с отслеживанием кода.

struct grpc_call имеет член типа gpr_refcount называется ext_ref, Объект ClientContext C ++ оборачивает grpc_call и удерживает его в элементе grpc_call *call_;. Только когда ext_ref равен 0, этот указатель grpc_call может быть удален.

Когда я использую GRPC синхронно с ClientReader:

  • В своей реализации он использует CreateCall () и PerformOps () для добавления в ext_ref (ext_ref == 2).
  • Затем я использую Pluck (), который вычитает из ext_ref так, чтобы (ext_ref == 1).
  • Последнее использование ~ ClientContext () вычитает из ext_ref, так что ext_ref == 0 и удаляет звонок

Но когда я использую grpc асинхронно с ClientAsyncReaderWriter:

  • Сначала используйте asyncXXX (), этот API использует CreateCall () и зарегистрируйте Write () (ext_ref == 2).
  • Затем он использует AsyncNext () для получения тега … который должен использовать оператор записи или чтения.
  • Так ext_ref > 1 навсегда, если только с got_event вы не справитесь.

Я называю это так:

struct Notice
{
std::unique_ptr<
grpc::ClientAsyncReaderWriter<ObserveNoticRequest, EventNotice>
>                          _rw;
ClientContext              _context;
EventNotice                _rsp;
}

Зарегистрировать тему

CompletionQueue *cq = new CompletionQueue;
Notice *notice = new Notice;
notice->rw = stub->AsyncobserverNotice(&context, cq, notice);

// here context.call_.ext_ref is 2
void *tag = NULL;
bool ok = false;
CompletionQueue::NextStatus got = CompletionQueue::NextStatus::TIMEOUT;
gpr_timespec deadline;
deadline.clock_type = GPR_TIMESPAN;
deadline.tv_sec = 0;
deadline.tv_nsec = 10000000;

got = cq->AsyncNext<gpr_timespec>(&tag, &ok, deadline);

if (GOT_EVENT == got) {
if (tag != NULL) {
Notice *notice = (Notice *)tag;
notice->_rw->Read(&_rsp, notice);

// here context.call_.ext_ref is 2.
// now I want to stop this CompletionQueue.

delete notice;

// use ~ClientContext(), ext_ref change to 1
// but only ext_ref == 0, call_ be deleted
}
}

2

Решение

Посмотрите на этот файл, client_async.cc, для хорошего использования ClientAsyncReaderWriter. Если у вас все еще есть путаница, пожалуйста, создайте очень четкое воспроизведение проблемы, и мы рассмотрим ее дальше.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]