10 Replies Latest reply on May 9, 2013 11:22 AM by clebert.suconic Branched from an earlier discussion.

    Should you overuse receiveNoWait

    newway

      Thanks for your help.

       

      regarding the question - why are you using receiveNoWait?

       

      My first response would have been that I picked up work done by someone else and I didn't find a reason to question it.

      and than my second response would be - why not using receiveNoWait? are there some best practices against this method?

        • 1. Re: Should you overuse receiveNoWait
          clebert.suconic

          overusing receiveNoWait has several implications.. and that's for any messaging provider.

           

           

          I -  it will usually introduce latency. It is common people using for this case: (which was very similar to your case).

           

           

          while (true)

          {

              message = consumer.receiveNoWait();

              if (message == null) Thread.currentThread().sleep(5000);

          }

           

           

          instead you could just:

           

          while (true)

          {

             message = consumer.receive(5000);

              if (message != null)

              {

                  // process...

              }

          }

           

           

           

          II - it will burn cpu on cases like this (say if you wanted to avoid the latency). It will make the server to do a roundtrip for every call, what will make the server send you thousands of messages per second saying... I'm empty

           

          while (true)

          {

             message = consumer.receiveNoWait();

             if (message != null)

             {

                 // process...

             }

          }

           

           

           

           

           

           

           

          The only case where receiveNoWait is advisable (AFAIK) is when you want to empt a queue and give up as soon as possible

           

           

          while ((message = consumer.receiveNoWait()) != null)

          {

          }

           

          ... and you're done... no loops here.

          • 2. Re: Should you overuse receiveNoWait
            clebert.suconic

            hmmm.. that's weird.. I branched the discussion as I wanted to fork a thread into a different subject.. and the original message disappeared :/

            • 3. Re: Should you overuse receiveNoWait
              newway

              The disappearing message is indeed a strange thing

               

              So to sum up here - just to check if I got what you meant.

               

              if our pattern is that if a message wasn't received for 10 minutes than maybe the connection was lost or something - so we reconnect.

               

              a saner way to obtain this would be:

               

              while (true)

              {

                 message = consumer.receive(10 minutes time out);

                  if (message != null)

                  {

                      // process...

                  } else {

                     // reconnect

                  }

              }

               

              and not

              while (true)

              {

                  message = consumer.receiveNoWait();

                  if (message == null) {

                    Thread.currentThread().sleep(5000);

                    // check if 10 minutes passed since last message received - if so - reconnect

                  }

              }

               

              Sounds a lot cleaner (unless there is some best practice on the upper limit of the timeout)

              • 4. Re: Should you overuse receiveNoWait
                clebert.suconic

                You don't need to reconnect on message == null. That just means there's no message. Although I'm not sure if you meant something different from your logic.

                 

                 

                If you do this, it will be waiting forever...

                 

                while (true)

                {

                   message = consumer.receive(10 minutes time out);

                    if (message != null)

                    {

                        // process...

                    }

                }

                 

                 

                 

                An even cleaner way would be to use a MessageListener.. you would just have a thread awake when a message is arriving.

                 

                 

                Consumer.setHandler(....); // I don't remember the actualy api names... I hope you got the idea...

                • 6. Re: Should you overuse receiveNoWait
                  newway
                  • I guess I will have to look back into the whole code and try and understand why they didn't go with the option of message listener - it does sound better.
                  • Regarding why I reconnect - if after 10 minutes no message was received, than we check maybe something in the communications went wrong - I guess this is another implementation issue to be reviewed

                   

                   

                  But thanks for all your inputs so far

                   

                   

                  -----

                  I think I remembered why we don't use the message listener - basically it's about running our main as a service and being available to respond to a shut down hook.

                   

                  so basically our code is like this

                   

                   

                  while (still running) {
                       get message
                  
                       If no message received - sleep, if it's been 10 minutes since the last message received - reconnect
                       else - process message
                  }
                  

                   

                  but I also see that on any other exception caught we attempt to reconnect - so I guess this forced reconnection after 10 minutes might be redundant

                   

                  Message was edited by: Noa Drach - I recalled some of the design decisions made when the consumer was written

                  • 7. Re: Should you overuse receiveNoWait
                    newway

                    OK - some digging up in the design brought the following conclusion:

                     

                    We are using pooling of messages and not a message listener because our processing of the messages is done in JNI and we need to ensure that we are working with a single thread and I guess the guy that developed this part got to a conclusion that they way to keep the thread it to work with pooling.

                    • 8. Re: Should you overuse receiveNoWait
                      clebert.suconic

                      I did a lot of JNI. and there are cases I needed to ensure a single thread as well (for instance the way I create a new native buffer on HornetQ has to be single threaded)... all I needed was to use a synchronize block before the JNI call.

                       

                      In cases where I really needed a single thread, to be the actual same thread... I used a single thread executor.

                       

                       

                      But tha's another discussion....  You will do what's best for your architecture I'm sure... I'm just sharing my POV...

                       

                      at least you should use receive with a wait instead of receiveNoWait and then sleep.

                       

                       

                      the ReceiveNoWait will be fixed on the next version anyways.. But I feel like this discussion was very productive for yout.

                      • 9. Re: Should you overuse receiveNoWait
                        newway

                        Yes.

                         

                        It was productive - thank you for all the detailed information.

                        • 10. Re: Should you overuse receiveNoWait
                          clebert.suconic

                          and BTW you could configure reconnection on hornetq... so you just receive the message..