I can answer the Java client questions.
>
> What is the difference, and the relationship, between CachingConnectionFactory, PublisherConnectionFactory and RabbitConnectionFactory?
> Why do we need so many different executor pools? What is the difference between them all?
There are different executor services for different purposes. The
Javadoc [1] documents their differences, but here is some additional
information:
- sharedExecutor: used to dispatch messages in consumers.
Connections created by the same connection factory will share it.
- shutdownExecutor: it is used in the AMQP closing sequence, see [2]
[3] for more details.
- heartbeat executor: the executor used by connections to schedule
heartbeat frames.
- topology recovery executor: to parallelize topology recovery (the
default is to not parallelize). This was a community contribution, see
[4].
- nioExecutor: the executor used for NIO loop (reading/writing) (the
thread factory is used if it is not set)
- nio shutdown executor: for internals (avoiding a deadlock when
closing the connection under specific circumstances) (the thread
factory is used if it is not set)
- params(consumerWorkServiceExecutor): this is the sharedExecutor.
I'm not the original author of this code, I don't know why this method
is public, maybe for testing, it's not meant to be used by application
developers.
All these settings have reasonable defaults, that work for most cases.
Developers can tune the client threading behavior by setting their own
executors. See [5] and [6] to see how our performance testing tool
makes use of these parameters to create thousands of connections with
a limited number of threads.
> Do these classes share their thread pools / executors?
> When a connection is opened, to which thread pool is it allocated?
If using blocking IO (the default), the thread factory is used to
create the thread that will read frames. If using NIO, the connection
IO operations happen in a thread allocated by the nioExecutor if it is
set or by the thread factory if the executor is not set.
> When a channel is opened, to which thread pool is it allocated?
Channels are not allocated to any pool. Inbound messages for a
channel's consumers are dispatched in the shared executor.
> Do publish and consume operations use different thread pools?
When using IO, the socket write from Channel#basicPublish happens in
the caller's thread, with NIO, it happens in the thread used for the
connection's IO.
Inbound messages are dispatched in the shared executors (for
asynchronous consumers registered with basicConsume, not basicGet).
> How do I pass in my own executor implementation or otherwise configure, each of the aformentioned executors?
When using the Java client directly, they can be passed in as
parameters of the setters or other methods.
> Would it be a good idea to merge/unify some or all of the executors?
>
You can use the same executor instance in different places, but you'll
have to make sure they're sized correctly depending on the connections
and applications needs to avoid too much competition. Otherwise
there's no real reason to merge the executors, because they all serve
different purposes.
[1]
https://rabbitmq.github.io/rabbitmq-java-client/api/current/
[2]
https://github.com/rabbitmq/rabbitmq-java-client/issues/91
[3]
https://github.com/rabbitmq/rabbitmq-java-client/issues/194
[4]
https://github.com/rabbitmq/rabbitmq-java-client/pull/370
[5]
https://rabbitmq.github.io/rabbitmq-perf-test/stable/htmlsingle/#simulating-high-loads
[6]
https://rabbitmq.github.io/rabbitmq-perf-test/stable/htmlsingle/#workloads-with-a-large-number-of-clients