Reliable Services-meldingen

Met meldingen kunnen clients de wijzigingen bijhouden die worden aangebracht in een object waarin ze geïnteresseerd zijn. Twee typen objecten ondersteunen meldingen: Reliable State Manager en Reliable Dictionary.

Veelvoorkomende redenen voor het gebruik van meldingen zijn:

  • Gerealiseerde weergaven bouwen, zoals secundaire indexen of geaggregeerde gefilterde weergaven van de status van de replica. Een voorbeeld is een gesorteerde index van alle sleutels in betrouwbare woordenlijst.
  • Het verzenden van bewakingsgegevens, zoals het aantal gebruikers dat het afgelopen uur is toegevoegd.

Meldingen worden geactiveerd als onderdeel van het toepassen van bewerkingen. Op een primaire replica worden bewerkingen toegepast na quorumbevestiging als onderdeel van transaction.CommitAsync() of this.StateManager.GetOrAddAsync(). Op secundaire replica's worden bewerkingen toegepast bij de verwerking van replicatiewachtrijgegevens. Daarom moeten meldingen zo snel mogelijk worden verwerkt en moeten synchrone gebeurtenissen geen dure bewerkingen bevatten. Anders kan dit een negatieve invloed hebben op de verwerkingstijd van transacties en op replica's.

Reliable State Manager-meldingen

Reliable State Manager biedt meldingen voor de volgende gebeurtenissen:

  • Transactie
    • Doorvoeren
  • Statusmanager
    • Opnieuw bouwen
    • Toevoeging van een betrouwbare status
    • Verwijderen van een betrouwbare status

Reliable State Manager houdt de huidige transacties aan boord bij. De enige wijziging in de transactiestatus die ervoor zorgt dat een melding wordt geactiveerd, is een transactie die wordt doorgevoerd.

Reliable State Manager onderhoudt een verzameling betrouwbare statussen, zoals Reliable Dictionary en Reliable Queue. Reliable State Manager krijgt meldingen wanneer deze verzameling wordt gewijzigd: een betrouwbare status wordt toegevoegd of verwijderd, of de hele verzameling wordt opnieuw opgebouwd. De Reliable State Manager-verzameling wordt in drie gevallen opnieuw opgebouwd:

  • Herstel: wanneer een replica wordt gestart, wordt de vorige status van de schijf hersteld. Aan het einde van het herstel wordt NotifyStateManagerChangedEventArgs gebruikt om een gebeurtenis te starten die de set herstelde betrouwbare statussen bevat.
  • Volledige kopie: voordat een replica kan worden gekoppeld aan de configuratieset, moet deze worden gebouwd. Soms moet hiervoor een volledige kopie van de status van Reliable State Manager van de primaire replica worden toegepast op de niet-actieve secundaire replica. Reliable State Manager op de secundaire replica maakt gebruik van NotifyStateManagerChangedEventArgs om een gebeurtenis te starten die de set betrouwbare statussen bevat die zijn verkregen van de primaire replica.
  • Herstellen: In scenario's voor herstel na noodgevallen kan de status van de replica worden hersteld vanuit een back-up via RestoreAsync. In dergelijke gevallen gebruikt Reliable State Manager op de primaire replica NotifyStateManagerChangedEventArgs om een gebeurtenis te starten die de set betrouwbare statussen bevat die vanuit de back-up zijn hersteld.

Als u zich wilt registreren voor transactiemeldingen en/of statusmanagermeldingen, moet u zich registreren bij de gebeurtenissen TransactionChanged of StateManagerChanged op Reliable State Manager. Een veelvoorkomende plaats om u te registreren bij deze gebeurtenis-handlers is de constructor van uw stateful service. Wanneer u zich registreert voor de constructor, mist u geen melding die wordt veroorzaakt door een wijziging tijdens de levensduur van IReliableStateManager.

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

De gebeurtenis-handler TransactionChanged gebruikt NotifyTransactionChangedEventArgs om details over de gebeurtenis op te geven. Het bevat de actie-eigenschap (bijvoorbeeld NotifyTransactionChangedAction.Commit) die het type wijziging aangeeft. Het bevat ook de transactie-eigenschap die een verwijzing biedt naar de transactie die is gewijzigd.

Notitie

Tegenwoordig worden TransactionChanged-gebeurtenissen alleen gegenereerd als de transactie is doorgevoerd. De actie is vervolgens gelijk aan NotifyTransactionChangedAction.Commit. Maar in de toekomst kunnen gebeurtenissen worden gegenereerd voor andere typen wijzigingen in de transactiestatus. We raden u aan de actie te controleren en de gebeurtenis alleen te verwerken als deze een gebeurtenis is die u verwacht.

Hieronder volgt een voorbeeld van een TransactionChanged-gebeurtenis-handler .

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);
    }
}

De gebeurtenis-handler StateManagerChanged gebruikt NotifyStateManagerChangedEventArgs om details over de gebeurtenis op te geven. NotifyStateManagerChangedEventArgs heeft twee subklassen: NotifyStateManagerRebuildEventArgs en NotifyStateManagerSingleEntityChangedEventArgs. U gebruikt de eigenschap action in NotifyStateManagerChangedEventArgs om NotifyStateManagerChangedEventArgs te casten naar de juiste subklasse:

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

Hieronder volgt een voorbeeld van een meldingshandler StateManagerChanged .

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

        return;
    }

    this.ProcessStateManagerSingleEntityNotification(e);
}

Meldingen van betrouwbare woordenlijst

Reliable Dictionary biedt meldingen voor de volgende gebeurtenissen:

  • Herbouwen: wordt aangeroepen wanneer ReliableDictionary de status heeft hersteld van een herstelde of gekopieerde lokale status of back-up.
  • Clear: wordt aangeroepen wanneer de status van ReliableDictionary is gewist via de ClearAsync-methode .
  • Toevoegen: wordt aangeroepen wanneer een item is toegevoegd aan ReliableDictionary.
  • Update: wordt aangeroepen wanneer een item in IReliableDictionary is bijgewerkt.
  • Verwijderen: wordt aangeroepen wanneer een item in IReliableDictionary is verwijderd.

Als u meldingen van Betrouwbare woordenlijst wilt ontvangen, moet u zich registreren bij de gebeurtenis-handler DictionaryChanged op IReliableDictionary. Een veelvoorkomende plaats voor registratie bij deze gebeurtenis-handlers is in de melding ReliableStateManager.StateManagerChanged voor toevoegen. Registreren wanneer IReliableDictionary wordt toegevoegd aan IReliableStateManager zorgt ervoor dat u geen meldingen mist.

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;
        }
    }
}

Notitie

ProcessStateManagerSingleEntityNotification is de voorbeeldmethode die in het voorgaande OnStateManagerChangedHandler-voorbeeld wordt aangeroepen.

Met de voorgaande code wordt de interface IReliableNotificationAsyncCallback ingesteld, samen met DictionaryChanged. Omdat NotifyDictionaryRebuildEventArgs een IAsyncEnumerable-interface bevat, die asynchroon moet worden opgesomd, worden herbouwmeldingen geactiveerd via RebuildNotificationAsyncCallback in plaats van 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);
    }
}

Notitie

In de voorgaande code wordt, als onderdeel van de verwerking van de herbouwmelding, eerst de samengevoegde status van het onderhoud gewist. Omdat de betrouwbare verzameling opnieuw wordt opgebouwd met een nieuwe status, zijn alle eerdere meldingen niet relevant.

De gebeurtenis-handler DictionaryChanged gebruikt NotifyDictionaryChangedEventArgs om details over de gebeurtenis op te geven. NotifyDictionaryChangedEventArgs heeft vijf subklassen. Gebruik de eigenschap action in NotifyDictionaryChangedEventArgs om NotifyDictionaryChangedEventArgs te casten naar de juiste subklasse:

  • 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;
    }
}

Aanbevelingen

  • Voltooi meldingen zo snel mogelijk.
  • Voer geen dure bewerkingen (bijvoorbeeld I/O-bewerkingen) uit als onderdeel van synchrone gebeurtenissen.
  • Controleer het actietype voordat u de gebeurtenis verwerkt. Er kunnen in de toekomst nieuwe actietypen worden toegevoegd.

Houd rekening met het volgende:

  • Meldingen worden geactiveerd als onderdeel van de uitvoering van een bewerking. Er wordt bijvoorbeeld een herstelmelding geactiveerd als laatste stap van een herstelbewerking. Een herstelbewerking wordt pas voltooid als de meldingsgebeurtenis is verwerkt.
  • Omdat meldingen worden geactiveerd als onderdeel van de toepassingsbewerkingen, zien clients alleen meldingen voor lokaal doorgevoerde bewerkingen. En omdat bewerkingen gegarandeerd alleen lokaal worden doorgevoerd (met andere woorden, geregistreerd), kunnen ze in de toekomst wel of niet ongedaan worden gemaakt.
  • Op het pad voor opnieuw uitvoeren wordt één melding geactiveerd voor elke toegepaste bewerking. Dit betekent dat als transactie T1 Create(X), Delete(X) en Create(X) bevat, u één melding krijgt voor het maken van X, één voor de verwijdering en nog een voor het maken, in die volgorde.
  • Voor transacties die meerdere bewerkingen bevatten, worden bewerkingen toegepast in de volgorde waarin ze zijn ontvangen op de primaire replica van de gebruiker.
  • Als onderdeel van het verwerken van onjuiste voortgang kunnen sommige bewerkingen ongedaan worden gemaakt op secundaire replica's. Er worden meldingen gegenereerd voor dergelijke bewerkingen voor ongedaan maken, zodat de status van de replica wordt teruggezet naar een stabiel punt. Een belangrijk verschil van ongedaan maken van meldingen is dat gebeurtenissen met dubbele sleutels worden samengevoegd. Als transactie T1 bijvoorbeeld ongedaan wordt gemaakt, ziet u één melding voor Delete(X).

Volgende stappen