@Override public void refresh(K key) { cache.refresh(key); }
@CheckNoWriter @CacheSpec(removalListener = { Listener.DEFAULT, Listener.REJECTING }) @Test(dataProvider = "caches", expectedExceptions = NullPointerException.class) public void refresh_null(LoadingCache<Integer, Integer> cache, CacheContext context) { cache.refresh(null); }
@CheckNoWriter @CacheSpec(loader = Loader.NULL) @Test(dataProvider = "caches") public void refresh_absent_null(LoadingCache<Integer, Integer> cache, CacheContext context) { cache.refresh(context.absentKey()); assertThat(cache.estimatedSize(), is(context.initialSize())); }
@CheckNoWriter @Test(dataProvider = "caches") @CacheSpec(implementation = Implementation.Caffeine, compute=Compute.SYNC, executor = CacheExecutor.DIRECT, loader = Loader.NULL, population = { Population.SINGLETON, Population.PARTIAL, Population.FULL }) public void refresh_remove(LoadingCache<Integer, Integer> cache, CacheContext context) { cache.refresh(context.firstKey()); assertThat(cache.estimatedSize(), is(context.initialSize() - 1)); assertThat(cache.getIfPresent(context.firstKey()), is(nullValue())); assertThat(cache, hasRemovalNotifications(context, 1, RemovalCause.EXPLICIT)); }
@Test(dataProvider = "caches") @CacheSpec(keys = ReferenceType.STRONG, values = {ReferenceType.WEAK, ReferenceType.SOFT}, implementation = Implementation.Caffeine, expireAfterAccess = Expire.DISABLED, expireAfterWrite = Expire.DISABLED, maximumSize = Maximum.DISABLED, weigher = CacheWeigher.DEFAULT, population = Population.FULL, stats = Stats.ENABLED, compute = Compute.SYNC, removalListener = Listener.CONSUMING, writer = Writer.EXCEPTIONAL) public void refresh_writerFails(LoadingCache<Integer, Integer> cache, CacheContext context) { Integer key = context.firstKey(); context.clear(); GcFinalization.awaitFullGc(); cache.refresh(key); context.disableRejectingCacheWriter(); assertThat(cache.asMap().isEmpty(), is(false)); }
public void run() throws InterruptedException { ConcurrentTestHarness.timeTasks(operation.maxThreads, () -> { int index = ThreadLocalRandom.current().nextInt(); for (;;) { Integer key = ints[index++ & MASK]; switch (operation) { case READ: cache.getIfPresent(key); break; case WRITE: cache.put(key, key); break; case REFRESH: cache.refresh(key); break; } } }); }
@CheckNoWriter @Test(dataProvider = "caches") @CacheSpec(executor = CacheExecutor.DIRECT, loader = Loader.EXCEPTIONAL, removalListener = { Listener.DEFAULT, Listener.REJECTING }, population = { Population.SINGLETON, Population.PARTIAL, Population.FULL }) public void refresh_failure(LoadingCache<Integer, Integer> cache, CacheContext context) { // Shouldn't leak exception to caller and should retain stale entry cache.refresh(context.absentKey()); cache.refresh(context.firstKey()); assertThat(cache.estimatedSize(), is(context.initialSize())); assertThat(context, both(hasLoadSuccessCount(0)).and(hasLoadFailureCount(2))); }
@Test(dataProvider = "caches", timeOut = 5000) // Issue #69 @CacheSpec(implementation = Implementation.Caffeine, population = Population.EMPTY, executor = CacheExecutor.THREADED, compute = Compute.ASYNC, values = ReferenceType.STRONG) public void refresh_deadlock(CacheContext context) { CompletableFuture<Integer> future = new CompletableFuture<>(); AsyncLoadingCache<Integer, Integer> cache = context.buildAsync((k, e) -> future); cache.synchronous().refresh(context.absentKey()); CompletableFuture<Integer> get = cache.get(context.absentKey()); future.complete(context.absentValue()); assertThat(get, futureOf(context.absentValue())); }
@Test(dataProvider = "caches") @CacheSpec(population = Population.EMPTY, executor = CacheExecutor.THREADED, removalListener = Listener.CONSUMING) public void refresh_conflict(CacheContext context) { AtomicBoolean refresh = new AtomicBoolean(); Integer key = context.absentKey(); Integer original = 1; Integer updated = 2; Integer refreshed = 3; LoadingCache<Integer, Integer> cache = context.build(k -> { await().untilTrue(refresh); return refreshed; }); cache.put(key, original); cache.refresh(key); assertThat(cache.asMap().put(key, updated), is(original)); refresh.set(true); await().until(() -> context.consumedNotifications().size(), is(2)); List<Integer> removed = context.consumedNotifications().stream() .map(RemovalNotification::getValue).collect(toList()); assertThat(cache.getIfPresent(key), is(updated)); assertThat(removed, containsInAnyOrder(original, refreshed)); assertThat(cache, hasRemovalNotifications(context, 2, RemovalCause.REPLACED)); assertThat(context, both(hasLoadSuccessCount(1)).and(hasLoadFailureCount(0))); }
@Test(dataProvider = "caches") @CacheSpec(requiresWeakOrSoft = true, expireAfterAccess = Expire.DISABLED, expireAfterWrite = Expire.DISABLED, maximumSize = Maximum.DISABLED, weigher = CacheWeigher.DEFAULT, population = Population.FULL, stats = Stats.ENABLED, loader = Loader.IDENTITY, removalListener = Listener.CONSUMING) public void refresh(LoadingCache<Integer, Integer> cache, CacheContext context) { Integer key = context.firstKey(); Integer value = context.original().get(key); context.clear(); GcFinalization.awaitFullGc(); awaitFullCleanup(cache); cache.refresh(key); assertThat(cache.estimatedSize(), is(1L)); assertThat(cache.getIfPresent(key), is(not(value))); long count = context.initialSize() - 1; assertThat(cache, hasRemovalNotifications(context, 1, RemovalCause.REPLACED)); assertThat(cache, hasRemovalNotifications(context, count, RemovalCause.COLLECTED)); verifyWriter(context, (verifier, writer) -> { verifier.deletions(count, RemovalCause.COLLECTED); }); }
@CheckNoWriter @Test(dataProvider = "caches") @CacheSpec(removalListener = { Listener.DEFAULT, Listener.REJECTING }) public void refresh_absent(LoadingCache<Integer, Integer> cache, CacheContext context) { cache.refresh(context.absentKey()); assertThat(cache.estimatedSize(), is(1 + context.initialSize())); assertThat(context, both(hasMissCount(0)).and(hasHitCount(0))); assertThat(context, both(hasLoadSuccessCount(1)).and(hasLoadFailureCount(0))); // records a hit assertThat(cache.get(context.absentKey()), is(-context.absentKey())); }
@CheckNoWriter @Test(dataProvider = "caches") @CacheSpec(implementation = Implementation.Caffeine, loader = Loader.NULL, population = { Population.SINGLETON, Population.PARTIAL, Population.FULL }) public void refresh_present_null(LoadingCache<Integer, Integer> cache, CacheContext context) { for (Integer key : context.firstMiddleLastKeys()) { cache.refresh(key); } int count = context.firstMiddleLastKeys().size(); assertThat(context, both(hasMissCount(0)).and(hasHitCount(0))); assertThat(context, both(hasLoadSuccessCount(0)).and(hasLoadFailureCount(count))); for (Integer key : context.firstMiddleLastKeys()) { assertThat(cache.getIfPresent(key), is(nullValue())); } assertThat(cache.estimatedSize(), is(context.initialSize() - count)); assertThat(cache, hasRemovalNotifications(context, count, RemovalCause.EXPLICIT)); }
@CheckNoWriter @Test(dataProvider = "caches") @CacheSpec(loader = Loader.IDENTITY, population = { Population.SINGLETON, Population.PARTIAL, Population.FULL }) public void refresh_present_differentValue( LoadingCache<Integer, Integer> cache, CacheContext context) { for (Integer key : context.firstMiddleLastKeys()) { cache.refresh(key); // records a hit assertThat(cache.get(key), is(key)); } int count = context.firstMiddleLastKeys().size(); assertThat(cache.estimatedSize(), is(context.initialSize())); assertThat(cache, hasRemovalNotifications(context, count, RemovalCause.REPLACED)); assertThat(context, both(hasMissCount(0)).and(hasHitCount(count))); assertThat(context, both(hasLoadSuccessCount(count)).and(hasLoadFailureCount(0))); }
@CheckNoWriter @Test(dataProvider = "caches") @CacheSpec(population = { Population.SINGLETON, Population.PARTIAL, Population.FULL }) public void refresh_present_sameValue( LoadingCache<Integer, Integer> cache, CacheContext context) { for (Integer key : context.firstMiddleLastKeys()) { cache.refresh(key); } int count = context.firstMiddleLastKeys().size(); assertThat(context, both(hasMissCount(0)).and(hasHitCount(0))); assertThat(context, both(hasLoadSuccessCount(count)).and(hasLoadFailureCount(0))); for (Integer key : context.firstMiddleLastKeys()) { assertThat(cache.get(key), is(context.original().get(key))); } assertThat(cache.estimatedSize(), is(context.initialSize())); assertThat(cache, hasRemovalNotifications(context, count, RemovalCause.REPLACED)); }
@Test(dataProvider = "caches") @CacheSpec(implementation = Implementation.Caffeine, keys = ReferenceType.STRONG, population = Population.FULL, expiryTime = Expire.ONE_MINUTE, mustExpireWithAnyOf = { AFTER_ACCESS, AFTER_WRITE, VARIABLE }, expiry = { CacheExpiry.DISABLED, CacheExpiry.CREATE, CacheExpiry.WRITE, CacheExpiry.ACCESS }, expireAfterAccess = {Expire.DISABLED, Expire.ONE_MINUTE}, expireAfterWrite = {Expire.DISABLED, Expire.ONE_MINUTE}, compute = Compute.SYNC, writer = Writer.EXCEPTIONAL, removalListener = Listener.REJECTING) public void refresh_writerFails(LoadingCache<Integer, Integer> cache, CacheContext context) { context.ticker().advance(1, TimeUnit.HOURS); cache.refresh(context.firstKey()); context.disableRejectingCacheWriter(); context.ticker().advance(-1, TimeUnit.HOURS); assertThat(cache.asMap(), equalTo(context.original())); }
@Test(dataProvider = "caches") @CacheSpec(population = Population.FULL, loader = Loader.IDENTITY, expiryTime = Expire.ONE_MINUTE, mustExpireWithAnyOf = { AFTER_ACCESS, AFTER_WRITE, VARIABLE }, expiry = { CacheExpiry.DISABLED, CacheExpiry.CREATE, CacheExpiry.WRITE, CacheExpiry.ACCESS }, expireAfterAccess = {Expire.DISABLED, Expire.ONE_MINUTE}, expireAfterWrite = {Expire.DISABLED, Expire.ONE_MINUTE}) public void refresh(LoadingCache<Integer, Integer> cache, CacheContext context) { context.ticker().advance(1, TimeUnit.MINUTES); Integer key = context.firstKey(); cache.refresh(key); long count = (cache.estimatedSize() == 1) ? context.initialSize() : 1; assertThat(cache, hasRemovalNotifications(context, count, RemovalCause.EXPIRED)); verifyWriter(context, (verifier, writer) -> { verifier.deleted(key, context.original().get(key), RemovalCause.EXPIRED); }); }
@Test(dataProvider = "caches") @CacheSpec(implementation = Implementation.Caffeine, population = Population.EMPTY, executor = CacheExecutor.THREADED, compute = Compute.ASYNC, values = ReferenceType.STRONG) public void refresh(CacheContext context) { AtomicBoolean done = new AtomicBoolean(); AsyncLoadingCache<Integer, Integer> cache = context.buildAsync(key -> { await().untilTrue(done); return -key; }); Integer key = 1; cache.synchronous().put(key, key); CompletableFuture<Integer> original = cache.get(key); for (int i = 0; i < 10; i++) { context.ticker().advance(1, TimeUnit.SECONDS); cache.synchronous().refresh(key); CompletableFuture<Integer> next = cache.get(key); assertThat(next, is(sameInstance(original))); } done.set(true); await().until(() -> cache.synchronous().getIfPresent(key), is(-key)); }
@Test(dataProvider = "caches") @CacheSpec(population = Population.EMPTY, executor = CacheExecutor.THREADED, removalListener = Listener.CONSUMING) public void refresh_invalidate(CacheContext context) { AtomicBoolean refresh = new AtomicBoolean(); Integer key = context.absentKey(); Integer original = 1; Integer refreshed = 2; LoadingCache<Integer, Integer> cache = context.build(k -> { await().untilTrue(refresh); return refreshed; }); cache.put(key, original); cache.refresh(key); cache.invalidate(key); refresh.set(true); await().until(() -> cache.getIfPresent(key), is(refreshed)); await().until(() -> cache, hasRemovalNotifications(context, 1, RemovalCause.EXPLICIT)); await().until(() -> context, both(hasLoadSuccessCount(1)).and(hasLoadFailureCount(0))); }
@Override public void refresh(K key) { cache.refresh(key); }
public void cacheAll() { for (String ident : dataStore.getAllIdentifiers(type)) { cache.get().synchronous().refresh(ident); } }