Is BlockOnAcknowledge supposed to be honored by ClientConsumerImpl?
noer2b May 21, 2010 2:30 AMI'm using the trunk and updated this evening. I'm only using Core features.
It looks to me like calling setBlockOnAcknowledge(true) on my ClientSessionFactory is not sufficient to block ClientMessage.acknowledge while the ack is processed. Shouldn't it?
The Javadoc for the session factory says that the consumers created from the factory will block on acknowledge. Stepping thru the code in the debugger shows me that ClientMessageImpl immediately delegates to the ClientConsumerImp. However, that class doesn't appear to know that the session is set to block on ack. It updates ackBytes and then checkes to see if ackBytes is greater than ackBatchSize. If not, it just remembers the message in lastAckedMessage.
I have a couple of work arounds. One of the simplest is to just close the ClientConsumer after each ack. That goes against the best practice of reusing the ClientConsumer. Another idea would be to set the ackBatchSize pretty small.
I do see the ClientSessionImpl checking blockOnAcknowledge and sending immediately (and waiting) if it got the ack at all. The buffering in the consumer seems to be the one not honoring the configuration.
I'm attaching a bit of code that can be used to see the issue. It's a derivitive of the core embedded server example as that allows for it to be self contained in one class. My 'real' configuration is multiple processes and multiple config files but the effect is exactly the same.
I haven't reduced it to a unit test. To see it fail wth my exmple code, you need to kill the VM after calling acknowlege and before calling consumer.close() since this will flush the acks. Having killed it as suggested, run it again and don't kill anything. This time two message will be found on the queue (the one from run #1 and a second from run #2). If it's run a 3rd time (and the second is not killed midstream) there will only be 1 message received and consumed.
I put a multi-line comment at the point where the code should exit ungracefully. Look for "kill the JVM at this point".
Please don't let my blunt method to reproduce this be a distraction. I'm not proposing that would happen (much) in a production environment. I was more trying to explore the behavior of block on ack as there are parts of my message flow that I expect to need the blocking behavior.
Thanks!
-
HQBlockOnAckIssue.java.zip 1.7 KB