summaryrefslogtreecommitdiffstats
path: root/vespajlib
diff options
context:
space:
mode:
authorValerij Fredriksen <valerij92@gmail.com>2021-02-26 10:54:42 +0100
committerValerij Fredriksen <valerij92@gmail.com>2021-02-26 14:58:20 +0100
commit73650649da0a0c3b60aefd06ef2043b55dafa604 (patch)
tree06265bbe2d7cae51cc7f4d367ee38aad2de086d3 /vespajlib
parent0dc96d22e51bf22e7afaa4e99abeed1c8c1bad43 (diff)
Crete CachedSupplier
Diffstat (limited to 'vespajlib')
-rw-r--r--vespajlib/src/main/java/com/yahoo/lang/CachedSupplier.java52
-rw-r--r--vespajlib/src/test/java/com/yahoo/lang/CachedSupplierTest.java39
2 files changed, 91 insertions, 0 deletions
diff --git a/vespajlib/src/main/java/com/yahoo/lang/CachedSupplier.java b/vespajlib/src/main/java/com/yahoo/lang/CachedSupplier.java
new file mode 100644
index 00000000000..07ce1250855
--- /dev/null
+++ b/vespajlib/src/main/java/com/yahoo/lang/CachedSupplier.java
@@ -0,0 +1,52 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.lang;
+
+import java.time.Clock;
+import java.time.Duration;
+import java.time.Instant;
+import java.util.function.Supplier;
+
+/**
+ * Supplier that caches the value for a given duration with ability to invalidate at demand.
+ * Is thread safe.
+ *
+ * @author freva
+ */
+public class CachedSupplier<T> implements Supplier<T> {
+
+ private final Supplier<T> delegate;
+ private final Duration period;
+ private final Clock clock;
+
+ private Instant nextRefresh;
+ private volatile T value;
+
+ public CachedSupplier(Supplier<T> delegate, Duration period) {
+ this(delegate, period, Clock.systemUTC());
+ }
+
+ CachedSupplier(Supplier<T> delegate, Duration period, Clock clock) {
+ this.delegate = delegate;
+ this.period = period;
+ this.clock = clock;
+ this.nextRefresh = Instant.MIN;
+ }
+
+ @Override
+ public T get() {
+ synchronized (this) {
+ if (clock.instant().isAfter(nextRefresh))
+ refresh();
+ }
+
+ return value;
+ }
+
+ public void refresh() {
+ synchronized (this) {
+ this.value = delegate.get();
+ this.nextRefresh = clock.instant().plus(period);
+ }
+ }
+
+}
diff --git a/vespajlib/src/test/java/com/yahoo/lang/CachedSupplierTest.java b/vespajlib/src/test/java/com/yahoo/lang/CachedSupplierTest.java
new file mode 100644
index 00000000000..b0dc1262ebc
--- /dev/null
+++ b/vespajlib/src/test/java/com/yahoo/lang/CachedSupplierTest.java
@@ -0,0 +1,39 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.lang;
+
+import com.yahoo.test.ManualClock;
+import org.junit.Test;
+
+import java.time.Duration;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @author freva
+ */
+public class CachedSupplierTest {
+
+ @Test
+ public void test() {
+ ManualClock clock = new ManualClock();
+ MutableInteger integer = new MutableInteger(0);
+ CachedSupplier<Integer> supplier = new CachedSupplier<>(() -> integer.add(1), Duration.ofMinutes(1), clock);
+
+ assertEquals(1, supplier.get().intValue());
+ assertEquals(1, supplier.get().intValue());
+
+ clock.advance(Duration.ofSeconds(30));
+ assertEquals(1, supplier.get().intValue());
+
+ clock.advance(Duration.ofSeconds(31));
+ assertEquals(2, supplier.get().intValue());
+ assertEquals(2, supplier.get().intValue());
+
+ supplier.refresh();
+ assertEquals(3, supplier.get().intValue());
+ assertEquals(3, supplier.get().intValue());
+
+ clock.advance(Duration.ofSeconds(61));
+ assertEquals(4, supplier.get().intValue());
+ }
+}