diff options
author | HÃ¥kon Hallingstad <hakon@oath.com> | 2018-06-22 10:44:26 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-06-22 10:44:26 +0200 |
commit | d17e36f062c38550a96ccee3e41d7ff5266efecb (patch) | |
tree | acfd09d394e792ac1f6733d47236177e3db68fea /vespajlib/src/main/java/com/yahoo/time | |
parent | ea9a1eea042617764dfe474cf161e422d1123338 (diff) | |
parent | 02f23addf2fe400e3eeadcee30b1ca9aba12953c (diff) |
Merge pull request #6264 from vespa-engine/revert-6260-revert-6256-hakonhall/move-timebudget-to-vespajlib-and-use-clock
Revert "Revert "Move TimeBudget to vespajlib and use Clock""
Diffstat (limited to 'vespajlib/src/main/java/com/yahoo/time')
3 files changed, 70 insertions, 118 deletions
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/main/java/com/yahoo/time/WallClockSource.java b/vespajlib/src/main/java/com/yahoo/time/WallClockSource.java deleted file mode 100644 index 8a77879adf5..00000000000 --- a/vespajlib/src/main/java/com/yahoo/time/WallClockSource.java +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright 2017 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.annotations.Beta; - -/** - * A source for high-resolution timestamps. - * - * @author arnej27959 - */ - -@Beta -public class WallClockSource { - - private volatile long offset; - - /** - * Obtain the current time in nanoseconds. - * The epoch is January 1, 1970 UTC just as for System.currentTimeMillis(), - * but with greater resolution. Note that the absolute accuracy may be - * no better than currentTimeMills(). - * @return nanoseconds since the epoch. - **/ - public final long currentTimeNanos() { - return System.nanoTime() + offset; - } - - /** - * Create a source with 1 millisecond accuracy at start. - **/ - WallClockSource() { - long actual = System.currentTimeMillis(); - actual *= 1000000; - this.offset = actual - System.nanoTime(); - initialAdjust(); - } - - /** adjust the clock source from currentTimeMillis() - * to ensure that it is no more than 1 milliseconds off. - * @return true if we want adjust called again soon - **/ - boolean adjust() { - long nanosB = System.nanoTime(); - long actual = System.currentTimeMillis(); - long nanosA = System.nanoTime(); - if (nanosA - nanosB > 100000) { - return true; // not a good time to adjust, try again soon - } - return adjustOffset(nanosB, actual, nanosA); - } - - private boolean adjustOffset(long before, long actual, long after) { - actual *= 1000000; // convert millis to nanos - if (actual > after + offset) { - // System.out.println("WallClockSource adjust UP "+(actual-after-offset)); - offset = actual - after; - return true; - } - if (actual + 999999 < before + offset) { - // System.out.println("WallClockSource adjust DOWN "+(before+offset-actual-999999)); - offset = actual + 999999 - before; - return true; - } - return false; - } - - private void initialAdjust() { - for (int i = 0; i < 100; i++) { - long nanosB = System.nanoTime(); - long actual = System.currentTimeMillis(); - long nanosA = System.nanoTime(); - adjustOffset(nanosB, actual, nanosA); - } - } - - - static private WallClockSource autoAdjustingInstance = new WallClockSource(); - - /** - * Get a WallClockSource which auto adjusts to wall clock time. - **/ - static public WallClockSource get() { - autoAdjustingInstance.startAdjuster(); - return autoAdjustingInstance; - } - - private Thread adjuster; - - private synchronized void startAdjuster() { - if (adjuster == null) { - adjuster = new AdjustThread(); - adjuster.setDaemon(true); - adjuster.start(); - } - } - - private class AdjustThread extends Thread { - public void run() { - int millis = 0; - int nanos = 313373; // random number - while (true) { - try { - sleep(millis, nanos); - if (++millis > 4321) { - millis = 1000; // do not sleep too long - } - } catch (InterruptedException e) { - return; - } - if (adjust()) { - // adjust more often in case clock jumped - millis = 0; - } - } - } - } - -} diff --git a/vespajlib/src/main/java/com/yahoo/time/package-info.java b/vespajlib/src/main/java/com/yahoo/time/package-info.java new file mode 100644 index 00000000000..1b24da17655 --- /dev/null +++ b/vespajlib/src/main/java/com/yahoo/time/package-info.java @@ -0,0 +1,5 @@ +// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +@ExportPackage +package com.yahoo.time; + +import com.yahoo.osgi.annotation.ExportPackage; |