[ 
https://issues.apache.org/jira/browse/AMQ-4151?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Christopher L. Shannon closed AMQ-4151.
---------------------------------------
    Resolution: Incomplete

no test case provided

> Duplicate non-persistent messages that are sent to a queue are either 
> dispatched multiple times (i.e., not detected as duplicates) or cause the 
> queue size to be miscalculated.
> -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: AMQ-4151
>                 URL: https://issues.apache.org/jira/browse/AMQ-4151
>             Project: ActiveMQ
>          Issue Type: Bug
>            Reporter: Stirling Chow
>
> Symptom
> =======
> We have a virtual topic that is shared by a network of brokers.  Each broker 
> has consumers that process the corresponding Consumer.*.VirtualTopic.> queue.
> While testing the effects of memory limits on our system, we encountered 
> AMQ-4148, which resulted in duplicate subscriptions being made to the virtual 
> topic.  These duplicate subcriptions were attempting to enqueue the same 
> topic message multiple times to the corresponding Consumer.*.VirtualTopic.>.
> Although logic exists in queues to handle duplicate messages, we noticed lots 
> of strange behaviour with duplicate handling.  We decided to investigate 
> further and found a race condition whereby duplicate non-persistent messages 
> that were correctly ignored resulted in the queue size appearing to be 
> non-empty when in fact there were no messages.
> While our original investigation was prompted by AMQ-4148, the test case we 
> attached to this ticket does not rely on the misbehaviour caused by AMQ-4148, 
> but can occur during normal operation of network bridges when there are 
> multiple consumers for a virtual topic (as is the case, e.g., when conduit 
> subscriptions are disabled).
> Cause
> =====
> If a virtual topic has multiple consumers, then sending a message to the 
> topic results in multiple dispatches of the same message (one to each 
> consumer).  If the multiple consumers originate from the same remote broker 
> (e.g., because conduit subscriptions are disabled), then a single message 
> sent to the virtual topic on broker1 will result in multiple duplicate 
> messages being sent to the virtual topic on broker2.
> If broker2 has corresponding Consumer.*.VirtualTopic.> queue, then the 
> multiple duplicate messages sent to the virtual topic on broker2 will result 
> in multiple duplicate messages being sent to the queue.  
> If the messages are non-persistent, the only logic that prevents each 
> duplicate message from being dispatched to a consumer is as follows:
> {code:title=Queue.java}
> private PendingList doPageInForDispatch(boolean force) throws Exception {
> ...
>         // Only add new messages, not already pagedIn to avoid multiple
>         // dispatch attempts
>         pagedInMessagesLock.writeLock().lock();
>         try {
>             if(isPrioritizedMessages()) {
>                 resultList = new PrioritizedPendingList();
>             } else {
>                 resultList = new OrderedPendingList();
>             }
>             for (QueueMessageReference ref : result) {
>                 if (!pagedInMessages.containsKey(ref.getMessageId())) {
>                     pagedInMessages.put(ref.getMessageId(), ref);
>                     resultList.addMessageLast(ref);
>                 } else {
>                     ref.decrementReferenceCount();
>                 }
>             }
>         } finally {
>             pagedInMessagesLock.writeLock().unlock();
>         }
> ...        
> {code}
> If the consumers are fast and acknowledge the initial message dispatch before 
> the next duplicate message is sent to the queue, then the 
> {{pagedInMessages.constainsKey(...)}} check will *not* prevent the duplicate 
> message from being dispatched since the message ID will have already been 
> removed as part of the acknowledgement.
> This is problem 1: duplicate detection fails if acknowledgements are quick
> If the consumers are slow and don't acknowledge the initial message dispatch 
> before the next duplicate message is sent to the queue, then duplicate 
> detection will correctly ignore the message.  However, by this time, the 
> duplicate message has already incremented the queue size:
> {code:title=Queue.java}
> final void messageSent(final ConnectionContext context, final Message msg) 
> throws Exception {
>     destinationStatistics.getEnqueues().increment();
>     destinationStatistics.getMessages().increment();
>     messageDelivered(context, msg);
> {code}
> The call to {{messageSent}} is made by the thread sending the message to the 
> queue.  This thread is completely unaware that the message was ignored since 
> the call to {{doPageInForDispatch}} is done by a separate thread (e.g., the 
> taskrunner calling {{iterate()}}.
> Since the queue size is incremented, but the duplicate message is never 
> dispatched, there is no subsequent acknowledgement ot reduce the queue size.  
> As a result, each duplicate message that is ignored remains counted in the 
> queue size even though it's no longer in the queue.  
> This is problem 2: if duplication detection succeeds, the queue size 
> incorrectly counts the duplicate/ignored message.
> Which problem gets exhibited depends on a race condition between the 
> thread(s) enqueueing the duplicate virtual topic subscriptions and consumer 
> threads acknowledging the dispatches.
> While the unit test's methodology of creating multiple virtual topic 
> consumers is somewhat contrived, there must be other circumstances under 
> which duplicate messages are sent to queues (otherwise, why would there be 
> logic to handle this case?)  In this context, the test case reveals a problem 
> with the handling of duplicate messages.
> Solution
> ========
> None at this time.  We worked around the problem by patching AMQ-4148 to 
> prevent the duplicate subscriptions that cause this bug.  However, our 
> concern has been raised about AMQ's generally handling of duplicate messages 
> sent to a queue.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to