0
votes

I'm playing with Hazelcast 3.12 Cache implementation, and trying to configure the Eviction policy. However, I noticed that none of my cache entry listeners are being triggered when a cache eviction occurs.

My cache is defined as:

        CacheSimpleConfig cacheSimpleConfig = new CacheSimpleConfig()
                .setName(CACHE_NAME)
                .setKeyType(String.class.getName())
                .setValueType((new String[0]).getClass().getName())
                .setStatisticsEnabled(true)
                .setReadThrough(true)
                .setWriteThrough(true)
                .setInMemoryFormat(InMemoryFormat.OBJECT)
                .setEvictionConfig(new EvictionConfig()
                        .setEvictionPolicy(EvictionPolicy.LRU)
                        .setSize(1000)
                        .setMaximumSizePolicy(EvictionConfig.MaxSizePolicy.ENTRY_COUNT))
                .setExpiryPolicyFactoryConfig(
                        new ExpiryPolicyFactoryConfig(
                                new TimedExpiryPolicyFactoryConfig(ACCESSED,
                                        new DurationConfig(
                                                ssoSessionTimeoutInSeconds,
                                                TimeUnit.SECONDS))));
        hazelcastInstance.getConfig().addCacheConfig(cacheSimpleConfig);

        ICache<String, String[]> cache = hazelcastInstance.getCacheManager().getCache(CACHE_NAME);
        cache.registerCacheEntryListener(new MutableCacheEntryListenerConfiguration<>(entryListenerFactory, null, true, false));

My listener implements the 4 CacheEntry*Listener interfaces:

public class UserRolesCacheEntryListener implements CacheEntryExpiredListener<String, String[]>, CacheEntryRemovedListener<String, String[]>, CacheEntryCreatedListener<String, String[]>, CacheEntryUpdatedListener<String, String[]>, HazelcastInstanceAware {

// all 4 on*() methods delegate to: private void logEvent(CacheEntryEvent cacheEntryEvent) { String[] value = cacheEntryEvent.getValue() != null ? cacheEntryEvent.getValue() : cacheEntryEvent.getOldValue(); LOG.info("Event[{}:{}] {} => {}", cacheEntryEvent.getEventType().toString(), cacheEntryEvent.getSource().getName(), cacheEntryEvent.getKey(), value);

    ICache cache = (ICache)cacheEntryEvent.getSource().unwrap(ICache.class);
    LOG.debug("Cache Evictions: {} ", cache.getLocalCacheStatistics().getCacheEvictions());

}

However, I never get any of my on*() methods called when an entry is evicted. On creation of an entry, however, I do see the following entry in my log:

2019-08-13 12:27:14 INFO  [hz.Hazelcast.event-1] UserRolesCacheEntryListener:70 - Event[CREATED:UserRoles] 950 => [99cedd4c-ee5b-480b-b374-eea2b919a58a, Tue Aug 13 12:27:14 EDT 2019]
2019-08-13 12:27:14 DEBUG [hz.Hazelcast.event-1] UserRolesCacheEntryListener:79 - Cache Evictions: 1 

Which indicates to me that values are getting evicted from the cache, but no listener is being triggered. Is this expected behaviour? I would have thought the "onRemoved()" method/listener would have been triggered.

Additionally, is there a reason why the cache would show an eviction after 950 entries, even if it is set for 1000?

I see that Hazelcast has an eviction listener for a Map. Is there a way to use the Map's eviction listener for a cache?

1

1 Answers

0
votes

You are correct, for JCache(ICache) expiration events based on setMaximumSizePolicy are not propagated. The reason is related to the JCache spec. The spec diffrenciate between evictions based on resource limits and ones based on time. It was interpreted that we should not call cacheEntryExpiryLisnter, based on a strict interpretation of the spec. We are currently reevaluating this behavior. See... https://github.com/hazelcast/hazelcast/issues/15455