Hi, Thank you for the detailed information. Can you explain how a message is passed through the thread pools in the opposite direction (when StreamObserver#onNext(Message) is called)?
Suppose we have a publish/subscribe application. A client subscribes for a topic. On the server the StreamObserver instance is cached, thus for each topic there are multiple StreamObserver instances. When an update for a topic arrives, the associated StreamObserver instances are iterated and for each of them #onNext(message) is called. Does #onNext(Message) blocks until the message is transferred to the client or it is queue somewhere in the network thread? Can a slower connection to a specific client influence the communication to other clients if the StreamObservers are iterated sequentially. If this is the case, then maybe a separate thread pool should be used, where each thread is associated with a single StreamObserver and calls its #onNext(Message) method? Thanks, Stefan вторник, 3 октомври 2017 г., 23:56:11 UTC+3, Carl Mastrangelo написа: > > 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 grpc-io+unsubscr...@googlegroups.com. To post to this group, send email to grpc-io@googlegroups.com. 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/cbe72e39-3bf8-4d5f-a765-de027b2bc02f%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.