TL; DR: Sie müssen beide rufen grpc::Server::Shutdown()
und grpc::CompletionQueue::Shutdown()
(für jeden in den Dienst verwendet Abschluss-Warteschlange) sauber herunterzufahren.
Wenn Sie cq_->Shutdown()
nennen, die einzige beobachtbare Effekt ist, dass nachfolgende Aufrufe Service::AsyncService::RequestFoo()
(die erzeugte Methode für die entsprechende Foo
RPC) mit einer Behauptung fehlschlagen. Nach dem Lesen der Dokumentation der entsprechenden C-API-Methode (grpc_completion_queue_shutdown()
) scheint es illegal zu sein, neue Arbeit in die Warteschlange — hinzuzufügen, dh RequestFoo()
—, so fügte ich ein is_shutdown_
Mitglied meiner Service Wrapper-Klassen (durch einen Mutex geschützt) damit keine Enqueue-Versuche unternommen werden, nachdem cq_->Shutdown()
aufgerufen wird. Nachdem Sie dies getan haben, blockiert die Abschlusswarteschlange jedoch unbegrenzt in cq_->Next()
. Keines der eingereihten Tags wird abgeschlossen (mit einem Fehler oder auf andere Weise). Wenn Sie stattdessen server_->Shutdown()
aufrufen, werden alle eingereihten Tags sofort (mit ok == false
) abgeschlossen. Die Beendigungswarteschlange wird jedoch weiterhin unbegrenzt in cq_->Next()
blockiert.
Aufruf sowohl cq_->Shutdown()
(für jede Abschluss-Warteschlange definiert ist) und server_->Shutdown()
Ergebnisse in einem sauberen Abschaltung.
Eine Warnung: Wenn Sie grpc::ServerContext::AsyncNotifyWhenDone()
verwenden, um einen Tag für Rufabstellung zu registrieren, wird diese nicht von cq_->Next()
zurückgegeben werden, wenn der Server heruntergefahren, bevor die ursprüngliche Anforderung für diesen Anruf empfangen wird. Sie müssen mit der Speicherverwaltung der entsprechenden Tag-Struktur vorsichtig sein, wenn Sie Speicherlecks vermeiden wollen.