2016-02-29 21 views
9

2つの非同期サービス(「マスター」と「ワーカー」)をホストするgRPCサーバーがあり、サーバーの正常なシャットダウンを実装したいと考えています。各サービスにはそれぞれgrpc::CompletionQueueがあります。gRPC:C++で非同期サーバーをシャットダウンするには、どのような方法が推奨されますか?

関連性のあるShutdown()の2つの方法があります。grpc::CompletionQueue::Shutdown()grpc::Server::Shutdown()ですが、ドキュメントから使用する必要があるのは明らかではありません。

非同期サービスをシャットダウンするための良いパターンは何ですか?

答えて

8

TL; DR:あなたがきれいにシャットダウンする(サービスで使用される各完了キュー用)grpc::Server::Shutdown()grpc::CompletionQueue::Shutdown()の両方を呼び出す必要があります。

  1. あなたがcq_->Shutdown()を呼び出した場合、唯一の観察可能な効果はService::AsyncService::RequestFoo()への後続の呼び出し(対応Foo RPCのための生成方法)は、アサーションで失敗していることです。対応するC APIメソッド(grpc_completion_queue_shutdown())のドキュメントを読むと、—という新しい作業を追加すること、つまりRequestFoo() —を呼び出すことによって、is_shutdown_というメンバをサービスラッパークラス(mutexによって保護されている)に追加しても、その結果、cq_->Shutdown()が呼び出された後でエンキューが試みられません。ただし、これを実行した後、完了キューは無期限にブロックcq_->Next()にブロックされます。エンキューされたタグのいずれも完了しません(エラーなどあります)。

  2. 代わりにserver_->Shutdown()を呼び出すと、すべてのエンキューされたタグはすぐに(ok == falseで)完了します。ただし、完了キューは無制限にブロックされ続けます(cq_->Next())。クリーンシャットダウンの両方の(定義された各完了キューの)cq_->Shutdown()server_->Shutdown()結果を呼び出す

1つの警告:あなたは、コールのキャンセル用のタグを登録するgrpc::ServerContext::AsyncNotifyWhenDone()を使用する場合、最初の要求は、そのコールのために受信される前に、サーバーがシャットダウンした場合、これらはcq_->Next()によって返されないます。メモリリークを避けたい場合は、対応するタグ構造のメモリ管理に注意する必要があります。

関連する問題