MichaCo / CacheManager

CacheManager is an open source caching abstraction layer for .NET written in C#. It supports various cache providers and implements many advanced features.
http://cachemanager.michaco.net
Apache License 2.0
2.34k stars 457 forks source link

Expiration never triggered using simple CacheManager.Microsoft.Extensions.Caching.Memory #243

Open MonDeveloper opened 6 years ago

MonDeveloper commented 6 years ago

Since my test is a very few steps beyond the "Hello World" of your amazing CacheManager I'm pretty sure I'm failing somewhere but I'm totally blind and I can't get out of it by myself.

As the Issue title says, using the Extension.Caching I'm not able to catch any eviction event, here there is my test code, if you switch the two handles (commented / uncommented) everything works as expected. Please, point me in the right direction sir,

        [Test]
        public async Task Test002Async()
        {
            int onRemoveByHandleCounter = 0;
            int onRemoveCounter = 0;

            using (var cache = CacheFactory.Build<int>(settings =>
                 settings.WithMicrosoftMemoryCacheHandle()
                         //.WithDictionaryHandle()
                         .WithExpiration(ExpirationMode.Sliding, TimeSpan.FromSeconds(2))))
            {
                cache.OnRemoveByHandle += (o, a) => Interlocked.Increment(ref onRemoveByHandleCounter);
                cache.OnRemove += (o, a) => Interlocked.Increment(ref onRemoveCounter);

                for (int i = 0; i < 3; i++)
                {
                    cache.Add($"key{i}", i);
                }

                await Task.Delay(TimeSpan.FromSeconds(10));

                onRemoveCounter.ShouldBe(0);            // this should be 0 and, in fact, it is
                onRemoveByHandleCounter.ShouldBe(3);    // this should be 3, but is still 0 !!!!!!
            }
        }

I noticed your library still references an old version of Microsoft.Extensions.Caching.Memory 1.0.2 while that library now reached the 2.1.1 version, I tried to directly reference some of the more recent versions but the outcomes are always the same, the event is never triggered.

MichaCo commented 6 years ago

Funny right? That's how the Microsoft.Extensions.Caching.Memory works. It does not have any kind of background job to run cleanup tasks. You have do perform an(y) action on the cache to trigger cache invalidation, e.g. Add or Get a key. Then, the MemoryCache thing runs an invalidation if the last invalidation ran more than MemoryCacheOptions.ExpirationScanFrequency ago...

To see that in action, change your code and add something like the following instead of your Task.Delay

while (true)
{
    await Task.Delay(TimeSpan.FromSeconds(5));

    Console.WriteLine(cache.Add("key1", 1));
}