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 wrote: > > On Monday, May 14, 2018 at 8:51:29 AM UTC-7, [email protected] 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]: > https://github.com/grpc/grpc/blob/5fc081acd101d345786ebb072a434f6efacfe0a1/examples/cpp/helloworld/greeter_async_server.cc#L70 > -- You received this message because you are subscribed to the Google Groups "grpc.io" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at https://groups.google.com/group/grpc-io. To view this discussion on the web visit https://groups.google.com/d/msgid/grpc-io/bcac4cba-029e-4d7d-b3bd-d12ab1466d62%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.
