Apr 5th, 2011, 04:17 PM
Listener exception = Channel.basicReject() = infinite redelivery?
On an exception in message processing, the exception is eventually caught and delegated to AbstractMessageListenerContainer.rollbackOnExcepti onIfNecessary. That method sends/commits a Basic.Reject with requeue = true if (!getAcknowledgeMode().isAutoAck() && !getAcknowledgeMode().isManual()). That means the message is sent back to the server at the back of the queue and is redelivered when it comes up again. Assuming it's a poison message, how would you break out of this infinite cycle?
Apr 6th, 2011, 02:32 AM
That's the way AMQP works, so we sort of have to go with the flow for the vanilla use case, and force the user to choose the correct retry and recovery behaviour. You can break the cycle by adding a retry interceptor to the listener execution (the message listener container has an advice-chain property, and you set it to the product of one of the *RetryOperationsInterceptorFactoryBeans). There are some unit tests that show how this can be done.
Apr 7th, 2011, 05:07 PM
That works great. What is this spring-retry module? I found it in the maven repos, but I can't find it on any of the Spring project pages. It's a very useful little thing. I thought of writing something like it myself just a few weeks ago. I'm using the stateful retry mechanism, and there's one peculiarity I'm seeing: when retries are exhausted and the invocation is handed off to the recoverer, the key is removed from the cache before the recoverer is invoked, and if the recoverer fails with an exception, the message gets requeued and redelivered/retried again, with the count starting at 0. In my case, I want the continued redelivery, but it just feels a little peculiar that the retry code essentially "forgets" that it has already retried this message before.