Immutable collection with expiration

guava, java

Solution

It's not unusual to have a static, singleton key for a Guava cache. `Cache` provides a lot of benefit even when not used as a `Map`. I would just do something like this:

 private static final Object CACHE_KEY = new Object();

 private LoadingCache<Object, List<SomeType>> cache = 
      CacheBuilder.newBuilder()
        .expireAfterWrite(5, TimeUnit.MINUTES)
        .softValues()
        .build(valuesLoader());

 //...
 List<SomeType> values = cache.get(CACHE_KEY);

In my code base, I use caches with single values in a few places, so I've abstracted this to a `SingleValueLoadingCache<T>` which exposes a no-arg `get()` method and encapsulates the cache and key.

It seems that way I access the entire collection in one go, and the collection is either in the cache or it isn't (in which case I rebuild it all). Are there pitfalls with this approach that I'm not seeing?

Just in case you haven't found it yet, you probably want a `LoadingCache` by passing a `CacheLoader` to the `build` method of the `CacheBuilder`. That way you just always call `get()`, and if the value isn't in the cache, it is loaded for you automatically and synchronously, using the `CacheLoader` you've provided.

Problem

What I'm doing: I'm gathering a potentially large collection of objects and asking the user for input based on the collection. I want to cache the objects to avoid reacquiring them, but I want the collection to expire after a short time in case the user flakes out. If needed, I'll reacquire the objects. The collection will not change over the short time span involved. What I've looked at: Guava's Cache looks promising because of the time-based expiration. However, a couple of things bother me about it. I don't really need a map -- the collection will be accessed in its entirety or not at all. And I'm worried that I can run into a race condition where items in the Cache start expiring as I'm accessing the Cache. That adds a level of complexity, having to track if all my items are in the Cache, eliminating some of the value of the cache. My Question: Am I asking for trouble if, instead of placing individual items in the Cache, I make a Guava ImmutableCollection of them and place that into the Cache? It seems that way I access the entire collection in one go, and the collection is either in the cache or it isn't (in which case I rebuild it all). Are there pitfalls with this approach that I'm not seeing?

Original source