gRPC:在C ++中关闭异步服务器的推荐方法是什么? [英] gRPC: What is the recommended way to shut down an asynchronous server in C++?

查看:400
本文介绍了gRPC:在C ++中关闭异步服务器的推荐方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个托管两个异步服务("Master"和"Worker")的gRPC服务器,并且我想对该服务器实施正常关机.每个服务都有自己的grpc::CompletionQueue.

I have a gRPC server that hosts two asynchronous services ("Master" and "Worker"), and I would like to implement graceful shutdown for the server. Each service has its own grpc::CompletionQueue.

似乎有两个可能相关的Shutdown()方法: grpc::Server::Shutdown() ,但是从该使用哪些文档.

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.

关闭异步服务的好模式是什么?

What is a good pattern for shutting down an asynchronous service?

推荐答案

TL; DR:您必须同时调用(c2

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.

  1. 如果您呼叫 cq_->Shutdown() ,则唯一可观察到的效果是随后的对Service::AsyncService::RequestFoo()(对应的Foo RPC的生成方法)的调用失败,并带有一个断言.通过阅读相应C API方法的文档( grpc_completion_queue_shutdown() )将新作品添加到队列中是非法的,即通过调用RequestFoo(),因此我在服务包装类中添加了is_shutdown_成员(受互斥锁保护),以便在调用cq_->Shutdown()之后不进行入队尝试.但是,执行此操作后,完成队列将在 cq_->Next() 中无限期地阻塞.排队的标签都没有完成(有错误或其他原因).

  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. 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—i.e. 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. However, after doing this, the completion queue blocks indefinitely in cq_->Next(). None of the enqueued tags complete (with an error or otherwise).

相反,如果您调用 server_->Shutdown() ,则所有入队标签都已完成立即(使用ok == false).但是,完成队列继续在cq_->Next()中无限期阻塞.

If instead you call server_->Shutdown(), all of the enqueued tags complete immediately (with ok == false). However, the completion queue continues to block indefinitely in cq_->Next().

同时调用cq_->Shutdown()(针对每个定义的完成队列)和server_->Shutdown()会导致干净关闭.

Calling both cq_->Shutdown() (for each defined completion queue) and server_->Shutdown() results in a clean shutdown.

一个警告:如果您使用grpc::ServerContext::AsyncNotifyWhenDone()注册用于呼叫取消的标签,则如果服务器在收到该呼叫的初始请求之前关闭,则> 不会返回这些消息. .如果要避免内存泄漏,则需要谨慎对待相应标记结构的内存管理.

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. You will need to be cautious with the memory management of the corresponding tag structure, if you want to avoid memory leaks.

这篇关于gRPC:在C ++中关闭异步服务器的推荐方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