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/8d389398-a003-4a55-b5cb-10f1e7c596a9%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.
