I'm trying to use caffeine cache and have a problem:
Let's say cache is empty and I query for a value, it uses loader and loads a new value into the cache, after 2 days have passed I query for the same value and I get OLD value first then refresh is initiated on a separate thread and the new value is loaded if loading is possible.
Caffeine.newBuilder()
.refreshAfterWrite(5, TimeUnit.MINUTES)
.expireAfterWrite(3, TimeUnit.DAYS)
.build(loader);
What I want to archive is - try to refresh first and return the new value first if possible, if something goes wrong only then return the old one. How can I archive this? How to implement simple, future proof, neat implementation, without workarounds? That would be awesome!
Edit: Would this solution work properly?
boolean needsSyncRefresh = cache.policy().expireAfterWrite()
.flatMap(stringBigDecimalExpiration -> stringBigDecimalExpiration.ageOf(key))
.filter(age -> age.toMinutes() < 0 || age.toMinutes() > REFRESH_AFTER_MINUTES)
.isPresent();
V value = cache.get(key);
if (needsSyncRefresh) {
return cache.asMap().computeIfPresent(key, (k, oldValue) -> {
if (oldValue.equals(value)) {
try {
return loader(key);
} catch (Exception e) {
//handle error
}
}
return oldValue;
});
}
return value;