You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
FusionCache will not leverage the new HybridCache, in the sense that it will not be built "on top of it", but it will do 2 main things:
it may leverage some of the new bits being created for it
will be available as an implementation of HybridCache
Long story short, Microsoft introduced not just a (default) implementation, but also an abstraction that anyone can implement: this may turn the HybridCache abstract class into some sort of "lingua franca" for a basic set of common features for all hybrid caches in .NET.
It means people will be able to do one of 2 things:
use FusionCache directly, as they did up until today
depend on a shared, Microsoft provided abstraction, but use a 3rd party implementation with maybe more features
To be clear, this does NOT mean that FusionCache will now be based on HybridCache from Microsoft, but that it will ALSO be available AS an implementation of it, via an adapter class.
Ok cool, but how?
Example
when setting up FusionCache in our Startup.cs file, we simply add .AsHybridCache():
Now, every time we'll ask for HybridCache via DI (taken as-is from the official docs):
publicclassSomeService(HybridCachecache){privateHybridCache_cache=cache;publicasyncTask<string>GetSomeInfoAsync(stringname,intid,CancellationTokentoken=default){returnawait_cache.GetOrCreateAsync($"{name}-{id}",// Unique key to the cache entryasync cancel =>awaitGetDataFromTheSourceAsync(name,id,cancel),cancellationToken:token);}publicasyncTask<string>GetDataFromTheSourceAsync(stringname,intid,CancellationTokentoken){stringsomeInfo=$"someinfo-{name}-{id}";returnsomeInfo;}}
we'll be using in reality FusionCache underneath acting as HybridCache, all transparently.
Oh, and we'll still be able to get IFusionCache too all at the same time, so another SomeService2 in the same app, similarly as the above example, can do this:
and the same FusionCache instance will be used for both, directly as well as via the HybridCache adapter.
Oh (x2), and we'll be even able to read and write from BOTH at the SAME time, fully protected from Cache Stampede!
Yup, this means that when doing hybridCache.GetOrCreateAsync("foo", ...) at the same time as fusionCache.GetOrSetAsync("foo", ...), they both will do only ONE database call, at all, among the 2 of them.
Oh (x3 😅), and since FusionCache supports both the sync and async programming model, this also means that Cache Stampede protection (and every other feature, of course) will work perfectly well even when calling at the same time:
hybridCache.GetOrCreateAsync("foo", ...) (async call from the HybridCache adapter)
fusionCache.GetOrSet("foo", ...) (sync call from FusionCache directly)
Damn if it feels good 😬
Of course, since the API surface area is more limited (eg: HybridCacheEntryOptions VS FusionCacheEntryOptions) we can enable and configure all of this goodness only at startup and not on a per-call basis: but still, it is a lot of power to have available for when you need/want to depend on the Microsoft abstraction.
Actually, to be more precise: the features available in both HybridCacheEntryOptions and FusionCacheEntryOptions (although with different names) have been automatically mapped and will work flawlessly: an example is using HybridCacheEntryFlags.DisableLocalCacheRead in the HybridCacheEntryOptions which becomes SkipMemoryCacheRead in FusionCacheEntryOptions, all automatically.
The idea was to put there the relavant code to avoid having to depend on extra stuff.
But, as some members of the community pointed out, the only dependency I need is with Microsoft.Extensions.Caching.Abstractions which is already a dependency FusionCache has.
Moral of the story, I'll move the relevant code in the main FusionCache package, empty the other one and deprecate it.
Microsoft (and Marc) and OSS
To me, this is a wonderful example of what it may look like when Microsoft and the OSS community have a constructive dialog. First and foremost many thanks to @mgravell himself for the openness, the back and forth and the time spent reading my mega-comments.
The text was updated successfully, but these errors were encountered:
When Microsoft (or rather: teams - people - inside Microsoft) discusses (discuss) whether to add functionality that overlaps some non-trivial portion of what existing OSS libraries offer, it is a socio-political minefield. Any random adding the same? Not a problem, but MSFT: were very aware of the perceived impact of the "behemoth" joining the party, and the impact of default choices.
As someone who has worked on many independent OSS libraries, I take this very seriously, and I take this note very positively. Thank you for taking the time to express this, and I look forward to continued successful interactions on this and other endeavours.
Problem
Recently Microsoft introduced the new HybridCache in .NET 9.
This of course sparked a lot of questions about what I thought about it and the future of FusionCache.
So the "problem" seems to be a "fight" between FusionCache and HybridCache, right?
Wrong, imho.
Features
Looking at HybridCache from Microsoft, the main features are:
All these features are there in FusionCache too (apart from compression, which I'm already working on).
FusionCache though has more, like:
Solution
You can read my thoughts about it.
The main take away from my answer is this:
Long story short, Microsoft introduced not just a (default) implementation, but also an abstraction that anyone can implement: this may turn the HybridCache abstract class into some sort of "lingua franca" for a basic set of common features for all hybrid caches in .NET.
It means people will be able to do one of 2 things:
To be clear, this does NOT mean that FusionCache will now be based on HybridCache from Microsoft, but that it will ALSO be available AS an implementation of it, via an adapter class.
Ok cool, but how?
Example
when setting up FusionCache in our Startup.cs file, we simply add
.AsHybridCache()
:Now, every time we'll ask for HybridCache via DI (taken as-is from the official docs):
we'll be using in reality FusionCache underneath acting as HybridCache, all transparently.
And this also means we'll have the power of FusionCache itself, including the resiliency of fail-safe, the speed of soft/hard timeouts and eager-refresh, the automatic synchronization of the backplane, the self-healing power of auto-recovery, the full observability thanks to native OpenTelemetry support and more.
Oh, and we'll still be able to get IFusionCache too all at the same time, so another SomeService2 in the same app, similarly as the above example, can do this:
and the same FusionCache instance will be used for both, directly as well as via the HybridCache adapter.
Oh (x2), and we'll be even able to read and write from BOTH at the SAME time, fully protected from Cache Stampede!
Yup, this means that when doing
hybridCache.GetOrCreateAsync("foo", ...)
at the same time asfusionCache.GetOrSetAsync("foo", ...)
, they both will do only ONE database call, at all, among the 2 of them.Oh (x3 😅), and since FusionCache supports both the sync and async programming model, this also means that Cache Stampede protection (and every other feature, of course) will work perfectly well even when calling at the same time:
hybridCache.GetOrCreateAsync("foo", ...)
(async call from the HybridCache adapter)fusionCache.GetOrSet("foo", ...)
(sync call from FusionCache directly)Damn if it feels good 😬
Of course, since the API surface area is more limited (eg:
HybridCacheEntryOptions
VSFusionCacheEntryOptions
) we can enable and configure all of this goodness only at startup and not on a per-call basis: but still, it is a lot of power to have available for when you need/want to depend on the Microsoft abstraction.Actually, to be more precise: the features available in both
HybridCacheEntryOptions
andFusionCacheEntryOptions
(although with different names) have been automatically mapped and will work flawlessly: an example is usingHybridCacheEntryFlags.DisableLocalCacheRead
in theHybridCacheEntryOptions
which becomesSkipMemoryCacheRead
inFusionCacheEntryOptions
, all automatically.Separate package
As said, in preview-3 I introduced a new package for the adapter.
The idea was to put there the relavant code to avoid having to depend on extra stuff.
But, as some members of the community pointed out, the only dependency I need is with
Microsoft.Extensions.Caching.Abstractions
which is already a dependency FusionCache has.Moral of the story, I'll move the relevant code in the main FusionCache package, empty the other one and deprecate it.
Microsoft (and Marc) and OSS
To me, this is a wonderful example of what it may look like when Microsoft and the OSS community have a constructive dialog. First and foremost many thanks to @mgravell himself for the openness, the back and forth and the time spent reading my mega-comments.
The text was updated successfully, but these errors were encountered: