Protokollkonsistenzanbieter
Das Microsoft.Orleans.EventSourcing
-Paket enthält mehrere Protokollkonsistenzanbieter, die grundlegende Szenarios abdecken, die für den Einstieg geeignet sind, und eine gewisse Erweiterbarkeit ermöglichen.
Zustandsspeicher
Der Orleans.EventSourcing.StateStorage.LogConsistencyProvider speichert Momentaufnahmen des Grainzustands mithilfe eines Standardspeicheranbieters, der unabhängig konfiguriert werden kann.
Die im Speicher aufbewahrten Daten sind ein Objekt, das sowohl den Grainzustand (wie durch den ersten Typparameter für JournaledGrain
angegeben) als auch einige Metadaten enthält (die Versionsnummer und ein spezielles Tag, mit dem Duplikate von Ereignissen vermieden werden, wenn Speicherzugriffe fehlschlagen).
Da der gesamte Grainzustand bei jedem Zugriff auf den Speicher gelesen/geschrieben wird, eignet sich dieser Anbieter nicht für Objekte, deren Grainzustand sehr groß ist.
Dieser Anbieter unterstützt nicht RetrieveConfirmedEvents, er kann die Ereignisse nicht aus dem Speicher abrufen, da die Ereignisse dort nicht aufbewahrt werden.
Protokollspeicher
Der Orleans.EventSourcing.LogStorage.LogConsistencyProvider speichert die vollständige Ereignissequenz als einzelnes Objekt mithilfe eines Standardspeicheranbieters, der unabhängig konfiguriert werden kann.
Die im Speicher aufbewahrten Daten sind ein Objekt, das einen List<EventType> object
und einige Metadaten enthält (ein spezielles Tag, das verwendet wird, um die Duplizierung von Ereignissen zu vermeiden, wenn Speicherzugriffe fehlschlagen).
Dieser Anbieter unterstützt RetrieveConfirmedEvents. Alle Ereignisse sind immer verfügbar und im Arbeitsspeicher gespeichert.
Da die gesamte Ereignissequenz bei jedem Zugriff auf den Speicher gelesen/geschrieben wird, eignet sich dieser Anbieter nicht für die Verwendung in der Produktion, es sei denn, die Ereignissequenzen bleiben garantiert relativ kurz. Der Standardzweck dieses Anbieters besteht darin, die Semantik des Ereignissourcing und für Beispiel-/Testumgebungen zu veranschaulichen.
Benutzerdefinierter Speicher
Dieser Orleans.EventSourcing.CustomStorage.LogConsistencyProvider ermöglicht Entwickler*innen, ihre Speicherschnittstellen anzuschließen, die dann vom Konsistenzprotokoll zu geeigneten Zeiten aufgerufen werden. Dieser Anbieter trifft keine spezifischen Annahmen darüber, ob Zustandsmomentaufnahmen oder Ereignisse gespeichert werden. Die Programmierer*innen können dies selbst steuern (und eines von beidem oder beides speichern).
Um diesen Anbieter zu verwenden, muss wie zuvor ein Grain von JournaledGrain<TGrainState,TEventBase> abgeleitet werden, aber zusätzlich muss auch die folgende Schnittstelle implementiert werden:
public interface ICustomStorageInterface<StateType, EventType>
{
Task<KeyValuePair<int, StateType>> ReadStateFromStorage();
Task<bool> ApplyUpdatesToStorage(
IReadOnlyList<EventType> updates,
int expectedVersion);
}
Der Konsistenzanbieter erwartet, dass diese sich auf eine bestimmte Weise verhalten. Programmierer*innen sollten Folgendes beachten:
Die erste Methode ReadStateFromStorage soll sowohl die Version als auch den gelesenen Zustand zurückgeben. Wenn noch nichts gespeichert ist, sollte für die Version null zurückgegeben werden, und ein Zustand, der dem Standardkonstruktor für
StateType
entspricht.ApplyUpdatesToStorage muss „false“ zurückgeben, wenn die erwartete Version nicht mit der tatsächlichen Version übereinstimmt (dies entspricht einer ETag-Überprüfung).
Wenn bei
ApplyUpdatesToStorage
ein Ausnahmefehler auftritt, wiederholt der Konsistenzanbieter den Vorgang. Dies bedeutet, dass einige Ereignisse dupliziert werden können, wenn eine solche Ausnahme ausgelöst wird, das Ereignis bleibt jedoch bestehen. Entwickler*innen sind dafür verantwortlich, dass dies sicher ist: entweder wird der Fall vermieden, indem keine Ausnahme ausgelöst wird, oder es wird sichergestellt, dass duplizierte Ereignisse für die Anwendungslogik unbedenklich sind, oder es wird ein zusätzlicher Mechanismus zum Filtern von Duplikaten hinzugefügt.
Dieser Anbieter unterstützt nicht RetrieveConfirmedEvents
. Da die Entwickler*innen die Speicherschnittstelle sowieso steuern, müssen sie dies natürlich nicht erst aufrufen, sondern können ihren Ereignisabruf implementieren.