πββοΈ Updating to v2 ? Please read here. |
---|
π Integrate All The Things!
Now that v2 isfinally here and with full Tagging support, it's time to integrate all the things π₯³
The first 2 can be found below:
- OutputCache
- EF 2nd Level Cache
π Output Cache, FusionCache style
The first one on my list is Output Cache, and the nice thing about the way it has been designed in ASP.NET is that the only thing that is needed to make a custom version is an implementation of IOutputCacheStore
.
And so I did, and thanks to native Tagging in FusionCache the whole implementation is a thing of beauty with just 1 line per method: behold.
Btw while I was working on this, community user @Fabman08 asked for the same thing, talk about good timing!
Anyway, why is all of this useful?
Because now, when using OutputCache, we'll not be limited by a simple memory cache anymore, and can instead have the power of all the features of FusionCache like fail-safe, L1+L2, backplane support and more: imagine having the performance of a memory cache (L1) but with the availability and database savings of a distributed cache (L2) including instant synchronization of the backplane.
If you ask me, it's awesome.
Ok so, how can we set it up?
Easy:
// FUSION CACHE
services.AddFusionCache();
// FUSION OUTPUT CACHE
services.AddFusionOutputCache();
// OUTPUT CACHE (STANDARD SETUP)
services.AddOutputCache(options =>
{
options.AddPolicy("Expire2", builder =>
builder.Expire(TimeSpan.FromSeconds(2))
);
options.AddPolicy("Expire5", builder =>
builder.Expire(TimeSpan.FromSeconds(5))
);
});
When using the normal OutputCache (with a memory-only cache store) we need to:
- setup OutputCache (settings, profiles, etc)
With the FusionCache-based version we just need 2 extra steps, before the common one:
- π setup a FusionCache instance
- π setup the FusionCache-based OutputCache
- setup OutputCache normally (settings, profiles, etc)
One thing to note is that, even though it's possible to use the default FusionCache instance like in the example above, it's usually better to have a separate named cache with a specific configuration for OutputCache: this can be useful both to avoid cache key collisions (even though it is already quite hard to have them because of the standard key structure in OutputCache itself) and to have different L1/L2/backplane configurations.
How? Easy:
// FUSION CACHE (WITH CUSTOM NAME, L2, BACKPLANE, DEFAULT ENTRY OPTIONS)
services.AddFusionCache("MyOutputCache")
.WithDefaultEntryOptions(options =>
{
options.IsFailSafeEnabled = true;
})
.WithSerializer(new FusionCacheProtoBufNetSerializer())
.WithDistributedCache(new RedisCache(new RedisCacheOptions
{
Configuration = "..."
}))
.WithBackplane(new RedisBackplane(new RedisBackplaneOptions
{
Configuration = "..."
}));
// FUSION OUTPUT CACHE
services.AddFusionOutputCache(options =>
{
// WHICH NAMED CACHE TO USE
options.CacheName = "MyOutputCache";
});
// OUTPUT CACHE (STANDARD SETUP)
services.AddOutputCache(options =>
{
options.AddPolicy("Expire2", builder =>
builder.Expire(TimeSpan.FromSeconds(2))
);
options.AddPolicy("Expire5", builder =>
builder.Expire(TimeSpan.FromSeconds(5))
);
});
Another important aspect is to be able to use a different serializers.
Wait, but why a different serializer?
Frequently it's common to use text-based serialziers (eg: JSON-based) for our entities and objects in the cache, and that is totally fine.
But OutputCache deals with byte[]
(containing the entire http response with headers, body, etc) and by using a text-based serializer we are not getting the best performance for our bucks.
So, my suggestion is to pick a natively binary serializer like protobuf-net
, MessagePack
or MemoryPack
(the available ones can be found here): in this way the payload in L2 will be as small as possible, and performance will be top notch.
Awesome.
π EF 2nd Level Cache
The other one is an interesting project by @VahidN called EFCoreSecondLevelCacheInterceptor, which proposes itself as a transparent 2nd level cache for EFCore.
The nice thing for this is that I did... nothing at all π
One community user @kooshan asked for it in their repo some time ago, more recently another user @bbehrens let me know about it and, before I was able to do anything, the maintainer worked on it, released the new v5 version with pluggable multi-provider support and... tada π
If interested, I suggest using at least v5.1
since it's the first that depends on the final FusionCache v2 bits.
π’ More async-y Backplane (docs)
The backplane has always been async at its core, meaning the messages sent and received.
A couple of smaller parts though were not as async-aware as ideally wanted, and now this is fixed: both the initial subscription and the ending unsubscription are now available in a fully async variant.
π Fix edge case bug with parallel init (Protobuf-net)
Comunity user @ilioan noticed (thanks!) a small regression in FusionCache v2 related to a particular edge case: highly parallel initializations.
In that case there was a missing check in a classic double-checked-lock, such that in some cases it resulted in a missing model registration.
Now this has been fixed.
See here for the original issue.
π Better Logging
Community user @sebbarg noticed (thanks!) that when filtering log messages for the Debug
level, the output was not totally consistent: the general method was being logged (eg: calling RemoveAsync
), and the L1 operation was being logged too, but the L2 operation was nowhere to be found.
The issue? L2 operations were using the Trace
log level π€¦.
Anyway now this has been fixed, and log messages are more consistent.
See here for the original issue.
𧬠Diagrams (docs)
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!
β Better Tests
As with any new release I made the tests better, this time adding a couple of additional scenarios covered.
I also reorganized all the tests in a better way, by splitting the sync and async ones in separated files thanks to partial classes, so that they are now nicer to work with and easier to keep aligned.
π Better Docs (and diagrams!)
I've added some more docs for the latest stuff, and fixed some typos, no big deal.