-
Notifications
You must be signed in to change notification settings - Fork 102
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[FEATURE] 🧼 Clear #331
Comments
Sounds terrific! My only thought was, should there be an option to opt-out of using We do resolve Or does FusionCache use its own instance of MemoryCache so this is not a problem? |
Great 😬
I thought about this, but cannot see a concrete reason why.
That is exactly what will happen! One of the criteria I listed is "if the underlying MemoryCache is owned", meaning FusionCache created it, so that check solves this problem.
Both via DI and directly (eg: via new()) you can pass FusionCache a MemoryCache instance or not (and in that case it will create its own, which is the default behavior): if you don't pass anything it means it's totally owned by FusionCache, and that is when the actual underlying Clear() kicks in. Thoughts? |
Yes that addresses my concern, we don't specify a MemoryCache instance for FusionCache so then it will create and own it and work as you described. Perfect! |
Hi all, v2.0.0-preview-3 is out 🥳 |
Problem
One of the most requested features for FusionCache has always been a
Clear()
mechanism.The reason why it has always been hard to do it is that we are not talking about a simple memory cache: that would've been quite easy.
Instead we need to consider all of these configurations:
Then multiply all of these for these scenarios:
Finally, as a cherry on top, everything should automatically handle transient errors and work with features like fail-safe, soft timeouts, auto-recovery and more.
And... that is a lot!
So how is it possible to do achieve all of this?
Solution
Now that Tagging is finally coming along, I think we have our solution.
By simply picking a "special" tag like
"*"
we can use Tagging to make a properClear()
mechanism work (for a detail of Tagging works underneath, please refer to that issue).Here's an example:
Damn if that is nice 😬
Note
In reality, the special tag I currently picked in preview-1 is
"__*"
so that it would not collide with a nice"*"
tag that users may potentially end up using... but I'm trying to understand what HybridCache will use and maybe use the same, so that doing aRemoveByTag("*")
in both libraries will get you the same result. I'll take a decision before going GA withv2
.Performance
On one hand, using Tagging to achieve clear is for sure a great design choice: all the plumbing available in FusionCache is used to achieve and empower Tagging, and in turn all the Tagging plumbing is used to achieve and empower
Clear()
support.Nice, really.
On the other hand, we can go one step further: since the special tag used for clear is one and one only, we may special-case it and do some things to make it even better.
This is why I'm also saving the expiration timestamp for the special clear tag directly in memory (eg: in a normal variable), so that FusionCache will keep it there forever and every
Clear()
call would also update it: in this way the speed of checking it would be even greater than checking the cache entry for the special tag.But wait, in a multi-node scenario a
Clear()
may happen on another node, and we may receive a backplane notification from that other node!Correct, and that is why when receiving a backplane notification FusionCache also checks to see if it is for the special tag and, if so, do what is needed so that the expiration timestamp (and the dedicated variable) is updated, automatically.
And what happens in case of transient issues while sending that backplane notification?
No big deal,we are already covered thanks to Auto-Recovery.
Again, really really nice, even if I say so myself.
Raw Clear()
From some time now the standard
MemoryCache
(currently used as the L1) actually supports a "real"Clear()
method that does what I call a "raw clear", meaning a full one like you do with aDictionary<TKey, TValue>
instead of the "simulated" one done thanks for the client-assisted approach of the Tagging feature.So, can't just FusionCache use it?
Actually no, for the reasons exposed at the beginning, meaning:
MemoryCache
instance is used with different FusionCache instances (usually also with cache-key prefix), aClear()
on theMemoryCache
instance would effectively clear all the FusionCache instances that use the same underlyingMemoryCache
instanceBut a lot of users use FusionCache without L2 and/or a backplane, and without sharing a
MemoryCache
instance between multiple FusionCache instances, so... can't FusionCache do a "raw clear" in those cases?Yes, yes it can!
This is in fact what FusionCache will do.
So, if:
MemoryCache
supports a raw clearMemoryCache
is not shared (between different FusionCache instances)then when
Clear()
is invoked FusionCache will actually callClear()
on the underlyingMemoryCache
, and immediately wipe out the entire cache.Can I say, again, nice 🙂 ?
The text was updated successfully, but these errors were encountered: