I have a use case where the method to load my cache's data is a bulk call, but I'm never going to use getAll to get data from the cache. Is there a way to have multiple concurrent gets all block on a single loadAll? I don't want individual gets on different keys to result in multiple calls to the data source.
cache.get(key1); // missing entry, starts refresh
cache.get(key2); // separate thread, already getting reloaded due to key1 miss
I think I'll have to implement my own synchronization after looking into the LocalCache, using something like a local cache in my data accessor that only allows a call through every so many units of time. When a call does go through, update the local copy with a single assignment statement.
Am I missing something from Guava's cache library?
Edit:
I'm considering something like the following. However, it could potentially continue returning stale data while loadAll finishes. I'd prefer everything blocks at load, and only the first request causes loadAll to proceed.
public class DataCacheLoader extends CacheLoader<String, Double>
{
private final Cache<String, Double> cache;
private ConcurrentMap<String, Double> currentData;
private final AtomicBoolean isloading;
public DataCacheLoader( final Cache<String, Double> cache )
{
this.cache = cache;
isLoading = new AtomicBoolean( false );
}
@Override
public Double load( final String key ) throws Exception
{
if ( isLoading.compareAndSet( false, true ) )
{
cache.putAll( loadAll( Lists.newArrayList( key ) ) ) );
}
return currentData.get( key );
}
@Override
public Map<String, Double> loadAll(Iterable<? extends String> keys) throws Exception
{
currentData = source.getAllData();
return currentData;
}
}
ForwardingCache? I'd be suspicious of recursiveCacheLoaders, though. - Louis WassermanForwardingCacheapproach. However, for the specific use case (this is a generalization), I realized I was caching at the wrong granularity. If I want the whole load to block, cache the whole load. I'll leave the question since I suspect there are use cases where an approach to block everything may make sense. - Steven Hood