3 Replies Latest reply on Oct 9, 2007 1:30 PM by jay.howell

    Need Notification when message is dropped due to max size

    jay.howell

      I have a customer that wants to put in an aspect to do some sort of notification if a message is dropped due to the maxsize. I can see in ChannelSupport that the max size is handed via

      protected Delivery handleInternal(DeliveryObserver sender, MessageReference ref,
       Transaction tx, boolean persist)
       {
       if (ref == null)
       {
       return null;
       }
      
       if (trace) { log.trace(this + " handles " + ref + (tx == null ? " non-transactionally" : " in transaction: " + tx)); }
       if (maxSize != -1 && getMessageCount() >= maxSize)
       {
       //Have reached maximum size - will drop message
       log.warn(this + " has reached maximum size, " + ref + " will be dropped");
       return null;
       }
      

      and the Delivery gets returned as null. I don't see anything that I can use to figure out if the message is dropped.

      I do see later on that if the delivery is null that we generate a JMSException in ServerConnectionEndpoint this....

      if (del == null)
       {
       throw new JMSException("Failed to route " + ref + " to " + dest.getName());
       }
      


      My guess is that theres nothing that they can do except catch the exception. Because we throw a JMSException and not a MessagingJMSException, it makes it hard. Should we throw a typed exception, like MaxMessageReachedException or throw a MessagingJMSException with a specific error code in it. I notice that there are several cases that can return a null delivery. I would recommend that we throw a specific exception in ChannelSupport? That way we could write an aspect that would catch the specific exception. Don't know what the impact would be, but I'm guessing that there is a reason that we return null for the delivery in ChannelSupport.

        • 1. Re: Need Notification when message is dropped due to max siz
          timfox

           

          "jhowell@redhat.com" wrote:
          I have a customer that wants to put in an aspect to do some sort of notification if a message is dropped due to the maxsize. I can see in ChannelSupport that the max size is handed via

          protected Delivery handleInternal(DeliveryObserver sender, MessageReference ref,
           Transaction tx, boolean persist)
           {
           if (ref == null)
           {
           return null;
           }
          
           if (trace) { log.trace(this + " handles " + ref + (tx == null ? " non-transactionally" : " in transaction: " + tx)); }
           if (maxSize != -1 && getMessageCount() >= maxSize)
           {
           //Have reached maximum size - will drop message
           log.warn(this + " has reached maximum size, " + ref + " will be dropped");
           return null;
           }
          

          and the Delivery gets returned as null. I don't see anything that I can use to figure out if the message is dropped.

          I do see later on that if the delivery is null that we generate a JMSException in ServerConnectionEndpoint this....

          if (del == null)
           {
           throw new JMSException("Failed to route " + ref + " to " + dest.getName());
           }
          


          My guess is that theres nothing that they can do except catch the exception. Because we throw a JMSException and not a MessagingJMSException, it makes it hard. Should we throw a typed exception, like MaxMessageReachedException or throw a MessagingJMSException with a specific error code in it. I notice that there are several cases that can return a null delivery. I would recommend that we throw a specific exception in ChannelSupport? That way we could write an aspect that would catch the specific exception. Don't know what the impact would be, but I'm guessing that there is a reason that we return null for the delivery in ChannelSupport.


          One thing the user could do is catch the JMSException in his interceptor, then enquire on the queue how many messages are in it.

          If number of messages in queue == maxSize, then you know queue is full.

          For JBM 2.0 we can think about adding more fine grained return values / exceptions. If you like, you could add a feature request for that.

          • 2. Re: Need Notification when message is dropped due to max siz
            jwilker

            Hi, Thanks for your response.

            Unfortunately, no exception appears to be thrown when topic messages are dropped due to MaxSize.

            Here's the relevant code from ServerConnectionEndpoint (1.4.0.GA), where the stack is sitting on the topic posteOffice.route() call which doesn't result in an exception.

            else if (dest.isQueue())
            {
            if (!postOffice.route(ref, new JMSCondition(true, dest.getName()), tx))
            {
            throw new JMSException("Failed to route " + ref + " to " + dest.getName());
            }
            }
            else
            {
            postOffice.route(ref, new JMSCondition(false, dest.getName()), tx);
            }


            Interesting, the queue case looks to result in an exception, where the topic case doesn't.

            Any idea as to why?



            ------------------------------------------------------
            Also, here's the full stack trace:

            MessagingQueue(ChannelSupport).handleInternal(DeliveryObserver, MessageReference, Transaction, boolean) line: 598
            MessagingQueue(ChannelSupport).handle(DeliveryObserver, MessageReference, Transaction) line: 144
            MessagingPostOffice.routeInternal(MessageReference, Condition, Transaction, boolean, Set) line: 2124
            MessagingPostOffice.route(MessageReference, Condition, Transaction) line: 478
            ServerConnectionEndpoint.sendMessage(JBossMessage, Transaction, boolean) line: 710
            ServerSessionEndpoint.send(JBossMessage, boolean) line: 343
            SessionAdvised.org$jboss$jms$server$endpoint$advised$SessionAdvised$send$aop(JBossMessage, boolean) line: 80
            SessionAdvised$send_6145266547759487588.invokeNext() line: not available
            SecurityAspect.handleSend(Invocation) line: 157
            GeneratedMethodAccessor78.invoke(Object, Object[]) line: not available
            DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25
            Method.invoke(Object, Object...) line: 585
            PerInstanceAdvice.invoke(Invocation) line: 121
            SessionAdvised$send_6145266547759487588.invokeNext() line: not available
            ServerLogInterceptor.invoke(Invocation) line: 105
            SessionAdvised$send_6145266547759487588.invokeNext() line: not available
            JBossMessagingServerInterceptor.handleSessionSend(Invocation) line: 183

            • 3. Re: Need Notification when message is dropped due to max siz
              jay.howell

              The reason that the topic is not handled the same way is because if we were to throw an exception, then it would stop the processing of the other subscribers. So you have a topic and you have 100 subscribers. If the 5th subscriber throws an exception, then the delivery will not happen for the other 95. This could be alleviated by catching the exception, but then the exception might not be tossed high enough.

              So the answer seems to be in some refactoring. After speaking to Tim, we may implement something like the batch sql function in jdbc. It returns an array/collection of objects that represents the success/failure of each one of the durable subscriptions. Not sure what this will look like, but this could be interpreted to see why the failure happened. This would provide the handling needed to see if a queue(durable subscriber) has rejected the entry due to a max size.

              Jay:)