Skip to content
Advertisement

Cache is not returning data after expiry even keepDataAfterExpired(true) is set

My Use case: I have to return the updated data from the cache every time without hitting the DB. So i have used RefreshAhead feature of Cache2K.

Issue: I am facing few issues.

  1. I have kept expiry interval as 1 Minute, eternal = false and keepDataAfterExpired = TRUE. But after 1 Minute when I am trying to get the expired content, it’s not getting served from the cache due to which spikes are coming in response time. Is there anyway to serve the expired cache content to avoid these spikes.

  2. I have used the loader but unable to find any parameter to set the loader execution interval. Do we have any property to set the loader execution interval. If not then what would happen if our DB call took more time and expiry interval get elapsed as expired content is not getting served from Cache.

  3. Please suggest which loader I have to use to load the findAll() data into the cache. It would be helpful if an example would be share for reference.

  4. Any logger provided by default to reflect that cache is refreshed successfully.

Code Snippet:

this.itemsCache = new Cache2kBuilder<String, List>(){}.name("allItems").keyType(String.class).valueType(List.class)
                .eternal(false)
                .expireAfterWrite(60, TimeUnit.SECONDS).setupWith(UniversalResiliencePolicy::enable, b-> b.resilienceDuration(2, TimeUnit.SECONDS))
                .keepDataAfterExpired(true).refreshAhead(true).boostConcurrency(true).disableStatistics(false).disableMonitoring(false).recordModificationTime(true)
                .addAsyncListener(new CacheEntryCreatedListener<String,List>() {
                    @Override
                    public void onEntryCreated(Cache cache, CacheEntry cacheEntry) throws Exception {
                        logger.info("Cached entry created: "+cacheEntry.toString());
                    }
                }).addAsyncListener(new CacheEntryExpiredListener<String,List>() {
                    @Override
                    public void onEntryExpired(Cache cache, CacheEntry cacheEntry) throws Exception {
                        logger.info("Cached entry expired: "+cacheEntry.toString());
                    }
                }).addAsyncListener(new CacheEntryUpdatedListener<String,List>() {
                    @Override
                    public void onEntryUpdated(Cache cache, CacheEntry cacheEntry, CacheEntry cacheEntry1) throws Exception {
                        logger.info("Cache entry updated from: "+cacheEntry.toString()+", to: "+cacheEntry1.toString());
                    }
                }).loader(key->{
                    logger.info("Cache repopulating by loader for key: "+key);
                    List<Item> iList = populateStrings();
                    logger.info("Loader Updated Items List: "+iList.toString());
                    return iList;
                }).permitNullValues(false).disableMonitoring(false).disableStatistics(false).recordModificationTime(true).build();


Advertisement

Answer

With refreshAhead(true) it should work as you intend. The documentation reads as:

When true, enable background refresh / refresh ahead. After the expiry time of a value is reached, the loader is invoked to fetch a fresh value. The old value will be returned by the cache, although it is expired, and will be replaced by the new value, once the loader is finished. In the case there are not enough loader threads available, the value will expire immediately and the next get() request will trigger the load.

. . .

Maybe you are having problems because not enough threads are available to call the loader? You can adjust the threads via loaderThreadCount or by specifying an executor in loaderExecutor.

keepDataAfterExpired does not change anything here. It is only useful together with an AdvancedCacheLoader or and AsyncCacheLoader.

For the next version of cache2k (2.8) I am planing to improve the refresh ahead configuration options. Then it will be possible to refresh before the expiry.

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement