diff options
author | HÃ¥kon Hallingstad <hakon@oath.com> | 2018-06-22 09:29:45 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-06-22 09:29:45 +0200 |
commit | 47bde30f37a075c664116fc918252573fc472ab7 (patch) | |
tree | 8da6f593afbdacb8e88f49278574991803d274c3 /vespajlib | |
parent | 7b34c4af8e19d5ccaad898b7c289433d8a6a7395 (diff) |
Revert "Revert "Move TimeBudget to vespajlib and use Clock""
Diffstat (limited to 'vespajlib')
-rw-r--r-- | vespajlib/pom.xml | 6 | ||||
-rw-r--r-- | vespajlib/src/main/java/com/yahoo/time/TimeBudget.java | 65 | ||||
-rw-r--r-- | vespajlib/src/test/java/com/yahoo/time/TimeBudgetTestCase.java | 40 |
3 files changed, 111 insertions, 0 deletions
diff --git a/vespajlib/pom.xml b/vespajlib/pom.xml index 81c385c96ab..880d039bc54 100644 --- a/vespajlib/pom.xml +++ b/vespajlib/pom.xml @@ -71,6 +71,12 @@ <groupId>org.apache.commons</groupId> <artifactId>commons-exec</artifactId> </dependency> + <dependency> + <groupId>com.yahoo.vespa</groupId> + <artifactId>testutil</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> </dependencies> <build> <plugins> diff --git a/vespajlib/src/main/java/com/yahoo/time/TimeBudget.java b/vespajlib/src/main/java/com/yahoo/time/TimeBudget.java new file mode 100644 index 00000000000..fa18cb5e467 --- /dev/null +++ b/vespajlib/src/main/java/com/yahoo/time/TimeBudget.java @@ -0,0 +1,65 @@ +// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.time; + +import com.google.common.util.concurrent.UncheckedTimeoutException; + +import java.time.Clock; +import java.time.Duration; +import java.time.Instant; + +/** + * A TimeBudget can be used to track the time of an ongoing operation with a timeout. + * + * @author hakon + */ +public class TimeBudget { + private final Clock clock; + private final Instant start; + private final Duration timeout; + + /** Returns a TimeBudget with a start time of now, and with the given timeout. */ + public static TimeBudget fromNow(Clock clock, Duration timeout) { + return new TimeBudget(clock, clock.instant(), timeout); + } + + private TimeBudget(Clock clock, Instant start, Duration timeout) { + this.clock = clock; + this.start = start; + this.timeout = makeNonNegative(timeout); + } + + /** Returns time since start. */ + public Duration timePassed() { + return nonNegativeBetween(start, clock.instant()); + } + + /** Returns the original timeout. */ + public Duration originalTimeout() { + return timeout; + } + + /** + * Returns the time until deadline. + * + * @return time until deadline. It's toMillis() is guaranteed to be positive. + * @throws UncheckedTimeoutException if the deadline has been reached or passed. + */ + public Duration timeLeftOrThrow() { + Instant now = clock.instant(); + Duration left = Duration.between(now, start.plus(timeout)); + if (left.toMillis() <= 0) { + throw new UncheckedTimeoutException("Time since start " + nonNegativeBetween(start, now) + + " exceeds timeout " + timeout); + } + + return left; + } + + private static Duration nonNegativeBetween(Instant start, Instant end) { + return makeNonNegative(Duration.between(start, end)); + } + + private static Duration makeNonNegative(Duration duration) { + return duration.isNegative() ? Duration.ZERO : duration; + } +} diff --git a/vespajlib/src/test/java/com/yahoo/time/TimeBudgetTestCase.java b/vespajlib/src/test/java/com/yahoo/time/TimeBudgetTestCase.java new file mode 100644 index 00000000000..ddd57c71a0d --- /dev/null +++ b/vespajlib/src/test/java/com/yahoo/time/TimeBudgetTestCase.java @@ -0,0 +1,40 @@ +// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.time; + +import com.google.common.util.concurrent.UncheckedTimeoutException; +import com.yahoo.test.ManualClock; +import org.junit.Test; + +import java.time.Clock; +import java.time.Duration; +import java.time.Instant; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; +import static org.mockito.Mockito.mock; + +public class TimeBudgetTestCase { + private final Clock clock = mock(Clock.class); + + @Test + public void testBasics() { + ManualClock clock = new ManualClock(); + clock.setInstant(Instant.ofEpochSecond(0)); + TimeBudget timeBudget = TimeBudget.fromNow(clock, Duration.ofSeconds(10)); + + clock.advance(Duration.ofSeconds(7)); + assertEquals(Duration.ofSeconds(3), timeBudget.timeLeftOrThrow()); + + // Verify that toMillis() of >=1 is fine, but 0 is not. + + clock.setInstant(Instant.ofEpochSecond(9, 999000000)); + assertEquals(1, timeBudget.timeLeftOrThrow().toMillis()); + clock.setInstant(Instant.ofEpochSecond(9, 999000001)); + try { + timeBudget.timeLeftOrThrow(); + fail(); + } catch (UncheckedTimeoutException e) { + // OK + } + } +}
\ No newline at end of file |