v1.0.0-preview2
Pre-releaseImportant
Yep, it's almost v1.0
time!
Please try this preview2
release and let me know if you find any issue, so the v1.0
can be as good as possible: from now until v1.0
is out I will no longer consider requests for new features.
Thanks 🙏
🚀 Performance, performance everywhere
FusionCache always tried to be as optimized as possible, but sometimes useful new features took some precedence over micro-optimizing this or that.
Now that all the major features (and then some) are there, it was time to do a deep dive and optimize a cpu cycle here, remove an allocation there and tweak some hot path to achieve the best use of resources.
So here's a non-comprehensive list of nice performance improvements in this release:
- zero allocations/minimal cpu usage in Get happy path
- minimal allocations/cpu usage in Set happy path
- less allocations/cpu usage when not using distributed components
- less allocations/cpu usage (via closures) when using events
- zero allocations at all when not using logging (no support structures init for operationId generation)
Oh, and thanks to community member @neon-sunset for the issue highlighting some shortcomings, that now have been solved!
See here for the issue.
🦅 Better Eager Refresh (docs)
When executing an Eager Refresh, the initial check for an updated cache entry on the distributed cache is now totally non-blocking, for even better performance.
🆕 Added IgnoreIncomingBackplaneNotifications
option (docs)
FusionCache always allowed to optionally skip sending backplane notifications granularly, for each operation (or globally thanks to DefaultEntryOptions
): it was not possible though to ignore receiving them.
Now we may be thinking "why would I want to use a backplane, but not receive its notifications?" and the answer to that can be found in the feature request made by community member @celluj34 .
See here for the issue.
⚠️ Better nullability annotations for generic types
This is linked to the evolution of nullable reference types, nullables with generics and the related static analysis with each new version of c# and its compiler.
Along the years I tried to adjust the annotations to better handle generic types + nullables with each new version, because what the compiler allowed me to do and was able to infer changed at every release (the first version had problems with generics without where T : class/struct
constraints, for example).
I've now updated them to reflect the latest behaviour, so that it's now more strict in the generic signatures, mostly for GetOrSet<T>
and GetOrSetAsync<T>
: in previous versions the return type was always nullable, so when calling GetOrSet<Person>
we would have a return value of Person?
(nullable) even if the call was not GetOrSet<Person?>
.
Now this is better.
Thanks for community member @angularsen for highlighting this.
See here for the issue.
⚠️ Changed FusionCacheEntryOptions.Size
to be nullable (docs)
The type of the Size
option in the FusionCacheEntryOptions
type has been historically long
(default: 1
): the underlying Size
option in the MemoryCacheEntryOption
type is instead long?
(default: null
).
So, to better align them, now the types and default values are the same.
✅ Better tests
I added some more tests to have a higher code coverage, and made the snapshot tests better.
(Follows recap from preview1
)
⚡ Reflection no more
Not technically a problem per se, but with the release of the new and improved auto-recovery in v0.24.0, I had to add a little bit of reflection usage to support complex scenario of recovering some of the transient distributed errors.
Now, the small amount of code that was using reflection is gone, and this in turn means:
- overall better performance
- be better positioned for, eventually, playing with AOT (where reflection is basically a no-go)
See here for the issue.
🔭 Add eviction reason to Open Telemetry metrics
With v0.26.0 native support for Open Telemetry has been added to FusionCache.
Now community members @JoeShook noticed that the eviction reason was missing from the Eviction counter, which could be in fact useful.
Now it has been added, thanks Joe!
See here for the PR.
🔭 Removed cache instance id from Open Telemetry metrics
Community member @rafalzabrowarny noticed that FusionCache was adding a tag to the metrics, specifically one with the cache instance id: now, since it's a random value generated for every FusionCache instance, it will have a high cardinality and that is usually problematic with APM platforms and tools.
Now it's gone, thanks Rafał!
See here for the issue.
👷♂️ Better detection of incoherent CacheName
s options
With the introduction of the builder in v0.20 FusionCache got a nice way to configure the various options and components, in a very flexible way.
In one particular scenario though, it was possible to specify something incoherent: a single instance with multiple CacheName
s, specified in different ways by using both the high level AddFusionCache("MyCache")
and the WithOptions(...)
methods.
A couple of examples:
services.AddFusionCache("foo")
.WithOptions(options => {
options.CacheName = "bar";
});
or, more subtly:
services.AddFusionCache()
.WithOptions(options => {
options.CacheName = "bar";
});
Now FusionCache correctly detects this scenario and throws an exception as soon as possible, helping the developer by showing the golden path to follow and how to do to solve it.
Thanks @albx for spotting this!
See here for the issue.
👷♂️ Better builder auto-setup
Again with the builder, when using the TryWithAutoSetup()
method in the builder it now also try to check for registered memory lockers by calling TryWithMemoryLocker()
, automatically.
📜 Better logs
More detailed log messages in some areas where they could've been better (mostly related to the backplane).
📕 Docs
Updated some docs with the latest new things.