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.
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));