alastairtree/LazyCache

Absolute expiration does not work v2.4.0

PatryxCShark opened this issue · 1 comments

Describe the bug
Absolute expiration seems to not work. In unit tests (C#, Windows) it's ok but after deploying on Linux server, each time function to load data is called.

To Reproduce

Let's say class: MyCachingManager:

        private MemoryCacheEntryOptions GetEntryCacheOptions()
        {
            return new MemoryCacheEntryOptions()
                .SetPriority(CacheItemPriority.Normal)
                .SetAbsoluteExpiration(TimeSpan.FromMinutes(3))
                .AddExpirationToken(new CancellationChangeToken(_myCacheCancellationTokenSource.Token));
        }
        public Task<ICollection<MyClass>> GetOrAddMyClassAsync(string key, Func<Task<ICollection<MyClass>>> addItemFactory)
        {
            return _cache.GetOrAddAsync(jey, addItemFactory, GetEntryCacheOptions());
        } 

And example of using:

            async Task<ICollection<MyClass>> LoadMyData()
            {
                var tc = new List<MyClass>() { new MyClass(), new MyClass() };

                return tc;
            }

            var claims = await _myCachingManager.GetOrAddMyClassAsync("userX", LoadMyData);

Any idea why every time addItemFactory is called (LoadMyData)?
When I used MemoryCache there was no problem and it worked as expected (expiry every 3 minutes).

Expected behavior
Entry in Lazy Cache should expiry 3 minutes after last loading data into cache.

Framework and Platform

  • OS: Windows/Linux (deploy)
  • Framework: net5.0
  • LazyCache.AspNetCore Version: 2.4.0

I found the problem. It seems that the problem is different than I described above and connected with:
.AddExpirationToken(new CancellationChangeToken(_myCacheCancellationTokenSource.Token))

_myCacheCancellationTokenSource is added as singleton and read from constructor (DI).

When I call _myCacheCancellationTokenSource.Cancel() all entries should dissapear from cache and it works as expected.
But when they are load again into cache, they are not saved in cache because _myCacheCancellationTokenSource has cancel state. I want to have "refreshed" (not canceled) token for new entries.

Any idea how I can achieve scenario:

  1. add entries in cache (ask for a given keys)
  2. call '_myCacheCancellationTokenSource.Cancel()' to clear entries done before
  3. ask for data in key what forces to load data into cache again but to preserve data in cache (currently not saved or automatically deleted because of cancelling _myCacheCancellationTokenSource)
  4. has possibility to cancel token '_myCacheCancellationTokenSource.Cancel()' to remove data from point 3?