Я не могу найти пример grpc, показывающий, как использовать ClientAsyncReaderWriter (есть один?). Я попробовал что-то самостоятельно, но у меня проблемы с количеством ссылок. Мой вопрос связан с отслеживанием кода.
struct grpc_call
имеет член типа gpr_refcount
называется ext_ref
, Объект ClientContext C ++ оборачивает grpc_call и удерживает его в элементе grpc_call *call_;
. Только когда ext_ref равен 0, этот указатель grpc_call может быть удален.
Когда я использую GRPC синхронно с ClientReader:
ext_ref == 2
). ext_ref == 1
).ext_ref == 0
и удаляет звонокНо когда я использую grpc асинхронно с ClientAsyncReaderWriter:
ext_ref == 2
).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
}
}
Посмотрите на этот файл, client_async.cc, для хорошего использования ClientAsyncReaderWriter. Если у вас все еще есть путаница, пожалуйста, создайте очень четкое воспроизведение проблемы, и мы рассмотрим ее дальше.
Других решений пока нет …