我有一个托管两个异步服务(“Master”和“Worker”)的 gRPC 服务器,我想为服务器实现正常关闭。每个服务都有自己的 grpc::CompletionQueue
。
似乎有两个可能相关的 Shutdown()
方法:grpc::CompletionQueue::Shutdown()
和 grpc::Server::Shutdown()
,但从文档中不清楚应该使用哪些。
什么是关闭异步服务的好模式?
最佳答案
TL;DR:您必须同时调用 grpc::Server::Shutdown()
和 grpc::CompletionQueue::Shutdown()
(对于服务中使用的每个完成队列)干净地关闭。
如果您调用
cq_->Shutdown()
,唯一可观察到的影响是对Service::AsyncService::RequestFoo()
(相应Foo
RPC 的生成方法)的后续调用失败并带有断言。从阅读相应 C API 方法 (grpc_completion_queue_shutdown()
) 的文档来看,将新工作添加到队列中似乎是非法的——即通过调用RequestFoo()
——所以我向我的服务包装类(受互斥体保护)添加了一个is_shutdown_
成员,这样在cq_->Shutdown()
被调用。然而,在这样做之后,完成队列在cq_->Next()
中无限期地阻塞。 .所有入队的标签都不完整(有错误或其他原因)。如果您改为调用
server_->Shutdown()
,所有排队的标签都会立即完成(使用ok == false
)。但是,完成队列在cq_->Next()
中继续无限期阻塞。
同时调用 cq_->Shutdown()
(对于每个定义的完成队列)和 server_->Shutdown()
会导致完全关闭。
一个警告:如果你使用 grpc::ServerContext::AsyncNotifyWhenDone()
注册一个取消调用的标签,这些将不会被 cq_ 返回->Next()
如果服务器在收到该调用的初始请求之前关闭。如果要避免内存泄漏,则需要谨慎处理相应标记结构的内存管理。
关于c++ - gRPC:在 C++ 中关闭异步服务器的推荐方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35708348/