You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@activemq.apache.org by "Dave Stanley (JIRA)" <ji...@apache.org> on 2009/11/23 21:07:52 UTC

[jira] Created: (AMQ-2507) When using a producer/session with a send timeout, send() doesn't throw an exception if the timeout is reached.

When using a producer/session with a send timeout, send() doesn't throw an exception if the timeout is reached.
---------------------------------------------------------------------------------------------------------------

                 Key: AMQ-2507
                 URL: https://issues.apache.org/activemq/browse/AMQ-2507
             Project: ActiveMQ
          Issue Type: Improvement
          Components: Broker
    Affects Versions: 5.3.0
         Environment: All platforms, 5.3.x
            Reporter: Dave Stanley


In the attached testcase we set a low broker memory limit (to force a producer to block due to the memory usage limit being hit), and also set a sendtimeout on the connection to force the producer.send() to return if it cannot send a message within the timeout period.

On running the test the broker sends messages until the timeout kicks in. Once the hits the memory limit it blocks and the producer.send() returns after the timeout.

The problem is there is no way to know that the send() failed. This improvement is to modify the session to throw an exception of some kind when the sendTimeout is reached.

I have attached the testcase without a fix as its not clear the best approach to fix.

One possible solution is to modify ActiveMQSession, but need some clarification on whats the best JMSException to throw.  It doesn't look like this is explicitly spelled out in the JMS Spec.

General area is the send() method

protected void send(ActiveMQMessageProducer producer, ActiveMQDestination destination, Message message, int deliveryMode, int priority, long timeToLive,
                        MemoryUsage producerWindow, int sendTimeout) throws JMSException {
           .....

           if (sendTimeout <= 0 && !msg.isResponseRequired() && !connection.isAlwaysSyncSend() && (!msg.isPersistent() || connection.isUseAsyncSend() || txid != null)) {
                this.connection.asyncSendPacket(msg);
                if (producerWindow != null) {
                    // Since we defer lots of the marshaling till we hit the
                    // wire, this might not
                    // provide and accurate size. We may change over to doing
                    // more aggressive marshaling,
                    // to get more accurate sizes.. this is more important once
                    // users start using producer window
                    // flow control.
                    int size = msg.getSize();
                    producerWindow.increaseUsage(size);
                }
            } else {
                // Handle send timeout here
                if (sendTimeout > 0) {
                	Object response = this.connection.syncSendPacket(msg,sendTimeout);
                    if(response == null) {
                    	LOG.debug(getSessionId() + " timeout sending message: " + msg);
                    }

                    // What jms exception is most appropriate to throw here?
                }else {
                    this.connection.syncSendPacket(msg);
                }
            }
}


-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Updated: (AMQ-2507) When using a producer/session with a send timeout, send() doesn't throw an exception if the timeout is reached.

Posted by "Dave Stanley (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/activemq/browse/AMQ-2507?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Dave Stanley updated AMQ-2507:
------------------------------

    Attachment: producer_timeout_test.txt

Attaching patch with testcase that shows the problem. Cut from trunk.

