0

Are there any examples of how to use per key expiry in Caffeine?

I see the following example -- does it mean we are create a Caffeine cache instance per key?

https://github.com/ben-manes/caffeine/issues/114#issuecomment-300602200

Caffeine.newBuilder()
.expireAfter(new Expiry<Key, Graph>() {
  public long expireAfterCreate(Key key, Graph graph, long currentTime) {
    return (graph instanceof NullGraph)
        ? TimeUnit.MINUTES.toNanos(1)
        : TimeUnit.MINUTES.toNanos(10);
  }
  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));

I looked at the implementation and see how the implementation of the expiry interface is used internally.

So say my graph object had a method for expiry duration .. would this be a correct usage?

final Cache<Key, Graph> cache = Caffeine.newBuilder()
.expireAfter(new Expiry<Key, Graph>() {
  public long expireAfterCreate(Key key, Graph graph, long currentTime) {
    return currentTime + graph.expireAfterNanos();
  }
  public long expireAfterUpdate(Key key, Graph graph, 
      long currentTime, long currentDuration) {
    return Long.Max;
  }
  public long expireAfterRead(Key key, Graph graph,
      long currentTime, long currentDuration) {
    return Long.Max;
  }
})
.build();

Now any time I do something like the following -- per key expiry will be enabled for the key inserted -

cache.put(key, graph); // key and graph creation not shown here.
ab m
  • 422
  • 3
  • 17
  • 1
    This means that for a given key, its expiration time within the cache varies. It may either have a 1 or 10 minute lifetime since it was created added into the cache, and a read/update do not modify this duration. The duration is custom per entry and based on an attribute of the value (is null graph - e.g. negative caching). All entries live within a single instance of the cache (a hash map). – Ben Manes Aug 14 '20 at 18:00
  • looked at the implementation and posted the update to my question. I have yet to test it but this is how it is to be used? Thanks for the quick response btw! – ab m Aug 14 '20 at 18:32
  • 2
    Almost. The return value is the new duration, so it would expire at `currentTime + duration`. You can drop the `currentTime +` part as that is incorrect. The MAX is then making the entry ineligible for expiration after a read or update, which is likely not your intent either. That's why the original sample doesn't change it by returning the `currentDuration`. – Ben Manes Aug 14 '20 at 18:55
  • Note that `Expiry` is a callback-style configuration because we strongly prefer loading through the cache via `get(key, mappingFunction)` rather than explicit puts. That helps avoid cache stampedes where multiple threads perform redundant work on a miss to populate the same cache entry. – Ben Manes Aug 14 '20 at 18:55

0 Answers0