Is it possible to configure Guava Cache (or other

2019-02-15 06:52发布

I'd like to have a cache that works like this:

  • A. If request is not cached: load and return results.
  • B. If request is cached, has not expired: return results.
  • C. If request is cached, has expired: start to reload results, return old results immediately.
  • D. If request is cached, has expired, reload is already running: return old results immediately.
  • E. If reloading fails (Exception): continue to return previous successful load results to requests.

(After a failed reload (case E), next request is handled following case C.)

(If case A ends in Exception, Exception is thrown)

Does anyone know an existing implementation, or will I have to implement it myself?

1条回答
倾城 Initia
2楼-- · 2019-02-15 07:36

In cache2k I implemented exactly the behavior you described above. Here is how you build a cache with these features:

  CacheBuilder.newCache(Key.class, Value.class)
    .name("myCache")
    .source(new YourSourceImplementation())
    .backgroundRefresh(true)
    .suppressExceptions(true)
    .maxSize(7777) // maximum entries in the cache
    .expiryDuration(60, TimeUnit.SECONDS)
    .exceptionExpiryDuration(15, TimeUnit.SECONDS)
    .build();

The exipryDuration is the duration the value is considered valid after it war inserted or modified. The separate setting for exceptionExpiryDuration is the time until the next refresh is tried after an exception happens.

If an exception happens, but there is no valid entry, the exception is cached and rethrown for the exceptionExpiryDuration time.

You can also dynamically compute the expiry duration, e.g. based on the exception type. Some more information is in the blog entry About caching exceptions

With backgroundRefresh an entry is refreshed after it is expired. When no access happens after an refresh within the expiry time, the entry will not get refreshed any more and then eventually evicted.

Unfortunately, I am really behind in documenting all these useful features properly. If you have any more questions you can use the tag cache2k. If you like some improvements, open an issue on GitHub.

The code works well in our production applications for about a year now. Actually, suppressExceptions is always the default. It helps very well, e.g. if there is a short network outage.

BTW: Meanwhile, I subsume these semantics under the term cache resiliency.

查看更多
登录 后发表回答