Кофеин: не может предоставить 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'scompute методы для выполнения записи или удаления и вызова в CacheWriter в этом блоке.

В AsyncLoadingCache, значение материализуется позже, когда CompletableFuture успешно или автоматически удаляется, если null или ошибка. Когда запись изменяется в хеш-таблице, это будущее может быть в полете. Это будет означать, что CacheWriter часто вызывается без материализованной ценности и, вероятно, не может делать очень умных вещей.

С точки зрения API, к сожалению, телескопические компоновщики (которые используют систему типов для запрета несовместимых цепочек) становятся более запутанными, чем использование исключений времени выполнения. Извините, что не прояснил ошибку, которая должна быть исправлена.

Другие вопросы по тегам