javacaffeine

Caffeine Cache - Specify expiry for an entry


I'm trying to further my understanding of the caffeine cache. I was wondering if there is a way to specify a timeout for an entry that's populated in the cache, but have no time based expiry for the rest of the records.

Essentially I would like to have the following interface:

put(key, value, timeToExpiry)// enter a key and value with a specified timeToExpiry

put(key, value) // enter a key value with no timeToExpiry

I can write the interfaces and plumbing, but I'd like to understand how I can configure caffeine for both of the above requirements. I'm also open to have two separate instances of the caffeine cache.


Solution

  • This can be done by using a custom expiration policy and leverage an unreachable duration. The maximum duration is Long.MAX_VALUE, which is 292 years in nanoseconds. Assuming your record holds when (and if) it expires then you might configure the cache as,

    LoadingCache<Key, Graph> graphs = Caffeine.newBuilder()
        .expireAfter(new Expiry<Key, Graph>() {
          public long expireAfterCreate(Key key, Graph graph, long currentTime) {
            if (graph.getExpiresOn() == null) {
              return Long.MAX_VALUE;
            }
            long seconds = graph.getExpiresOn()
                .minus(System.currentTimeMillis(), MILLIS)
                .toEpochSecond();
            return TimeUnit.SECONDS.toNanos(seconds);
          }
          public long expireAfterUpdate(Key key, Graph graph, 
              long currentTime, long currentDuration) {
            return currentDuration;
          }
          public long expireAfterRead(Key key, Graph graph,
              long currentTime, long currentDuration) {
            return currentDuration;
          }
        })
        .build(key -> createExpensiveGraph(key));