我正在尝试让客户端在超时的情况下工作。为此,我修改了 async_greeter_server.cpp 和 async_greeter_client.cpp 文件来测试这个概念。
我在客户端(在客户端上下文上)设置截止日期,如果超时,我会等待,直到收到来自服务器的实际(延迟)响应。以下是更改(在 Finish() 调用之后)。
同样,服务器端在延迟一段时间后发送响应,以在客户端产生超时。
由于 CallData cq_.Next() 循环“GPR_ASSERT(ok)”中的断言,服务器端崩溃。
客户端在添加的超时代码中永远等待实际响应。
知道这个程序有什么问题吗?
greeter_async_client.cc
std::string SayHello(const std::string& user)
{
// Data we are sending to the server.
HelloRequest request;
request.set_name(user);
HelloReply reply;
ClientContext context;
CompletionQueue cq;
Status status;
std::chrono::system_clock::time_point deadline = std::chrono::system_clock::now() + std::chrono::seconds(10);
context.set_deadline(deadline);
std::unique_ptr<ClientAsyncResponseReader<HelloReply> > rpc(stub_->AsyncSayHello(&context, request, &cq));
rpc->Finish(&reply, &status, (void*)1);
void* got_tag;
bool ok = false;
GPR_ASSERT(cq.Next(&got_tag, &ok));
GPR_ASSERT(got_tag == (void*)1);
GPR_ASSERT(ok);
// -------------- HANDLE TIMEOUT ------------------------------------------
// If timeout error wait for the actual reply
if (status.error_code() == grpc::StatusCode::DEADLINE_EXCEEDED)
{
std::cout << "Timeout exceeded .., waiting for the next event "<< status.error_message() << std::endl;
GPR_ASSERT(cq.Next(&got_tag, &ok));
GPR_ASSERT(got_tag == (void *) 1);
GPR_ASSERT(ok);
}
// Act upon the status of the actual RPC.
if (status.ok())
{
return reply.message();
}
else
{
return "RPC failed";
}
}
greeter_async_server.cc
void Proceed()
{
if (status_ == CREATE)
{
status_ = PROCESS;
service_->RequestSayHello(&ctx_, &request_, &responder_, cq_, cq_,this);
}
else if (status_ == PROCESS)
{
new CallData(service_, cq_);
std::string prefix("Hello ");
reply_.set_message(prefix + request_.name());
std::cout << "Sleeping for 20 seconds .... \n";
std::this_thread::sleep_for(std::chrono::seconds(20));
std::cout << "Out of sleep ..... \n";
status_ = FINISH;
responder_.Finish(reply_, Status::OK, this);
std::cout <<" Reply sent - Finish ....... \n";
}
else
{
GPR_ASSERT(status_ == FINISH);
// Once in the FINISH state, deallocate ourselves (CallData).
delete this;
}
}