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 456 forks source link

What will CompactOnMemoryPressure wil do when we use WithMicrosoftMemoryCacheHandle(MemoryCacheOptions) #172

Closed vijay8059 closed 7 years ago

vijay8059 commented 7 years ago

Hi, I am trying to use WithMicrosoftMemoryCacheHandle as my in memory Cache. WithMicrosoftMemoryCacheHandle takes MemoryCacheOptions object MemoryCache has a property CompactOnMemoryPressure . There is no documentation on CompactOnMemoryPressure in the internet also . Why this property is useful.?

MichaCo commented 7 years ago

Some documentation for the asp.net core MemoryCache can be found here: https://docs.microsoft.com/en-us/aspnet/core/performance/caching/memory

The CompactOnMemoryPressure enables or disables a functionality of that cache which might evict cached keys if necessary.

I wouldn't be worried to much about it and also, a reason you don't find much information about that is that they removed that functionality already in the latest 2.x version => see dev branch: https://github.com/aspnet/Caching/blob/dev/src/Microsoft.Extensions.Caching.Memory/MemoryCacheOptions.cs

In the current version (master branch) this code gets triggered after a Gen2 garbage collection: https://github.com/aspnet/Caching/blob/master/src/Microsoft.Extensions.Caching.Memory/MemoryCache.cs#L331. This means it is up to the garbage collector when and how often to trigger a compact...

Again, this will be removed in the next version of that cache.

The only in-memory cache supporting this compact based on memory pressure functionality, and which is also supported by CacheManager, is the System.Runtime.Caching one.

MaxTranced commented 6 years ago

I'm interested if there is a way to disable unpredictable eviction for MemoryCache. Can that be done? If I define a SizeLimit and an expiration time for all of the items that I insert, is there any way to make sure that the items don't get evicted in any other scenarios except for going over the size limit and items expiring? If so, how can I do that? Is it possible to do this for the System.Runtime.Caching one?

What I'm basically asking is: If I do nothing for version 2.x and if I set CompactOnMemoryPressure = false for version 1.x, will this guarantee predictable behavior? If so, can this be documented? Is there any equivalent for System.Runtime.Caching.MemoryCache?

MichaCo commented 6 years ago

Hi @MaxTranced If you do not specify any of those options, MemoryCache will not randomly evict anything. CompactOnMemoryPressure will not be used in version 2.x anymore.

Also, another remark on SizeLimit. This is actually not supported by CacheManager, you'll receive an exception like

Unhandled Exception: System.InvalidOperationException: Cache entry must specify a value for Size when SizeLimit is set.
   at Microsoft.Extensions.Caching.Memory.MemoryCache.SetEntry(CacheEntry entry)

When you set that option, because CacheManager doesn't set any size for the cached value (because it's impossible to predict size).

I'd probably have to add some feature or configuration to set that size on each cache entry.

SizeLimit is actually pretty nice, and the eviction logic is not random, it has some logic of what get evicted, have a look here:. But again, this feature cannot be used together with CacheManager for now.

Re: System.Runtime.Caching, this cache still supports memory pressure based eviction, although it semi reliable as any .NET based solution will be. You can set that via app/web.config and, when the PR #228 is merged, by code, too.

MaxTranced commented 6 years ago

If you do not specify any of those options, MemoryCache will not randomly evict anything.

Is this explicitly specified in the documentation? If not it might help confused developers, such as myself, to find their way around. :) I've skimmed over http://cachemanager.michaco.net/documentation/CacheManagerConfiguration but could not figure it out clearly...

On the other hand, is it even possible to make such guarantees for future versions of the platform, as you don't have control over the underlying code? Or is there a clear decision on Microsoft's part on this? I've skimmed over the documentation at https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.caching.memory.memorycache and could not figure that out either...

I guess that for my use-case I might end up implementing my own data structure (as it's quite a particular use-case, that needs some stronger guarantees) but making the code thread-safe is not something I'm looking forward to....

Thank you for the quick answer!

MichaCo commented 6 years ago

I don't have much documentation specific for each Cache type because that should be documented already by the cache vendor (In this case on the MSDN site, although it is not very well documented right now...)

So, I don't really see that as my job to document all those things ;)

Re the changes in MemoryCache. Yes MS did make that decision to drop MemoryPressure based eviction. The property is marked obsolete in 2.0 and will be removed later. It also doesn't do anything in 2.0, it is just there to not break your code. CacheManager will just work with both versions, because the rest of the API has been kept stable. Otherwise I'd have to add some ifdefs here and there.

For SizeLimit support, I just added a new issue for me to track #237

MaxTranced commented 6 years ago

So, I don't really see that as my job to document all those things ;)

Agreed.

In this case on the MSDN site, although it is not very well documented right now...

Very much agreed... Maybe I should bug them to document their stuff with more than code. They seem to be doing that a lot lately.

Thank you for the help!