7 Replies Latest reply on Sep 15, 2005 3:35 PM by timfox

    A couple of questions on expected JMS behaviour / edge cases

    timfox

      I have a couple of JMS use cases where I'd like to check with any JMS gurus out there what the expected behaviour should be:

      1)
      Acknowledgment after consumer is closed:

      Connection conn = cf.createConnection();
      Session sess = conn.createSession(true, Session.TRANSACTED);
      MessageConsumer consumer = sess.createConsumer(queue);
      Message m = consumer.receive();
      consumer.close();
      sess.commit();
      conn.close();

      I believe the above is legal, can anyone confirm?

      The ack should be sent when the session commits, by when the consumer is closed.

      Currently this fails in JBoss Messaging since we rightly or wrongly handle acks in the consumer.

      However it passes the TCK since there doesn't seem to be any TCK test that traps this.

      I have added a test for this anyway in our test suite.


      2) Redelivery of messages to non durable topic subscribers.

      Consider the following:

      Create 2 non durable subscribers on a topic using different sessions, each session is CLIENT_ACKNOWLEDGE:

      Session sess1 = conn1.createSession(false, Session.CLIENT_ACKNOWLEDGE);
      Session sess2 = conn1.createSession(false, Session.CLIENT_ACKNOWLEDGE);

      MessageConsumer cons1 = sess1.createConsumer(topic);
      MessageConsumer cons2 = sess2.createConsumer(topic);

      then send a message to the topic:

      producer.send(m);

      now receive the message on both consumers:

      Message m1 = (TextMessage)cons1.receive();
      Message m2 = (TextMessage)cons2.receive();

      but only ack it at *one* of the consumer sessions.

      m1.acknowledge();

      then call recover() on the *other* consumer session:

      sess2.recover();

      My understanding is that the message should not be received again at cons1, but only received again at cons2, which corresponds to sess2 which hadn't acked it.

      Is this correct?

      Again this is not what happens in the current code, but, also again, there's no TCK test to trap this.



        • 1. Re: A couple of questions on expected JMS behaviour / edge c

           

          "timfox" wrote:

          1)
          Acknowledgment after consumer is closed:

          Connection conn = cf.createConnection();
          Session sess = conn.createSession(true, Session.TRANSACTED);
          MessageConsumer consumer = sess.createConsumer(queue);
          Message m = consumer.receive();
          consumer.close();
          sess.commit();
          conn.close();

          I believe the above is legal, can anyone confirm?

          The ack should be sent when the session commits, by when the consumer is closed.


          Correct. The state belongs to the session - or more accurately in this case
          the transaction.


          • 2. Re: A couple of questions on expected JMS behaviour / edge c

             

            "timfox" wrote:

            m1.acknowledge();

            then call recover() on the *other* consumer session:

            sess2.recover();

            My understanding is that the message should not be received again at cons1, but only received again at cons2, which corresponds to sess2 which hadn't acked it.


            m1 from the first subscription should not be redelivered regardless!
            After m1.acknowledge() returns successfully, it no longer exists.

            Operations on sess2 should never affect sess1.

            Different sessions are intended to be used on different threads, they aren't even
            threadsafe.

            • 3. Re: A couple of questions on expected JMS behaviour / edge c
              timfox

              Sorry, I mis-stated the second case. :)

              What I meant to say was:

              Sess1 acks the message

              Sess2 doesn't ack the message

              When sess1.recover is called, it doesn't get the message redelivered.

              When sess2.recover is called, it does get the message redelivered (since it's been acked).

              Is that right?

              Currently (as in the current state of JBoss messaging), what actually happens is that neither of the consumers gets the message redelivered on recovery.

              This is because, currently in the implementation of the channel that makes up the topic,we only say the message is unacknowledged, we don't say the message is unacked from a specific consumer. This is fine for a Queue , but not for a topic where we can have multiple consumers.

              I think the current implementation is wrong.

              It's curious the TCK doesn't catch this though.

              • 4. Re: A couple of questions on expected JMS behaviour / edge c

                 

                "timfox" wrote:
                Sorry, I mis-stated the second case. :)

                What I meant to say was:

                Sess1 acks the message

                Sess2 doesn't ack the message

                When sess1.recover is called, it doesn't get the message redelivered.

                When sess2.recover is called, it does get the message redelivered (since it's been acked).

                Is that right?


                It is if your last sentance was meant to be:
                "When sess2.recover is called, it does get the message redelivered (since it has NOT been acked)."


                • 5. Re: A couple of questions on expected JMS behaviour / edge c

                   

                  "timfox" wrote:

                  This is because, currently in the implementation of the channel that makes up the topic,we only say the message is unacknowledged, we don't say the message is unacked from a specific consumer. This is fine for a Queue , but not for a topic where we can have multiple consumers.

                  I think the current implementation is wrong.


                  Very broken. Two topic subscriptions == two messages (at least logically)
                  i.e. different redelivered flags, different message.getJMSDestination(), etc.

                  • 6. Re: A couple of questions on expected JMS behaviour / edge c

                     

                    "timfox" wrote:

                    It's curious the TCK doesn't catch this though.


                    Please do not discuss the TCK in public. Even if it is just flippant comments.
                    The TCK is licensed under NDA.

                    Except for whatever Sun releases via Glassfish?
                    Which isn't very much :-)
                    https://glassfish.dev.java.net/source/browse/glassfish/appserv-tests/QuickLook-README.txt?rev=1.2&view=markup

                    • 7. Re: A couple of questions on expected JMS behaviour / edge c
                      timfox

                      Ok, thanks for the clarification.

                      I shall add JIRA tasks for these issues (and some others), and make sure there are tests for these conditions.