Слушатели событий выселения для кофеина или любого API кэша JVM?

Java 8 здесь. Есть ли способ с помощью структуры кеширования Caffeine (или любой другой совместимой с JSR-107 структурой для этого имеет значение) получать уведомления, когда запись вытесняется из кеша?

Может какая то EvictionEventListener что ли?

public class MyEvictionListener implements EvictionEventListener<String> {
    @Override
    public void onEvictionEvent(EvictionEvent eviction, String key) {
        // Now I have access to the String "key" that was evicted and
        // some information surrounding the eviction and I can do
        // whatever I want with this information....
    }
}

Есть ли что-нибудь подобное в Caffeine, Guava, Hazelcast (в основном "JVM cache land") и т. д.?


person hotmeatballsoup    schedule 25.07.2018    source источник
comment
guava имеет LoadingCache с removalListener, если вам интересно   -  person Eugene    schedule 25.07.2018
comment
Не для реализации JSR-107, но в Hazelcast существует EntryEvictedListener для IMap распределенной карты. Подробнее см. Здесь: docs.hazelcast.org/docs/latest/manual/html-single/   -  person Alparslan Avci    schedule 26.07.2018
comment
Кофеин поддерживает как асинхронный RemovalListener (стиль гуавы), так и синхронный CacheWriter. Но JCache довольно ограничен в том, что он предлагает, и ограничивает вас до CacheEntryListener.   -  person Ben Manes    schedule 26.07.2018
comment
С пометкой java и кешированием, поскольку это общий вопрос, не связанный конкретно с Java 8.   -  person cruftex    schedule 26.07.2018


Ответы (1)


Выселение временем или пространством?

В JSR107 вы должны получить событие для первого, а не для второго. См. Раздел 8.4 спецификации «8.4. Вызов слушателей».

Все реализации JCache должны поддерживать вытеснение по времени, и вы будете знать об этом через javax.cache.event.CacheEntryExpiredListener<K, V>. Срок действия может быть нетерпеливым или ленивым в зависимости от реализации, элементы не обязательно будут исчезать в момент, когда наступает их ограничение по времени.

JCache позволяет реализациям расширять это за счет пространства.

С Hazelcast вы можете это сделать

 <eviction size="50" max-size-policy="ENTRY_COUNT" eviction-policy="LRU"/>

для удаления элементов из кеша в соответствии с настраиваемым порогом пространства. Однако, поскольку это зависит от реализации, для него нет события JCache.

Событие JCache EXPIRED создается системой и не может быть запущено пользователем напрямую. Событие REMOVED предназначено только для действий, инициированных пользователем, например cache.remove(k). Два других типа CREATED и UPDATED здесь тоже не помогут.

person Neil Stevenson    schedule 25.07.2018
comment
Я не думаю, что REMOVED на самом деле настолько ограничивает. Спецификация имеет тенденцию ссылаться на JavaDoc, а не уточнять намерения. JavaDoc часто бывает неопределенным или диктует детали реализации. TCK довольно минимален, но даже его тесты иногда основываются на сомнительных предположениях. Так что, может ли REMOVED включать вытесненные элементы размера, кажется, выбор реализации. - person Ben Manes; 26.07.2018
comment
Неплохо подмечено. если вы посмотрите, вызывает ли выселение из космоса событие, неопределено, тогда вы не можете на это полагаться - поведение может варьироваться между поставщиками или если один поставщик меняет свою реализацию от выпуска к выпуску. В общем, похоже, что JSR107 - не решение этой проблемы. - person Neil Stevenson; 26.07.2018
comment
Точно. В поставщике Caffeine я решил опубликовать мероприятие по выселению из-за размера. В противном случае казалось, что это хуже, на случай, если пользователю потребуется очистить ресурсы. Но я бы не хотел, чтобы код моего приложения зависел от неопределенного поведения. Я думаю, что JCache подходит для интеграции фреймворка (например, Hibernate), где точки соприкосновения просты, но в остальном использование собственных API-интерфейсов, вероятно, лучше соответствует потребностям приложений, которые могут быть довольно разнообразными / сложными / сложными. - person Ben Manes; 26.07.2018