gRPC: каков рекомендуемый способ завершения работы асинхронного сервера в C++?
у меня есть сервер gRPC, на котором размещены две асинхронные службы ("Master" и "Worker"), и я хотел бы реализовать изящное завершение работы для сервера. Каждая услуга имеет свой grpc::CompletionQueue
.
есть два Shutdown()
методы, которые могут иметь отношение: grpc::CompletionQueue::Shutdown()
и grpc::Server::Shutdown()
, но из документации не ясно, какие из них следует использовать.
что такое хороший шаблон для выключения асинхронной службы?
2 ответов
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()
если сервер выключается до того, как первоначальный запрос на этот звонок получен. Вам нужно будет быть осторожным с управлением памятью соответствующей структуры тегов, если вы хотите избежать утечек памяти.
- ждать()
void grpc:: Server:: Wait ()
overridevirtual Блокируйте, пока сервер не выключится.
предупреждение Сервер должен либо завершать работу, либо какой-либо другой поток должен вызывать завершение работы для возврата этой функции.
- grpc:: завершение работы сервера ()
http://static.grumpycoder.net/pixel/ref/c++/html/classgrpc_1_1_server.html