3

I can't find a grpc example showing how to use the ClientAsyncReaderWriter (is there one?). I tried something on my own, but am having trouble with the reference counts. My question comes from tracing through the code.

struct grpc_call has a member of type gpr_refcount called ext_ref. The ClientContext C++ object wraps the grpc_call, and holds onto it in a member grpc_call *call_;. Only when ext_ref is 0, can this grpc_call pointer be deleted.

When I use grpc synchronously with ClientReader:

  • In its implementation it uses CreateCall() and PerformOps() to add to ext_ref (ext_ref == 2).
  • Then I use Pluck() which subtracts from ext_ref so that (ext_ref == 1).
  • The last use ~ClientContext() subtracts from ext_ref, so that ext_ref == 0 and deletes the call

But when I use grpc asynchronously with ClientAsyncReaderWriter:

  • First use asyncXXX(), this API use CreateCall() and register Write() (ext_ref == 2).
  • Then it uses AsyncNext() to get tag...which must use a write or read operator.
  • So ext_ref > 1 forever, unless got_event you don't handle.

I'm calling it like this:

struct Notice
{
    std::unique_ptr<
        grpc::ClientAsyncReaderWriter<ObserveNoticRequest, EventNotice>
    >                          _rw;
    ClientContext              _context;
    EventNotice                _rsp;
}

Register Thread

CompletionQueue *cq = new CompletionQueue;
Notice *notice = new Notice;
notice->rw = stub->AsyncobserverNotice(&context, cq, notice); 

// here context.call_.ext_ref is 2

Get CompletionQueue Event Thread

void *tag = NULL;
bool ok = false;
CompletionQueue::NextStatus got = CompletionQueue::NextStatus::TIMEOUT;
gpr_timespec deadline;
deadline.clock_type = GPR_TIMESPAN;
deadline.tv_sec = 0;
deadline.tv_nsec = 10000000;

got = cq->AsyncNext<gpr_timespec>(&tag, &ok, deadline);

if (GOT_EVENT == got) {
    if (tag != NULL) {
        Notice *notice = (Notice *)tag;
        notice->_rw->Read(&_rsp, notice);

        // here context.call_.ext_ref is 2.
        // now I want to stop this CompletionQueue. 

        delete notice;

        // use ~ClientContext(), ext_ref change to 1
        // but only ext_ref == 0, call_ be deleted
    }
}
ezLeo
  • 31
  • 1
  • 3
  • thank you reply me , i'm already update code – ezLeo Oct 16 '17 at 12:47
  • There is an [asynchronous example here](https://grpc.io/docs/tutorials/async/helloasync-cpp.html). Without really digging in to understand the specifics of what you're asking, do you feel the problem you are facing exists in that example? How is what you are doing different? – HostileFork says dont trust SE Oct 16 '17 at 14:07
  • Thank you for your continuing concerns for me. but I'm not reslove this problem. I compile example and find it use class ClientAsyncResponseReader, when use AsyncSayHello register call, the key is that ClientAsyncResponseReader use SneakyCallOpSet for init. than use Next() , it call FinalizeResult() and return false. so UNREF ext_ref operate twice. but I use ClientAsyncReaderWriter transport stream grpc. and it all op use CallOpSet. so can you tell me how to use Client AsyncReadWrite? – ezLeo Oct 17 '17 at 02:02
  • I was just trying to help you along, while I know C++ I know nothing about this. It seemed you were looking at a detailed question and had an (English) language barrier, and you were a new StackOverflow user, so I wanted to give you a positive impression of the people here. But maybe the thing to do, is to keep editing until you're sure you've expressed a point of misunderstanding, and ask the developers to come here and respond. StackOverflow is a good site but can only help you if you follow the protocol. – HostileFork says dont trust SE Oct 17 '17 at 08:17
  • Really appreciate your geneous help. thank you give so much advise. I want to know how to use ClientAsyncReaderWriter. – ezLeo Oct 17 '17 at 10:20
  • Since this is maybe a niche question you might search GitHub for ClientAsyncReaderWriter, and use the ["blame" log](https://github.com/grpc/grpc/blame/441a14fd43f6033714a5022667e1591967947bb5/test/cpp/qps/client_async.cc#L314) to find the GitHub accounts for people who work on that code, and see if they publish contact information, to forward this to them. If you think it's potentially their bug with a *complete* compilable example, you might raise a GitHub issue. You might also look at the [tag:grpc] tag and see if there's anything you know to help people with by answering. :-) – HostileFork says dont trust SE Oct 17 '17 at 21:59

1 Answers1

2

Take a look at this file, client_async.cc, for good use of the ClientAsyncReaderWriter. If you still have confusion, please create a very clean reproduction of the issue, and we will look into it further.

Noah Eisen
  • 268
  • 1
  • 6