You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@activemq.apache.org by "Eddie Epstein (JIRA)" <ji...@apache.org> on 2008/06/30 23:28:00 UTC

[jira] Created: (AMQCPP-186) CMSExpiration computed incorrectly (?)

CMSExpiration computed incorrectly (?)
--------------------------------------

                 Key: AMQCPP-186
                 URL: https://issues.apache.org/activemq/browse/AMQCPP-186
             Project: ActiveMQ C++ Client
          Issue Type: Bug
    Affects Versions: 2.1.3
            Reporter: Eddie Epstein
            Assignee: Nathan Mittler


The C++ consumer is treating messages as expired in situations where the Java consumer is not.

It could be that the problem is due to the code in connector/openwire/commands/ActiveMQMessageBase.h which compares the CMSExpiration time specified by producer.setTimeToLive()  with the local clock on the consumer machine.

        /**
         * Returns if this message has expired, meaning that its
         * Expiration time has elapsed.
         * @returns true if message is expired.
         */
        virtual bool isExpired() const {
            long long expireTime = this->getCMSExpiration();
            long long currentTime = decaf::util::Date::getCurrentTimeMilliseconds();
            if( expireTime > 0 && currentTime > expireTime ) {
                return true;
            }
            return false;
        }



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


[jira] Commented: (AMQCPP-186) CMSExpiration computed incorrectly (?)

Posted by "Timothy Bish (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/activemq/browse/AMQCPP-186?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=43949#action_43949 ] 

Timothy Bish commented on AMQCPP-186:
-------------------------------------

>From the JMS API

bq. SetTimeToLive - Sets the default length of time in milliseconds from its dispatch time that a produced message should be retained by the message system. 

bq. getJMSExpiration - When a message is sent, the JMSExpiration header field is left unassigned. After completion of the send or publish method, it holds the expiration time of the message. This is the sum of the time-to-live value specified by the client and the GMT at the time of the send or publish.

This implies that clock drift could cause you to lose messages on the client machines, or inversely not tag them as expired when they actually are.


> CMSExpiration computed incorrectly (?)
> --------------------------------------
>
>                 Key: AMQCPP-186
>                 URL: https://issues.apache.org/activemq/browse/AMQCPP-186
>             Project: ActiveMQ C++ Client
>          Issue Type: Bug
>    Affects Versions: 2.1.3
>            Reporter: Eddie Epstein
>            Assignee: Nathan Mittler
>
> The C++ consumer is treating messages as expired in situations where the Java consumer is not.
> It could be that the problem is due to the code in connector/openwire/commands/ActiveMQMessageBase.h which compares the CMSExpiration time specified by producer.setTimeToLive()  with the local clock on the consumer machine.
>         /**
>          * Returns if this message has expired, meaning that its
>          * Expiration time has elapsed.
>          * @returns true if message is expired.
>          */
>         virtual bool isExpired() const {
>             long long expireTime = this->getCMSExpiration();
>             long long currentTime = decaf::util::Date::getCurrentTimeMilliseconds();
>             if( expireTime > 0 && currentTime > expireTime ) {
>                 return true;
>             }
>             return false;
>         }

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


[jira] Commented: (AMQCPP-186) CMSExpiration computed incorrectly (?)

Posted by "Timothy Bish (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/activemq/browse/AMQCPP-186?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=43819#action_43819 ] 

Timothy Bish commented on AMQCPP-186:
-------------------------------------

If you could provide C++ and Java sample code to reproduce the problem that would be helpful.  The C++ isExpired code looks like this:

{noformat} 

        virtual bool isExpired() const {
            long long expireTime = this->getCMSExpiration();
            long long currentTime = decaf::util::Date::getCurrentTimeMilliseconds();
            if( expireTime > 0 && currentTime > expireTime ) {
                return true;
            }
            return false;
        }

{noformat} 

And the Java code

{noformat} 

    public boolean isExpired() {
        long expireTime = this.getExpiration();
        if (expireTime > 0 && System.currentTimeMillis() > expireTime) {
            return true;
        }
        return false;
    }

{noformat} 



