You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@qpid.apache.org by "Pavel Moravec (JIRA)" <ji...@apache.org> on 2013/01/03 09:30:14 UTC

[jira] [Created] (QPID-4524) Java client timeouts after sending huge message to existing durable queue

Pavel Moravec created QPID-4524:
-----------------------------------

             Summary: Java client timeouts after sending huge message to existing durable queue
                 Key: QPID-4524
                 URL: https://issues.apache.org/jira/browse/QPID-4524
             Project: Qpid
          Issue Type: Bug
          Components: Java Client
    Affects Versions: 0.18
            Reporter: Pavel Moravec
            Priority: Minor


Description of problem:
Having a durable queue created, if one tries to send two huge messages (e.g. of 2MiB each), Java client timeouts after sending the first and before sending the second.


Version-Release number of selected component (if applicable):
0.18-3


How reproducible:
100%


Steps to Reproduce:
Use attached reproducer (that sends one huge message followed by a small one):
1. qpid-config add queue test --durable
2. java test_00734429

  
Actual results:
Exception in thread "main" javax.jms.JMSException: Exception when sending message:timed out waiting for completion
	at org.apache.qpid.client.BasicMessageProducer_0_10.sendMessage(BasicMessageProducer_0_10.java:241)
	at org.apache.qpid.client.BasicMessageProducer.sendImpl(BasicMessageProducer.java:511)
	at org.apache.qpid.client.BasicMessageProducer.send(BasicMessageProducer.java:309)
	at test_00734429.<init>(test_00734429.java:45)
	at test_00734429.main(test_00734429.java:24)
Caused by: org.apache.qpid.transport.SessionException: timed out waiting for completion
	at org.apache.qpid.transport.Session.invoke(Session.java:742)
	at org.apache.qpid.transport.Session.invoke(Session.java:615)
	at org.apache.qpid.transport.SessionInvoker.messageTransfer(SessionInvoker.java:93)
	at org.apache.qpid.client.BasicMessageProducer_0_10.sendMessage(BasicMessageProducer_0_10.java:227)
	... 4 more


Expected results:
No such exception, also 2nd message is sent.


Additional info:
- if the queue is _not_ existing before running the reproducer, no issue occurs (the reproducer creates the "auto-create" queue, see properties file)
- the root cause of the bug is that when the client library gets AMQP message session.completed with commands = [], it does not notify commandsLock in org.apache.qpid.transport.Session.invoke, hence it waits there until timeout; proper behavior (similar to the one when getting session.completed with non-empty commands) is to notify the lock and send next session.flush
- jstack from the timing-out reproducer:

"main" prio=10 tid=0x00007fcee8007800 nid=0x1ebb in Object.wait() [0x00007fceedc04000]
   java.lang.Thread.State: TIMED_WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x00000000f25d1bc0> (a java.lang.Object)
        at org.apache.qpid.transport.util.Waiter.await(Waiter.java:54)
        at org.apache.qpid.transport.Session.invoke(Session.java:716)
        - locked <0x00000000f25d1bc0> (a java.lang.Object)
        at org.apache.qpid.transport.Session.invoke(Session.java:615)
        at org.apache.qpid.transport.SessionInvoker.messageTransfer(SessionInvoker.java:93)
        at org.apache.qpid.client.BasicMessageProducer_0_10.sendMessage(BasicMessageProducer_0_10.java:227)
        at org.apache.qpid.client.BasicMessageProducer.sendImpl(BasicMessageProducer.java:511)
        at org.apache.qpid.client.BasicMessageProducer.send(BasicMessageProducer.java:309)
        - locked <0x00000000f31fb060> (a java.lang.Object)
        at test_00734429.<init>(test_00734429.java:45)
        at test_00734429.main(test_00734429.java:24)

- Source code root cause:

getting session.complete with empty range causes org.apache.qpid.transport.SessionDelegate.sessionCompleted does not step into this if-branch:

        if (ranges != null)
        {
            if(ranges.size() == 1)
            {
                Range range = ranges.getFirst();
                boolean advanced = ssn.complete(range.getLower(), range.getUpper());
        ..
 
where ssn.complete calls commandsLock.notifyAll(); at its end.

Therefore, "else" branch of this if command has to either:
- call the same method (modified such that it works with -1 as its both arguments)
- or call some auxiliary method invoking "commandsLock.notifyAll();"

I don't know what approach is preferable thus leaving the JIRA without patch.

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@qpid.apache.org
For additional commands, e-mail: dev-help@qpid.apache.org