Sdílet prostřednictvím


Oznámení Reliable Services

Oznámení umožňují klientům sledovat změny prováděné u objektu, který je zajímá. Oznámení podporují dva typy objektů: Reliable State Manager a Reliable Dictionary.

Mezi běžné důvody použití oznámení patří:

  • Vytváření materializovaných zobrazení, jako jsou sekundární indexy nebo agregovaná filtrovaná zobrazení stavu repliky. Příkladem je seřazený index všech klíčů ve spolehlivém slovníku.
  • Odesílání dat monitorování, například počtu uživatelů přidaných za poslední hodinu

Oznámení se aktivují jako součást použití operací. Na primární replice se operace po potvrzení kvora použijí jako součást nebo transaction.CommitAsync()this.StateManager.GetOrAddAsync(). Na sekundárních replikách se operace použijí při zpracování dat replikační fronty. Z tohoto důvodu by se oznámení měla zpracovávat co nejrychleji a synchronní události by neměly zahrnovat žádné nákladné operace. Jinak by to mohlo negativně ovlivnit dobu zpracování transakcí i sestavení replik.

Oznámení správce stavu Reliable State Manager

Reliable State Manager poskytuje oznámení pro následující události:

  • Transakce
    • Potvrzení
  • State Manager
    • Opětovné sestavení (Rebuild)
    • Přidání spolehlivého stavu
    • Odebrání spolehlivého stavu

Reliable State Manager sleduje aktuální příchozí transakce. Jedinou změnou stavu transakce, která způsobuje, že oznámení je aktivována, je transakce potvrzena.

Reliable State Manager udržuje kolekci spolehlivých stavů, jako je Reliable Dictionary a Reliable Queue. Reliable State Manager aktivuje oznámení při změně této kolekce: je přidán nebo odebrán spolehlivý stav nebo je celá kolekce znovu sestavena. Kolekce Reliable State Manager je znovu sestavena ve třech případech:

  • Obnovení: Při spuštění repliky se z disku obnoví její předchozí stav. Na konci obnovení používá NotifyStateManagerChangedEventArgs k vyvolání události, která obsahuje sadu obnovených spolehlivých stavů.
  • Úplná kopie: Před tím, než se replika může připojit ke konfigurační sadě, je potřeba ji sestavit. Někdy to vyžaduje, aby se na nečinnou sekundární repliku použila úplná kopie stavu Reliable State Manager z primární repliky. Reliable State Manager na sekundární replice používá NotifyStateManagerChangedEventArgs k vyvolání události, která obsahuje sadu spolehlivých stavů získané z primární repliky.
  • Obnovení: Ve scénářích zotavení po havárii je možné stav repliky obnovit ze zálohy prostřednictvím metody RestoreAsync. V takových případech Reliable State Manager na primární replice používá NotifyStateManagerChangedEventArgs k vyvolání události, která obsahuje sadu spolehlivých stavů, které obnovil ze zálohy.

Chcete-li zaregistrovat oznámení transakcí nebo oznámení správce stavu, musíte se zaregistrovat pomocí TransactionChanged nebo StateManagerChanged události v Reliable State Manager. Běžným místem pro registraci s těmito obslužnými rutinami událostí je konstruktor stavové služby. Při registraci konstruktoru, nezmeškáte žádné oznámení, které je způsobeno změnou během životnosti IReliableStateManager.

public MyService(StatefulServiceContext context)
    : base(MyService.EndpointName, context, CreateReliableStateManager(context))
{
    this.StateManager.TransactionChanged += this.OnTransactionChangedHandler;
    this.StateManager.StateManagerChanged += this.OnStateManagerChangedHandler;
}

TransactionChanged obslužná rutina události používá NotifyTransactionChangedEventArgs k poskytnutí podrobností o události. Obsahuje vlastnost akce (například NotifyTransactionChangedAction.Commit), která určuje typ změny. Obsahuje také vlastnost transakce, která poskytuje odkaz na transakci, která se změnila.

Poznámka

Dnes jsou události TransactionChanged vyvolány pouze v případě, že je transakce potvrzena. Akce se pak rovná NotifyTransactionChangedAction.Commit. V budoucnu však mohou být vyvolány události pro jiné typy změn stavu transakce. Doporučujeme zkontrolovat akci a zpracovat událost pouze v případě, že se jedná o očekávanou událost.

Následuje příklad TransactionChanged obslužné rutiny události.

private void OnTransactionChangedHandler(object sender, NotifyTransactionChangedEventArgs e)
{
    if (e.Action == NotifyTransactionChangedAction.Commit)
    {
        this.lastCommitLsn = e.Transaction.CommitSequenceNumber;
        this.lastTransactionId = e.Transaction.TransactionId;

        this.lastCommittedTransactionList.Add(e.Transaction.TransactionId);
    }
}

StateManagerChanged obslužná rutina události používá NotifyStateManagerChangedEventArgs k poskytnutí podrobností o události. NotifyStateManagerChangedEventArgs má dvě podtřídy: NotifyStateManagerRebuildEventArgs a NotifyStateManagerSingleEntityChangedEventArgs. Vlastnost action v NotifyStateManagerChangedEventArgs použijete k přetypování NotifyStateManagerChangedEventArgs do správné podtřídy:

  • NotifyStateManagerChangedAction.Rebuild: NotifyStateManagerRebuildEventArgs
  • NotifyStateManagerChangedAction.Add and NotifyStateManagerChangedAction.Remove: NotifyStateManagerSingleEntityChangedEventArgs

Následuje příklad obslužné rutiny oznámení StateManagerChanged .

public void OnStateManagerChangedHandler(object sender, NotifyStateManagerChangedEventArgs e)
{
    if (e.Action == NotifyStateManagerChangedAction.Rebuild)
    {
        this.ProcessStateManagerRebuildNotification(e);

        return;
    }

    this.ProcessStateManagerSingleEntityNotification(e);
}

Oznámení spolehlivého slovníku

Reliable Dictionary poskytuje oznámení pro následující události:

  • Opětovné sestavení: Volá se, když ReliableDictionary obnovil svůj stav z obnoveného nebo zkopírovaného místního stavu nebo zálohy.
  • Clear: Volá se, když byl stav ReliableDictionary vymazán metodou ClearAsync .
  • Add: Volá se, když byla položka přidána do ReliableDictionary.
  • Aktualizace: Volá se, když byla aktualizována položka v IReliableDictionary .
  • Remove: Volá se při odstranění položky v IReliableDictionary .

Pokud chcete dostávat oznámení Reliable Dictionary, musíte se zaregistrovat u obslužné rutiny události DictionaryChanged na IReliableDictionary. Běžné místo pro registraci s těmito obslužnými rutinami událostí je v ReliableStateManager.StateManagerChanged přidat oznámení. Registrace při přidání slovníku IReliableDictionary do IReliableStateManager zajišťuje, že vám neuniknou žádná oznámení.

private void ProcessStateManagerSingleEntityNotification(NotifyStateManagerChangedEventArgs e)
{
    var operation = e as NotifyStateManagerSingleEntityChangedEventArgs;

    if (operation.Action == NotifyStateManagerChangedAction.Add)
    {
        if (operation.ReliableState is IReliableDictionary<TKey, TValue>)
        {
            var dictionary = (IReliableDictionary<TKey, TValue>)operation.ReliableState;
            dictionary.RebuildNotificationAsyncCallback = this.OnDictionaryRebuildNotificationHandlerAsync;
            dictionary.DictionaryChanged += this.OnDictionaryChangedHandler;
        }
    }
}

Poznámka

ProcessStateManagerSingleEntityNotification je ukázková metoda, kterou výše uvedený příklad OnStateManagerChangedHandler volá.

Předchozí kód nastaví IReliableNotificationAsyncCallback rozhraní spolu s DictionaryChanged. Vzhledem k tomu , NotifyDictionaryRebuildEventArgs obsahuje IAsyncEnumerable rozhraní --- které musí být výčtu asynchronně--opětovné sestavení oznámení jsou aktivovány prostřednictvím RebuildNotificationAsyncCallback místo OnDictionaryChangedHandler.

public async Task OnDictionaryRebuildNotificationHandlerAsync(
    IReliableDictionary<TKey, TValue> origin,
    NotifyDictionaryRebuildEventArgs<TKey, TValue> rebuildNotification)
{
    this.secondaryIndex.Clear();

    var enumerator = e.State.GetAsyncEnumerator();
    while (await enumerator.MoveNextAsync(CancellationToken.None))
    {
        this.secondaryIndex.Add(enumerator.Current.Key, enumerator.Current.Value);
    }
}

Poznámka

V předchozím kódu se v rámci zpracování oznámení o opětovném sestavení nejprve vymaže udržovaný agregovaný stav. Vzhledem k tomu, že spolehlivá kolekce je znovu sestavena s novým stavem, jsou všechna předchozí oznámení irelevantní.

DictionaryChanged obslužná rutina události používá NotifyDictionaryChangedEventArgs k poskytnutí podrobností o události. NotifyDictionaryChangedEventArgs má pět podtříd. Pomocí vlastnosti action v NotifyDictionaryChangedEventArgs přetypujte NotifyDictionaryChangedEventArgs do správné podtřídy:

  • NotifyDictionaryChangedAction.Rebuild: NotifyDictionaryRebuildEventArgs
  • NotifyDictionaryChangedAction.Clear: NotifyDictionaryClearEventArgs
  • NotifyDictionaryChangedAction.Add: NotifyDictionaryItemAddedEventArgs
  • NotifyDictionaryChangedAction.Update: NotifyDictionaryItemUpdatedEventArgs
  • NotifyDictionaryChangedAction.Remove: NotifyDictionaryItemRemovedEventArgs
public void OnDictionaryChangedHandler(object sender, NotifyDictionaryChangedEventArgs<TKey, TValue> e)
{
    switch (e.Action)
    {
        case NotifyDictionaryChangedAction.Clear:
            var clearEvent = e as NotifyDictionaryClearEventArgs<TKey, TValue>;
            this.ProcessClearNotification(clearEvent);
            return;

        case NotifyDictionaryChangedAction.Add:
            var addEvent = e as NotifyDictionaryItemAddedEventArgs<TKey, TValue>;
            this.ProcessAddNotification(addEvent);
            return;

        case NotifyDictionaryChangedAction.Update:
            var updateEvent = e as NotifyDictionaryItemUpdatedEventArgs<TKey, TValue>;
            this.ProcessUpdateNotification(updateEvent);
            return;

        case NotifyDictionaryChangedAction.Remove:
            var deleteEvent = e as NotifyDictionaryItemRemovedEventArgs<TKey, TValue>;
            this.ProcessRemoveNotification(deleteEvent);
            return;

        default:
            break;
    }
}

Doporučení

  • Co nejrychleji dokončete události oznámení.
  • Neprovídejte žádné nákladné operace (například vstupně-výstupní operace) v rámci synchronních událostí.
  • Před zpracování události zkontrolujte typ akce. Nové typy akcí mohou být přidány v budoucnu.

Tady je pár věcí, které byste měli mít na paměti:

  • Oznámení se aktivují jako součást provádění operace. Oznámení o obnovení se například aktivuje jako poslední krok operace obnovení. Obnovení se nedokončí, dokud se nezpracuje událost oznámení.
  • Vzhledem k tomu, že se oznámení aktivují jako součást operací použití, klienti uvidí pouze oznámení pro místně potvrzené operace. A protože je zaručeno, že operace budou potvrzeny pouze místně (jinými slovy protokolovány), mohou nebo nemusí být v budoucnu vráceny zpět.
  • Na cestě k opakování se pro každou použitou operaci aktivuje jedno oznámení. To znamená, že pokud transakce T1 zahrnuje Create(X), Delete(X) a Create(X), dostanete jedno oznámení o vytvoření X, jedno pro odstranění a jedno pro vytvoření znovu v tomto pořadí.
  • U transakcí, které obsahují více operací, se operace použijí v pořadí, ve kterém byly přijaty v primární replice od uživatele.
  • V rámci zpracování falešně pokroku se můžou některé operace na sekundárních replikách vrátit zpět. Pro takové operace vrácení zpět se aktivují oznámení, kdy se stav repliky vrátí do stabilního bodu. Jedním z důležitých rozdílů mezi oznámeními o vrácení zpět je agregace událostí, které mají duplicitní klíče. Pokud například probíhá vrácení transakce T1, zobrazí se jedno oznámení delete(X).

Další kroky