summaryrefslogtreecommitdiffstats
path: root/vespajlib/src/main/java/com/yahoo/time
diff options
context:
space:
mode:
authorHÃ¥kon Hallingstad <hakon@oath.com>2018-06-22 10:44:26 +0200
committerGitHub <noreply@github.com>2018-06-22 10:44:26 +0200
commitd17e36f062c38550a96ccee3e41d7ff5266efecb (patch)
treeacfd09d394e792ac1f6733d47236177e3db68fea /vespajlib/src/main/java/com/yahoo/time
parentea9a1eea042617764dfe474cf161e422d1123338 (diff)
parent02f23addf2fe400e3eeadcee30b1ca9aba12953c (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')
-rw-r--r--vespajlib/src/main/java/com/yahoo/time/TimeBudget.java65
-rw-r--r--vespajlib/src/main/java/com/yahoo/time/WallClockSource.java118
-rw-r--r--vespajlib/src/main/java/com/yahoo/time/package-info.java5
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;