A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/ZiggyCreatures/FusionCache below:

ZiggyCreatures/FusionCache: FusionCache is an easy to use, fast and robust hybrid cache with advanced resiliency features.

FusionCache is an easy to use, fast and robust hybrid cache with advanced resiliency features.

It was born after years of dealing with all sorts of different types of caches: memory, distributed, hybrid, HTTP caching, CDNs, browser cache, offline cache, you name it.

So I tried to put together these experiences and came up with FusionCache.

Being a hybrid cache means it can transparently work as either a normal memory cache (L1) or as a multi-level cache (L1+L2), where the distributed 2nd level (L2) can be any implementation of the standard IDistributedCache interface: this will get us better cold starts, better horizontal scalability, more resiliency and overall better performance.

FusionCache includes an optional backplane for realtime sync between multiple nodes and advanced resiliency features like cache stampede protection, a fail-safe mechanism, soft/hard timeouts, eager refresh, full observability via logging and OpenTelemetry, tagging and much more.

It's being used in production on real-world projects with huge volumes for years, and is even used by Microsoft itself in its products like Data API Builder.

It's also compatible with the new HybridCache from Microsoft, thanks to a powerful integration.

In 2021 FusionCache received the Google Open Source Peer Bonus Award: here is the official blogpost.

With ๐Ÿฆ„ A Gentle Introduction you'll get yourself comfortable with the overall concepts.

Want to start using it immediately? There's a โญ Quick Start for you.

What about each global or entry option? Sure thing, there's an ๐ŸŽš๏ธ Options page for that.

Curious about what you can achieve from start to finish? There's a ๐Ÿ‘ฉโ€๐Ÿซ Step By Step guide.

In search of all the docs? There's a page for that, too.

Sometimes it's nice to be able to visualize the internal flow of a system, even more so for such a complex beast as an hybrid cache like FusionCache.

So, diagrams!

Are you more into videos?

I've been lucky enough to be invited on some shows and podcasts here and there: you can find them in the Media section.

A good example is when the fine folks at On .NET invited me on the show to allow me to mumbling random caching stuff.

FusionCache has a lot of features, let's see them grouped together:

Performance & Scalability

That was a lot, but not all!

Something more ๐Ÿ˜ ?

Also, FusionCache has some nice additional features:

We've probably all heard about the new kid on the block introduced by Microsoft with .NET 9: HybridCache.

So what does it mean for FusionCache? Does one replace the other? Or can they somehow work together?

It's pretty cool actually, so let's find out!

Main packages:

Serializers:

Backplanes:

Third-party packages:

Just install the ZiggyCreatures.FusionCache Nuget package:

PM> Install-Package ZiggyCreatures.FusionCache

Then, let's say we have a method that loads a product from the database:

Product GetProductFromDb(int id) {
	// DATABASE CALL HERE
}

(This is using the sync programming model, but it would be equally valid with the newer async one)

Then we create a FusionCache instance:

var cache = new FusionCache(new FusionCacheOptions());

or, if using dependency injection:

services.AddFusionCache();

Now, to get the product from the cache and, if not there, get it from the database in an optimized way and cache it for 30 sec:

var id = 42;

cache.GetOrSet<Product>(
	$"product:{id}",
	_ => GetProductFromDb(id),
	TimeSpan.FromSeconds(30)
);

That's it.

Want a little bit more ๐Ÿ˜ ?

We can also specify some global options, like a default FusionCacheEntryOptions object to serve as a default for each call we'll make, with a duration of 2 minutes and a Low priority:

var cache = new FusionCache(new FusionCacheOptions() {
	DefaultEntryOptions = new FusionCacheEntryOptions {
		Duration = TimeSpan.FromMinutes(2),
		Priority = CacheItemPriority.Low
	}
});

Or, using DI, like this:

services.AddFusionCache()
	.WithDefaultEntryOptions(new FusionCacheEntryOptions {
		Duration = TimeSpan.FromMinutes(2),
		Priority = CacheItemPriority.Low
	})
;

Now, imagine we want to do the same, but also:

To do all of that we simply have to change the last line (reformatted for better readability):

cache.GetOrSet<Product>(
	$"product:{id}",
	_ => GetProductFromDb(id),
	// THIS IS WHERE THE MAGIC HAPPENS
	options => options
		.SetDuration(TimeSpan.FromSeconds(30))
		.SetPriority(CacheItemPriority.High)
		.SetFailSafe(true, TimeSpan.FromHours(2))
		.SetFactoryTimeouts(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(2))
);

Basically, on top of specifying the cache key and the factory, instead of specifying just a duration as a TimeSpan we specify a FusionCacheEntryOptions object - which contains all the options needed to control the behavior of FusionCache during each operation - in the form of a lambda that automatically duplicates the default entry options defined before (to copy all our defaults) while giving us a chance to modify it as we like for this specific call.

Now let's say we really like these set of options (priority, fail-safe and factory timeouts) and we want them to be the overall defaults, while keeping the ability to change something on a per-call basis (like the duration).

To do that we simply move the customization of the entry options where we created the DefaultEntryOptions, by changing it to something like this (the same is true for the DI way):

var cache = new FusionCache(new FusionCacheOptions() {
	DefaultEntryOptions = new FusionCacheEntryOptions()
		.SetDuration(TimeSpan.FromMinutes(2))
		.SetPriority(CacheItemPriority.High)
		.SetFailSafe(true, TimeSpan.FromHours(2))
		.SetFactoryTimeouts(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(2))
});

Now these options will serve as the cache-wide default, usable in every method call as a "starting point".

Then, we just change our method call to simply this:

var id = 42;

cache.GetOrSet<Product>(
	$"product:{id}",
	_ => GetProductFromDb(id),
	options => options.SetDuration(TimeSpan.FromSeconds(30))
);

The DefaultEntryOptions we did set before will be duplicated and only the duration will be changed for this call.

If you are in for a ride you can read a complete step by step example of why a cache is useful, why FusionCache could be even more so, how to apply most of the options available and what results you can expect to obtain.

Distributed systems are, in general, quite complex to understand.

When using FusionCache with the distributed cache, the backplane and auto-recovery the Simulator can help us see the whole picture.

FusionCache targets .NET Standard 2.0 so any compatible .NET implementation is fine: this means .NET Framework (the old one), .NET Core 2+ and .NET 5/6/7/8+ (the new ones), Mono 5.4+ and more (see here for a complete rundown).

NOTE: if you are running on .NET Framework 4.6.1 and want to use .NET Standard packages Microsoft suggests to upgrade to .NET Framework 4.7.2 or higher (see the .NET Standard Documentation) to avoid some known dependency issues.

There are various alternatives out there with different features, different performance characteristics (cpu/memory) and in general a different set of pros/cons.

A feature comparison between existing .NET caching solutions may help you choose which one to use.

๐Ÿ’ผ Is it Production Ready โ„ข๏ธ ?

Yes!

FusionCache is being used in production on real world projects for years, happily handling billions of requests.

Considering that the FusionCache packages have been downloaded more than 15 million times (thanks everybody!) it may very well be used even more.

Oh, and it is being used in products by Microsoft itself, like Data API Builder!

If you find FusionCache useful please let me know, I'm interested in knowing your use case!

This is the only way for me to know how it is helping people.

Nothing to do here.

After years of using a lot of open source stuff for free, this is just me trying to give something back to the community.

Will FusionCache one day switch to a commercial model? Nope, not gonna happen.

Mind you: nothing against other projects making the switch, if done in a proper way, but no thanks not interested. And FWIW I don't even accept donations, which are btw a great thing: that should tell you how much I'm into this for the money.

Again, this is me trying to give something back to the community.

If you really want to talk about money, please consider making ๐Ÿฉท a donation to a good cause of your choosing, and let me know about that.


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4