我试图让客户端超时工作。为此我修改了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;
}
}
答案 0 :(得分:1)
在您的客户端,在您遇到deadline_exceeded错误后,您不应该再尝试获取标记1 ...标记只会从cq中出来一次。