繁体   English   中英

如何从客户端关闭gRPC服务器(使用RPC功能)

[英]How to shutdown gRPC server from Client (using RPC function)

我将gRPC用于C ++ App(gRPC服务器)和Java App(gRPC客户端)之间的进程间通信。 一切都在一台机器上运行。 我想为客户提供关闭服务器的可能性。 我的想法是将RPC函数添加到服务中,以实现此目的。

C ++实现为:

class Service : public grpcGeneratedService
{
public:
......
private:  
    grpc::Server* m_pServer;
};
grpc::Status Service::ShutDown(grpc::ServerContext* pContext, const ShutDownRequest* pRequest, ShutDownResponse* pResponse)
{
    if (m_pServer)
        m_pServer->Shutdown();
    return grpc::Status(grpc::StatusCode::OK, "");
}

但是ShutDown会阻塞,直到处理完所有RPC调用为止,这意味着死锁。 有什么优雅的方法可以实现它吗?

我使用的std :: promise几乎与您的方法完全一样。

// Somewhere in the global scope :/
std::promise<void> exit_requested;

// My method looks nearly identical to yours 
Status CoreServiceImpl::shutdown(ServerContext *context, const SystemRequest *request, Empty*)
{
  LOG(INFO) << context->peer() << " - Shutdown request acknowledged.";
  exit_requested.set_value();
  return Status::OK;
}

为了使此工作正常进行,我在第二个线程中调用server->Wait() ,并在将来等待exit_requested诺言来阻止关闭调用:

auto serveFn = [&]() {
  server->Wait();
};

std::thread serving_thread(serveFn);

auto f = exit_requested.get_future();
f.wait();
server->Shutdown();
serving_thread.join();

一旦有了这个,我还可以通过信号处理程序支持干净关闭:

auto handler = [](int s) {
  exit_requested.set_value();
};
std::signal(SIGINT, handler);
std::signal(SIGTERM, handler);
std::signal(SIGQUIT, handler);

到目前为止,我对这种方法很满意,它使我始终处于gRPC和标准c ++库的范围之内。 与其使用某些全局范围的promise(我必须在服务实现源中将其声明为外部的promise),不如考虑更优雅的方法。

这里要注意的一件事是,多次设置promise的值将引发异常。 如果您以某种方式发送关闭消息并同时发送pkill -2 my_awesome_service ,则可能会发生这种情况。 当我的持久层中存在一个死锁阻止关闭完成时,当我尝试再次发送SIGINT时,我实际上遇到了这个问题,而是服务被中止了! 对于我的需求,这仍然是可以接受的解决方案,但是我很想听听能解决或解决这个小问题的替代方案。

您可以从ShutDown()处理程序创建std :: function,然后在单独的线程(或线程池)中运行该函数。 这将允许将RPC处理与关闭逻辑的执行脱钩,并消除死锁。

暂无
暂无

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

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