Skip to content

[FEATURE] ⚙️ New MemoryCacheDuration option #571

@jodydonetti

Description

@jodydonetti

Scenario

In a multi-node scenario we have one L1 (memory cache) for each node and one L2 (distributed cache) as a shared remote cache.

When in this scenario, every write operation would normally make the cache incoherent.

Example:

  • T0: we cache something on NODE A for 10 min
  • T1: we get it from NODE B: now the entry in the 2 L1s are synchronized (the same)
  • T2: after 1 min we call cache.Set("key", newValue) on NODE A

For the remaining 9 min the cached value will be:

  • the new one on NODE A
  • the old one on NODE B

In these scenarios we can use the Backplane to easily have distributed notifications and keep the cache coherent automatically, even after a write operation.

Problem

Sometimes we may not be able to use a backplane, or we may prefer not to (for... reasons): in those cases the cache, as a whole, will remain incoherent after a write operation for the remaining part of the specified Duration.

As a mitigation for this, we can keep the entry in the L1 for a smaller amount of time, so that it will refresh more frequently from the L2.

But here's the thing: the way we think about it would be to "set the L1 duration to a lower one", but historically we did not have a MemoryCacheDuration as a potential override, but only a DistributedCacheDuration.

This would force users to "think backward" and instead of:

  • setting the L1 duration to something lower

they would need to:

  • set the DistributedCacheDuration to the "normal" value, the one normally set as Duration
  • set the Duration to the lower vale

On top of this, there's another issue.

People tend to specify a different Duration for each use case: for example when working with Products they specify 2 min, when working with Orders they specify 5 min, and so on.

If they suddently want to use the "lower L1 duration" mitigation, they can't use the DefaultEntryOptions to achieve that in one fell swoop, and instead they would need to go to each method call and "swap" the Duration and the DistributedCacheDuration as specified above.

Ideally, it should be better than this.

Solution

Introduce a new MemoryCacheDuration, similar to the DistributedCacheDuration to override the option for L1 instead of for L2.

The behavior would be basically the same as the one we have today with DistributedCacheDuration when working internally with the L2:

  • L2: if a DistributedCacheDuration has been specified, it will be used, otherwise the normal Duration will
  • L1: if a DistributedCacheDuration has been specified, it will be used, otherwise the normal Duration will

This will allow a more granular (and intuitive) control overall, while also allowing a global override during setup, like this:

services.AddFusionCache()
  .WithDefaultEntryOptions(options => {
    options.MemoryCacheDuration = TimeSpan.FromSeconds(10);
  });

By doing this, every existing (and future) cache calls in our code will work with an automatic refresh from L2 to L1 every 10s.

Nice.

Alternatives

The existing one mentione above:

  • set the DistributedCacheDuration to the "normal" value, the one normally set as Duration
  • set the Duration to the lower vale

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions