0

I am using caffeine cache and looking for a way to update the value in cache without changing its expire time.

The scenario is that I am using cache for speed up data loading. A 5 seconds' delay of data changing is acceptable while I expect returns to be fast. Besides, I want these cache to expiry after 1 day of its first hit to avoid unnecessary memory use.

Thus, I want every cached keys lasts for one day but its value is updated every 5 second.

The refreshAfterWrite method seems to be close but its first returned value after refresh duration is still the old one. This is not ideal for me because the duration between two hits can be hours. In this case I still want a relatively new result (no more than 5 seconds).

So I am trying to manually updating each key.

Firstly I built a cache with 24 hours' expire time in this way:

cache = Caffeine.newBuilder()
    .expireAfterWrite(24, TimeUnit.HOURS)
    .build();

Then I wrote a scheduled task per 5 seconds which iterate keys in cache and do following:

cache.asMap().computeIfPresent(key, mapperFunction);

Then I checked the age of the key:

cache.policy().expireAfterWrite().get().ageOf(key)

However, the age is not growing as expected. I think the computeIfPresent method is considered as a "write" so that the expiry time is also updated.

Is there a way to do the value update without change its expire time in caffeine? Or any other approach for my scenario?

Yoskyalogn
  • 1
  • 1
  • 2

1 Answers1

1

A write is the creation or update of a mapping, so expireAfterWrite is not a good fit for you. Instead you can set a custom expiration policy that sets the initial duration and does nothing on a read or update. This is done using expireAfter(Expiry), such as

LoadingCache<Key, Graph> graphs = Caffeine.newBuilder()
    .expireAfter(new Expiry<Key, Graph>() {
      public long expireAfterCreate(Key key, Graph graph, long currentTime) {
        return TimeUnit.HOURS.toNanos(24);
      }
      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));
Ben Manes
  • 9,178
  • 3
  • 35
  • 39