Segfault in C++ Client async streaming

855 views
Skip to first unread message

Anirudh Kasturi

unread,
May 23, 2017, 8:29:36 PM5/23/17
to grpc.io
Hello folks,

I am trying a bidi async streaming service. 

I am streaming a request asynchronously from the client and expecting a stream of replies back from the server.  Can you please let me know if the way I am handling the client is right?

This is how my async streaming client in C++ looks like :

MuffinsResponse reply;


    // Context for the client. It could be used to convey extra information to

    // the server and/or tweak certain RPC behaviors.

    ClientContext context;


    // The producer-consumer queue we use to communicate asynchronously with the

    // gRPC runtime.

    CompletionQueue cq;


    // Storage for the status of the RPC upon completion.

    Status status;


    void* got_tag_read;

    void* got_tag_write;

    void* got_tag_finish;

    bool ok = false;


    // stub_->AsyncSendMuffins() performs the RPC call, returning an instance we

    // store in "rpc". Because we are using the asynchronous API, we need to

    // hold on to the "rpc" instance in order to get updates on the ongoing RPC.i


    std::unique_ptr<grpc::ClientAsyncReaderWriter<Muffins::MuffinsMessage, Muffins::MuffinsResponse>> stream(

        stub_->AsyncSendMuffins(&context, &cq, got_tag_read));


    // Request that, upon completion of the RPC, "reply" be updated with the

    // server's response; "status" with the indication of whether the operation

    // was successful. Tag the request with the integer 1.

   // rpc->Finish(&reply, &status, (void*)1);

    stream->Write(request, got_tag_write);

    std::string req = request.muffin_description();

    std::cout << "The req sent is " << req << std::endl;

    cq.Next(&got_tag_write, &ok);

        if (ok && got_tag_write == (void*)1) {

            printf("\n CLient sent the req");

            stream->Read(&reply, got_tag_read);

    }


    cq.Next(&got_tag_read, &ok);

        if (ok && got_tag_read == (void*)1) {

            stream->Finish(&status, got_tag_finish);

        }


    cq.Next(&got_tag_finish, &ok);

    GPR_ASSERT(ok);


    if (status.ok()) {

       return reply.Muffin_description();

    } else {

          return "RPC failed";

    }

  }

Vijay Pai

unread,
May 25, 2017, 12:23:06 PM5/25/17
to grpc.io
Hi there,
There are multiple issues here:

1. You need to first make sure that you actually initiated the call before doing Write on it. You should first do a cq.Next to make sure that your stream created by AsyncSendMuffins is actually ready to start posting events on.

2. You are reusing the same variable to catch the tag from cq.Next as you used to actually set the tag of the Write.  Note that in general tags passed on rpc creation, Read, Write, Finish, etc. should be something meaningful, but you're currently using the values of uninitialized variables.

3. In general, you should check the return value of Next since the received tag and ok are not relevant if Next returns false. It's probably ok in this case.
Reply all
Reply to author
Forward
0 new messages