Uploaded image for project: 'JBoss Enterprise Application Platform'
  1. JBoss Enterprise Application Platform
  2. JBEAP-3273

Standalone JMS consumer does not failover due to wait in LargeMessageControllerImpl.waitCompletion()

    XMLWordPrintable

Details

    • Bug
    • Resolution: Done
    • Blocker
    • 7.0.0.ER7
    • 7.0.0.ER5, 7.0.0.ER6
    • ActiveMQ
    • None

    Description

      Standalone JMS consumer does not failover in situation when it tries to receive large message during failover.

      Consumer hangs after failover waiting in:

      Stack trace of thread: Thread[Thread-16,5,main]
      ---java.lang.Object.wait(Native Method)
      ---org.apache.activemq.artemis.core.client.impl.LargeMessageControllerImpl.waitCompletion(LargeMessageControllerImpl.java:302)
      ---org.apache.activemq.artemis.core.client.impl.LargeMessageControllerImpl.saveBuffer(LargeMessageControllerImpl.java:276)
      ---org.apache.activemq.artemis.core.client.impl.ClientLargeMessageImpl.checkBuffer(ClientLargeMessageImpl.java:161)
      ---org.apache.activemq.artemis.core.client.impl.ClientLargeMessageImpl.checkCompletion(ClientLargeMessageImpl.java:82)
      ---org.apache.activemq.artemis.jms.client.ActiveMQMessage.doBeforeReceive(ActiveMQMessage.java:746)
      ---org.apache.activemq.artemis.jms.client.ActiveMQObjectMessage.doBeforeReceive(ActiveMQObjectMessage.java:92)
      ---org.apache.activemq.artemis.jms.client.ActiveMQMessageConsumer.getMessage(ActiveMQMessageConsumer.java:204)
      ---org.apache.activemq.artemis.jms.client.ActiveMQMessageConsumer.receive(ActiveMQMessageConsumer.java:119)
      ---org.jboss.qa.hornetq.apps.clients.ReceiverTransAck.receiveMessage(ReceiverTransAck.java:401)
      ---org.jboss.qa.hornetq.apps.clients.ReceiverTransAck.run(ReceiverTransAck.java:172)
      

      By reviewing the code LargeMessageControllerImpl there is problem with never ending while cycle in:

      public synchronized boolean waitCompletion(final long timeWait) throws ActiveMQException {
            if (outStream == null) {
               // There is no stream.. it will never achieve the end of streaming
               return false;
            }
      
            long timeOut;
      
            // If timeWait = 0, we will use the readTimeout
            // And we will check if no packets have arrived within readTimeout milliseconds
            if (timeWait != 0) {
               timeOut = System.currentTimeMillis() + timeWait;
            }
            else {
               timeOut = System.currentTimeMillis() + readTimeout;
            }
      
            while (!streamEnded && handledException == null) {
               try {
                  this.wait(timeWait == 0 ? readTimeout : timeWait);
               }
               catch (InterruptedException e) {
                  throw new ActiveMQInterruptedException(e);
               }
      
               if (!streamEnded && handledException == null) {
                  if (timeWait != 0 && System.currentTimeMillis() > timeOut) {
                     throw ActiveMQClientMessageBundle.BUNDLE.timeoutOnLargeMessage();
                  }
                  else if (System.currentTimeMillis() > timeOut && !packetAdded) {
                     throw ActiveMQClientMessageBundle.BUNDLE.timeoutOnLargeMessage();
                  }
               }
            }
      

      it seems that the last else if statement else if (System.currentTimeMillis() > timeOut && !packetAdded) is never true. Variable packetAdded must have to be set to true.

      Attachments

        Issue Links

          Activity

            People

              rh-ee-ataylor Andy Taylor
              mnovak1@redhat.com Miroslav Novak
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: