Skip to content

Refresh

Ben Manes edited this page Aug 7, 2023 · 4 revisions
LoadingCache<Key, Graph> graphs = Caffeine.newBuilder()
    .maximumSize(10_000)
    .refreshAfterWrite(1, TimeUnit.MINUTES)
    .build(key -> createExpensiveGraph(key));

Refreshing is not quite the same as eviction. As specified in LoadingCache.refresh(K), refreshing a key loads a new value for the key asynchronously. The old value (if any) is still returned while the key is being refreshed, in contrast to eviction, which forces retrievals to wait until the value is loaded anew.

In contrast to expireAfterWrite, refreshAfterWrite will make a key eligible for refresh after the specified duration, but a refresh will only be actually initiated when the entry is queried. So, for example, you can specify both refreshAfterWrite and expireAfterWrite on the same cache so that the expiration timer on an entry isn't blindly reset whenever an entry becomes eligible for a refresh. If an entry isn't queried after it comes eligible for refreshing, it is allowed to expire.

A CacheLoader may specify smart behavior to use on a refresh by overriding CacheLoader.reload(K, V) which allows you to use the old value in computing the new value. The coalescing-bulkloader-reactor example demonstrates how to accumulated multiple reloads into a batch request by using Reactor.

Refresh operations are executed asynchronously using an Executor. The default executor is ForkJoinPool.commonPool() and can be overridden via Caffeine.executor(Executor).

If an exception is thrown while refreshing then the old value is kept and the exception is logged (using System.Logger) and swallowed.