> CMSExpiration computed incorrectly (?)
> --------------------------------------
>
>                 Key: AMQCPP-186
>                 URL: https://issues.apache.org/activemq/browse/AMQCPP-186
>             Project: ActiveMQ C++ Client
>          Issue Type: Bug
>    Affects Versions: 2.1.3
>            Reporter: Eddie Epstein
>            Assignee: Nathan Mittler
>
> The C++ consumer is treating messages as expired in situations where the Java consumer is not.
> It could be that the problem is due to the code in connector/openwire/commands/ActiveMQMessageBase.h which compares the CMSExpiration time specified by producer.setTimeToLive()  with the local clock on the consumer machine.
>         /**
>          * Returns if this message has expired, meaning that its
>          * Expiration time has elapsed.
>          * @returns true if message is expired.
>          */
>         virtual bool isExpired() const {
>             long long expireTime = this->getCMSExpiration();
>             long long currentTime = decaf::util::Date::getCurrentTimeMilliseconds();
>             if( expireTime > 0 && currentTime > expireTime ) {
>                 return true;
>             }
>             return false;
>         }

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


[jira] Commented: (AMQCPP-186) CMSExpiration computed incorrectly (?)

Posted by "Eddie Epstein (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/activemq/browse/AMQCPP-186?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=43961#action_43961 ] 

Eddie Epstein commented on AMQCPP-186:
--------------------------------------

bq. Yes, this is known behavior. Our solution has been to turn on the timestamp plug-in that will override the producer's timestamp, and adjust the message's timestamps to be in-sync with the broker machine's time.

As I understand it, the TimeStampingBrokerPlugin changes the message timestamp set by the producer's clock to the equivalent time on the broker's clock. This still doesn't fix the problem because the test for expiration is done using yet a different clock: the consumer's. Seems like the only way expiration can be done properly is to do the timestamp shift as per the TimeStampingBrokerPlugin and then do the expiration test on the broker when it is fetching the next message to deliver.

Does anybody agree with this?

> CMSExpiration computed incorrectly (?)
> --------------------------------------
>
>                 Key: AMQCPP-186
>                 URL: https://issues.apache.org/activemq/browse/AMQCPP-186
>             Project: ActiveMQ C++ Client
>          Issue Type: Bug
>    Affects Versions: 2.1.3
>            Reporter: Eddie Epstein
>            Assignee: Nathan Mittler
>
> The C++ consumer is treating messages as expired in situations where the Java consumer is not.
> It could be that the problem is due to the code in connector/openwire/commands/ActiveMQMessageBase.h which compares the CMSExpiration time specified by producer.setTimeToLive()  with the local clock on the consumer machine.
>         /**
>          * Returns if this message has expired, meaning that its
>          * Expiration time has elapsed.
>          * @returns true if message is expired.
>          */
>         virtual bool isExpired() const {
>             long long expireTime = this->getCMSExpiration();
>             long long currentTime = decaf::util::Date::getCurrentTimeMilliseconds();
>             if( expireTime > 0 && currentTime > expireTime ) {
>                 return true;
>             }
>             return false;
>         }

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


[jira] Commented: (AMQCPP-186) CMSExpiration computed incorrectly (?)

Posted by "Eddie Epstein (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/activemq/browse/AMQCPP-186?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=43836#action_43836 ] 

Eddie Epstein commented on AMQCPP-186:
--------------------------------------

Yes, a simple way to reproduce this problem is to use ProducerTool from the Java distribution combined with ConsumerTool from Java and simple_async_consumer from C++.

My testing has been done using AMQ v4.1.1. 

Setup a producerMachine and a consumerMachine such that the consumer clock is 30 seconds ahead of the producer's clock.

Modify ProducerTool as follows:

