diff options
author | Valerij Fredriksen <valerij92@gmail.com> | 2021-02-26 10:54:42 +0100 |
---|---|---|
committer | Valerij Fredriksen <valerij92@gmail.com> | 2021-02-26 14:58:20 +0100 |
commit | 73650649da0a0c3b60aefd06ef2043b55dafa604 (patch) | |
tree | 06265bbe2d7cae51cc7f4d367ee38aad2de086d3 /vespajlib | |
parent | 0dc96d22e51bf22e7afaa4e99abeed1c8c1bad43 (diff) |
Crete CachedSupplier
Diffstat (limited to 'vespajlib')
-rw-r--r-- | vespajlib/src/main/java/com/yahoo/lang/CachedSupplier.java | 52 | ||||
-rw-r--r-- | vespajlib/src/test/java/com/yahoo/lang/CachedSupplierTest.java | 39 |
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()); + } +} |