我有一个gRPC服务器,它托管两个异步服务(“Master”和“Worker”),我想为服务器实现正常关闭。每项服务都有自己的 # replace backslash with slash
workspace.unix = ${replace;${workspace};(\\\\);/}
。
似乎有两种可能相关的grpc::CompletionQueue
方法:grpc::CompletionQueue::Shutdown()
和grpc::Server::Shutdown()
,但是文档中不清楚应该使用哪些方法。
关闭异步服务有什么好的模式?
答案 0 :(得分:13)
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()
将返回 接到那个电话。如果要避免内存泄漏,则需要对相应标记结构的内存管理保持谨慎。
答案 1 :(得分:-1)
警告 服务器必须正在关闭,或者某些其他线程必须调用Shutdown才能使此函数返回。
http://static.grumpycoder.net/pixel/ref/c++/html/classgrpc_1_1_server.html