TL; DR: Należy zadzwonić zarówno grpc::Server::Shutdown()
i grpc::CompletionQueue::Shutdown()
(dla każdej kolejce zakończenia używane w służbie) do wyłączenia czysto.
Jeśli zadzwonisz cq_->Shutdown()
, jedyny efekt zauważalny jest fakt, że kolejne wywołania Service::AsyncService::RequestFoo()
(wygenerowany Sposób odpowiedniego Foo
RPC) niepowodzeniem z twierdzeniem. Od przeczytania dokumentacji odpowiedniej metody interfejsu API C (grpc_completion_queue_shutdown()
) wydaje się, że niedozwolone jest dodawanie nowej pracy do kolejki — tj. Przez wywołanie RequestFoo()
—, więc dodałem członka is_shutdown_
do moich klas pakowania usług (chronionych przez muteks) tak, aby nie były wykonywane próby kolejkowania po wywołaniu cq_->Shutdown()
. Jednak po wykonaniu tej czynności kolejka dokończenia blokuje się w nieskończoność w cq_->Next()
. Żaden z zakolumnowanych tagów nie jest kompletny (z błędem lub w inny sposób).
Jeśli zamiast tego zadzwonisz pod numer server_->Shutdown()
, wszystkie zagnieżdżone znaczniki zakończą się natychmiast (z ok == false
). Jednak kolejka zakończenia kontynuuje blokowanie w nieskończoność w cq_->Next()
.
Wywołanie zarówno cq_->Shutdown()
(dla każdego określonego kolejki wykonania) i server_->Shutdown()
wyniki w czystej wyłączenia.
Jedno zastrzeżenie: jeśli używasz grpc::ServerContext::AsyncNotifyWhenDone()
zarejestrować znacznik odwołania połączeń, będą nie zostać zwrócone przez cq_->Next()
jeśli serwer wyłącza się, zanim zostanie odebrany pierwotny wniosek dla tego połączenia. Będziesz musiał zachować ostrożność przy zarządzaniu pamięcią odpowiedniej struktury znaczników, jeśli chcesz uniknąć wycieków pamięci.