FSCache (Memory Cache)
Warning
Dieses Feature befindet sich noch in Entwicklung und sollte noch nicht frei eingesetzt werden. Derzeit werden in eNVenta mit Begleitung durch des FS-Teams noch weitere Grundlagen geschaffen.
Framework Studio stellt eine Infrastruktur auf Basis des IMemoryCache von Microsoft bereit.
Erreichbar ist diese über einen Singleton FSCache.Instance
.
FSCache.Instance
bietet in erster Ebene Methoden, um an den Cache für den gewünschten Scope zu gelangen - z.B. FSCache.Instance.Static()
, FSCache.Instance.Session()
oder FSCache.Instance.Request()
.
Weitere Scopes z.B. für BusinessUnit()
und User()
werden von eNVenta mihilfe von Extension-Methods für das Interface IFSCache
implementiert.
An den zurückgegebenen Memory Caches können alle angebotenen Features frei verwendet werden. Vor allem ist es möglich den Lifecycle eines CacheEntries mit Hilfe von Timeouts oder ExpirationTokens zu steuern.
Beispiele:
// Verwendung des Static-Caches:
IcdCountryColl oCountries = FSCache.Instance.Static().GetOrCreate("Countries", entry =>
{
// Verwerfen, wenn 20 Minuten nicht verwendet.
entry.SetSlidingExpiration(TimeSpan.FromMinutes(20));
var countries = cdCountryCollFactory.Create();
countries.Load();
return countries;
});
// Verwendung des Session-Caches:
oCurrencyColl = FSCache.Instance.Session().GetOrCreate("Currencies", entry =>
{
var currencies = cdCurrencyCollFactory.Create();
currencies.Load();
return currencies;
});
Spielregeln
Bei der Verwendung des FSCache müssen einige Regeln beachtet werden:
Der FSCache ist flüchtig.
Zugriffe müssen so gestaltet sein, dass die Einträge sich bei Bedarf und jederzeit neu aufbauen können. Existierende Einträge können jederzeit verworfen werden, entsprechende Expiration-Tokens oder -Zeiten zuschlagen. Auch die Methode
FSCache.Reset()
kann den FSCache jederzeit komplett abräumen.Keine Parameter übertragen.
Der FSCache sollte nicht für den Transport von Informationen genutzt werden. Aufgrund der Flüchtigkeit des FSCache können diese Informationen jederzeit verworfen werden.
Nur Readonly Objekte cachen.
Im FSCache sollen nur Objekte abgelegt werden, die Readonly bzw. gegen Veränderungen gesichert sind (z.B. mit Freeze()). Insbesondere in einem sitzungsübergreifenden Cache (Static, BusinessUnit, User) bestünde die Gefahr für ungewollte Seiteneffekte.
Einträge müssen threadsafe sein.
Wird ein Objekt in den Cache gepackt, dass veränderlich sein muss, dann muss dieses threadsafe gestaltet sein. Das gilt insbesondere bei einem sitzungsübergreifenden Cache.
Weitere Scopes
Weitere Scopes können mithilfe von Extension-Methods geschaffen werden, die die Scope-Methode aufrufen.
Beispiel:
// Eigener User-Scope
public static class CacheExtensions
{
public static IMemoryCache User(this IFSCache cache)
{
// Der User-Name ist teil des Scope-Keys.
string scopeKey = "User|" + FSGlobal.Current.AUHelper.UserName;
return cache.Scope(scopeKey, entry => {
// Cache wird nach einer Stunde nicht Verwendung verworfen
entry.SetSlidingExpiration(TimeSpan.FromHours(1));
});
}
}
// Verwendung:
string sValue = FSCache.Instance.User().GetOrCreate("UserSettings", entry =>
{
return LoadUserSettings();
});
Instanzen für Veränderungen sperren - Freeze()
Objekte, welche im Cache verwendet werden, können mittels der Methode Freeze vor Veränderungen geschützt werden.
Ein Freeze ist nur für ungeänderte und neue Objekte erlaubt.
Einmal aufgerufen kann die Instanz für Änderungen nicht mehr "geöffnet" werden.
Wird versucht eine eingefrorene Instanz zu verändern, wird eine InvalidOperationException()
geworfen.
Es stehen folgende Methoden/Property bereit:
- bool IsFrozen
- bool CanFreeze()
- void Freeze()
Die Abprüfung auf IsFrozen
erfolgt auf jedem internen Value Property.
Zu beachten ist: Individueller Code wird dennoch durchlaufen, wenn nicht selbstständig auf die Eigenschaft IsFrozen
geprüft wird.
Erst wenn ein internes Value versucht wird zu ändern, wird eine Exception geworfen.
Freeze ist auch für Collections implementiert. Hier wird die Collection selbst und alle internen Objekte gesperrt.
Änderungen Triggern mit Change-Tokens
Der FSCache bietet mithilfe von ChangeTokens die Möglichkeit, Änderungen zu triggern.
Die Tokens werden Static organisiert. Das bedeutet: Ein Invalidate greift immer in allen Sessions innerhald des eigenen Broker-Prozesses.
Beim Aufbau eines Caches wird dafür mithilfe eines Key ein Token bereitgestellt.
Dies erfolgt mit der Methode FSCache.GetTokenFor<T>()
.
Der Token wird mit der Methode AddExpirationToken()
am Cache-Eintrag registriert.
return FSCache.Instance.Static().GetOrCreate("Countries", entry =>
{
entry.AddExpirationToken(FSCache.Instance.GetTokenFor<IcdCountry>() );
var countries = cdCountryCollFactory.Create();
countries.Load();
return countries;
});
Bei Bedarf können auch mehrere Tokens für verschiedene Keys registriert werden. In diesem Fall läuft der Cache-Eintrag aus, sobald sich der erste Token meldet.
Auf der anderen Seite beim Save, kann dem Cache bescheid gegeben werden.
Das erfolgt mit der Methode FSCache.Invalidate<T>()
.
protected override void OnAfterSave()
{
FSCache.Instance.Invalidate<IcdCountry>()
}
Standardmäßig werden die beiden generischen Methoden FSCache.GetTokenFor<T>()
und FSCache.Invalidate<T>()
verwendet.
Der generische Typ fungiert als Key.
Es sollte das Interface des einzelnen Records verwendet werden.
Es gibt auch allgemeine Methoden, denen als Key ein beliebiges object
übergeben werden kann: IFSCache.GetTokenForKey(key)
, IFSCache.InvalidateKey(key)
.
Diese sollten aber nur in Ausnahmefällen verwendet werden.