Notifiche di Reliable ServicesReliable Services notifications

Le notifiche consentono ai client di tenere traccia delle modifiche apportate a un oggetto a cui sono interessati.Notifications allow clients to track the changes that are being made to an object that they're interested in. Le notifiche sono supportate da due tipi di oggetto: Reliable State Manager e Reliable Dictionary.Two types of objects support notifications: Reliable State Manager and Reliable Dictionary.

I motivi comuni per l'uso di notifiche sono i seguenti:Common reasons for using notifications are:

  • Compilazione di viste materializzate, come indici secondari o visualizzazioni filtrate aggregate dello stato della replica.Building materialized views, such as secondary indexes or aggregated filtered views of the replica's state. Un esempio è costituito da un indice ordinato di tutte le chiavi in un oggetto Reliable Dictionary.An example is a sorted index of all keys in Reliable Dictionary.
  • Invio di dati di monitoraggio, ad esempio il numero di utenti aggiunti nell'ultima ora.Sending monitoring data, such as the number of users added in the last hour.

Le notifiche vengono attivate come parte dell'applicazione dell'operazione.Notifications are fired as part of applying operations. Per questo motivo, le notifiche devono essere gestite nel più breve tempo possibile e gli eventi sincroni non devono includere operazioni dispendiose.Because of that, notifications should be handled as fast as possible, and synchronous events shouldn't include any expensive operations.

Notifiche di Reliable State ManagerReliable State Manager notifications

Reliable State Manager prevede notifiche per gli eventi seguenti:Reliable State Manager provides notifications for the following events:

  • TransazioneTransaction
    • CommitCommit
  • State ManagerState manager
    • RicompilazioneRebuild
    • Aggiunta di uno stato affidabileAddition of a reliable state
    • Rimozione di uno stato affidabileRemoval of a reliable state

Reliable State Manager tiene traccia delle transazioni correnti in fase di elaborazione.Reliable State Manager tracks the current inflight transactions. L'unica modifica dello stato della transazione che causa l'attivazione di una notifica è il commit.The only change in transaction state that causes a notification to be fired is a transaction being committed.

Reliable State Manager gestisce una raccolta di stati affidabili come Reliable Dictionary e Reliable Queue.Reliable State Manager maintains a collection of reliable states like Reliable Dictionary and Reliable Queue. Reliable State Manager attiva le notifiche quando viene modificata la raccolta con l'aggiunta o rimozione di uno stato affidabile o la ricompilazione dell'intera raccolta.Reliable State Manager fires notifications when this collection changes: a reliable state is added or removed, or the entire collection is rebuilt. La raccolta di Reliable State Manager viene ricompilata in tre casi.The Reliable State Manager collection is rebuilt in three cases:

  • Recupero: quando viene avviata, una replica recupera il proprio stato precedente dal disco.Recovery: When a replica starts, it recovers its previous state from the disk. Al termine del recupero, usa NotifyStateManagerChangedEventArgs per attivare un evento contenente il set di stati affidabili recuperati.At the end of recovery, it uses NotifyStateManagerChangedEventArgs to fire an event that contains the set of recovered reliable states.
  • Copia completa: prima che una replica possa essere aggiunta al set di configurazione, deve essere compilata.Full copy: Before a replica can join the configuration set, it has to be built. In alcuni casi, potrebbe essere necessario applicare una copia completa dello stato di Reliable State Manager dalla replica primaria alla replica secondaria inattiva.Sometimes, this requires a full copy of Reliable State Manager's state from the primary replica to be applied to the idle secondary replica. Reliable State Manager sulla replica secondaria usa NotifyStateManagerChangedEventArgs per attivare un evento contenente il set di stati affidabili acquisito dalla replica primaria.Reliable State Manager on the secondary replica uses NotifyStateManagerChangedEventArgs to fire an event that contains the set of reliable states that it acquired from the primary replica.
  • Ripristino: negli scenari di ripristino di emergenza, lo stato della replica può essere ripristinato da un backup tramite RestoreAsync.Restore: In disaster recovery scenarios, the replica's state can be restored from a backup via RestoreAsync. In questi casi, Reliable State Manager sulla replica primaria usa NotifyStateManagerChangedEventArgs per attivare un evento contenente il set di stati affidabili ripristinato dal backup.In such cases, Reliable State Manager on the primary replica uses NotifyStateManagerChangedEventArgs to fire an event that contains the set of reliable states that it restored from the backup.

Per abilitare le notifiche delle transazioni e/o le notifiche di gestione dello stato, è necessario registrarsi negli eventi TransactionChanged o StateManagerChanged in Reliable State Manager.To register for transaction notifications and/or state manager notifications, you need to register with the TransactionChanged or StateManagerChanged events on Reliable State Manager. Una posizione frequente per la registrazione in questi gestori eventi è il costruttore del servizio con stato.A common place to register with these event handlers is the constructor of your stateful service. Con la registrazione sul costruttore, non si perde alcuna notifica causata da una modifica nel corso della durata di IReliableStateManager.When you register on the constructor, you won't miss any notification that's caused by a change during the lifetime of IReliableStateManager.

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

Il gestore eventi TransactionChanged usa NotifyTransactionChangedEventArgs per fornire dettagli sull'evento.The TransactionChanged event handler uses NotifyTransactionChangedEventArgs to provide details about the event. Contiene la proprietà dell'azione (ad esempio, NotifyTransactionChangedAction.Commit) che specifica il tipo di modifica,It contains the action property (for example, NotifyTransactionChangedAction.Commit) that specifies the type of change. nonché la proprietà della transazione che fornisce un riferimento alla transazione modificata.It also contains the transaction property that provides a reference to the transaction that changed.

Nota

Gli eventi TransactionChanged vengono attualmente generati solo in caso di commit della transazione.Today, TransactionChanged events are raised only if the transaction is committed. L'azione è quindi uguale a NotifyTransactionChangedAction.Commit.The action is then equal to NotifyTransactionChangedAction.Commit. È tuttavia possibile che in futuro vengano generati eventi per altri tipi di modifica dello stato della transazione.But in the future, events might be raised for other types of transaction state changes. È consigliabile controllare l'azione ed elaborare l'evento solo se previsto.We recommend checking the action and processing the event only if it's one that you expect.

Di seguito è riportato un esempio del gestore eventi TransactionChanged .Following is an example TransactionChanged event 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);
    }
}

Il gestore eventi StateManagerChanged usa NotifyStateManagerChangedEventArgs per fornire dettagli sull'evento.The StateManagerChanged event handler uses NotifyStateManagerChangedEventArgs to provide details about the event. NotifyStateManagerChangedEventArgs ha due sottoclassi: NotifyStateManagerRebuildEventArgs e NotifyStateManagerSingleEntityChangedEventArgs.NotifyStateManagerChangedEventArgs has two subclasses: NotifyStateManagerRebuildEventArgs and NotifyStateManagerSingleEntityChangedEventArgs. La proprietà dell'azione in NotifyStateManagerChangedEventArgs viene usata per eseguire il cast di NotifyStateManagerChangedEventArgs nella sottoclasse corretta.You use the action property in NotifyStateManagerChangedEventArgs to cast NotifyStateManagerChangedEventArgs to the correct subclass:

  • NotifyStateManagerChangedAction.Rebuild: NotifyStateManagerRebuildEventArgsNotifyStateManagerChangedAction.Rebuild: NotifyStateManagerRebuildEventArgs
  • NotifyStateManagerChangedAction.Add e NotifyStateManagerChangedAction.Remove: NotifyStateManagerSingleEntityChangedEventArgsNotifyStateManagerChangedAction.Add and NotifyStateManagerChangedAction.Remove: NotifyStateManagerSingleEntityChangedEventArgs

Di seguito è riportato un esempio del gestore delle notifiche StateManagerChanged .Following is an example StateManagerChanged notification handler.

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

        return;
    }

    this.ProcessStateManagerSingleEntityNotification(e);
}

