I've been working through a problem regarding temporary queues, ActiveMQ failover, and Apache Camel. The scenario is:
1. Two brokers started in a network of brokers 2. Camel producers and consumers connect to a random broker creating temporary reply queues 3. I take one broker offline (clean shutdown) 4. The ActiveMQ failover protocol kicks in and any consumers or producers silently switch to the other broker 5. The next request/reply message sent causes the consumer on the other end to get a "Cannot publish to a deleted Destination: temp-queue:..." error. I believe I understand what is happening and I'm familiar with similar issues on the Camel mailing list (for example, CAMEL-3193). At step 3, ActiveMQ removes all the temporary queues created on that broker from the network of brokers. Step 4 allows all the connections to continue uninterrupted on the clients. Because the clients don't see a connection failure, Spring's DefaultMessageListenerContainer used in the TemporaryQueueReplyManager doesn't notice that the temporary queue it is listening on is now gone. I did some testing and it appears that if the DefaultMessageListenerContainer attempts to recreate the consumer, it will notice that the queue is gone and recover appropriately. But the TemporaryQueueReplyManager leaves the default cacheLevel on the listener container which will default to CACHE_AUTO (i.e. CACHE_CONSUMER) so the consumer is never recreated. Because the single reply manager is used for the life of the endpoint, all request/reply messages are broken until the app is bounced. I think the way to fix this would be to allow an easy way to set the cacheLevel/cacheLevelName on the listener container used in the TemporaryQueueReplyManager and/or set the maxMessagesPerTask so the consumer is recreated with each poll task in the listener container. Around line 111 of TemporaryQueueReplyManager it does use some of the endpoint configuration when configuring the listener, but it doesn't use cacheLevel or maxMessagesPerTask. These values are set on a JmsConsumer's listener container via JmsConfigured.configureDefaultMessageListenerContainer(...) so it seems reasonable that they should be set for the reply manager's listener container. I'd prefer not to have to use permanent reply queues to reduce my queue management and route configuration. I couldn't see any easy way to get a subclass of the TemporaryQueueReplyManager injected into the JmsEndpoint in order to set these properties on the listener container myself. Any suggestions on how I could work around this or is this an issue that could be fixed in the code base? -mike [cid:[email protected]] | Mike Pilone | Software Architect, Distribution | [email protected]<mailto:[email protected]> | o: 202-513-2679 m: 703-969-7493
