【发布时间】:2021-06-02 18:05:24
【问题描述】:
使用 Caffeine 2.8.1 和 Java 8。
我创建了LoadingCache<String, Boolean>。我正在使用cache.putAll(getAllKeyValues()) 加载缓存,其中getAllKeyValues() 返回Map<String, Boolean>。
我指定了一个 CacheLoader 来通过调用 keyExistsOnServer(key) 方法来计算值,该方法调用外部服务来获取值。
我已经指定了一个自定义过期策略,如果值设置为false 同时创建/更新缓存中的条目,我想在 10 分钟内从缓存中逐出条目。如果值为true,则将其保留为Long.MAX_VALUE。
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 issue 中所述的清理任务的累积。
但是,我的代码的正确性取决于这样一个事实,即一旦一个条目的过期持续时间(false 值的情况下为 10 分钟)已经过去,如果我们调用 cache.get(key) 那么它不应该从缓存,而是调用CacheLoader 即keyExistsOnServer(key) 方法来获取值。有人可以断言这就是它的行为方式吗?
这是@Louis Wasserman 在 github 问题上所说的,但我不清楚这是否能澄清它:
实际上,发生的是get调用本身发现条目已过期并将其添加到要清理的条目队列中
问题#3:如果CacheLoader 抛出RuntimeException 是keyExistsOnServer(key) 方法调用cache.get(key) 时会发生什么?
问题#4:cache.asMap() 是否包含已过期但未因应计清理而被驱逐的条目?
问题#5:当我在expireAfterRead() 方法中记录currentDuration 时,它似乎与经过的时间不一致。即,如果它设置为 600000000000(10 分钟)并将值更新为 false 我预计 5 分钟后它应该是 300000000000 但它不是.为什么会这样?
【问题讨论】:
-
@Louis Wasserman 你能帮忙吗?
标签: java caching guava caffeine-cache