2017-02-20 5 views
1

Скажем, у меня есть метод, который перебирает все строки в ReliableDictionary так:Обработка переходных исключений при переборе над Fabric Service ReliableDictionary

var reliableDictionary = await StateManager.GetOrAddAsync<IReliableDictionary<TKey, TValue>>(dictionaryName); 

using (var tx = StateManager.CreateTransaction()) 
{ 
    var enumerable = await reliableDictionary.CreateEnumerableAsync(tx); 
    var enumerator = enumerable.GetAsyncEnumerator(); 
    while (await enumerator.MoveNextAsync(cancellationToken)) 
    { 
     // Read enumerator.Current and do something with the value 
     // (not writing back to the dictionary here) 
    } 
} 

Как я мог обрабатывать повторные попытки переходных исключений здесь (т.е. TimeoutException , FabricNotReadableException и FabricTransientException)?

В документации кода для счетчика неясно, какие исключения могут быть выбраны для каждого метода. Какие методы могут использовать эти временные исключения - CreateTransaction, CreateEnumerableAsync, GetAsyncEnumerator, MoveNextAsync и enumerator.Current?

Если из одного из этих методов выбрано переходное исключение, как мне повторить попытку?

Если исключение переходного процесса выбрано из MoveNextAsync или enumerator.Current, могу ли я его повторить, не прерывая цикл while, или я должен создать совершенно новую транзакцию и начать перечислить с начала снова?

+0

См. Статью [это] (https://www.codeproject.com/Articles/872099/Transient-Exception-Handling); у него много отличной информации. – CodingYoshi

ответ

1

В этой статье https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-work-with-reliable-collections описывается работа с надежными коллекциями по транзакциям. В общем, вы должны сделать следующее:

retry: 

try { 
    // Create a new Transaction object for this partition 
    using (ITransaction tx = base.StateManager.CreateTransaction()) { 
     // AddAsync takes key's write lock; if >4 secs, TimeoutException 
     await m_dic.AddAsync(tx, key, value, cancellationToken); 

     await tx.CommitAsync(); 
    } 
} 
catch (TimeoutException) { 
    await Task.Delay(100, cancellationToken); goto retry; 
} 

использования Образца здесь с Гото заявлением, но любая обработка повторов должна работать.

Вы можете изменить таймаут, если вы знаете, что ваша транзакция займет больше времени (как и в вашем случае), но вы должны подумать о том, какое влияние это может оказать на ваше решение. https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-reliable-services-reliable-collections

Время ожидания по умолчанию составляет 4 секунды для всех API-интерфейсов надежной коллекции. Большинство пользователей не должны переопределять это.

И

Не используйте TimeSpan.MaxValue для тайм-аута. Тайм-ауты следует использовать для обнаружения взаимоблокировок.

Что касается других типов исключений, вы упоминаете (FabricNotReadableException и FabricTransientException), вы могли бы/должны повторить эти, а также. Они обычно забрасываются службой Fabric, когда что-то меняется в конфигурации ваших сервисов (например, изменение первичной информации или если вы почему-то заканчиваете разговор со вторичным. В большинстве случаев его следует повторить. FabricTransientException - это всего лишь базовый класс для ряда исключений, которые могут возникать при связи с надежными службами, и это указывает на исключение, которое могло бы уйти, если повторено.

This answer: FabricNotReadableException, например, есть случаи, когда вам нужно повторно разрешить вашу службу на клиенте, чтобы попасть на другую реплику.

+0

Спасибо за ответ.Я должен был сделать это более ясным в вопросе о том, что я действительно искал указания о том, что делать, когда возникает исключение при перечислении надежного словаря - следует ли начинать перечислять с самого начала или пытаться продолжать идти с текущей точки ? Образец, который вы предоставили, предположил, что я должен просто повторить всю транзакцию (т. Е. Начать перечислить с начала снова)? –

+1

Да, насколько я могу судить, начало - это действительно единственный вариант. Исключение TimeOutException, скорее всего, произойдет при попытке инициировать транзакцию, в то время как другие временные исключения могут быть вызваны тем, что ваша реплика изменила роль или не удалось (или какое-то другое действие, которое изменило его роль). Любой из них может означать, что данные, которые вы просматриваете или пытаетесь прочитать, уже не точны. Повторная попытка всей транзакции, вероятно, единственная вещь, которая имеет смысл в большинстве случаев. – yoape