Skip to content

[MemoryCache] Add possibility to disable linked cache entries #45592

@adamsitnik

Description

@adamsitnik

Background and Motivation

MemoryCache by default tracks linked cache entries to allow for propagating options.

In the following example, the expirationToken added for child is also applied to parent:

using (var parent = cache.CreateEntry(key))
{
    parent.SetValue(obj);

    using (var child = cache.CreateEntry(key1))
    {
        child.SetValue(obj);
        child.AddExpirationToken(expirationToken);
    }
}

Tracking internally uses AsyncLocal<T>, which is expensive and adds non-trivial overhead. The cost of using it has popped out in the performance reports that we have received from our customers (#45436).

Currently, this feature can not be disabled.

Proposed API

As suggested by @Tratcher in #45436 (comment), we can extend the existing MemoryCacheOptions with a flag that disables this behaviour.

Naming is hard and the best idea I currently have is TrackLinkedCacheEntries:

namespace Microsoft.Extensions.Caching.Memory
{
    public class MemoryCacheOptions
    {
+        public bool TrackLinkedCacheEntries { get ; init; } = true;
    }
}

I am open to suggestions.

Usage Examples

var options = new MemoryCacheOptions
{
    TrackLinkedCacheEntries = false
};

var cache = new MemoryCache(options);

Alternative Designs

As an alternative, we could add a new method to MemoryCache that would allow for creating cache entries without tracking:

namespace Microsoft.Extensions.Caching.Memory
{
    public class MemoryCache
    {
        public ICacheEntry CreateEntry(object key); // existing method
+        public ICacheEntry CreateUnlinkedEntry(object key);
    }

But there is a lot of existing extension methods that allow for adding new cache entries to the cache and we would most probably need to add new overloads for them...

Risks

Introducing this API has no risks as long as we don't change the default settings (enabled by default).

cc @eerhardt @maryamariyan @davidfowl

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions