MARC BOULANGER created CAMEL-17486:
--------------------------------------

             Summary: ThrottlePermit compareTo cast to int causes issues
                 Key: CAMEL-17486
                 URL: https://issues.apache.org/jira/browse/CAMEL-17486
             Project: Camel
          Issue Type: Bug
          Components: camel-core
            Reporter: MARC BOULANGER


When a Throttler has not been used for longer than Integer#MAX_VALUE, casting 
the result of the ThrottlePermit comparison to an int causes a bit overflow.

Using a value comparison prevents this issue.
 
Current :
{code:java}
private static class ThrottlePermit implements Delayed {

    @Override
    public int compareTo(final Delayed o) {
        return (int) (getDelay(TimeUnit.MILLISECONDS) - 
o.getDelay(TimeUnit.MILLISECONDS));
    }
}
{code}

Proposal :
{code:java}
private static class ThrottlePermit implements Delayed {

        @Override
        public int compareTo(final Delayed o) {
            return Long.compare(getDelay(TimeUnit.MILLISECONDS), 
o.getDelay(TimeUnit.MILLISECONDS));
        }
}
{code}

Unit Test :
{code:java}
public class ThrottlerPermitTest {

    /**
     *   When a Throttler has not been used for longer than {@link 
java.lang.Integer#MAX_VALUE},
     *   casting the result of the {@link ThrottlePermit} comparison to an int 
causes a bit overflow.
     *   Using a value comparison prevents this issue.
     **/
    @Test
    public void testThrottlerPermitWithOldScheduledTime() {
        long timeMillis = System.currentTimeMillis();
        // 30 days in the past
        ThrottlePermit throttlePermitOld = new ThrottlePermit(timeMillis 
-2592000000L);
        // Now
        ThrottlePermit throttlePermitNow = new ThrottlePermit(timeMillis);
        ThrottlePermit throttlePermitNow2 = new ThrottlePermit(timeMillis);
        // Future
        ThrottlePermit throttlePermitFuture = new ThrottlePermit(timeMillis + 
1000);

        assertEquals(-1, throttlePermitOld.compareTo(throttlePermitNow));
        assertEquals(0, throttlePermitNow.compareTo(throttlePermitNow2));
        assertEquals(1, throttlePermitFuture.compareTo(throttlePermitNow));
    }

    private final class ThrottlePermit implements Delayed {
        private volatile long scheduledTime;

        ThrottlePermit(final long delayMs) {
            setDelayMs(delayMs);
        }

        public void setDelayMs(final long delayMs) {
            this.scheduledTime = System.currentTimeMillis() + delayMs;
        }

        @Override
        public long getDelay(final TimeUnit unit) {
            return unit.convert(scheduledTime - System.currentTimeMillis(), 
TimeUnit.MILLISECONDS);
        }

        @Override
        public int compareTo(final Delayed o) {
            return Long.compare(getDelay(TimeUnit.MILLISECONDS), 
o.getDelay(TimeUnit.MILLISECONDS));
        }
    }
}
{code}



--
This message was sent by Atlassian Jira
(v8.20.1#820001)

Reply via email to