1

I use Caffeine cache to cache data coming from the DB that need to served to a rest endpoint. So the cache is updated ONLY on read operations on the DB.

In the nominal case, I want the cache to take the lead of responding until the data is not older than some point of time ( => this case is ok by defining the correct expiration options)

In case of DB access failure, I want to fallback to the cache even if the data in the cache is expired. This use case supposes that expired data are not yet removed.

The solution I'm thinking of is to make Eviction of Items from the cache only after a successful PUT (a successful PUT means the DB is working correctly). Is that possible to do?

Monta
  • 1,136
  • 1
  • 12
  • 28

1 Answers1

4

This could be accomplished by using a victim cache to capture recently expired entries and resurrect from it on a load if the db is down. The victim cache would need its own bounding, e.g. a longer expiration threshold.

Cache<K, V> victimCache = Caffeine.newBuilder()
    .expireAfterWrite(10, TimeUnit.MINUTE)
    .build();
LoadingCache<K, V> mainCache = Caffeine.newBuilder()
    .expireAfterWrite(1, TimeUnit.MINUTE)
    .writer(new CacheWriter<K, V>() {
      public void write(K key, V value) { /* ignored */ }
      public void delete(K key, V value, RemovalCause cause) {
        if (cause == RemovalCause.EXPIRED) {
          victimCache.put(key, value);
        }
      })
     .build(key -> {
       try {
         // load from db
       } catch (DatabaseAccessException e) {
         return victimCache.asMap().remove(key);
       }
     });

This would allow a load failure to resurrect the entry from the victim cache, if the entry is present.

Ben Manes
  • 9,178
  • 3
  • 35
  • 39
  • Do you need `expireAfterWrite` on `victimCache`? I would like to use always some value, even if DB is down (doesn't matter if value is X hours old). Can I just use here HashMap instead of `victimCache`? – Bojan Vukasovic Oct 18 '22 at 16:17
  • In that case the victim cache would otherwise grow unbounded, whereas you probably want to capture up to some threshold. Note that `CacheWriter` was deprecated and removed, after being replaced by `EvictionListener`, in a later release. – Ben Manes Oct 19 '22 at 04:32