Reliable Services bildirimleri
Bildirimler, istemcilerin ilgilendikleri bir nesnede yapılan değişiklikleri izlemesine olanak tanır. İki tür nesne bildirimleri destekler: Reliable State Manager ve Reliable Dictionary.
Bildirimleri kullanmanın yaygın nedenleri şunlardır:
- İkincil dizinler veya çoğaltmanın durumunun toplu filtrelenmiş görünümleri gibi gerçekleştirilmiş görünümler oluşturma. Reliable Dictionary'deki tüm anahtarların sıralanmış dizini buna örnek olarak verilmiştir.
- Son saatte eklenen kullanıcı sayısı gibi izleme verileri gönderme.
Bildirimler, işlemleri uygulamanın bir parçası olarak tetiklenir. Birincil çoğaltmada, işlemler veya this.StateManager.GetOrAddAsync()
öğesinin bir parçası transaction.CommitAsync()
olarak çekirdek onayının ardından uygulanır. İkincil çoğaltmalarda işlemler çoğaltma kuyruğu veri işleme sırasında uygulanır. Bu nedenle bildirimler mümkün olduğunca hızlı işlenmeli ve zaman uyumlu olaylar pahalı işlemler içermemelidir. Aksi takdirde, işlem işleme süresini ve çoğaltma derlemelerini olumsuz etkileyebilir.
Reliable State Manager bildirimleri
Reliable State Manager aşağıdaki olaylar için bildirimler sağlar:
- İşlem
- İşleme
- Eyalet yöneticisi
- Yeniden derleme
- Güvenilir durum ekleme
- Güvenilir bir durumun kaldırılması
Reliable State Manager geçerli uçak içi işlemleri izler. Bir bildirimin tetiklenmesini sağlayan işlem durumundaki tek değişiklik, işlenen bir işlemdir.
Reliable State Manager, Reliable Dictionary ve Reliable Queue gibi güvenilir durumlardan oluşan bir koleksiyon tutar. Bu koleksiyon değiştiğinde Reliable State Manager bildirimleri tetikler: güvenilir bir durum eklenir veya kaldırılır ya da koleksiyonun tamamı yeniden oluşturulur. Reliable State Manager koleksiyonu üç durumda yeniden oluşturulur:
- Kurtarma: Bir çoğaltma başlatıldığında önceki durumunu diskten kurtarır. Kurtarmanın sonunda, kurtarılan güvenilir durum kümesini içeren bir olayı tetikleyen NotifyStateManagerChangedEventArgs kullanır.
- Tam kopya: Bir çoğaltmanın yapılandırma kümesine katılabilmesi için önce derlenmiş olması gerekir. Bazen bu, reliable state Manager'ın birincil çoğaltmadaki durumunun tam kopyasının boşta kalan ikincil çoğaltmaya uygulanmasını gerektirir. İkincil çoğaltmadaki Reliable State Manager, notifyStateManagerChangedEventArgs kullanarak birincil çoğaltmadan aldığı güvenilir durum kümesini içeren bir olayı tetikler.
- Geri yükleme: Olağanüstü durum kurtarma senaryolarında çoğaltmanın durumu RestoreAsync aracılığıyla bir yedekten geri yüklenebilir. Böyle durumlarda, birincil çoğaltmadaki Reliable State Manager, yedekten geri yüklediği güvenilir durum kümesini içeren bir olayı tetikleyen NotifyStateManagerChangedEventArgs kullanır.
İşlem bildirimlerine ve/veya durum yöneticisi bildirimlerine kaydolmak için Reliable State Manager'da TransactionChanged veya StateManagerChanged olaylarına kaydolmanız gerekir. Bu olay işleyicilerine kaydolmak için ortak bir yer, durum bilgisi olan hizmetinizin oluşturucusdur. Oluşturucuya kaydolduğunuz zaman, IReliableStateManager ömrü boyunca yapılan bir değişikliğin neden olduğu hiçbir bildirimi kaçırmazsınız.
public MyService(StatefulServiceContext context)
: base(MyService.EndpointName, context, CreateReliableStateManager(context))
{
this.StateManager.TransactionChanged += this.OnTransactionChangedHandler;
this.StateManager.StateManagerChanged += this.OnStateManagerChangedHandler;
}
TransactionChanged olay işleyicisi, olayla ilgili ayrıntıları sağlamak için NotifyTransactionChangedEventArgs kullanır. Değişiklik türünü belirten eylem özelliğini (örneğin NotifyTransactionChangedAction.Commit) içerir. Ayrıca, değiştirilen işleme başvuru sağlayan işlem özelliğini içerir.
Not
Bugün, TransactionChanged olayları yalnızca işlem işlendiğinde oluşturulur. Eylem daha sonra NotifyTransactionChangedAction.Commit'e eşittir. Ancak gelecekte, diğer işlem durumu değişiklikleri türleri için olaylar tetiklenebilir. Eylemi denetlemenizi ve olayı yalnızca beklediğiniz bir olaysa işlemenizi öneririz.
Aşağıda örnek bir TransactionChanged olay işleyicisi verilmiştir.
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 olay işleyicisi, olayla ilgili ayrıntıları sağlamak için NotifyStateManagerChangedEventArgs kullanır. NotifyStateManagerChangedEventArgs'ın iki alt sınıfı vardır: NotifyStateManagerRebuildEventArgs ve NotifyStateManagerSingleEntityChangedEventArgs. NotifyStateManagerChangedEventArgs içindeki eylem özelliğini kullanarak NotifyStateManagerChangedEventArgs öğesini doğru alt sınıfa yayınlarsınız:
- NotifyStateManagerChangedAction.Rebuild: NotifyStateManagerRebuildEventArgs
- NotifyStateManagerChangedAction.Add ve NotifyStateManagerChangedAction.Remove: NotifyStateManagerSingleEntityChangedEventArgs
Aşağıda örnek bir StateManagerChanged bildirim işleyicisi verilmiştir.
public void OnStateManagerChangedHandler(object sender, NotifyStateManagerChangedEventArgs e)
{
if (e.Action == NotifyStateManagerChangedAction.Rebuild)
{
this.ProcessStateManagerRebuildNotification(e);
return;
}
this.ProcessStateManagerSingleEntityNotification(e);
}
Güvenilir Sözlük bildirimleri
Reliable Dictionary aşağıdaki olaylar için bildirimler sağlar:
- Yeniden derleme: ReliableDictionary kurtarılan veya kopyalanan yerel bir durumdan veya yedeklemeden okunabilir bir aracı kurtarma durumuna kurtarıldığında çağrılır. Bu kurtarma durumunun oluşturulmasından bu yana yapılan işlemlerin kaydı, yeniden oluşturma işlemi tamamlanmadan önce uygulanır. Bu kaydın uygulanması net, ekleme, güncelleştirme ve/veya kaldırma bildirimleri sağlar.
- Clear: ReliableDictionary'nin durumu ClearAsync yöntemiyle temizlendiğinde çağrılır.
- Ekle: ReliableDictionary'e bir öğe eklendiğinde çağrılır.
- Güncelleştirme: IReliableDictionary'deki bir öğe güncelleştirildiğinde çağrılır.
- Kaldır: IReliableDictionary içindeki bir öğe silindiğinde çağrılır.
Reliable Dictionary bildirimlerini almak için IReliableDictionary'de DictionaryChanged olay işleyicisine kaydolmanız gerekir. Bu olay işleyicilerine kaydolmak için ortak bir yer ReliableStateManager.StateManagerChanged ekleme bildirimidir. IReliableDictionary IReliableStateManager'a eklendiğinde kaydolmak, hiçbir bildirimi kaçırmamanızı sağlar.
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;
}
}
}
Not
ProcessStateManagerSingleEntityNotification , önceki OnStateManagerChangedHandler örneğinin çağırıldığı örnek yöntemdir.
Yukarıdaki kod, DictionaryChanged ile birlikte IReliableNotificationAsyncCallback arabirimini ayarlar. NotifyDictionaryRebuildEventArgs zaman uyumsuz olarak numaralandırılması gereken bir IAsyncEnumerable arabirimi içerdiğinden, yeniden derleme bildirimleri OnDictionaryChangedHandler yerine RebuildNotificationAsyncCallback aracılığıyla tetiklenir.
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);
}
}
Not
Önceki kodda, yeniden derleme bildiriminin işlenmesinin bir parçası olarak, önce korunan toplu durum temizlenir. Güvenilir koleksiyon yeni bir durumla yeniden derlendiğinden, önceki tüm bildirimler ilgisizdir.
DictionaryChanged olay işleyicisi, olayla ilgili ayrıntıları sağlamak için NotifyDictionaryChangedEventArgs kullanır. NotifyDictionaryChangedEventArgs'in beş alt sınıfı vardır. NotifyDictionaryChangedEventArgs içindeki eylem özelliğini kullanarak NotifyDictionaryChangedEventArgs öğesini doğru alt sınıfa dönüştürebilirsiniz:
- 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;
}
}
Öneriler
- Bildirim olaylarını mümkün olan en hızlı şekilde tamamlayın.
- Zaman uyumlu olayların bir parçası olarak pahalı işlemler (örneğin G/Ç işlemleri) yürütmeyin.
- Olayı işlemeden önce eylem türünü denetleyin. Gelecekte yeni eylem türleri eklenebilir.
Aklınızda bulundurması gereken bazı şeyler şunlardır:
- Bildirimler, bir işlemin yürütülmesinin bir parçası olarak tetiklenir. Örneğin, geri yükleme işleminin bir adımı olarak geri yükleme bildirimi tetiklenir. Bildirim olayı işlenene kadar geri yükleme devam edecektir.
- Bildirimler uygulama işlemlerinin bir parçası olarak tetiklendiğinden, istemciler yalnızca yerel olarak işlenen işlemler için bildirimleri görür. İşlemlerin yalnızca yerel olarak işlenmesi (başka bir deyişle günlüğe kaydedilen) garanti edildiğinden, gelecekte geri alınıp alınamayabilir.
- Yineleme yolunda, uygulanan her işlem için tek bir bildirim tetiklenir. Başka bir deyişle, T1 işlemi Create(X), Delete(X) ve Create(X) içeriyorsa, X'in oluşturulması için bir bildirim, silme için bir bildirim ve oluşturma işlemi için bir bildirim alırsınız.
- Birden çok işlem içeren işlemler için, işlemler kullanıcıdan birincil çoğaltmada alınma sırasına göre uygulanır.
- Yanlış ilerlemeyi işlemenin bir parçası olarak, ikincil çoğaltmalarda bazı işlemler geri alınabilir. Bu tür geri alma işlemleri için bildirimler oluşturulur ve çoğaltmanın durumu kararlı bir noktaya geri alınır. Geri alma bildirimlerinin önemli bir farkı, yinelenen anahtarlara sahip olayların toplanmasıdır. Örneğin, T1 işlemi geri alınıyorsa Delete(X) için tek bir bildirim görürsünüz.
Sonraki adımlar
- Güvenilir Koleksiyonlar
- Reliable Services hızlı başlangıcı
- Reliable Services yedekleme ve geri yükleme (olağanüstü durum kurtarma)
- Güvenilir Koleksiyonlar için geliştirici başvurusu
Bilinen Sorunlar
- Belirli durumlarda, yeniden oluşturma sırasında bazı işlem bildirimleri atlanabilir. Bu durumda, doğru değer hala mevcuttur ve hala okunabilir veya yinelenebilir; yalnızca bildirim eksik. Bellek içi durumu kurtarmak için, güvenilir koleksiyonlar düzenli aralıklarla denetim noktası dosyasına sıkıştırılmış bir önceden yazma günlüğü kullanır. Geri yükleme sırasında, önce temel durum yeniden oluşturma bildirimi tetikleyen denetim noktası dosyalarından yüklenir. Ardından günlüğe kaydedilen işlemler uygulanır ve her biri kendi açık, ekleme, güncelleştirme veya kaldırma bildirimini tetikler. Bu sorun, geri yüklemeden sonra hızlı bir şekilde yeni bir denetim noktasının alındığı yarış durumundan kaynaklanabilir. Denetim noktası günlüğün uygulanmasından önce tamamlanırsa, bellek durumu yeni denetim noktasının durumuna ayarlanır. Bu durum doğru duruma neden olsa da, günlükteki henüz uygulanmamış olan işlemlerin bildirim göndermeyeceği anlamına gelir.