LazyCache icon indicating copy to clipboard operation
LazyCache copied to clipboard

Remove a range of cached values based on a key prefix

Open NanFengCheong opened this issue 5 years ago • 3 comments

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");

NanFengCheong avatar Jun 05 '19 14:06 NanFengCheong

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.

alastairtree avatar Jun 05 '19 14:06 alastairtree

Got it

NanFengCheong avatar Jun 05 '19 15:06 NanFengCheong

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();

alastairtree avatar Sep 20 '20 15:09 alastairtree