Possible to have a cache entry auto refresh after it expires? #897
-
Howdy sir, We have certain values in our cache that we need to ensure returns the most recently updated data after N minutes. To do this, I've written a custom expiration for those flagged entries, and I've confirmed that my entry is getting evicted from my cache as expected. I believe the entry is not populated in cache again until someone comes along and requests it again, at which point it's a blocking operation while we fetch the latest entry from the db, cache that value and return to the user. Is there anything similar to refreshAfterWrite, but refreshAfterExpiration? Ideally, when the value is expired I'd like it to fetch the latest value and update it in the cache. I know I could write some sort of scheduled thing to poll the cache for those expired values every so often and keep them 'warm' but I was wondering if there was a better way? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
A periodic task that reloads the entries is simple and explicit so that is a common solution. Otherwise someone might have conditions (e.g. only reload for a subset) so then a predicate is needed to test with. That becomes a slippery slope of configuration bits that can be harder to understand and debug. A task that reloads all of the contents or loops over the To do what you are asking for, though, you might try using a removal listener to repopulate the cache when the cause is "expired". If you set a scheduler then it will be notified promptly rather than piggybacking on other activity, which if absent would delay the notification. Otherwise our refreshAfterWrite is pretty good when you want to restrict to a size bounding and hide latencies for popular entries, like configuration used on every request. If the entry is accessed after it became eligible for refresh (stale) but before it expired (unusable), then it will be asynchronously reloaded (fresh) and serve the current value. If the entry is inactive then it expires so more useful data may be cached and a cache miss will be a blocking load. This way you take advantage of high hit rates, keep data fresh while hiding the reload latency, and don't rely on an unbounded cache where too much might be kept by an auto refresh strategy. |
Beta Was this translation helpful? Give feedback.
A periodic task that reloads the entries is simple and explicit so that is a common solution. Otherwise someone might have conditions (e.g. only reload for a subset) so then a predicate is needed to test with. That becomes a slippery slope of configuration bits that can be harder to understand and debug. A task that reloads all of the contents or loops over the
asMap()
view for a partial reload is more explicit and could bulk load the entries instead of doing them one-by-one.To do what you are asking for, though, you might try using a removal listener to repopulate the cache when the cause is "expired". If you set a scheduler then it will be notified promptly rather than piggybacking on …