gRPC:RPC处理程序如何正确检测“服务器”是否为“ Shutdown()”?

时间:2018-07-05 17:08:32

标签: c++ qt grpc

当前,我正在使用一种怪诞的方式-全局变量-使RPC处理程序能够检测到Server被(即将被称为)Shutdown()

bool g_ServerIsNotDead = true;   // Hack!

Status StreamServiceImpl::GetCurrentTemperature(ServerContext *context_,
                                                const UpdateInterval *request_,
                                                ServerWriter<Temperature> *stream_)
{
  auto currentTemp = 100.0f;
  while(g_ServerIsNotDead)   // Hack!!!
  {
    qDebug() << QThread::currentThreadId() << currentTemp << "farenheit.";

    Temperature message;
    message.set_temperature(currentTemp);
    stream_->Write(message);

    QThread::sleep(2);

    currentTemp += 1.0f;
  }

  return Status::OK;
}

void insideSomeFunction() {
   // Testing shutdown 5 seconds later
   QTimer::singleShot(std::chrono::seconds(5), this, [=]() {
      qDebug() << "Shuting down!";

      g_ServerIsNotDead = false;   // Hack!!

      this->server->Shutdown();    // This method actually blocks until all RPC handlers have exited, believe it or not!

      emit shutdown();

      qDebug() << "All dead.";
  });
}

参考:https://github.com/C0D1UM/grpc-qt-example/blob/master/rpc_server/hellostream_server.cpp

如果我能以某种方式检查ServerShutdown()的{​​{1}},那真是太好了,但是我没有找到实现此目标的任何相关方法。

如果有人可以提出一种完全消除while循环的方法(?),那就更好了。我正在使用Qt,所以一切都是事件驱动的。

2 个答案:

答案 0 :(得分:5)

因此,我认为有必要弄清楚Shutdown的作用。这里有一个detailed comment about this,但基本上,服务器Shutdown不会失败,取消或终止您现有的正在进行的调用(除非您使用Duration参数和gRPC C ++异步API)。

相反,它将停止侦听新连接,停止接受新呼叫,使请求但尚未接受的呼叫失败。如果您想失败或在关机时终止调用,则可以按照上面的操作在应用程序级代码处完成。

我只建议您不要使用全局变量,而应该使用StreamServiceImpl类的成员函数,以便可以选择支持在同一进程中运行的多个服务。

答案 1 :(得分:0)

我们可以使用 ServerContext::IsCancelled 作为流式 API 中的中断/终止条件。我将 GetCurrentTemperature(...) 更改如下(只是将 g_ServerIsNotDead 替换为 !context_->IsCancelled())并且它起作用了:

Status StreamServiceImpl::GetCurrentTemperature(ServerContext *context_,
                                                const UpdateInterval *request_,
                                                ServerWriter<Temperature> *stream_) {
  auto currentTemp = 100.0f;
  while(!context_->IsCancelled) {
    qDebug() << QThread::currentThreadId() << currentTemp << "farenheit.";
    Temperature message;
    message.set_temperature(currentTemp);
    stream_->Write(message);
    QThread::sleep(2);
    currentTemp += 1.0f;
  }
  return Status::OK;
}