alastairtree / LazyCache

An easy to use thread safe in-memory caching service with a simple developer friendly API for c#
https://nuget.org/packages/LazyCache
MIT License
1.72k stars 159 forks source link

Remove a range of cached values based on a key prefix #74

Open NanFengCheong opened 5 years ago

NanFengCheong commented 5 years ago

Similar question to #66 cache.Remove("all-products"); When I am trying to remove a bunch of keys from the class, it is difficult to search all keys Is it possible to implement something like cache.RemoveStartsWith("all-products");

alastairtree commented 5 years ago

There is not an easy way to solve this because key iteration is not available on the underlying MemoryCache due to the nature of concurrent threads iterating a list that is always mutating. The solutions to this are really the same as #66 - basically a workaround rather than based on a particular key prefix.

NanFengCheong commented 5 years ago

Got it

alastairtree commented 4 years ago

One way to dispose a range of items would be through the use of a shared cancellation token on the options object in LazyCache 2.1 like so:

// Say I already have a cache:
IAppCache cache = new CachingService();

// I need a cancellation token to link every all cached product items to the same CancellationTokenSource instance
// this instance must be shared everywhere you add stuff to the cache so they are all linked togther
var sharedExpiryTokenSource = new CancellationTokenSource(); // IDisposable!

// add first item to the cache and link to the global expiry token
var expireToken1 = new CancellationChangeToken(sharedExpiryTokenSource.Token);
var options1 = new MemoryCacheEntryOptions()
                   .AddExpirationToken(expireToken)
var product1 = cache.GetOrAdd($"Products-1", () => dbContext.Products.GetAsync(1), options1);

// add second item to the cache and link to the same expiry token
var options2 = new MemoryCacheEntryOptions()
                   .AddExpirationToken(new CancellationChangeToken(sharedExpiryTokenSource.Token))
var product2 = cache.GetOrAdd($"Products-2", () => dbContext.Products.GetAsync(2), options2);

// And now later on I can remove both products from the cache by cancelling on the shared token
sharedExpiryTokenSource.Cancel();