> When using a producer/session with a send timeout, send() doesn't throw an exception if the timeout is reached.
> ---------------------------------------------------------------------------------------------------------------
>
>                 Key: AMQ-2507
>                 URL: https://issues.apache.org/activemq/browse/AMQ-2507
>             Project: ActiveMQ
>          Issue Type: Improvement
>          Components: Broker
>    Affects Versions: 5.3.0
>         Environment: All platforms, 5.3.x
>            Reporter: Dave Stanley
>         Attachments: producer_timeout_test.txt
>
>
> In the attached testcase we set a low broker memory limit (to force a producer to block due to the memory usage limit being hit), and also set a sendtimeout on the connection to force the producer.send() to return if it cannot send a message within the timeout period.
> On running the test the broker sends messages until the timeout kicks in. Once the hits the memory limit it blocks and the producer.send() returns after the timeout.
> The problem is there is no way to know that the send() failed. This improvement is to modify the session to throw an exception of some kind when the sendTimeout is reached.
> I have attached the testcase without a fix as its not clear the best approach to fix.
> One possible solution is to modify ActiveMQSession, but need some clarification on whats the best JMSException to throw.  It doesn't look like this is explicitly spelled out in the JMS Spec.
> General area is the send() method
> protected void send(ActiveMQMessageProducer producer, ActiveMQDestination destination, Message message, int deliveryMode, int priority, long timeToLive,
>                         MemoryUsage producerWindow, int sendTimeout) throws JMSException {
>            .....
>            if (sendTimeout <= 0 && !msg.isResponseRequired() && !connection.isAlwaysSyncSend() && (!msg.isPersistent() || connection.isUseAsyncSend() || txid != null)) {
>                 this.connection.asyncSendPacket(msg);
>                 if (producerWindow != null) {
>                     // Since we defer lots of the marshaling till we hit the
>                     // wire, this might not
>                     // provide and accurate size. We may change over to doing
>                     // more aggressive marshaling,
>                     // to get more accurate sizes.. this is more important once
>                     // users start using producer window
>                     // flow control.
>                     int size = msg.getSize();
>                     producerWindow.increaseUsage(size);
>                 }
>             } else {
>                 // Handle send timeout here
>                 if (sendTimeout > 0) {
>                 	Object response = this.connection.syncSendPacket(msg,sendTimeout);
>                     if(response == null) {
>                     	LOG.debug(getSessionId() + " timeout sending message: " + msg);
>                     }
>                     // What jms exception is most appropriate to throw here?
>                 }else {
>                     this.connection.syncSendPacket(msg);
>                 }
>             }
> }

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Resolved: (AMQ-2507) When using a producer/session with a send timeout, send() doesn't throw an exception if the timeout is reached.

Posted by "Dejan Bosanac (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/activemq/browse/AMQ-2507?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Dejan Bosanac resolved AMQ-2507.
--------------------------------

       Resolution: Fixed
    Fix Version/s: 5.4.0
                   5.3.1

Fixed with svn revision 904160.

The solution to this problem is to use the timeout with producer flow control. I've added {{sendFailIfNoSpaceAfterTimeout}} parameter which can be used to configure it. It can be set like this (documented at http://cwiki.apache.org/confluence/display/ACTIVEMQ/Producer+Flow+Control)

{code}
<systemUsage>
 <systemUsage sendFailIfNoSpaceAfterTimeout="3000">
   <memoryUsage>
     <memoryUsage limit="20 mb"/>
   </memoryUsage>
 </systemUsage>
</systemUsage>
{code}

which will cause the {{send()}} method to throw an exception if space doesn't become available in specified amount of time. Note that if you use {{sendTimeout}} option with this, it must be a higher value than {{sendFailIfNoSpaceAfterTimeout}} so that later could have an effect.

> When using a producer/session with a send timeout, send() doesn't throw an exception if the timeout is reached.
> ---------------------------------------------------------------------------------------------------------------
>
>                 Key: AMQ-2507
>                 URL: https://issues.apache.org/activemq/browse/AMQ-2507
>             Project: ActiveMQ
>          Issue Type: Improvement
>          Components: Broker
>    Affects Versions: 5.3.0
>         Environment: All platforms, 5.3.x
>            Reporter: Dave Stanley
>            Assignee: Dejan Bosanac
>             Fix For: 5.3.1, 5.4.0
>
>         Attachments: producer_timeout_test.txt
>
>
> In the attached testcase we set a low broker memory limit (to force a producer to block due to the memory usage limit being hit), and also set a sendtimeout on the connection to force the producer.send() to return if it cannot send a message within the timeout period.
> On running the test the broker sends messages until the timeout kicks in. Once the hits the memory limit it blocks and the producer.send() returns after the timeout.
> The problem is there is no way to know that the send() failed. This improvement is to modify the session to throw an exception of some kind when the sendTimeout is reached.
> I have attached the testcase without a fix as its not clear the best approach to fix.
> One possible solution is to modify ActiveMQSession, but need some clarification on whats the best JMSException to throw.  It doesn't look like this is explicitly spelled out in the JMS Spec.
> General area is the send() method
> protected void send(ActiveMQMessageProducer producer, ActiveMQDestination destination, Message message, int deliveryMode, int priority, long timeToLive,
>                         MemoryUsage producerWindow, int sendTimeout) throws JMSException {
>            .....
>            if (sendTimeout <= 0 && !msg.isResponseRequired() && !connection.isAlwaysSyncSend() && (!msg.isPersistent() || connection.isUseAsyncSend() || txid != null)) {
>                 this.connection.asyncSendPacket(msg);
>                 if (producerWindow != null) {
>                     // Since we defer lots of the marshaling till we hit the
>                     // wire, this might not
>                     // provide and accurate size. We may change over to doing
>                     // more aggressive marshaling,
>                     // to get more accurate sizes.. this is more important once
>                     // users start using producer window
>                     // flow control.
>                     int size = msg.getSize();
>                     producerWindow.increaseUsage(size);
>                 }
>             } else {
>                 // Handle send timeout here
>                 if (sendTimeout > 0) {
>                 	Object response = this.connection.syncSendPacket(msg,sendTimeout);
>                     if(response == null) {
>                     	LOG.debug(getSessionId() + " timeout sending message: " + msg);
>                     }
>                     // What jms exception is most appropriate to throw here?
>                 }else {
>                     this.connection.syncSendPacket(msg);
>                 }
>             }
> }

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Assigned: (AMQ-2507) When using a producer/session with a send timeout, send() doesn't throw an exception if the timeout is reached.

