[rabbitmq-discuss] Channel thread safety in Java client
Jiri Krutil
jiri at krutil.com
Thu Jul 7 17:16:06 BST 2011
Steve,
Can you please clarify your post a bit for me:
You say that a client application may continue to use a Channel from
its main thread even if the RabbitMQ client library uses the same
Channel for async receiving.
How is the use of a Channel from the RabbitMQ client library
connection thread sychronized with the use of the same Channel from
the client application thread?
Is such concurrent Channel access different from a situation when two
client application threads access the same Channel concurrently?
Cheers
Jiri
> 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
>
>
More information about the rabbitmq-discuss
mailing list