Zreplikowane ziarna

Czasami może istnieć wiele wystąpień tego samego ziarna aktywnego, na przykład podczas obsługi wielu klastrów i przy użyciu klasy OneInstancePerClusterAttribute. JournaledGrain jest przeznaczony do obsługi replikowanych wystąpień przy minimalnym tarciu. Opiera się on na dostawcach spójności dzienników w celu uruchamiania niezbędnych protokołów w celu zapewnienia, że wszystkie wystąpienia zgadzają się na tę samą sekwencję zdarzeń. W szczególności zajmuje się następującymi aspektami:

  • Spójne wersje: wszystkie wersje stanu ziarna (z wyjątkiem wersji wstępnych) są oparte na tej samej globalnej sekwencji zdarzeń. W szczególności jeśli dwa wystąpienia widzą ten sam numer wersji, zobaczy ten sam stan.

  • Zdarzenia wyścigowe: wiele wystąpień może jednocześnie zgłosić zdarzenie. Dostawca spójności rozwiązuje ten wyścig i zapewnia, że wszyscy zgadzają się na tę samą sekwencję.

  • Powiadomienia/reakcyjność: po wystąpieniu zdarzenia jednego ziarna dostawca spójności nie tylko aktualizuje magazyn, ale także powiadamia wszystkie inne wystąpienia ziarna.

Aby zapoznać się z ogólną dyskusją na temat spójności, zobacz nasz raport TechReport i dokument GSP (Global Sequence Protocol).

Zdarzenia warunkowe

Zdarzenia wyścigowe mogą być problematyczne, jeśli mają konflikt, tj. nie powinny być zatwierdzane z jakiegoś powodu. Na przykład w przypadku wypłaty pieniędzy z konta bankowego dwa wystąpienia mogą niezależnie określić, że istnieją wystarczające fundusze na wypłatę i wydać zdarzenie wypłaty. Ale połączenie obu zdarzeń może przerysować. Aby tego uniknąć, JournaledGrain interfejs API obsługuje metodę RaiseConditionalEvent .

bool success = await RaiseConditionalEvent(
    new WithdrawalEvent() { /* ... */ });

Zdarzenia warunkowe dokładnie sprawdzają, czy wersja lokalna jest zgodna z wersją w magazynie. Jeśli nie, oznacza to, że sekwencja zdarzeń wzrosła w międzyczasie, co oznacza, że to wydarzenie przegrało wyścig z innym wydarzeniem. W takim przypadku zdarzenie warunkowe nie jest dołączane do dziennika i RaiseConditionalEvent zwraca wartość false.

Jest to analogia używania tagów e-tagów z aktualizacjami magazynu warunkowego, a także zapewnia prosty mechanizm umożliwiający uniknięcie zatwierdzania zdarzeń powodujących konflikt.

Możliwe i rozsądne jest użycie zarówno warunkowych, jak i bezwarunkowych zdarzeń dla tego samego ziarna, takiego jak i DepositEventWithdrawalEvent. Depozyty nie muszą być warunkowe: nawet jeśli DepositEvent przegra wyścig, nie trzeba go anulować, ale nadal można dołączyć do globalnej sekwencji zdarzeń.

Oczekiwanie na zadanie zwrócone przez RaiseConditionalEvent jest wystarczające, aby potwierdzić zdarzenie, tj. nie jest konieczne również wywołanie metody ConfirmEvents.

Jawna synchronizacja

Czasami pożądane jest zapewnienie, że ziarno jest w pełni uwikłane w najnowszą wersję. Można to wymusić przez wywołanie:

await RefreshNow();

Robi to dwie rzeczy:

  1. Potwierdza wszystkie niepotwierdzone zdarzenia.
  2. Ładuje najnowszą wersję z magazynu.