Skip to content

v1.0.0-preview2

Pre-release
Pre-release
Compare
Choose a tag to compare
@jodydonetti jodydonetti released this 23 Feb 22:38

Important

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 CacheNames 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 CacheNames, 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.