JmsTemplate с RECEIVE_TIMEOUT_NO_WAIT не извлекает сообщения из очереди JMS

Учитывая, что у меня есть очередь ActiveMQ, в которой уже присутствует много сообщений.

Когда я устанавливаю тайм-аут приема JmsTemplate на RECEIVE_TIMEOUT_NO_WAIT, который равен -1:

jmsTemplate.setReceiveTimeout(JmsTemplate.RECEIVE_TIMEOUT_NO_WAIT); 

и попробуйте получить одно из этих сообщений:

Message msg = jmsTemplate.receive(queueName);

тогда msg равно null, но это не должно соответствовать JavaDoc:

/**
 * Timeout value indicating that a receive operation should
 * check if a message is immediately available without blocking.
 */
public static final long RECEIVE_TIMEOUT_NO_WAIT = -1;

Почему это?

Когда я делаю:

jmsTemplate.setReceiveTimeout(1000);

затем сообщения извлекаются.


person Patrik Mihalčin    schedule 20.06.2018    source источник
comment
Я подозреваю, что последующие вызовы без ожидания будут работать (после первого с ожиданием). Я только что посмотрел на метод ActiveMQMessageConsumer.receiveNoWait(), и он отправляет запрос на извлечение, но, конечно, этот запрос не выполняется сразу, поэтому сообщений пока нет. В конце концов, эти сообщения придут, и опция «не ждать» должна работать.   -  person Gary Russell    schedule 20.06.2018
comment
Это кажется странным ... в чем преимущество перенастройки JmsTemplate с некоторого тайм-аута на RECEIVE_TIMEOUT_NO_WAIT .. Я могу просто продолжать использовать исходный тайм-аут.. Я не вижу для этого никакого варианта использования :)   -  person Patrik Mihalčin    schedule 21.06.2018


Ответы (1)


Он не имеет абсолютно никакого отношения к JmsTemplate, поскольку он просто делегирует базовый объект JMS Consumer:

protected Message receiveFromConsumer(MessageConsumer consumer, long timeout) throws JMSException {
    if (timeout > 0) {
        return consumer.receive(timeout);
    }
    else if (timeout < 0) {
        return consumer.receiveNoWait();
    }
    else {
        return consumer.receive();
    }
}

Я бы сказал, что он работает именно так, как задумали разработчики JMS:

/** Receives the next message if one is immediately available.
  *
  * @return the next message produced for this message consumer, or 
  * null if one is not available
  *  
  * @exception JMSException if the JMS provider fails to receive the next
  *                         message due to some internal error.
  */ 

Message receiveNoWait() throws JMSException;

Другими словами, это для случаев использования, когда вы абсолютно не хотите блокировать поток на какое-либо время, если в настоящее время нет сообщения, которое уже было отправлено потребителю брокером - даже не дожидаясь сообщения. сетевой ввод-вывод для завершения, именно так ActiveMQ реализовал его - инициирует ввод-вывод, но возвращает нуль, если этот ввод-вывод не завершается немедленно (что, скорее всего, имеет место, если задействована сеть).

person Gary Russell    schedule 21.06.2018