简体   繁体   English

gRPC:在C ++中关闭异步服务器的推荐方法是什么?

[英]gRPC: What is the recommended way to shut down an asynchronous server in C++?

I have a gRPC server that hosts two asynchronous services ("Master" and "Worker"), and I would like to implement graceful shutdown for the server. 我有一个gRPC服务器,它承载两个异步服务(“Master”和“Worker”),我想为服务器实现正常关闭。 Each service has its own grpc::CompletionQueue . 每个服务都有自己的grpc::CompletionQueue

There appear to be two Shutdown() methods that might be relevant: grpc::CompletionQueue::Shutdown() and grpc::Server::Shutdown() , but it's not clear from the documentation which ones should be used. 似乎有两个可能相关的Shutdown()方法: grpc::CompletionQueue::Shutdown()grpc::Server::Shutdown() ,但是从文档中不清楚应该使用哪些方法。

What is a good pattern for shutting down an asynchronous service? 关闭异步服务有什么好的模式?

TL;DR: You must call both grpc::Server::Shutdown() and grpc::CompletionQueue::Shutdown() (for each completion queue used in the service) to shut down cleanly. TL; DR:你必须同时调用grpc::Server::Shutdown()grpc::CompletionQueue::Shutdown() (对于服务中使用的每个完成队列)来干净地关闭。

  1. If you call cq_->Shutdown() , the only observable effect is that subsequent calls to Service::AsyncService::RequestFoo() (the generated method for the corresponding Foo RPC) fail with an assertion. 如果你调用cq_->Shutdown() ,唯一可观察的效果是后续调用Service::AsyncService::RequestFoo() (相应的Foo RPC的生成方法)失败并带有断言。 From reading the documentation of the corresponding C API method ( grpc_completion_queue_shutdown() ), it appears that it is illegal to add new work to the queue—ie by calling RequestFoo() —so I added an is_shutdown_ member to my service wrapper classes (protected by a mutex) so that no enqueue attempts are made after cq_->Shutdown() is called. 通过阅读相应的C API方法( grpc_completion_queue_shutdown() )的文档,似乎将新工作添加到队列是非法的 - 即通过调用RequestFoo()我将is_shutdown_成员添加到我的服务包装类(protected)通过互斥锁),以便在调用cq_->Shutdown()之后不会进行入队尝试。 However, after doing this, the completion queue blocks indefinitely in cq_->Next() . 但是,执行此操作后,完成队列将无限期地阻塞在cq_->Next() None of the enqueued tags complete (with an error or otherwise). 没有排队的标签完成(有错误或其他)。

  2. If instead you call server_->Shutdown() , all of the enqueued tags complete immediately (with ok == false ). 如果您调用server_->Shutdown() ,则所有排队的标签立即完成(使用ok == false )。 However, the completion queue continues to block indefinitely in cq_->Next() . 但是,完成队列继续在cq_->Next()无限期地阻塞。

Calling both cq_->Shutdown() (for each defined completion queue) and server_->Shutdown() results in a clean shutdown. 同时调用cq_->Shutdown() (对于每个已定义的完成队列)和server_->Shutdown()导致干净关闭。

One caveat: if you use grpc::ServerContext::AsyncNotifyWhenDone() to register a tag for call cancellation, these will not be returned by cq_->Next() if the server shuts down before the initial request is received for that call. 需要注意的是:如果使用grpc::ServerContext::AsyncNotifyWhenDone()来注册呼叫取消标签,那么如果服务器在收到该呼叫的初始请求之前关闭,则cq_->Next()不会返回这些标签。 You will need to be cautious with the memory management of the corresponding tag structure, if you want to avoid memory leaks. 如果要避免内存泄漏,则需要对相应标记结构的内存管理保持谨慎。

  • Wait() void grpc::Server::Wait () Wait()void grpc :: Server :: Wait()
    overridevirtual Block until the server shuts down. overridevirtual阻塞,直到服务器关闭。

Warning The server must be either shutting down or some other thread must call Shutdown for this function to ever return. 警告服务器必须要么关闭,要么其他线程必须调用Shutdown才能返回此功能。

  • grpc::Server Shutdown() grpc :: Server Shutdown()

http://static.grumpycoder.net/pixel/ref/c++/html/classgrpc_1_1_server.html http://static.grumpycoder.net/pixel/ref/c++/html/classgrpc_1_1_server.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM