There are three main threadpools that gRPC Java uses in Server mode: * Boss Event Loop Group (a.k.a. bossEventLoopGroup() ) * Worker Event Loop Group ( a.k.a. workerEventLoopGroup() ) * Application Executor (a.k.a. executor() )
The Boss group can be the same as the worker group. It's purpose is to accept calls from the network, and create Netty channels (not gRPC Channels) to handle the socket. Effectively, this is the thread pool that calls listen() and accept(). Once the Netty channel has been created it gets passes to the Worker Event Loop Group. This is the threadpool dedicating to doing socket read() and write() calls. This is often called the "network thread". In addition to doing the direct reads and writes, it can also do small amounts of processing, such as turn a collection of bytes into an HTTP/2 request, or do SSL / TLS encryption. The main thing to know about this group is that it must never block. That is, it cannot call wait(), or sleep(), or await results from a Future, or things like that. The reason is that doing this prevents the worker thread (the "event loop") from servicing other requests. The last thread group is the application executor, also called the "app thread". This is where the gRPC stubs do their main work. It is for handling the callbacks that bubble up from the network thread. For example, when a packet comes in, the worker thread decrypts it, decodes the HTTP/2 code, and then notifies the app thread that data has arrived. It immediately goes back to doing other network work. The App thread notices that there is data available, and converts the data into (usually) a Protobuf, and then invokes your stub. Note that the Application executor could have no threads at all. This would make the network thread immediately do the work of handling the request. On the builder this is the directExecutor() function. The reason for using this is that it saves a thread hop from worker event loop to the app thread, or about 15 microseconds. In very latency sensitive environments this is a good idea. However, it makes it very easy to accidentally do blocking work, which is deadlock prone. It is rarely correct to do. As for usages: Most people should use either reuse the same boss event loop group as the worker group. Barring this, the boss eventloop group should be a single thread, since it does very little work. For the app thread, users should provide a fixed size thread pool. By default, we use an unbounded cached threadpool, but this is just for safety. It is not the most efficient, and can be dangerous in some circumstances. It just happens to be the safest default, given no other information. On Tuesday, October 3, 2017 at 12:43:30 PM UTC-7, Pierre wrote: > > Hello, > > What is the difference between setting an executor(Threadpool) and setting > a workerEventLoopGroup(EventLoopThreadPool) on NettyServerBuilder. > > > If I understand, all the IO operations (accept connexions, read/send > packet...) are done by the bossEventLoopGroup thread. > > > But what about the RPC call themself ? Are they done by executor > threadpool or workerEventLoop threads ? > -- 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/d534e68e-857a-47fa-8ad3-d68db9871e13%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.
