In the Java client guide, it states that channels should not be used
by more than one thread simultaneously. How can I guarantee this when
I have a consumer on a channel? I'd like to have a consumer that puts
messages into a local java BlockingQueue, and then once the messages
are handled by other threads, they are acked on the channel that they
came from. I can easily ensure that none of my acks coincide with
each other, but how can I ensure that the Connection thread isn't
using the Channel while I'm trying to do an ack?

Search Discussions

  • Ben Hood at Jul 4, 2009 at 8:33 am
    Tsuraan,

    On Fri, Jul 3, 2009 at 9:34 PM, tsuraanwrote:
    In the Java client guide, it states that channels should not be used
    by more than one thread simultaneously. ?How can I guarantee this when
    I have a consumer on a channel? ?I'd like to have a consumer that puts
    messages into a local java BlockingQueue, and then once the messages
    are handled by other threads, they are acked on the channel that they
    came from. ?I can easily ensure that none of my acks coincide with
    each other, but how can I ensure that the Connection thread isn't
    using the Channel while I'm trying to do an ack?
    The race condition can occur within a single channel is when message
    sending gets interleaved and hence sends jumbled frames to the broker.
    The connection thread OTOH is not using the channel to transmit
    messages, rather, it is the channel that is using the connection to
    transmit messages, so I don't think you'll run into an issue if you
    are, as I assume, maintaining a mutex around the shared channel
    instance.

    BTW (I know that app might not permit this), but have you considered
    using a channel per consumer?

    HTH,

    Ben
  • Tsuraan at Jul 5, 2009 at 3:54 am

    BTW (I know that app might not permit this), but have you considered
    using a channel per consumer?
    I could do that. I'd just have to keep track of which channel each
    message came from. Either way, I shouldn't be getting contention
    between the Connection thread that's doing the message receiving and
    the (properly synchronized) threads that are doing the acks and
    publishes, right?
  • Ben Hood at Jul 5, 2009 at 7:45 pm
    Tsuraan,

    On Sun, Jul 5, 2009 at 4:54 AM, tsuraanwrote:
    BTW (I know that app might not permit this), but have you considered
    using a channel per consumer?
    I could do that. ?I'd just have to keep track of which channel each
    message came from.
    Why is this?
    Either way, I shouldn't be getting contention
    between the Connection thread that's doing the message receiving and
    the (properly synchronized) threads that are doing the acks and
    publishes, right?
    Yes, that's right.

    Ben
  • Tsuraan at Jul 6, 2009 at 3:41 pm

    I could do that. I'd just have to keep track of which channel each
    message came from.
    Why is this?
    My current app needs to process messages in batches of 4, and it's
    getting messages from multiple queues (although I think that might be
    unnecessary). Once the messages are batched together into a group of
    4, they are put into a BlockingQueue, where another thread processes
    the batch and then acks the messages as being done. So, my basic
    design is to have Consumers on each queue (each batch of work has only
    messages from a single queue) aggregating messages and putting them
    into the BlockingQueue once enough have been received.

    If I only have one channel that's shared everywhere, I can just give
    that channel to the thread that's doing the batch processing and it
    can ack the messages on the only channel that there is. If there are
    multiple channels, then each message must be acked on the channel that
    it was received on, so the message, the dtag, and the channel must all
    be kept track of. It's not a difficult thing, but a single shared
    channel just seems cleaner somehow.

    All this might be obsolete, since I may be able to just use a single
    queue for all of these messages. The messages all have the same
    structure, and they're all processed by the same program, but they are
    messages about different events, so I have them in different queues.
    I might change that, since it's starting to look like excessive
    complication now that I look at it carefully.
  • Tony Garnock-Jones at Jul 17, 2009 at 1:18 pm

    tsuraan wrote:
    I could do that. I'd just have to keep track of which channel each
    message came from.
    FYI, any subclass of DefaultConsumer has getChannel(), which returns the
    channel that the Consumer is associated with. So, for example, given a
    QueueingConsumer "qc":

    while (true) {
    QueueingConsumer.Delivery delivery = qc.nextDelivery();
    System.out.println("Message: " + new String(delivery.getBody()));
    qc.getChannel().basicAck(delivery.getEnvelope().getDeliveryTag(),
    false);
    }

    Regards,
    Tony
    --
    [][][] Tony Garnock-Jones | Mob: +44 (0)7905 974 211
    [][] LShift Ltd | Tel: +44 (0)20 7729 7060
    [] [] http://www.lshift.net/ | Email: tonyg at lshift.net

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouprabbitmq-discuss @
categoriesrabbitmq
postedJul 3, '09 at 8:34p
activeJul 17, '09 at 1:18p
posts6
users3
websiterabbitmq.com
irc#rabbitmq

People

Translate

site design / logo © 2022 Grokbase