Кофеин: не может предоставить CacheWriter для AsyncLoadingCache
Я пытаюсь написать AsyncLoadingCache
который принимает CacheWriter
и я получаю IllegalStateException
,
Вот мой код:
CacheWriter<String, UUID> cacheWriter = new CacheWriter<String, UUID>() {
@Override
public void write(String key, UUID value) {
}
@Override
public void delete(String key, UUID value, RemovalCause cause) {
}
};
AsyncLoadingCache<String, UUID> asyncCache = Caffeine.newBuilder()
.expireAfterWrite(60, TimeUnit.SECONDS)
.writer(cacheWriter)
.maximumSize(100L)
.buildAsync((String s) -> { /* <== line 41, exception occurs here */
return UUID.randomUUID();
});
И я получаю этот след
Исключение в потоке "main" java.lang.IllegalStateException на com.github.benmanes.caffeine.cache.Caffeine.requireState(Caffeine.java:174) на com.github.benmanes.caffeine.cache.Caffeine.buildAsync(Caffeine.java).:854) на com.mycompany.caffeinetest.Main.main(Main.java:41)
Если я изменю кеш на LoadingCache
или удалить .writer(cacheWriter)
код будет работать правильно. Что я делаю неправильно? кажется, я предоставляю правильные типы для обоих объектов.
1 ответ
К сожалению, эти две функции несовместимы. В то время как документация утверждает это, я обновил исключение, чтобы сообщить об этом лучше. В Caffeine.writer
Говорится,
Эту функцию нельзя использовать вместе с {@link #weakKeys()} или {@link #buildAsync}.
CacheWriter
является синхронным перехватчиком для мутации записи. Например, его можно использовать для извлечения в кэш диска в качестве вторичного слоя, тогда как RemovalListener
является асинхронным и использование его приведет к гонке, где запись не присутствует ни в одном из кэшей. Механизм заключается в использовании ConcurrentHashMap's
compute
методы для выполнения записи или удаления и вызова в CacheWriter
в этом блоке.
В AsyncLoadingCache
, значение материализуется позже, когда CompletableFuture
успешно или автоматически удаляется, если null
или ошибка. Когда запись изменяется в хеш-таблице, это будущее может быть в полете. Это будет означать, что CacheWriter
часто вызывается без материализованной ценности и, вероятно, не может делать очень умных вещей.
С точки зрения API, к сожалению, телескопические компоновщики (которые используют систему типов для запрета несовместимых цепочек) становятся более запутанными, чем использование исключений времени выполнения. Извините, что не прояснил ошибку, которая должна быть исправлена.