Notifiche di Reliable DictionaryReliable Dictionary notifications

Reliable Dictionary prevede notifiche per gli eventi seguenti.Reliable Dictionary provides notifications for the following events:

  • Ricompilazione: chiamata quando l'oggetto ReliableDictionary ha recuperato il proprio stato da un backup o uno stato locale copiato o ripristinato.Rebuild: Called when ReliableDictionary has recovered its state from a recovered or copied local state or backup.
  • Cancellazione: chiamata quando lo stato di ReliableDictionary è stato cancellato tramite il metodo ClearAsync.Clear: Called when the state of ReliableDictionary has been cleared through the ClearAsync method.
  • Aggiunta: chiamata quando è stato aggiunto un elemento a ReliableDictionary.Add: Called when an item has been added to ReliableDictionary.
  • Aggiornamento: chiamata quando è stato aggiornato un elemento in IReliableDictionary .Update: Called when an item in IReliableDictionary has been updated.
  • Rimozione: chiamata quando è stato eliminato un elemento in IReliableDictionary .Remove: Called when an item in IReliableDictionary has been deleted.

Per ricevere le notifiche di Reliable Dictionary, è necessario registrarsi nel gestore eventi DictionaryChanged in IReliableDictionary.To get Reliable Dictionary notifications, you need to register with the DictionaryChanged event handler on IReliableDictionary. Una posizione frequente per la registrazione in questi gestori eventi è la notifica di aggiunta ReliableStateManager.StateManagerChanged .A common place to register with these event handlers is in the ReliableStateManager.StateManagerChanged add notification. La registrazione al momento dell'aggiunta di IReliableDictionary a IReliableStateManager garantisce che non verrà persa alcuna notifica.Registering when IReliableDictionary is added to IReliableStateManager ensures that you won't miss any notifications.

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

Nota

ProcessStateManagerSingleEntityNotification è il metodo di esempio chiamato dall'esempio OnStateManagerChangedHandler precedente.ProcessStateManagerSingleEntityNotification is the sample method that the preceding OnStateManagerChangedHandler example calls.

Il codice precedente imposta l'interfaccia IReliableNotificationAsyncCallback e DictionaryChanged.The preceding code sets the IReliableNotificationAsyncCallback interface, along with DictionaryChanged. Poiché NotifyDictionaryRebuildEventArgs contiene un'interfaccia IAsyncEnumerable, che richiede un'enumerazione asincrona, le notifiche di ricompilazione vengono attivate tramite RebuildNotificationAsyncCallback anziché OnDictionaryChangedHandler.Because NotifyDictionaryRebuildEventArgs contains an IAsyncEnumerable interface--which needs to be enumerated asynchronously--rebuild notifications are fired through RebuildNotificationAsyncCallback instead of 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);
    }
}

Nota

Nel codice precedente, nell'ambito dell'elaborazione della notifica di ricompilazione, viene cancellato prima lo stato aggregato mantenuto.In the preceding code, as part of processing the rebuild notification, first the maintained aggregated state is cleared. Poiché la raccolta Reliable Collections viene ricompilata con un nuovo stato, tutte le notifiche precedenti sono irrilevanti.Because the reliable collection is being rebuilt with a new state, all previous notifications are irrelevant.

