Se ti chiedessi di parlarmi della cache, se fossi uno sviluppatore backend mi parleresti di Redis, mentre se fossi uno sviluppatore frontend sicuramente mi diresti “quel maledetto meccanismo per cui devo fare ctrl f5 per far vedere le mie modifiche sul browser”.
Io invece oggi sono qui a parlarti di un tipo di cache “dev friendly”, una cache di tipo ibrido per i progetti .Net.
Benvenuti a OpenDev Explorer, la mia rubrica dedicata all’esplorazione del mondo Open Source che strizza un occhio alla developer experience. Io sono Riccardo (aka TheZal) e oggi vi parlerò di FusionCache, una libreria che vi permetterá di gestire in maniera ibrida la cache sui vostri progetti .NET.
Panoramica Generale
FusionCache è una cache ibrida progettata per essere semplice da usare, veloce e resiliente, con funzionalità avanzate di gestione degli errori.
Nasce dall’esperienza accumulata negli anni affrontando le più diverse tipologie di cache: dalla cache in memoria a quella distribuita, dalla cache HTTP alle CDN, fino alla cache offline e del browser.
FusionCache, essendo una cache ibrida, può funzionare in modo trasparente sia come cache in memoria (L1) che come cache multi-livello (L1+L2). In questo secondo caso, il livello distribuito (L2) può essere qualsiasi implementazione dell’interfaccia standard IDistributedCache
. Questo approccio offre avvii a freddo più rapidi, migliore scalabilità orizzontale, maggiore resilienza e prestazioni complessive superiori.
Manuale d’istruzioni
Installazione
Installare fusioncache é semplicissimo, infatti é disponibile come pacchetto su nuget ed é possibile installarlo sia tramite Nuget UI (cercando il pachetto ZiggyCreatures.FusionCache
) che tramite la console di nuget tramite il comando
PM> Install-Package ZiggyCreatures.FusionCache
Utilizzo
Per iniziare a usare FusionCache, la prima cosa da fare è creare un’istanza di cache:
var cache = new FusionCache(new FusionCacheOptions());
Code language: JavaScript (javascript)
Se invece stai utilizzando la Dependency Injection, ti basta aggiungere questa riga:
services.AddFusionCache();
Code language: CSS (css)
È possibile anche configurare delle opzioni globali, come ad esempio un oggetto FusionCacheEntryOptions predefinito con una durata di 2 minuti per ogni operazione che andremo a fare:
var cache = new FusionCache(new FusionCacheOptions() {
DefaultEntryOptions = new FusionCacheEntryOptions {
Duration = TimeSpan.FromMinutes(2)
}
});
Code language: JavaScript (javascript)
Oppure, sempre tramite Dependency Injection:
services.AddFusionCache()
.WithDefaultEntryOptions(new FusionCacheEntryOptions {
Duration = TimeSpan.FromMinutes(2)
});
Code language: JavaScript (javascript)
Ora, per ottenere un prodotto dalla cache e, se non è presente, recuperarlo dal database in modo ottimizzato e salvarlo in cache per 30 secondi (sovrascrivendo i 2 minuti predefiniti di cui sopra), basta fare così:
var id = 42;
cache.GetOrSet<Product>(
$"product:{id}",
_ => GetProductFromDb(id),
TimeSpan.FromSeconds(30)
);
Code language: PHP (php)
La developer experience
La semplicitá di utilizzo di FusionCache lo rende un progetto super appetibile per quello che riguarda la developer experience, avendo tra le sue principali armi la sua facilitá di implementazione e il fatto di essere un progetto production ready out of the box.
Inoltre FusionCache ha nella sua documentazione diverse risorse molto utili per quello che riguarda il bootstrap iniziale, permettendo di avere una curva d’apprendimento relativemente bassa.
In piú visto che l’autore del progetto si é reso conto che a volte figurare un sistema distribuito é il modo migliore per capirlo, ha anche implementato un simulatore che permette di capire come funzioni FusionCache.
L’extra mile
L’extra mile di FusionCache é dato sicuramente dal sistema di autorecovery che permette di recuperare la salute del nostro sistema di cache in caso di malfunzionamento.
In caso di problemi transitori con i componenti distribuiti (come la cache distribuita o il backplane), FusionCache cercherà di risolverli automaticamente, senza bisogno di alcun intervento.
L’autorecovery puó essere approfondito qui
Il confronto con lo status quo
Ci sono innumerevoli librerie che si occupano di gestione cache in circolazione, peró per avere un confronto diretto, nel repository ufficiale del progetto é possibile trovare la seguente tabella che riassume le differenze con altre librerie.
FusionCache | HybridCache | CacheManager | CacheTower | EasyCaching | LazyCache | |
Cache Stampede | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ |
Sync Api | ✔ | ❌ | ✔ | ❌ | ✔ | ✔ |
Async Api | ✔ | ✔ | ❌ | ✔ | ✔ | ! |
Fail-Safe | ✔ | ❌ | ❌ | ❌ | ❌ | ❌ |
Timeouts | ✔ | ❌ | ❌ | ❌ | ❌ | ❌ |
Adaptive caching | ✔ | ❌ | ❌ | ❌ | ❌ | ✔ |
Cancellation | ✔ | ✔ | ❌ | ❌ | ❌ | ❌ |
Multi provider | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ |
Multi level | ✔ | ✔ | ✔ | ✔ | ! | ❌ |
Backplane | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ |
Auto recovery | ✔ | ❌ | ❌ | ❌ | ❌ | ❌ |
Events | ✔ | ❌ | ✔ | ❌ | ❌ | ❌ |
Open Telemetry | ✔ | ❌ | ❌ | ❌ | ❌ | ❌ |
Logging | ✔ | ❌ | ✔ | ❌ | ✔ | ❌ |
Portable | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
Tests | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
Xml Comments | ✔ | ❌ | ✔ | ✔ | ✔ | ❌ |
Docs | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
License | MIT | Same as .net | Apache 2.0 | MIT | MIT | MIT |
Tiriamo le somme!
Reputo FusionCache uno dei progetti piú interessanti che ho avuto la possibilitá di conoscere a Codemotion 2024, sia per quello che riguarda la sua developer experience, che per le potenzialitá del progetto che si capiscono anche dal fatto che
Microsoft ha deciso di implementare la sua HybridCache seguendo gli stessi passi di FusionCache.