使用Caffeine 2.8.1和 Java 8。我创建了LoadingCache<String, Boolean>
. 我正在加载缓存,cache.putAll(getAllKeyValues())
其中getAllKeyValues()
返回一个Map<String, Boolean>
.
我已经指定了一个CacheLoader来通过调用keyExistsOnServer(key)
调用外部服务来获取值的方法来计算值。
我已经指定了一个自定义过期策略,如果该值设置为false
在缓存中创建/更新条目时,我想在 10 分钟内从缓存中逐出该条目。并保持它只要Long.MAX_VALUE
值是true
。
private RemovalListener<String, Boolean> removeListener =
(key, value, cause) ->
logger.info(
"Entry for Key={} with value={} was removed ({}) from cache", key, value, cause);
private LoadingCache<String, Boolean> cache =
Caffeine.newBuilder()
.expireAfter(
new Expiry<String, Boolean>() {
private static final long EXPIRATION_TEN_MINS_IN_NANOSECONDS = 600000000000L;
@Override
public long expireAfterCreate(String key, Boolean value, long currentTime) {
// If value is false that means key does not exist, so set expiration to 10 mins
return value ? Long.MAX_VALUE : EXPIRATION_TEN_MINS_IN_NANOSECONDS;
}
@Override
public long expireAfterUpdate(
String key, Boolean value, long currentTime, long currentDuration) {
// If value is changed from true to false then set expiration to 10 mins
return value ? Long.MAX_VALUE : EXPIRATION_TEN_MINS_IN_NANOSECONDS;
}
@Override
public long expireAfterRead(
String key, Boolean value, long currentTime, long currentDuration) {
// Don't modify expiration time after read
return currentDuration;
}
})
.recordStats()
.removalListener(removeListener)
.build(key -> keyExistsOnServer(key));
问题#1:根据我想要实现的目标,我的到期政策看起来是否正确?
问题2:
我没有看到RemovalListener
根据驱逐政策被召唤。这可能是由于此github 问题中所述的清理任务的累积。
但是,我的代码的正确性取决于这样一个事实,即一旦false
一个条目的过期持续时间(如果是值,则为 10 分钟)已经过去,如果我们调用,cache.get(key)
那么它不应该从缓存中返回过期值,而是调用CacheLoader
即keyExistsOnServer( key)方法来获取值。有人可以断言这就是它的行为方式吗?
这是@Louis Wasserman 在 github 问题上所说的,但我不清楚这是否能澄清它:
实际上,发生的情况是 get 调用本身发现条目已过期并将其添加到要清理的条目队列中
问题#3:如果调用时RuntimeException
抛出了CacheLoader
keyExistsOnServer (key)方法会发生cache.get(key)
什么?
问题#4:cache.asMap()
是否包含已过期但由于应计清理而未被驱逐的条目?
问题#5:当我currentDuration
在expireAfterRead()
方法中记录时,它似乎与经过的时间不一致。即,如果将其设置为6000000000000(10 分钟)并更新该值,false
我预计 5 分钟后它应该是300000000000,但事实并非如此。为什么这样?