Determining when to terminate a Jms Listener in SpringBoot when Queue has zero messages

Viewed 1580

What is the proper way, or the popular convention of deciding when to kill a listener? I can't seem to find a solid answer really anywhere. The queues I'm dealing with are IBM's MQ Queues, and I know typically that you would read until you receive a 2033 error code (my company does this in other applications) at which point you can wrap up, but for a SpringBoot Jms application what's the convention here? Once the queue is empty the listener just hangs until more messages come. I know HOW to kill it if I want, but how can I know WHEN?

As an example, here is a config for a sample project I threw together

@Configuration
@EnableTransactionManagement
public class JmsConfig {

@Bean
protected DefaultJmsListenerContainerFactory defaultJmsListenerContainerFactory() throws JMSException {
    DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
    factory.setConnectionFactory(mqQueueConnectionFactory());
    factory.setConcurrency("1");
    factory.setSessionTransacted(true);
    factory.setAutoStartup(true);
    factory.setSessionAcknowledgeMode(Session.CLIENT_ACKNOWLEDGE);
        factory.setErrorHandler(new JmsErrorHandler());
    return factory;
}

@Bean
public MQQueueConnectionFactory mqQueueConnectionFactory() {
    MQQueueConnectionFactory mqQueueConnectionFactory = new MQQueueConnectionFactory();
    mqQueueConnectionFactory.setHostName(host);
    try {
        mqQueueConnectionFactory.setTransportType(WMQConstants.WMQ_CM_CLIENT);
        mqQueueConnectionFactory.setCCSID(1208);
        mqQueueConnectionFactory.setChannel(channel);
        mqQueueConnectionFactory.setPort(port);
        mqQueueConnectionFactory.setQueueManager(queueManager);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return mqQueueConnectionFactory;
}

and here is the listener

@Component
public class Consumer {

    @JmsListener(id = "myQueue", destination = "queue")
    public void processMessage(Message message) throws MQException, IOException {
        try {
            String messageString = ((TextMessage) message).getText();
        } catch (JMSException e) {
            e.printStackTrace();
        }
    }
}

Besides the main class and the ErrorHandler, that is literally the whole sample project, and it will process messages. What I have done in other applications is instantiated a MQQueue given the queue values and just simple did queue.getCurrentDepth() and if I get a zero I then call on an instance of a ListenerContainerController that then calls stop from a JmsListenerEndpointRegistry given the queues id.

Does Spring have an easy way of communication "hey your queue is now empty" or is there a way to end it after x amount of time has passed?

1 Answers
Related