Use of subscriber consumer/handler channel after handler exits

9 views
Skip to first unread message

Dave Tenny

unread,
Aug 18, 2015, 12:30:14 PM8/18/15
to clojure-rabbitmq
I have a bit of code I was trying to fix and am looking for suggestions.

I have a subscribe {:auto-ack false} callback.  
It relays data to some queues for processing by other threads and returns.
It *also* passes the channel supplied to the callback to the data-structures enqueued.

When the callback data is processed later, asynchronously, it then acks the delivery tag on the channel
that was passed.  In other words, we've finally processed the data and ack it so it won't get re-delivered.

I was thinking this was bad for the following reasons
  1. We're using the channel passed to the callback after exit from the callback, which seems philosophically like some abuse of argument lifetime/extent, but which may in fact be fine.  Thoughts?
  2. We're using the channel asynchronously from another thread, and there is documentation that says channel operations are not all thread safe.
If #1 is acceptable, then I'll just wrap the channel usage in a (locking channel ....) form in the subscriber callback and callback-external asynchronous job processor doing the ack.


Thinking I needed to get rid of this asynchronous post-callback-lifetime use of the channel, I tried to ack the delivery tag on another channel used in the job processors for the callback data.

However it appears I can't ack a delivery tag on a distinct channel.

So my questions are basically
  1. Is it okay to use the subscriber callback channel as noted above?
  2. If it is not okay, how can one ack the message if doing asynchronous processing of the callback data?
I would think the callback-relays-work-to-work-queue strategy was good for callbacks to minimize the time spent in the channel subscription handler, but there this is this issue of how to ack it.


Michael Klishin

unread,
Aug 18, 2015, 1:17:40 PM8/18/15
to clojure-...@googlegroups.com
This is OK and a fairly common thing to do to pass channels around like this. Sharing channels when publishing is a no-no but due to the way consumer operations are dispatched in the underlying Java client, you have linear invocation of your callback.

What is not safe to do in your case is acing multiple messages at once (given that you pass deliveries to other threads, there will be a race condition between acks that may "overlap").

I recall a discussion of this on GitHub or rabbitmq-users where I explained this in a lot more detail. It was in the last few months.

MK
Reply all
Reply to author
Forward
0 new messages