Il gestore eventi DictionaryChanged usa NotifyDictionaryChangedEventArgs per fornire dettagli sull'evento.The DictionaryChanged event handler uses NotifyDictionaryChangedEventArgs to provide details about the event. NotifyDictionaryChangedEventArgs ha cinque sottoclassi.NotifyDictionaryChangedEventArgs has five subclasses. Usare la proprietà dell'azione in NotifyDictionaryChangedEventArgs per eseguire il cast di NotifyDictionaryChangedEventArgs nella sottoclasse corretta.Use the action property in NotifyDictionaryChangedEventArgs to cast NotifyDictionaryChangedEventArgs to the correct subclass:

  • NotifyDictionaryChangedAction.Rebuild: NotifyDictionaryRebuildEventArgsNotifyDictionaryChangedAction.Rebuild: NotifyDictionaryRebuildEventArgs
  • NotifyDictionaryChangedAction.Clear: NotifyDictionaryClearEventArgsNotifyDictionaryChangedAction.Clear: NotifyDictionaryClearEventArgs
  • NotifyDictionaryChangedAction.Add e NotifyDictionaryChangedAction.Remove: NotifyDictionaryItemAddedEventArgsNotifyDictionaryChangedAction.Add and NotifyDictionaryChangedAction.Remove: NotifyDictionaryItemAddedEventArgs
  • NotifyDictionaryChangedAction.Update: NotifyDictionaryItemUpdatedEventArgsNotifyDictionaryChangedAction.Update: NotifyDictionaryItemUpdatedEventArgs
  • NotifyDictionaryChangedAction.Remove: NotifyDictionaryItemRemovedEventArgsNotifyDictionaryChangedAction.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;
    }
}

ConsigliRecommendations

  • Completare gli eventi di notifica nel più breve tempo possibile.Do complete notification events as fast as possible.
  • Non eseguire operazioni dispendiose (ad esempio, operazioni di I/O) nell'ambito di eventi sincroni.Do not execute any expensive operations (for example, I/O operations) as part of synchronous events.
  • Controllare il tipo di azione prima di elaborare l'evento.Do check the action type before you process the event. In futuro potrebbero essere aggiunti nuovi tipi di azione.New action types might be added in the future.

Occorre tenere presente i concetti seguenti:Here are some things to keep in mind:

  • Le notifiche vengono attivate come parte dell'esecuzione di un'operazione.Notifications are fired as part of the execution of an operation. Una notifica di ripristino, ad esempio, viene attivata come ultimo passaggio di un'operazione di ripristino.For example, a restore notification is fired as the last step of a restore operation. Un ripristino non viene completato finché non viene elaborato l'evento di notifica.A restore will not finish until the notification event is processed.
  • Poiché le notifiche vengono attivate nell'ambito dell'applicazione di operazioni, i client visualizzano solo le notifiche per le operazioni con commit in locale.Because notifications are fired as part of the applying operations, clients see only notifications for locally committed operations. Poiché è garantito solo il commit in locale (in altri termini, la registrazione), inoltre, potrebbe non essere possibile annullare le operazioni in futuro.And because operations are guaranteed only to be locally committed (in other words, logged), they might or might not be undone in the future.
  • Nel percorso di ripristino viene attivata una singola notifica per ogni operazione applicata.On the redo path, a single notification is fired for each applied operation. Di conseguenza, se la transazione T1 include Create(X), Delete(X) e Create(X), si riceverà una notifica per la creazione di X, una per l'eliminazione e una per una nuova creazione, nell'ordine specificato.This means that if transaction T1 includes Create(X), Delete(X), and Create(X), you'll get one notification for the creation of X, one for the deletion, and one for the creation again, in that order.
  • Per le transazioni che contengono più operazioni, queste verranno applicate nell'ordine in cui sono state ricevute nella replica primaria dall'utente.For transactions that contain multiple operations, operations are applied in the order in which they were received on the primary replica from the user.
  • Come parte dell'elaborazione di un'incoerenza, alcune operazioni potrebbero essere annullate.As part of processing false progress, some operations might be undone. Per queste operazioni di annullamento vengono generate notifiche, con rollback dello stato della replica a un punto stabile.Notifications are raised for such undo operations, rolling the state of the replica back to a stable point. Una differenza importante delle notifiche di annullamento è che gli eventi con chiavi duplicate vengono aggregati.One important difference of undo notifications is that events that have duplicate keys are aggregated. Se la transazione T1 viene annullata, ad esempio, viene visualizzata una singola notifica per Delete(X).For example, if transaction T1 is being undone, you'll see a single notification to Delete(X).

Passaggi successiviNext steps