Skip to content

Releases: ZiggyCreatures/FusionCache

v0.1.10-alpha2

30 Jan 16:18
Compare
Choose a tag to compare
v0.1.10-alpha2 Pre-release
Pre-release

This is the second alpha release containing the new Backplane #11 🎉.

It contains:

📞 Events (backplane)

For both message sent/received.

📜 Logging (backplane)

Added logging about the backplane.

📜 Logging (fail-safe activation)

Also, thanks to a tip by the community (see here #38), I changed a log level used when no fallback entry was available for a fail-safe activation, since it seemed more correct this way.

🙏 Tell me what you think

Please try it and let me know so I can push the final version out!


Of course, everything in the alpha1 is still included.

v0.1.10-alpha1

27 Jan 20:19
Compare
Choose a tag to compare
v0.1.10-alpha1 Pre-release
Pre-release

Finally, this is the first (alpha) release containing the Backplane #11 🎉.

📢 Backplane (alpha)

FusionCache finally has a fully functioning backplane: see here for more.

⚠ Removed CacheKeyPrefix

The FusionCacheOptions.CacheKeyPrefix option is now fully obsolete: it has been marked with the [Obsolete] attribute including the additional error flag, so its use will not compile anymore (see #33 for more).

🙏 Tell me what you think

Please try it and let me know so I can push the final version out!

v0.1.9

24 Nov 10:28
Compare
Choose a tag to compare

This is a small release, in preparation of the big one where the Backplane #11 will be added 🎉.

🆕 Added CacheName

It is now possible to specify a cache name, namely a logical name that identify a cache.

It can be used for identification, and in a multi-node scenario it is typically shared between nodes to create a logical association that may be useful to have them communicate together (ref Backplane).

It is possible to specify it in the FusionCacheOptions, and is acessible as a read-only prop directly on any FusionCache instance.

🆕 Added InstanceId

Each time a new FusionCache instance is created (eg: via a new FusionCache(...) directly or via DI) a new id will be generated, globally and uniquely identifying that specific instance.

It can be useful to uniquely identify a single instance in a multi-node scenario, for example to precisely route notifications to each one (ref Backplane).

It is acessible as a read-only prop directly on any FusionCache instance.

🆕 Added Evict method

A new Evict method has been added: this method evicts an entry from the cache, like the Remove method, but with 2 very important differencs:

  • it only act on the primary layer (memory cache) and does not propagate the removal in the distributed cache, if any
  • it does not raise a Remove event

Again, this is useful in the Backplane that is coming.

It is only available in a sync fashion and not in an async one, since it acts only locally and there's nothing to do asynchronously.

⚠ Marked CacheKeyPrefix as [Obsolete] for future removal

The CacheKeyPrefix option is now obsolete: it still works, but will be kinda removed in the next version.

See here for more info.

🚀 Performance

Added a couple of small perf optimizations here and there.

v0.1.7

16 Oct 19:18
Compare
Choose a tag to compare

🔀 New option

A new FusionCacheOptions.DistributedCacheKeyModifierMode option has been added, so that you can now control how the cache key will be modified to be used in the distributed cache (Prefix, Suffix or None).
The default value is Prefix but, if for example you are having problems with Redis ACLs (which are prefix-based), you can change this to Suffix (or even None) to solve them.

🙏 Thanks

Thanks to RogerSep for the hint about Redis ACLs, I hope this will solve your problem!

v0.1.6

01 Aug 18:16
Compare
Choose a tag to compare

🚀 Switch from Task<T> to ValueTask<T>

The async part of the api surface area has been migrated from using the Task<T> type to the ValueTask<T> type.
This allows saving a good amount of memory allocations, making our apps more performant.

Is this a breaking change? In short, no.
To expand on it a little bit more, it could be if you directly used a Task<T> returned from one of the async methods, instead of awaiting it normally. In that case simply add .AsTask() to turn the ValueTask<T> into a Task<T> and everything will be fine.

In all other normal usage scenarios, just awaiting on one of the async methods would work absolutely the same, while also allocating less memory 🎉

⚠️ Breaking changes

I've finally removed the TryGetResult<T> type, marked as [Obsolete] from a lot of time now.
It has been replaced a long ago with the MaybeValue<T> type, which is better designed and used also as an input, and not just an output.
For more information about the change please read the "Breaking change" section of the v0.1.3 release.
The same goes for the Success prop in the MaybeValue<T> type, also marked as [Obsolete] since the beginning and added just to allow a more pleasant transition from the old type to the new one.

🙏 Thanks

Thanks to the the great Marc Gravell and Stephen Toub for their writings on this subject, in particular this and this which helped clear my mind on the subject.

v0.1.5

18 Jul 15:43
Compare
Choose a tag to compare

🧩 Plugins (more)

FusionCache now has an extensibility mechanism thanks to a plugins subsystem: you can easily create your own plugin and subscribe to core events to do whatever you want.

There's an introductory guide and a complete sample available.

v0.1.4

05 Jun 23:02
Compare
Choose a tag to compare

📞 Events (more)

FusionCache now has a comprehensive set of events to subscribe to, so you can be notified of core events when they happen.

Example:

// SUBSCRIBE TO CACHE MISS EVENTS
cache.Events.Miss += (s, e) => {
    // REACT TO THE EVENT HERE, WITH THE RELATED CACHE KEY AVAILABLE VIA e.Key
};

This is also a stepping stone towards the next step: plugins (#15).

And thanks to @JoeShook for the invaluable help!

🚀 Performance

Added some perf optimizations.

v0.1.3

03 Apr 14:25
Compare
Choose a tag to compare

🤷 Introducing MaybeValue<T> (more)

A new type has been introduced to model a value that may be there or not, just like the standard .NET nullables but for both reference and value types.
It supports implicit convesion to/from T and is used in a couple of places (see below).

🕹️ Better TryGet[Async] (more)

The TryGet[Async] return type is now MaybeValue<T> for better ease of use (more like the standard .NET nullables).

Example:

var maybeFoo = cache.TryGet<int>("foo");

if (maybeFoo.HasValue) {
  // EXPLICIT ACCESS
  var foo = maybeFoo.Value;
  // OR IMPLICIT CONVERSION
  int foo = maybeFoo;
}

🕹️ Better GetOrSet[Async] (more)

The GetOrSet[Async] methods now has an additional failSafeDefaultValue param to handle factory failures (with fail-safe enabled) in case there's no expired/stale value to use (eg: cold start, first use, etc).

Example:

// WITH FAIL-SAFE ENABLED
cache.GetOrSet<int>("foo", _ => GetFooFromDb(), 42);

There's also a new GetOrSet[Async] overload available that accepts a value directly instead of a factory: this covers the cases when you already have a default value to use so you don't have to allocate a useless lambda.

Example:

// BEFORE
cache.GetOrSet<int>("foo", _ => 42);

// FROM v0.1.3
cache.GetOrSet<int>("foo", 42);

⚠️ Breaking changes

The TryGet[Async] methods now returns a MaybeValue<T> instead of a TryGetResult<T>.
This new type also contains the Success prop present in the old TryGetResult<T> type, but marked as [Obsolete] to better ease the transition.

Also, the old TryGetResult<T> type is still there, in case you've used that somewhere, but the type as a whole has been marked as [Obsolete] to warn of the usage.

The only case of an actual breaking change is if you were doing something like this:

// USING IMPLICIT bool CONVERSION
if (cache.TryGet<int>("foo")) {
  [...]
}

but it should have been rare, since the value would have been discarded.
Anyway, in that case, you simply have to do this now:

if (cache.TryGet<int>("foo").HasValue) {
  [...]
}

or, even better:

var maybeFoo = cache.TryGet<int>("foo");

if (maybeFoo.HasValue) {
  // EXPLICIT ACCESS
  var foo = maybeFoo.Value;
  // OR IMPLICIT CONVERSION
  int foo = maybeFoo;
}

🚀 Performance

Optimized cpu and memory usage so that common scenarios will consume less resources.

v0.1.2

26 Feb 20:49
Compare
Choose a tag to compare

🐞 Bugfix

Fixed a bug about deserializing an entry's metadata with the System.Text.Json serializer (thanks @Paulskit!)

v0.1.1

19 Jan 18:40
Compare
Choose a tag to compare

💫 More flexible type handling

Better support for caching flows with flexible types.
Previously, doing this:

var data = (object)42;
cache.Set("foo", data);
cache.GetOrDefault<int>("foo");

would not have resulted in getting back 42 .

Thanks to type inference the Set method call in the 2nd line in reality is a Set<object> and this, in addition to various internal details to support advanced features (fail-safe, etc), made it incompatible to transparently swich from one type to the other.

Now this scenario is fully supported 🎉

⚠️ Namespace change

The first and last namespace change: the general namespace changed from ZiggyCreatures.FusionCaching to ZiggyCreatures.Caching.Fusion.

The fix should be very easy: update the packages, compile, see where it fails and change a couple of usings, that's it.

Sorry for this hassle 🙏 , it will be the last time.

🚀 Performance

Optimized cpu and memory usage so that common scenarios will consume less resources.