Posted by "Dejan Bosanac (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/activemq/browse/AMQ-2507?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Dejan Bosanac reassigned AMQ-2507:
----------------------------------

    Assignee: Dejan Bosanac

> When using a producer/session with a send timeout, send() doesn't throw an exception if the timeout is reached.
> ---------------------------------------------------------------------------------------------------------------
>
>                 Key: AMQ-2507
>                 URL: https://issues.apache.org/activemq/browse/AMQ-2507
>             Project: ActiveMQ
>          Issue Type: Improvement
>          Components: Broker
>    Affects Versions: 5.3.0
>         Environment: All platforms, 5.3.x
>            Reporter: Dave Stanley
>            Assignee: Dejan Bosanac
>         Attachments: producer_timeout_test.txt
>
>
> In the attached testcase we set a low broker memory limit (to force a producer to block due to the memory usage limit being hit), and also set a sendtimeout on the connection to force the producer.send() to return if it cannot send a message within the timeout period.
> On running the test the broker sends messages until the timeout kicks in. Once the hits the memory limit it blocks and the producer.send() returns after the timeout.
> The problem is there is no way to know that the send() failed. This improvement is to modify the session to throw an exception of some kind when the sendTimeout is reached.
> I have attached the testcase without a fix as its not clear the best approach to fix.
> One possible solution is to modify ActiveMQSession, but need some clarification on whats the best JMSException to throw.  It doesn't look like this is explicitly spelled out in the JMS Spec.
> General area is the send() method
> protected void send(ActiveMQMessageProducer producer, ActiveMQDestination destination, Message message, int deliveryMode, int priority, long timeToLive,
>                         MemoryUsage producerWindow, int sendTimeout) throws JMSException {
>            .....
>            if (sendTimeout <= 0 && !msg.isResponseRequired() && !connection.isAlwaysSyncSend() && (!msg.isPersistent() || connection.isUseAsyncSend() || txid != null)) {
>                 this.connection.asyncSendPacket(msg);
>                 if (producerWindow != null) {
>                     // Since we defer lots of the marshaling till we hit the
>                     // wire, this might not
>                     // provide and accurate size. We may change over to doing
>                     // more aggressive marshaling,
>                     // to get more accurate sizes.. this is more important once
>                     // users start using producer window
>                     // flow control.
>                     int size = msg.getSize();
>                     producerWindow.increaseUsage(size);
>                 }
>             } else {
>                 // Handle send timeout here
>                 if (sendTimeout > 0) {
>                 	Object response = this.connection.syncSendPacket(msg,sendTimeout);
>                     if(response == null) {
>                     	LOG.debug(getSessionId() + " timeout sending message: " + msg);
>                     }
>                     // What jms exception is most appropriate to throw here?
>                 }else {
>                     this.connection.syncSendPacket(msg);
>                 }
>             }
> }

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.