You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@qpid.apache.org by "Keith Wall (JIRA)" <ji...@apache.org> on 2011/02/07 13:22:30 UTC

[jira] Commented: (QPID-2900) CommitRollbackTest#testGetThenRollback and CommitRollbackTest#testSend2ThenRollback fail on java.0.10 profile

    [ https://issues.apache.org/jira/browse/QPID-2900?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12991350#comment-12991350 ] 

Keith Wall commented on QPID-2900:
----------------------------------

I've traced the problem down to a race condition - broker side - within SimpleAMQQueue.

The nub of the problem is the update of the atomic QueueContext._releasedEntry.  There is a circumstance where _releasedEntry  is overwritten prematurely and therefore the broker fails to resend the message to the client.

Here's how it happens:

In the cases where the tests fail, the thread (SubFlushRunner or QueueRunner) executing SimpleAMQQueue.deliverMessage() is yielded part way through the method.   The thread has successfully sent the message to the client (MESSAGE_TRANSFER etc), but the JVM yields the thread before it reaches setLastSeen().  (SetLastSeen is responsible for advancing the lastSeen pointer, and resetting _releasedEntry if necessary). 

Meanwhile, the client receives the message, calls JMS rollback, which causes MESSASE_RELEASE (etc) command to be sent to the broker, before it calls JMS receive().  The broker processes the MESSAGE_RELEASE by invoking SimpleAMQ.requeue() which in turn invokes updateSubRequeueEntry() to update _releaseEntry with the QueueEntry to be resent. 

Now, the JVM wakes-up the thread (SubFlushRunner or QueueRunner) that was part way through processing SimpleAMQQueue .deliverMessage() for the initial send of the message. The setLastSeen() method is invoked, which ***incorrectly*** resets _releasedEntry to null because _releaseEntry now is the same as the entry being processed.   The broker goes around the loop, calls getNextAvailableEntry which returns null because _releaseEntry has been prematurely cleared.

I've illustrated the success and failure cases as sequence diagrams (attached to this JIRA).

> CommitRollbackTest#testGetThenRollback and CommitRollbackTest#testSend2ThenRollback fail on java.0.10 profile
> -------------------------------------------------------------------------------------------------------------
>
>                 Key: QPID-2900
>                 URL: https://issues.apache.org/jira/browse/QPID-2900
>             Project: Qpid
>          Issue Type: Bug
>          Components: Java Broker, Java Client
>            Reporter: Robbie Gemmell
>            Assignee: Keith Wall
>            Priority: Critical
>             Fix For: 0.9
>
>
> org.apache.qpid.test.unit.transacted.CommitRollbackTest#testGetThenRollback
> org.apache.qpid.test.unit.transacted.CommitRollbackTest#testSend2ThenRollback
> These two tests fail very regularly (but not always) on the java.0.10 test profile:
> TestName: testGetThenRollback Duration: 6.882
>                                 test message was consumed and rolled back, but is gone
>                                 junit.framework.AssertionFailedError: test message was consumed and rolled back, but is gone
> 	at org.apache.qpid.test.unit.transacted.CommitRollbackTest.testGetThenRollback(CommitRollbackTest.java:273)
> 	at org.apache.qpid.test.utils.QpidBrokerTestCase.runBare(QpidBrokerTestCase.java:232)
> 	at org.apache.qpid.test.utils.QpidTestCase.run(QpidTestCase.java:120)
>                             
> TestName: testSend2ThenRollback Duration: 6.879
>                                 Didn't receive redelivered message one
>                                 
>                                 junit.framework.AssertionFailedError: Didn't receive redelivered message one
> 	at org.apache.qpid.test.unit.transacted.CommitRollbackTest.verifyMessages(CommitRollbackTest.java:379)
> 	at org.apache.qpid.test.unit.transacted.CommitRollbackTest.verifyMessages(CommitRollbackTest.java:415)
> 	at org.apache.qpid.test.unit.transacted.CommitRollbackTest.testSend2ThenRollback(CommitRollbackTest.java:357)
> 	at org.apache.qpid.test.utils.QpidBrokerTestCase.runBare(QpidBrokerTestCase.java:232)
> 	at org.apache.qpid.test.utils.QpidTestCase.run(QpidTestCase.java:120)
>                             

-- 
This message is automatically generated by JIRA.
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

---------------------------------------------------------------------
Apache Qpid - AMQP Messaging Implementation
Project:      http://qpid.apache.org
Use/Interact: mailto:dev-subscribe@qpid.apache.org