-
Requirement:
Update: it seems like the behavior is different in real environments as opposed to unit-tests, meaning that if @Test
void testRefreshAfterWriteWhenNullIsFetched() throws InterruptedException {
Cache<String, String> testCache = Caffeine.newBuilder()
.refreshAfterWrite(Duration.ofSeconds(1))
.expireAfterWrite(Duration.ofSeconds(10))
.build(this::fetchFromRemote);
testCache.put("foo", "bar");
assertThat(testCache.getIfPresent("foo")).isEqualTo("bar");
Thread.sleep(3000);
assertThat(testCache.getIfPresent("foo")).isEqualTo("bar");
Thread.sleep(9000);
assertThat(testCache.getIfPresent("foo")).isNull();
}
private @Nullable String fetchFromRemote(String s) {
return null;
} Is this because according to caffeine, |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
Sorry, I'm unsure what the question is. A refresh to a null value should remove the entry. The various loads try to follow their Map compute counterpart, here a refresh is an asynchronous |
Beta Was this translation helpful? Give feedback.
-
That what the question indeed, in my unit tests I saw the value was not nullified, but I guess that's because the background thread didn't get a chance to run. Thanks @ben-manes! |
Beta Was this translation helpful? Give feedback.
Sorry, I'm unsure what the question is. A refresh to a null value should remove the entry. The various loads try to follow their Map compute counterpart, here a refresh is an asynchronous
computeIfPresent
. If you implement theCacheLoader
explicitly then you can overridereload
orasyncReload
to leverage the old value. TheasyncReload
is the callback and you can delay the future, e.g. to batch reloads or simply never complete one. If the entry is updated, removed, or evicted then the in-flight reload will be abandoned as the cache tries to have linearizable semantics for reasoning against (or close enough to be a good mental model). I'm not sure if any of that helped but let me know eithe…