Megosztás a következőn keresztül:


A JournaledGrain alapjai

A naplózott szemcsék a JournaledGrain<TGrainState,TEventBase>következő típusparaméterekkel származnak:

  • A TGrainState szemcse állapotát jelöli. Nyilvános alapértelmezett konstruktorral rendelkező osztálynak kell lennie.
  • TEventBase ez egy gyakori szupertípus az összes olyan eseményhez, amely erre a szemre emelhető, és bármilyen osztály vagy felület lehet.

Minden állapot- és eseményobjektumnak szerializálhatónak kell lennie (mivel előfordulhat, hogy a naplókonzisztencia-szolgáltatóknak meg kell őrizniük őket, és/vagy értesítési üzenetekben kell elküldeniük őket).

Olyan szemcsék esetében, amelyek eseményei POCOS-ok (egyszerű régi C#-objektumok), JournaledGrain<TGrainState> rövidítésként használhatók.JournaledGrain<TGrainState,TEventBase>

A szemcse állapotának olvasása

Az aktuális gabonaállapot beolvasásához és verziószámának meghatározásához a JournaledGrain tulajdonsággal rendelkezik

GrainState State { get; }
int Version { get; }

A verziószám mindig megegyezik a megerősített események teljes számával, és az állapot annak az eredménye, hogy az összes megerősített eseményt a kezdeti állapotra alkalmazza. A kezdeti állapotot, amely 0-s verzióval rendelkezik (mivel nem alkalmaztak eseményeket), a GrainState osztály alapértelmezett konstruktora határozza meg.

Fontos: Az alkalmazásnak soha nem szabad közvetlenül módosítania a visszaadott Stateobjektumot. Csak olvasásra szolgál. Ehelyett, ha az alkalmazás módosítani szeretné az állapotot, ezt közvetett módon kell megtennie események növelésével.

Események emelése

Az események növelése a függvény meghívásával RaiseEvent történik. Egy csevegést jelképező szemcsék például arra PostedEvent utalhatnak, hogy egy felhasználó elküldött egy bejegyzést:

RaiseEvent(new PostedEvent()
{
    Guid = guid,
    User = user,
    Text = text,
    Timestamp = DateTime.UtcNow
});

Vegye figyelembe, hogy RaiseEvent elindít egy írást a tárhoz való hozzáféréshez, de nem várja meg, amíg az írás befejeződik. Sok alkalmazás esetében fontos megvárni, amíg megerősítést kapunk az esemény megőrzéséről. Ebben az esetben mindig a következőre ConfirmEventsvárunk:

RaiseEvent(new DepositTransaction()
{
    DepositAmount = amount,
    Description = description
});
await ConfirmEvents();

Vegye figyelembe, hogy még ha nem is hív ConfirmEventsmeg explicit módon, az események végül megerősítést kapnak – ez automatikusan megtörténik a háttérben.

Állapotáttrasztálási módszerek

A futtatókörnyezet automatikusan frissíti a szemcsés állapotot események felmerülése esetén. Nincs szükség arra, hogy az alkalmazás explicit módon frissítse az állapotot egy esemény létrehozása után. Az alkalmazásnak azonban továbbra is meg kell adnia azt a kódot, amely meghatározza , hogyan frissítheti az állapotot egy eseményre válaszul. Ez kétféleképpen végezhető el.

a) Az GrainState osztály egy vagy több Apply metódust implementálhat a StateTyperendszeren. Általában több túlterhelést hoz létre, és a legközelebbi egyezést választja ki az esemény futtatókörnyezeti típusához:

class GrainState
{
    Apply(E1 @event)
    {
        // code that updates the state
    }

    Apply(E2 @event)
    {
        // code that updates the state
    }
}

(b) A gabona felülbírálhatja a függvényt TransitionState :

protected override void TransitionState(
    State state, EventType @event)
{
   // code that updates the state
}

Az áttűnési módszereknek az állapotobjektum módosításán kívül nincs más mellékhatásuk, és determinisztikusnak kell lenniük (ellenkező esetben a hatások kiszámíthatatlanok). Ha az áttűnési kód kivételt eredményez, a rendszer a napló konzisztenciaszolgáltatója által kiadott figyelmeztetésben Orleans rögzíti és tartalmazza ezt a kivételt.

Amikor a futtatókörnyezet pontosan meghívja az áttűnési módszereket, a kiválasztott naplókonzisztencia-szolgáltatótól és annak konfigurációjától függ. Az alkalmazásoknak nem szabad egy adott időzítésre támaszkodniuk, kivéve, ha a naplókonzisztencia-szolgáltató kifejezetten garantálja.

Egyes szolgáltatók, például a Orleans.EventSourcing.LogStorage naplókonzisztencia-szolgáltató, minden alkalommal visszajátszják az eseményütemezést, amikor betöltik a magot. Ezért mindaddig, amíg az eseményobjektumok továbbra is megfelelően deszerializálhatók a tárolóból, radikálisan módosíthatja az osztályt és az GrainState áttűnési módszereket. Más szolgáltatók, például a Orleans.EventSourcing.StateStorage naplókonzisztencia-szolgáltató esetében azonban csak az GrainState objektum marad meg, ezért a fejlesztőknek gondoskodniuk kell arról, hogy megfelelően deszerializálhatók legyenek a tárolóból való olvasáskor.

Több esemény létrehozása

Hívás előtt ConfirmEventstöbb hívást RaiseEvent is kezdeményezhet:

RaiseEvent(e1);
RaiseEvent(e2);
await ConfirmEvents();

Ez azonban valószínűleg két egymást követő tárhozzáférést okoz, és azzal a kockázattal jár, hogy a gabona csak az első esemény írása után meghiúsul. Így általában jobb, ha egyszerre több eseményt is

RaiseEvents(IEnumerable<EventType> events)

Ez garantálja, hogy az események adott sorozata atomilag meg van írva a tárolóba. Vegye figyelembe, hogy mivel a verziószám mindig megegyezik az eseménysorozat hosszával, több esemény felemelése egyszerre többsel növeli a verziószámot.

Az eseményütemezés lekérése

Az alaposztály JournaledGrain következő metódusa lehetővé teszi, hogy az alkalmazás lekérje az összes megerősített esemény sorozatának egy adott szegmensét:

Task<IReadOnlyList<EventType>> RetrieveConfirmedEvents(
    int fromVersion,
    int toVersion);

Ezt azonban nem támogatja minden naplókonzisztencia-szolgáltató. Ha nem támogatott, vagy ha a szekvencia megadott szegmense már nem érhető el, a program eldobja a parancsot NotSupportedException .

Ha az összes eseményt a legújabb visszaigazolt verzióig szeretné lekérni, akkor az

await RetrieveConfirmedEvents(0, Version);

Csak megerősített események kérhetők le: a rendszer kivételt jelez, ha toVersion nagyobb, mint a tulajdonság Versionaktuális értéke.

Mivel a megerősített események soha nem változnak, nincs olyan verseny, amely miatt aggódnia kell, még több példány vagy késleltetett megerősítés jelenlétében sem. Ilyen helyzetekben azonban a tulajdonság Version értéke nagyobb lehet az await önéletrajzok visszahívásakor, mint az adott időpontban RetrieveConfirmedEvents , ezért célszerű lehet az értékét egy változóban menteni. Lásd még az egyidejűségi garanciákról szóló szakaszt.