【发布时间】:2021-06-03 14:45:52
【问题描述】:
我正在为 gRPC 一元调用编写一个包装器,但我遇到了一个问题:假设我有一个 ClientAsyncResponseReader 对象,它被创建并像这样启动一个请求
response_reader_ = std::unique_ptr<grpc::ClientAsyncResponseReader<ResponseType>>(
grpc::internal::ClientAsyncResponseReaderFactory<ResponseType>::Create(
channel.get(), completion_queue, rpc_method, &client_context_, request, true
)
);
response_reader_->Finish(
response_sharedptr_.get(), status_sharedptr_.get(), static_cast<void*>(some_tag)
);
// Set a breakpoint here
所有参数都有效。
我的印象是,当Finish 调用返回时,request 对象肯定会通过网络发送出去。但是,通过在 Finish() 调用之后设置断点(在客户端程序中,要清楚)并检查我的服务器日志,我发现服务器直到我 resume 之后才记录request em> 从断点开始。
这似乎表明我需要等待其他一些事情以确保请求被真正发送出去:而且,执行上述代码的线程在发送请求方面仍然具有某种作用出现断点后。
当然,也许我的假设是错误的,并且服务器没有在请求进入时立即记录它。如果不是,那么显然我没有像我应该的那样理解 gRPC 的语义,所以我希望获得一些更有经验的见解。
你可以看到我的一元调用抽象代码here。应该足够了,但如果需要其他任何东西,我很乐意提供。
编辑:情节变厚了。在服务器的处理程序上为传入请求设置断点后,看起来对 Finish 的调用通常确实“确保”请求已发送出去:except进程发送的第一个请求。我猜grpc::channel 甚至可能在grpc::completion_queue 中维护了一些状态,这会延迟初始请求
【问题讨论】: