Condividi tramite


Grani replicati

In alcuni casi, più istanze dello stesso grano possono essere attive, ad esempio quando si esegue un sistema multi-cluster e si usa OneInstancePerClusterAttribute. JournaledGrain è progettato per supportare istanze replicate con un attrito minimo. Si basa sui provider di coerenza dei log per eseguire i protocolli necessari assicurando che tutte le istanze concordino sulla stessa sequenza di eventi. In particolare, gestisce gli aspetti seguenti:

  • Versioni coerenti: tutte le versioni dello stato di granularità (ad eccezione delle versioni provvisorie) si basano sulla stessa sequenza globale di eventi. In particolare, se due istanze vedono lo stesso numero di versione, vedono lo stesso stato.

  • Eventi di gara: più istanze possono attivare simultaneamente un evento. Il provider di coerenza risolve questa gara e garantisce che tutte le istanze siano d'accordo sulla stessa sequenza.

  • Notifiche/Reazione: Dopo che un evento viene generato in un'istanza di grano, il provider di coerenza non solo aggiorna l'archiviazione, ma notifica anche tutte le altre istanze di grano.

Per una descrizione generale del modello di coerenza, vedere il documento TechReport e GSP (Global Sequence Protocol).

Eventi condizionali

Gli eventi di gara possono essere problematici se sono in conflitto, cioè entrambi non dovrebbero impegnarsi per qualche motivo. Ad esempio, quando si ritirano denaro da un conto bancario, due istanze potrebbero determinare in modo indipendente che esistano fondi sufficienti per un prelievo ed emettere un evento di prelievo. Tuttavia, la combinazione di entrambi gli eventi potrebbe sovraccaricare l'account. Per evitare questo problema, l'API JournaledGrain supporta il RaiseConditionalEvent metodo .

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

Gli eventi condizionali controllano due volte se la versione locale corrisponde alla versione in archiviazione. In caso contrario, significa che la sequenza di eventi è cresciuta nel frattempo, indicando che questo evento ha perso una gara contro un altro evento. In tal caso, l'evento condizionale non viene aggiunto al log e RaiseConditionalEvent restituisce false.

Questo è analogo all'uso di e-tag con gli aggiornamenti dell'archiviazione condizionale e offre un meccanismo semplice per evitare il commit di eventi in conflitto.

È possibile e ragionevole usare eventi condizionali e non condizionali per la stessa granularità, ad esempio DepositEvent e WithdrawalEvent. I depositi non devono essere condizionali: anche se una DepositEvent gara perde, non deve essere annullata, ma può comunque essere accodata alla sequenza di eventi globale.

L'attesa dell'attività restituita da RaiseConditionalEvent è sufficiente per confermare l'evento. Non è necessario anche chiamare ConfirmEvents.

Sincronizzazione esplicita

In alcuni casi, potrebbe essere necessario assicurarsi che una granularità sia completamente aggiornata con la versione più recente. È possibile applicare questa operazione chiamando:

await RefreshNow();

Questa chiamata esegue due operazioni:

  1. Conferma tutti gli eventi non confermati.
  2. Carica la versione più recente dall'archiviazione.