Thanks for the detailed explanation.

If we have a polling thread that polls a CQ(calls next), it would mean that 
the polling thread would be doing the IO also right? I say this because if 
a client connection "writes" something, then that write will be picked up 
by the cq->next call of the polling thread (which internally looks for any 
work that needs to be done). Right?

On Tuesday, May 15, 2018 at 4:26:07 PM UTC-7, Christopher Warrington - MSFT 
> On Monday, May 14, 2018 at 8:51:29 AM UTC-7, wrote:
> > Had a question: How can we multipllex connections over handful of CQs?
> > Dont all the individual client (represented by its unique *tag*) have to
> > poll on the CQs in its own thread? Which means we need N number of 
> threads
> > to call 'next' on the CQ for N *tags* . Right?
> Individual client's are not represented by tags. The tag void* value is
> opaque to gRPC: your application gives it to gRPC when starting some
> asynchronous operation. When gRPC has completed the operation, the tag 
> value
> will end up coming out of a completion queue.
> In an application implementing an async gRPC server, you will need to call
> grpc::ServerBuilder::AddCompletionQueue at least once for each server that
> you have. (Remember that a server can host multiple services). You will
> typically have a dedicated poller thread for each of these CQs, but not one
> for each client that connects to the server.
> The tag value is *often* a pointer to a per-request data structure with
> application-specific state.
> Take a look at the C++ server async example [1], in particular the CallData
> class. This implementation of a service uses the address of its CallData
> instance as its tag value over multiple asynchronous operations (receiving 
> a
> request, sending a response, shutdown).
> CallData is implemented as a little state machine for the life-cycle of the
> server handling a request. For tracking specific clients, you could add a
> data member to CallData that is your business logic's representation of the
> client connection (e.g., something derived from
> ServerContext::auth_context() that is accessible one the request gets to 
> the
> PROCESS stage). Then, in the subsequent handling of the request you could
> use this data member in whatever logic you need to be client specific.
> In this scheme the CQ polling threads have zero knowledge of which client 
> is
> assocaited with the request. All the polling threads do is retrieve the 
> next
> tag from the completion queue, cast it to CallData (this assumes that you
> only ever enqueue CallData instances), and then tell that CallData instance
> to do what ever is next based on its knowledge of the current state of the
> request. CallData knows about the client identity, not the CQ.
> Hope this helps.
> [1]: 

You received this message because you are subscribed to the Google Groups 
"" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
To post to this group, send email to
Visit this group at
To view this discussion on the web visit
For more options, visit

Reply via email to