gRPC: каков рекомендуемый способ завершения работы асинхронного сервера в C++?

у меня есть сервер gRPC, на котором размещены две асинхронные службы ("Master" и "Worker"), и я хотел бы реализовать изящное завершение работы для сервера. Каждая услуга имеет свой grpc::CompletionQueue.

есть два Shutdown() методы, которые могут иметь отношение: grpc::CompletionQueue::Shutdown() и grpc::Server::Shutdown(), но из документации не ясно, какие из них следует использовать.

что такое хороший шаблон для выключения асинхронной службы?

2 ответов


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_ член моих классов обертки службы (защищенных мьютексом), чтобы после cq_->Shutdown() называется. Однако после этого очередь завершения блокируется бесконечно в cq_->Next(). Ни один из поставленных в очередь тегов не завершен (с ошибкой или иным образом).

  2. если вместо этого вы называете 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