{noformat}

	public static void main(String[] args) {
		ProducerTool producerTool = new ProducerTool();
+		producerTool.url = "tcp://consumerMachine:61616";
+		producerTool.subject="TEST.FOO";
+		producerTool.timeToLive=20000;

{noformat}


Modify the java ConsumerTool:

{noformat}

	public static void main(String[] args) {
		ConsumerTool consumerTool = new ConsumerTool();
+		consumerTool.subject = "TEST.FOO";

{noformat}


Run the java ConsumerTool on consumerMachine and then the java ProducerTool on the producer machine. The messages are received by the consumer.

Stop the java ConsumerTool, start the C++ simple_async_consumer on the consumer machine, and run the ProducerTool. No messages are received, but the JMX stats on the broker will show all the messages as being delivered.

Change producer timeToLive to be 0 or greater than the time difference between machines and the C++ consumer will work.



> CMSExpiration computed incorrectly (?)
> --------------------------------------
>
>                 Key: AMQCPP-186
>                 URL: https://issues.apache.org/activemq/browse/AMQCPP-186
>             Project: ActiveMQ C++ Client
>          Issue Type: Bug
>    Affects Versions: 2.1.3
>            Reporter: Eddie Epstein
>            Assignee: Nathan Mittler
>
> The C++ consumer is treating messages as expired in situations where the Java consumer is not.
> It could be that the problem is due to the code in connector/openwire/commands/ActiveMQMessageBase.h which compares the CMSExpiration time specified by producer.setTimeToLive()  with the local clock on the consumer machine.
>         /**
>          * Returns if this message has expired, meaning that its
>          * Expiration time has elapsed.
>          * @returns true if message is expired.
>          */
>         virtual bool isExpired() const {
>             long long expireTime = this->getCMSExpiration();
>             long long currentTime = decaf::util::Date::getCurrentTimeMilliseconds();
>             if( expireTime > 0 && currentTime > expireTime ) {
>                 return true;
>             }
>             return false;
>         }

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


[jira] Commented: (AMQCPP-186) CMSExpiration computed incorrectly (?)

Posted by "Jim Gomes (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/activemq/browse/AMQCPP-186?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=43913#action_43913 ] 

Jim Gomes commented on AMQCPP-186:
----------------------------------

Yes, this is known behavior.  Our solution has been to turn on the timestamp plug-in that will override the producer's timestamp, and adjust the message's timestamps to be in-sync with the broker machine's time.

> CMSExpiration computed incorrectly (?)
> --------------------------------------
>
>                 Key: AMQCPP-186
>                 URL: https://issues.apache.org/activemq/browse/AMQCPP-186
>             Project: ActiveMQ C++ Client
>          Issue Type: Bug
>    Affects Versions: 2.1.3
>            Reporter: Eddie Epstein
>            Assignee: Nathan Mittler
>
> The C++ consumer is treating messages as expired in situations where the Java consumer is not.
> It could be that the problem is due to the code in connector/openwire/commands/ActiveMQMessageBase.h which compares the CMSExpiration time specified by producer.setTimeToLive()  with the local clock on the consumer machine.
>         /**
>          * Returns if this message has expired, meaning that its
>          * Expiration time has elapsed.
>          * @returns true if message is expired.
>          */
>         virtual bool isExpired() const {
>             long long expireTime = this->getCMSExpiration();
>             long long currentTime = decaf::util::Date::getCurrentTimeMilliseconds();
>             if( expireTime > 0 && currentTime > expireTime ) {
>                 return true;
>             }
>             return false;
>         }

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


[jira] Commented: (AMQCPP-186) CMSExpiration computed incorrectly (?)

Posted by "Eddie Epstein (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/activemq/browse/AMQCPP-186?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=43910#action_43910 ] 

Eddie Epstein commented on AMQCPP-186:
--------------------------------------

Re-tested this scenario with AMQ 5.1.0. There are two changes in behavior:

1. the Java consumer is now the same as cpp
2. the broker moves the messages to the DLQ.

So with 5.1.0 the behavior is broken for both Java and cpp: message expiration is affected by the clock differences between producer and consumer machines. Is this a known limitation?

https://issues.apache.org/activemq/browse/AMQ-1162 made the same comment last year, but that issue is marked fixed. Doesn't look fixed as of 5.1.0.

Should this issue be moved to a different category?

Thanks,
Eddie

> CMSExpiration computed incorrectly (?)
> --------------------------------------
>
>                 Key: AMQCPP-186
>                 URL: https://issues.apache.org/activemq/browse/AMQCPP-186
>             Project: ActiveMQ C++ Client
>          Issue Type: Bug
>    Affects Versions: 2.1.3
>            Reporter: Eddie Epstein
>            Assignee: Nathan Mittler
>
> The C++ consumer is treating messages as expired in situations where the Java consumer is not.
> It could be that the problem is due to the code in connector/openwire/commands/ActiveMQMessageBase.h which compares the CMSExpiration time specified by producer.setTimeToLive()  with the local clock on the consumer machine.
>         /**
>          * Returns if this message has expired, meaning that its
>          * Expiration time has elapsed.
>          * @returns true if message is expired.
>          */
>         virtual bool isExpired() const {
>             long long expireTime = this->getCMSExpiration();
>             long long currentTime = decaf::util::Date::getCurrentTimeMilliseconds();
>             if( expireTime > 0 && currentTime > expireTime ) {
>                 return true;
>             }
>             return false;
>         }

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


[jira] Closed: (AMQCPP-186) CMSExpiration computed incorrectly (?)

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

Timothy Bish closed AMQCPP-186.
-------------------------------

      Assignee: Timothy Bish  (was: Nathan Mittler)
    Resolution: Won't Fix

Non-issue.

> CMSExpiration computed incorrectly (?)
> --------------------------------------
>
>                 Key: AMQCPP-186
>                 URL: https://issues.apache.org/activemq/browse/AMQCPP-186
>             Project: ActiveMQ C++ Client
>          Issue Type: Bug
>    Affects Versions: 2.1.3
>            Reporter: Eddie Epstein
>            Assignee: Timothy Bish
>
> The C++ consumer is treating messages as expired in situations where the Java consumer is not.
> It could be that the problem is due to the code in connector/openwire/commands/ActiveMQMessageBase.h which compares the CMSExpiration time specified by producer.setTimeToLive()  with the local clock on the consumer machine.
>         /**
>          * Returns if this message has expired, meaning that its
>          * Expiration time has elapsed.
>          * @returns true if message is expired.
>          */
>         virtual bool isExpired() const {
>             long long expireTime = this->getCMSExpiration();
>             long long currentTime = decaf::util::Date::getCurrentTimeMilliseconds();
>             if( expireTime > 0 && currentTime > expireTime ) {
>                 return true;
>             }
>             return false;
>         }

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


[jira] Commented: (AMQCPP-186) CMSExpiration computed incorrectly (?)

Posted by "Timothy Bish (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/activemq/browse/AMQCPP-186?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=43974#action_43974 ] 

Timothy Bish commented on AMQCPP-186:
-------------------------------------

Even if you did that you'd still have to do it at the client as the broker can't account for the time a message spends in transmission or the time it sits in the client's dispatch queue before being dispatched.  So in either case there are still going to be several clocks involved, so a more optimal solution would be to use NTP to sync the clocks and the client and broker machines if you require the message TLL processing to be accurate.  

As it stands this is not an ActiveMQ-CPP issue though so I'm going to close it here, you are free to open an issue on the broker if you think it appropriate.



> CMSExpiration computed incorrectly (?)
> --------------------------------------
>
>                 Key: AMQCPP-186
>                 URL: https://issues.apache.org/activemq/browse/AMQCPP-186
>             Project: ActiveMQ C++ Client
>          Issue Type: Bug
>    Affects Versions: 2.1.3
>            Reporter: Eddie Epstein
>            Assignee: Nathan Mittler
>
> The C++ consumer is treating messages as expired in situations where the Java consumer is not.
> It could be that the problem is due to the code in connector/openwire/commands/ActiveMQMessageBase.h which compares the CMSExpiration time specified by producer.setTimeToLive()  with the local clock on the consumer machine.
>         /**
>          * Returns if this message has expired, meaning that its
>          * Expiration time has elapsed.
>          * @returns true if message is expired.
>          */
>         virtual bool isExpired() const {
>             long long expireTime = this->getCMSExpiration();
>             long long currentTime = decaf::util::Date::getCurrentTimeMilliseconds();
>             if( expireTime > 0 && currentTime > expireTime ) {
>                 return true;
>             }
>             return false;
>         }

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