我有一个托管两个异步服务(“Master”和“Worker”)的 gRPC 服务器,我想为服务器实现正常关闭。每个服务都有自己的grpc::CompletionQueue
.
似乎有两种Shutdown()
方法可能相关:grpc::CompletionQueue::Shutdown()
和grpc::Server::Shutdown()
,但从文档中不清楚应该使用哪些方法。
关闭异步服务的好模式是什么?
我有一个托管两个异步服务(“Master”和“Worker”)的 gRPC 服务器,我想为服务器实现正常关闭。每个服务都有自己的grpc::CompletionQueue
.
似乎有两种Shutdown()
方法可能相关:grpc::CompletionQueue::Shutdown()
和grpc::Server::Shutdown()
,但从文档中不清楚应该使用哪些方法。
关闭异步服务的好模式是什么?
TL;DR:您必须同时调用grpc::Server::Shutdown()
and grpc::CompletionQueue::Shutdown()
(对于服务中使用的每个完成队列)才能干净地关闭。
如果您调用cq_->Shutdown()
,唯一可观察到的效果是后续调用Service::AsyncService::RequestFoo()
(为相应Foo
RPC 生成的方法)失败并带有断言。从阅读相应的 C grpc_completion_queue_shutdown()
APIRequestFoo()
方法is_shutdown_
(入队尝试在cq_->Shutdown()
被调用后进行。但是,在这样做之后,完成队列会无限期地阻塞在cq_->Next()
. 入队的标签都没有完成(有错误或其他原因)。
相反,如果您调用server_->Shutdown()
,则所有排队的标签都会立即完成(使用ok == false
)。但是,完成队列继续无限期地阻塞在cq_->Next()
.
调用两者cq_->Shutdown()
(对于每个定义的完成队列)并server_->Shutdown()
导致完全关闭。
一个警告:如果您使用grpc::ServerContext::AsyncNotifyWhenDone()
为呼叫取消注册标签,如果服务器在收到该呼叫的初始请求之前关闭,则不会返回这些标签。cq_->Next()
如果要避免内存泄漏,则需要谨慎处理相应标记结构的内存管理。
警告服务器必须正在关闭,或者某个其他线程必须调用 Shutdown 才能使此函数返回。
http://static.grumpycoder.net/pixel/ref/c++/html/classgrpc_1_1_server.html