8 Replies Latest reply on Feb 23, 2010 10:22 AM by pieter.martin

    JMS and correlationID ?

    pieter.martin

      Hi,

       

      I am using the JMSMessageID and JMSCorrelationID to sync the responses.

       

      I have a Set<String> messageIDs containing the ids for every message sent.

      On the result queue I then remove the ids and when the set is empty I know that I have received a response for every message sent.

       

      However as one can only retrieve the JMSMessageID after the message has already been sent it happens that the response comes back before the Set<String>messageId has been set.

       

      producer code...

       

      queueFactory.getExecutorProducer().send(message);

      messageIds.add(message.getJMSMessageID());

      jmsExecutorResultListener.setMessageIds(messageIds);

       

      Is there something wrong with my design?

       

      Thanks

      Pieter

        • 1. Re: JMS and correlationID ?
          timfox

          Sure, message delivery can be so fast that the message appears in your consumer before you've executed the next line of code on your sender thread.

           

          Why is this a problem?

          • 2. Re: JMS and correlationID ?
            pieter.martin

            In the listener I have the following code

             

            Response response = (Response)objectMessage.getObject();

            messageIds.remove(objectMessage.getJMSCorrelationID());

             

            if (messageIds.isEmpty()) {

                 computationComplete.fire(true);

            }

             

             

            The problem is that the messageIds never becomes empty.

            The response comes back before I messageIds is populated.

            So I do not remove the message but I do add it later in which case the computationComplete.fire(true) event never fires.

             

            Thanks

            Pieter

            • 3. Re: JMS and correlationID ?
              timfox

              What am I missing herew? You just need to wait for the id to be added to the map.

               

              You can easily do this by using a lock.

               

              E.g.

               

              synchronized (myLock)

              {

                 producer.send(msg);

               

                 map.put(msg.getJMSMessageID, foo);

              }

               

              then in your consumer:

               

              Msg msg = consumer.receive();

               

              synchronized (lock)

              {

                 Foo foo = map.get(msg.getJMSMessageID());

              }

              • 4. Re: JMS and correlationID ?
                pieter.martin

                Ok, what I did now was setting DisableMessageID to false on the MessageProducer and then set the JMSMessageID manually.

                 

                queueFactory.getExecutorProducer().setDisableMessageID(true);

                String uid = new UID().toString();

                message.setJMSMessageID("ID:" + uid);

                messageIds.add(message.getJMSMessageID());

                jmsExecutorResultListener.setMessageIds(messageIds);

                 

                queueFactory.getExecutorProducer().send(message);

                 

                This seems to be working fine.

                 

                Is this ok, or would you suggest your way using synchronized...?

                 

                 

                • 5. Re: JMS and correlationID ?
                  timfox

                  You shouldn't need to do that, and I don't see how it makes a difference anyway.

                   

                  If you understand that messages can be received very quickly after sending, then it's clear that some simple locking would be necessary.

                   

                  This is more of a general programming question, rather than anything messaging specific.

                  • 6. Re: JMS and correlationID ?
                    pieter.martin

                    Well now the map with the correct messageIds  is set on the listener before the message is sent, so it seems to me no locking is needed in this case.

                     

                    Thanks

                    Pieter

                    • 7. Re: JMS and correlationID ?
                      timfox

                      Fine, but you shouldn't need to do that.

                       

                      Simple locking would suffice, and would probably give you better performance.

                      • 8. Re: JMS and correlationID ?
                        pieter.martin
                        Thanks