【问题标题】:gRPC: What is the recommended way to shut down an asynchronous server in C++?gRPC:在 C++ 中关闭异步服务器的推荐方法是什么?
【发布时间】:2016-06-13 00:16:23
【问题描述】:
【问题讨论】:
标签:
c++
asynchronous
server
grpc
shutdown
【解决方案2】:
TL;DR:您必须同时调用grpc::Server::Shutdown() 和grpc::CompletionQueue::Shutdown()(对于服务中使用的每个完成队列)才能彻底关闭。
1234563从阅读相应 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() 将不会返回这些标签.如果要避免内存泄漏,则需要谨慎处理相应标记结构的内存管理。
【讨论】:
-
伟大的自我回答!一些笔记。首先:根据the tutorial,服务器必须在完成队列(或多个队列)之前关闭。
-
第二:AsyncNotifyWhenDone() 没有被cq_->Next() 返回的事实可能是the docs for Next() 的意思,当它神秘地说“AsyncNotifyWhenDone: ok 应该始终为真”时。它还说对于客户端完成,因此可能在关闭期间也不会返回其标签。