6 Replies Latest reply on Nov 5, 2012 1:54 PM by clebert.suconic

    Behavior of Durable TopicSubscriber with noLocal and filter

    saguirre

      I am using HornetQ2.1.2.  I set up a standalone non-clustered configuration with a single topic defined.  I have an application which both consumes and produces messages.  It created a TopicSubscriber using TopicSession.createDurableSubscriber(Topic topic, String name, String messageSelector, boolean noLocal).  The noLocal setting was true and a messageSelector string was provided to filter messages.  The messages are received as expected if they match the filter.  I output the message selector string being used by the subscriber using getMessageSelector(), which shows that the selection is based on the string I passed in AND __HQ_CID<> {the-value-of-my-connection}.

       

      When I exit the application and reconnect later using the same topic, name, messageSelector and noLocal parameters, createDurableSubscriber creates a subscriber with the same message selection criteria I specified in my messageSelector parameter, but with the new connection specified.  My intention was to subscribe to all messages that this client did not publish that have the given attribute set to the message selection criteria, as before.  None of the messages published during the time the client was down are received.  I used jconsole to verify that they are still in the topic before the client connects.  After connection, the durable subscriber is in place, but there are no messages in the topic that match the criteria, and the client has not received any.

       

      If I set the noLocal to false, it works as I expected, but the subscriber also receives its own published messages.  I assume that what happened is that the durable subscriber created is seen as a change to the subscription because the connection id is changed, even though all parameters that I can provide to the createDurableSubscriber method have remain unchanged.  Is this the desired behavior or is this a bug?

        • 1. Re: Behavior of Durable TopicSubscriber with noLocal and filter
          timfox

          That's to be expected. In JMS changing the selector causes the old subscription to be deleted and a new one to be created.

           

          See JMS javadoc:

           

          http://download.oracle.com/javaee/5/api/javax/jms/Session.html#createDurableSubscriber%28javax.jms.Topic,%20java.lang.String,%20java.lang.String,%20boolean%29

           

          "A client can change an existing durable subscription by creating   a durable TopicSubscriber with the same name and a new   topic and/or   message selector. Changing a durable subscriber is equivalent to   unsubscribing (deleting) the old one and creating a new one."

          1 of 1 people found this helpful
          • 2. Re: Behavior of Durable TopicSubscriber with noLocal and filter
            saguirre

            I read portion of the documentation that describes changing the selector.  My question was that I didn't change the call to createDurableSubscriber at all because I didn't intend to change the messageSelector.  The change occurred because I had noLocal set (both times), and the connection ID changed.  I don't control the connection ID, so I can't make it stay the same.  What I am trying to accomplish is a subscriber with a filter someAttribute="someValue" and connection=NOT_THIS_ONE.  It seems that the unsubscribe happens because the noLocal setting is rolled into the messageSelector.  Is this implementation specific, or do all JMS providers work this way?

            • 3. Re: Behavior of Durable TopicSubscriber with noLocal and filter
              clebert.suconic

              As far as I know all JMS providers work this way.

               

              When ou change the connectionID, you are creating a different subscriber. If you want to recover your previous subscription, you must use the same ConnectionID.

               

              You could have a higher control on the publish/subscriber if you are not using JMS. Like you could have an Address, and a Queue associated with that address, and have your consumer always using the same queue.

               

              Those things are automated under the covers with the JMS layer for you, but you could use the core-api directly if you needed more specicialized behaviour.

              • 4. Re: Behavior of Durable TopicSubscriber with noLocal and filter
                srazza

                Hi Clebert,

                in our environment we have the same problem and we could have situations in which subscribers lost their connection (due to server restart) and when they reconnect,

                they need to re-use the same connectionID in order to avoid that  old subscription will be deleted and a new one will be created.

                How can we set the same ConnectionID every time the subscriber starts?

                 

                Thanks in advance.

                 

                Stefano

                • 5. Re: Behavior of Durable TopicSubscriber with noLocal and filter
                  dc-williams

                  Actually I think the story doesn't end here though.

                   

                  Yes, I think it is correct in JMS terms that if the message selector changes, the subscription is effectively changed so messages from the 'old' version will be lost.  But I also think Sue and Stefano are correct because NO, I don't think HornetQ's implementation of JMS should add the __HQ_CID<>... into the selector string because this makes durable subscriptions as specified in the JMS spec. impossible using HQ JMS (and assuming you DON'T want to use core - as in my case where we have dozens of JMS processes and don't want to go around re-developing them to use HQ core API).

                   

                  As has been mentioned, the JMS API does not provide a call to set the connection ID (and it doesn't make sense for it to else how can the server manage dups?).  I think the HQ implementation of JMS is partly broken because it does not properly support durable subscriptions - in other words, a durable subscriber cannot disconnect then reconnect with (what it thinks) is the identical details (clientID, selector, name) and pick up messages published while it was down or disconnected - in other words, it's only durable if HQ goes down otherwise it might as well not be durable.

                   

                  I'm using HQ2.2.14_FINAL in stand-alone, non-clustered mode under JDK1.6 on solaris 10 and have the same issue as the other two. Fortunately, I can get around it by setting noLocal = false because my subscriber does not also publish - hence these posts were very useful, thankyou!  I used jConsole to list the subscribers as JSON and noticed the __HQ_CID added and my tiny braincell sparked and I searched for 'noLocal and HornetQ durable subscriber' and found this thread. 

                   

                  I still think this should be fixed though.

                   

                  We close processes down weekly or overnight and are in the process of upgrading from JBOSSMQ under JBAS4 to JBAS5 and a stand-alone HQ JVM.  JBOSSMQ did not add this connection ID to the selector and neither does IBM WAS as far as I can tell because we have IBM WAS topics here also and you can connect / disconect the client with noLocal set to true and it still picks up messages published while the client was down.