Closed WarrenFerrell closed 4 years ago
When you know you want to remove something from the cache because the data has become invalid why not just call Remove(..)
then and wait till the next call that callls GetOrAdd(...)
before generating the value?
And if you want to remove the item and refresh it no need to call both methods - just call Add() with the generated value you want to update into the cache and it will force the item to be replaced.
If the call to get the value is fast then waiting for the next query to the cache is reasonable but if the value call is slow then you want to have the value cached before any queries to retrieve the data.
Calling Add means making the value call then updating the cache. This leaves open the opportunity for a new query to cause the value call to occur twice. You can get around this by caching tasks but kinda defeats part of the point of LazyCache.
Sounds like you want to proactively populate the cache in the background, in addition to the main GetOrAdd(..) use so that the cache is always up to date and primed before anyone accesses it. Say your cached thing takes 9s to generate, and you want to refresh it once per minute. You need to start generating a new version about 50s (1s premature for safety) after it is first created, and then every minute after that. If I was going to implement it I would have a background thread or IHostedService with a timer that ticked after 50s, then 1m50s, 2m50s etc. The "tick" would just call LazyCache.Add as no locking is required because we know we are earlier than the planned expiry.
If you were less worried about the delay when expired in GetOrAdd but still wanted an auto refresh feature, you could also do something like this example in the docs using the ExpirationMode.ImmediateEviction feature in LazyCache 2.1.
background thread or IHostedService with a timer that ticked after 50s, then 1m50s, 2m50s etc.
:) For a separate use case we actually use a IHostedService to start a DI'ed list of background threads (commit date 2019-12-31). Except that our item takes 90 - 300s to generate (timed out frequently when on demand) due to the amount of data sent across cloud providers (and the lack of TDS compression).
If I can get the time I'll check out the 2.1 features. I did wrap AddOrUpdateAsync into extension methods so it hasn't really been an issue.
Thanks - 300s is a long time to fetch some data!
If you have solved your issue with an extension method then maybe we can close this issue?
We are using (in production) RefreshebleCache
It's often necessary to force cache invalidation based on some event (someone logs in, there is an infrequent update that is known to modify data). I find myself having to call Remove then GetOrAddAsync in these scenarios but it would be great to just encapsulate this behavior inside LazyCache.