2
votes

Say you have two Spring DefaultMessageListenerContainer listening on the same Queue (ActiveMQ for example), started in different VMs.

Send 1 000 000 messages in. After 500 000 of messages you want the rest of them to be handled by only one DefaultMessageListenerContainer, BUT without calling destroy or shutdown on the other (since you might needed it in the future - and must keep it manageable with JMX). The numbers are just for example here and should be ignored, could be replaced with - "after some time, after some messages, etc etc"

This sounds easy : call stop on the other DefaultMessageListenerContainer. Wrong, since messages are dispatched in a Round Robin fashion and they get registered with the Consumer.

Add transaction support and throw an error in the second DefaultMessageListenerContainer every time a messages comes in, it will be rolled-back and taken (round-robin) by the first one. Wrong again, the messages somehow registers with the consumer, not allowing the first DefaultMessageListenerContainer to take the message.

Even if you you shutdown/destroy the first DMLC - the message is NOT consumed by the other DMLC. They ARE Consumed only if I kill the JVM that the now shutdown/destroyed DMLC was running in.

My Solution so far : Because of the Session.AUTO_ACKNOWLEDGE messages are taken out from the Queue before they enter the onMessage method in the MessageListener of the DefaultMessageListenerContainer. In the MessageListener implement SessionAwareMessageListener and re-send a fresh copy of the message with the same payload. But this looks really dirty - I wish I could do it more in a "JMS"-ish way.

1
well, can I "un-register" the the messages from a particular Consumer?Eugene

1 Answers

1
votes

I don't fully grasp this part: "[the messages] get registered with the Consumer". Do you mean that ActiveMQ decides which listener to send it to? What exactly happens when you call "stop" on the DMLC?

I don't know if this is going to overcome your difficulties, but here's an idea: message selectors in DMLCs are live: you can change them any time and they are effective immediately. Perhaps try changing the message selector to "FALSE"; all cached messages should finish processing and new ones should stop coming.