show the removal listener of HotEntryCache is not called on expire
This commit is contained in:
@@ -1,301 +1,30 @@
|
|||||||
//package org.lucares.utils.cache;
|
package org.lucares.utils.cache;
|
||||||
//
|
|
||||||
//import java.time.Duration;
|
import java.time.Duration;
|
||||||
//import java.time.Instant;
|
import java.util.concurrent.CountDownLatch;
|
||||||
//import java.util.ArrayList;
|
import java.util.concurrent.TimeUnit;
|
||||||
//import java.util.Arrays;
|
|
||||||
//import java.util.List;
|
import org.testng.Assert;
|
||||||
//import java.util.concurrent.CompletableFuture;
|
import org.testng.annotations.Test;
|
||||||
//import java.util.concurrent.CountDownLatch;
|
|
||||||
//import java.util.concurrent.ExecutionException;
|
@Test
|
||||||
//import java.util.concurrent.ExecutorService;
|
public class HotEntryCacheTest {
|
||||||
//import java.util.concurrent.Executors;
|
|
||||||
//import java.util.concurrent.TimeUnit;
|
@Test(invocationCount = 1)
|
||||||
//import java.util.concurrent.TimeoutException;
|
public void testRemovalListenerCalledOnExpire() throws InterruptedException
|
||||||
//
|
{
|
||||||
//import org.apache.logging.log4j.Level;
|
final String key = "key";
|
||||||
//import org.apache.logging.log4j.core.config.Configurator;
|
final String value ="value";
|
||||||
//import org.lucares.utils.cache.HotEntryCache.EventType;
|
final CountDownLatch latch = new CountDownLatch(1);
|
||||||
//import org.testng.Assert;
|
|
||||||
//import org.testng.annotations.Test;
|
final HotEntryCache<String, String> cache = new HotEntryCache<>(Duration.ofMillis(10), 10);
|
||||||
//
|
cache.addListener((k, v) -> {
|
||||||
//@Test
|
Assert.assertEquals(k, key);
|
||||||
//public class HotEntryCacheTest {
|
Assert.assertEquals(v, value);
|
||||||
// public void testPutAndGet() throws InterruptedException, ExecutionException, TimeoutException {
|
latch.countDown();
|
||||||
// final HotEntryCache<String, String> cache = new HotEntryCache<>(Duration.ofSeconds(10));
|
});
|
||||||
//
|
|
||||||
// final String replacedNull = cache.put("key", "value1");
|
cache.put(key, value);
|
||||||
// Assert.assertEquals(replacedNull, null);
|
Assert.assertTrue(latch.await(100, TimeUnit.MILLISECONDS), "removal listener called");
|
||||||
//
|
}
|
||||||
// final String cachedValue1 = cache.get("key");
|
}
|
||||||
// Assert.assertEquals(cachedValue1, "value1");
|
|
||||||
//
|
|
||||||
// final String replacedValue1 = cache.put("key", "value2");
|
|
||||||
// Assert.assertEquals(replacedValue1, "value1");
|
|
||||||
//
|
|
||||||
// final String cachedValue2 = cache.get("key");
|
|
||||||
// Assert.assertEquals(cachedValue2, "value2");
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public void testPutTouches() throws InterruptedException, ExecutionException, TimeoutException {
|
|
||||||
// final ModifiableFixedTimeClock clock = new ModifiableFixedTimeClock();
|
|
||||||
// final Duration timeToLive = Duration.ofSeconds(10);
|
|
||||||
// final HotEntryCache<String, String> cache = new HotEntryCache<>(timeToLive, clock);
|
|
||||||
//
|
|
||||||
// cache.put("key", "value1");
|
|
||||||
//
|
|
||||||
// clock.plusSeconds(2);
|
|
||||||
// cache.updateTime();
|
|
||||||
//
|
|
||||||
// cache.put("key", "value2");
|
|
||||||
//
|
|
||||||
// clock.plus(timeToLive.minusSeconds(1));
|
|
||||||
// cache.triggerEvictionAndWait();
|
|
||||||
// // at this point the entry would have been evicted it it was not touched by the
|
|
||||||
// // second put.
|
|
||||||
//
|
|
||||||
// final String cachedValue2 = cache.get("key");
|
|
||||||
// Assert.assertEquals(cachedValue2, "value2");
|
|
||||||
//
|
|
||||||
// clock.plus(timeToLive.plusSeconds(1));
|
|
||||||
// // time elapsed since the last put: timeToLive +1s
|
|
||||||
// cache.triggerEvictionAndWait();
|
|
||||||
//
|
|
||||||
// final String cachedValue1_evicted = cache.get("key");
|
|
||||||
// Assert.assertEquals(cachedValue1_evicted, null);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public void testGetTouches() throws Exception {
|
|
||||||
// final ModifiableFixedTimeClock clock = new ModifiableFixedTimeClock();
|
|
||||||
// final Duration timeToLive = Duration.ofSeconds(10);
|
|
||||||
// final HotEntryCache<String, String> cache = new HotEntryCache<>(timeToLive, clock);
|
|
||||||
//
|
|
||||||
// cache.put("key", "value1");
|
|
||||||
//
|
|
||||||
// // skip forward in time, but do not yet trigger eviction
|
|
||||||
// clock.plus(timeToLive.plusMillis(1));
|
|
||||||
// cache.updateTime();
|
|
||||||
//
|
|
||||||
// cache.get("key"); // will touch the entry
|
|
||||||
//
|
|
||||||
// cache.triggerEvictionAndWait(); // if get didn't touch, then this will evict the entry
|
|
||||||
//
|
|
||||||
// final String cachedValue1 = cache.get("key");
|
|
||||||
// Assert.assertEquals(cachedValue1, "value1");
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public void testEvictionByBackgroundThread() throws InterruptedException, ExecutionException, TimeoutException {
|
|
||||||
// final ModifiableFixedTimeClock clock = new ModifiableFixedTimeClock();
|
|
||||||
// final Duration timeToLive = Duration.ofSeconds(10);
|
|
||||||
// final HotEntryCache<String, String> cache = new HotEntryCache<>(timeToLive, clock);
|
|
||||||
//
|
|
||||||
// final CompletableFuture<String> evictionEventFuture = new CompletableFuture<>();
|
|
||||||
// cache.addListener(event -> {
|
|
||||||
// evictionEventFuture.complete(event.getValue());
|
|
||||||
// }, EventType.EVICTED);
|
|
||||||
//
|
|
||||||
// cache.put("key", "value1");
|
|
||||||
//
|
|
||||||
// clock.plus(timeToLive.minusSeconds(1));
|
|
||||||
// cache.updateTime();
|
|
||||||
//
|
|
||||||
// cache.put("key2", "value2");
|
|
||||||
// clock.plus(Duration.ofSeconds(1).plusMillis(1));
|
|
||||||
// cache.triggerEvictionAndWait();
|
|
||||||
//
|
|
||||||
// final String evictedValue1 = evictionEventFuture.get(5, TimeUnit.MINUTES); // enough time for debugging
|
|
||||||
// Assert.assertEquals(evictedValue1, "value1");
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public void testRemove() throws InterruptedException, ExecutionException, TimeoutException {
|
|
||||||
// final HotEntryCache<String, String> cache = new HotEntryCache<>(Duration.ofSeconds(10));
|
|
||||||
//
|
|
||||||
// final List<String> removedValues = new ArrayList<>();
|
|
||||||
// cache.addListener(event -> removedValues.add(event.getValue()), EventType.REMOVED);
|
|
||||||
//
|
|
||||||
// cache.put("key", "value1");
|
|
||||||
//
|
|
||||||
// final String removedValue = cache.remove("key");
|
|
||||||
// Assert.assertEquals(removedValue, "value1");
|
|
||||||
//
|
|
||||||
// Assert.assertEquals(removedValues, Arrays.asList("value1"));
|
|
||||||
//
|
|
||||||
// Assert.assertEquals(cache.get("key"), null);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public void testClear() throws InterruptedException, ExecutionException, TimeoutException {
|
|
||||||
// final HotEntryCache<String, String> cache = new HotEntryCache<>(Duration.ofSeconds(10));
|
|
||||||
//
|
|
||||||
// final List<String> removedValues = new ArrayList<>();
|
|
||||||
// cache.addListener(event -> removedValues.add(event.getValue()), EventType.REMOVED);
|
|
||||||
//
|
|
||||||
// cache.put("key1", "value1");
|
|
||||||
// cache.put("key2", "value2");
|
|
||||||
//
|
|
||||||
// cache.clear();
|
|
||||||
//
|
|
||||||
// Assert.assertEquals(cache.get("key1"), null);
|
|
||||||
// Assert.assertEquals(cache.get("key2"), null);
|
|
||||||
//
|
|
||||||
// Assert.assertEquals(removedValues, Arrays.asList("value1", "value2"));
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public void testForEachTouches() throws InterruptedException, ExecutionException, TimeoutException {
|
|
||||||
// final ModifiableFixedTimeClock clock = new ModifiableFixedTimeClock();
|
|
||||||
// final Duration timeToLive = Duration.ofSeconds(10);
|
|
||||||
// final HotEntryCache<String, String> cache = new HotEntryCache<>(timeToLive, clock);
|
|
||||||
//
|
|
||||||
// final CompletableFuture<String> evictionEventFuture = new CompletableFuture<>();
|
|
||||||
// cache.addListener(event -> {
|
|
||||||
// evictionEventFuture.complete(event.getValue());
|
|
||||||
// }, EventType.EVICTED);
|
|
||||||
//
|
|
||||||
// // add value
|
|
||||||
// cache.put("key", "value1");
|
|
||||||
//
|
|
||||||
// // seek, so that it is almost evicted
|
|
||||||
// clock.plus(timeToLive.minusMillis(1));
|
|
||||||
// cache.updateTime();
|
|
||||||
//
|
|
||||||
// // the for each should touch the entries
|
|
||||||
// cache.forEach(s -> {
|
|
||||||
// /* no-op */});
|
|
||||||
//
|
|
||||||
// // seek again
|
|
||||||
// clock.plus(timeToLive.minusMillis(1));
|
|
||||||
// cache.triggerEvictionAndWait();
|
|
||||||
//
|
|
||||||
// // if the touch didn't happen, then the value is now evicted
|
|
||||||
// Assert.assertEquals(evictionEventFuture.isDone(), false);
|
|
||||||
//
|
|
||||||
// // seek again, so that the entry will get evicted
|
|
||||||
// clock.plus(timeToLive.minusMillis(1));
|
|
||||||
// cache.triggerEvictionAndWait();
|
|
||||||
//
|
|
||||||
// Assert.assertEquals(cache.get("key"), null);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// /**
|
|
||||||
// * Checks that
|
|
||||||
// * {@link HotEntryCache#putIfAbsent(Object, java.util.function.Function)
|
|
||||||
// * putIfAbsent} is atomic by calling
|
|
||||||
// * {@link HotEntryCache#putIfAbsent(Object, java.util.function.Function)
|
|
||||||
// * putIfAbsent} in two threads and asserting that the supplier was only called
|
|
||||||
// * once.
|
|
||||||
// *
|
|
||||||
// * @throws Exception
|
|
||||||
// */
|
|
||||||
// public void testPutIfAbsentIsAtomic() throws Exception {
|
|
||||||
// final HotEntryCache<String, String> cache = new HotEntryCache<>(Duration.ofSeconds(10));
|
|
||||||
//
|
|
||||||
// final ExecutorService pool = Executors.newCachedThreadPool();
|
|
||||||
// try {
|
|
||||||
// final CountDownLatch latch = new CountDownLatch(1);
|
|
||||||
//
|
|
||||||
// final String key = "key";
|
|
||||||
// final String valueA = "A";
|
|
||||||
// final String valueB = "B";
|
|
||||||
//
|
|
||||||
// pool.submit(() -> {
|
|
||||||
// cache.putIfAbsent(key, k -> {
|
|
||||||
// latch.countDown();
|
|
||||||
// sleep(TimeUnit.MILLISECONDS, 20);
|
|
||||||
// return valueA;
|
|
||||||
// });
|
|
||||||
// return null;
|
|
||||||
// });
|
|
||||||
// pool.submit(() -> {
|
|
||||||
// waitFor(latch);
|
|
||||||
// cache.putIfAbsent(key, k -> valueB);
|
|
||||||
// return null;
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// pool.shutdown();
|
|
||||||
// pool.awaitTermination(1, TimeUnit.MINUTES);
|
|
||||||
//
|
|
||||||
// final String actual = cache.get(key);
|
|
||||||
// Assert.assertEquals(actual, valueA);
|
|
||||||
// } finally {
|
|
||||||
// pool.shutdownNow();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public void testPutIfAbsentReturnsExistingValue() throws Exception {
|
|
||||||
// final HotEntryCache<String, String> cache = new HotEntryCache<>(Duration.ofSeconds(10));
|
|
||||||
//
|
|
||||||
// final String key = "key";
|
|
||||||
// final String valueA = "A";
|
|
||||||
// final String valueB = "B";
|
|
||||||
//
|
|
||||||
// cache.put(key, valueA);
|
|
||||||
//
|
|
||||||
// final String returnedByPutIfAbsent = cache.putIfAbsent(key, k -> valueB);
|
|
||||||
// Assert.assertEquals(returnedByPutIfAbsent, valueA);
|
|
||||||
//
|
|
||||||
// final String actualInCache = cache.get(key);
|
|
||||||
// Assert.assertEquals(actualInCache, valueA);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public void testPutIfAbsentDoesNotAddNull() throws Exception {
|
|
||||||
// final HotEntryCache<String, String> cache = new HotEntryCache<>(Duration.ofSeconds(10));
|
|
||||||
//
|
|
||||||
// final String key = "key";
|
|
||||||
// final String returnedByPutIfAbsent = cache.putIfAbsent(key, k -> null);
|
|
||||||
// Assert.assertNull(returnedByPutIfAbsent, null);
|
|
||||||
//
|
|
||||||
// final String actualInCache = cache.get(key);
|
|
||||||
// Assert.assertEquals(actualInCache, null);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// private void sleep(final TimeUnit timeUnit, final long timeout) {
|
|
||||||
// try {
|
|
||||||
// timeUnit.sleep(timeout);
|
|
||||||
// } catch (final InterruptedException e) {
|
|
||||||
// throw new IllegalStateException(e);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// private void waitFor(final CountDownLatch latch) {
|
|
||||||
// try {
|
|
||||||
// latch.await(1, TimeUnit.MINUTES);
|
|
||||||
// } catch (final InterruptedException e) {
|
|
||||||
// throw new IllegalStateException(e);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public static void main(final String[] args) throws InterruptedException {
|
|
||||||
//
|
|
||||||
// Configurator.setRootLevel(Level.TRACE);
|
|
||||||
//
|
|
||||||
// final Duration timeToLive = Duration.ofSeconds(1);
|
|
||||||
// final HotEntryCache<String, String> cache = new HotEntryCache<>(timeToLive);
|
|
||||||
//
|
|
||||||
// cache.addListener(event -> {
|
|
||||||
// System.out.println(Instant.now() + " evicting: " + event);
|
|
||||||
// }, EventType.EVICTED);
|
|
||||||
// cache.put("key", "value that is touched");
|
|
||||||
// for (int i = 0; i < 20; i++) {
|
|
||||||
//
|
|
||||||
// System.out.println(Instant.now() + " putting value" + i);
|
|
||||||
// cache.put("key" + i, "value" + i);
|
|
||||||
// cache.put("key", "value that is touched" + i);
|
|
||||||
// TimeUnit.MILLISECONDS.sleep(450);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// for (int i = 20; i < 23; i++) {
|
|
||||||
// System.out.println(Instant.now() + " putting value" + i);
|
|
||||||
// cache.put("key" + i, "value" + i);
|
|
||||||
// TimeUnit.MILLISECONDS.sleep(Duration.ofSeconds(5).plusMillis(10).toMillis());
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// TimeUnit.MILLISECONDS.sleep(Duration.ofSeconds(5).plusMillis(10).toMillis());
|
|
||||||
//
|
|
||||||
// for (int i = 23; i < 27; i++) {
|
|
||||||
// System.out.println(Instant.now() + " putting value" + i);
|
|
||||||
// cache.put("key" + i, "value" + i);
|
|
||||||
// TimeUnit.MILLISECONDS.sleep(Duration.ofSeconds(5).plusMillis(10).toMillis());
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// TimeUnit.SECONDS.sleep(300);
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user