2017-12-05 28 views
0

クライアントをタイムアウトで動作させようとしています。このために、async_greeter_server.cppとasync_greeter_client.cppファイルを修正してそのコンセプトをテストしました。GRPC:クライアントサイドのタイムアウト

私はクライアント側で(クライアントコンテキスト上で)期限を設定しています。タイムアウトがある場合は、実際の(遅延した)応答をサーバから受信するまで待機します。変更は(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; 
    } 
} 

答えて

1

あなたがdeadline_exceededエラーを取得した後、あなたはタグを取得しようとするべきではありませんもう一度...タグはcqから一度だけ出ます。

関連する問題