I need a cache of failed entries, which I am trying to build using the following statements:
failedJobCache =
CacheBuilder.newBuilder()
.maximumSize(100) // maximum 100 records can be cached
.expireAfterAccess(30, TimeUnit.MINUTES) // cache will expire after 30 minutes of access
.build(new CacheLoader<String, JobDto>() {
@Override
public JobDto load(String s) throws Exception {
JobDto found = failedJobCache.get(s);
if (found != null)
return found;
else
return null;
}
});
And:
// add failed entries
failedJobCache.put(jobDto.getUniqueId(), jobDto);
// respective check before running the job if its
// already in the cache and should be skipped:
JobDto existing = failedJobCache.get(jobDto.getUniqueId());
if (existing != null) {
logger.debug("Nothing to do, job already processed!" + jobDto.getUniqueId());
return;
}
Unfortunately I encounter:
Exception in thread "main" com.google.common.util.concurrent.UncheckedExecutionException: java.lang.IllegalStateException: Recursive load of: ...
Question How do I add only failed entries to the cache?
CacheLoader.load(K)
is only called if there isn't "an already-loaded value for a given key" (CacheBuilder.build(LoadingCache)
).
As such, calling LoadingCache.get(K)
from CacheLoader.load(K)
creates a recursive load that, if allowed to execute, would recurse too deeply causing a StackOverflowError
to be thrown.
From the information provided in your example it does not appear you need a LoadingCache<K, V>
but just a Cache<K, V>
. Call CacheBuilder.build()
without a CacheLoader<K, V>
.
See CachesExplained · google/guava Wiki for more details.