[rabbitmq-discuss] Channel thread safety in Java client

Steve Powell steve at rabbitmq.com
Tue Jul 5 12:06:57 BST 2011


Jiri,
The current implementation of the Java Client calls the Consumer interface on the same thread that the Channel work is done on.  This means that anything done in the Consumer callbacks is synchronised with all the other channel stuff going on, and could potentially block it.  There are notes on the api-guide pages to warn you about this.

The QueueingConsumer class basically makes sure that the Consumer callbacks do not cause any problems, putting the messages on the (dedicated) queue for any (usually the main) thread to access them.

This means that, even though there may be many consumers defined for a Channel, ownership of the Channel is not passed to the 'lib's connection thread', and you can continue to use the Channel from the main thread, or whatever thread you have allocated to run it from.  You can ack messages, and anything else you want, too.

The thing you shouldn't do is to call Channel methods (for the same channel) from more than one thread at a time.  This is because the threading model in the channel is 'challenged'.

We are currently working on the Consumer and Channel threading restrictions -- we want to run all the Consumer callbacks on a thread which is distinct from the Connection thread; and allow channels to be driven from multiple threads.  This would mean it is feasible to do most Channel operations from the Consumer callback itself, and from any other thread.

Incidentally, the way our changes are going at the moment, we will expose the execution thread pool for Consumer callbacks; and allow the user to have control over how many threads are allocated.  For example, it might be thought sensible to have a single thread per channel allocated for Consumer callbacks; but this could mean a large penalty for a large number of channels that may be doing very little work.  Instead we pass work to an Executor (managed so that all the work required by a single channel is serialised) which runs it on a thread from a pool.  The default Executor will use a (fixed) pool of 16 threads, but the interface will allow passing in any Executor implementation for the Connection.

I hope this helps.  Feedback is welcome.
Steve Powell  (a happy bunny)
----------some definitions from the SPD----------
Rigatoni n. A prime-ministerial grin.
Nigella n. The next bottle-size up from a Nebuchadnezzar.
Homily adv. Rather like a frenchman.

On 5 Jul 2011, at 09:42, Jiri Krutil wrote:

> Hi
> 
> I'm trying to understand the limitations of using a Channel in a
> multi-threaded application using the Java client. Sorry for this longish
> post...
> 
> I have read http://www.rabbitmq.com/api-guide.html#channel-threads but
> did not find any other, more detailed info.
> 
> I want to receive messages by subscription. I create a Channel and
> invoke basicConsume() on it, passing a QueueingConsumer.
> 
> The moment I call basicConsume(), I would imagine the Channel becomes
> "owned" by the client lib's connection thread, which feeds messages to
> QueueingConsumer.
> 
> My app is retrieving those messages from the QueueingConsumer in the
> main thread. I would like to know to which extent can I keep using the
> Channel passed to basicConsume() from the main thread.
> 
> I guess I can use it to ack messages, because ack would not work on
> another channel, correct? Can I also use the channel for other things,
> such as sending messages, using transactions, or starting another
> subscription?
> 
> JMS specs seem to be quite explicit on this. It says a session with an
> active subscription is owned by the connection thread and client app
> threads cannot use the session; they can only shut it down. That's why
> if I want multiple subscriptiopns on one session, I must set them all up
> before I call Connection.start(), which passes the session ownership to
> the client library. Afterwards I can no longer use the session from my
> threads except closing it.
> 
> Could you please elaborate on how exactly this works in the rabbit Java
> client?
> 
> Cheers
> Jiri
> 
> _______________________________________________
> rabbitmq-discuss mailing list
> rabbitmq-discuss at lists.rabbitmq.com
> https://lists.rabbitmq.com/cgi-bin/mailman/listinfo/rabbitmq-discuss

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rabbitmq.com/pipermail/rabbitmq-discuss/attachments/20110705/bb23716b/attachment.htm>


More information about the rabbitmq-discuss mailing list