2015-01-14 20 views
14

Czy ktoś może zaoferować trochę więcej wskazówek dotyczących korzystania z Azure Service Bus OnMessageOptions.AutoRenewTimeout http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.onmessageoptions.autorenewtimeout.aspxWytyczne OnMessageOptions.AutoRenewTimeout

jak nie znalazłem wiele dokumentacji dotyczącej tej opcji, a chcieliby wiedzieć, czy jest to poprawny sposób odnowić blokadę wiadomość

Mój przypadek użycia:

1) Message Processing Queue ma blokady okres 5 minut (maksymalny dozwolony)

2) Procesor komunikatów korzystający z pompy komunikatów OnMessageAsync do odczytu z kolejki (z modułem ReceiveMode.PeekLock) Przetwarzanie długiego przetwarzania może zająć do 10 minut przed ręcznym wywołaniem komendy msg.CompleteAsync

3) Chcę procesor wiadomości automatycznie odnawia blokadę aż do czasu, w którym oczekuje się zakończenia przetwarzania (~ 10 minut). Jeśli po tym okresie nie zostanie ukończony, zamek powinien zostać automatycznie zwolniony.

Dzięki

- Aktualizacja

nigdy nie kończy się uzyskaniem jakiejkolwiek więcej wskazówek dotyczących AutoRenewTimeout. Skończyło się na zastosowaniu niestandardowej klasy MessageLock, która automatycznie odnawia blokadę wiadomości na podstawie licznika czasu.

Zobacz sens - https://gist.github.com/Soopster/dd0fbd754a65fc5edfa9

Odpowiedz

1

Mam bardzo sam problem z moich pracowników. Nawet wiadomość została pomyślnie przetworzona, ze względu na długi czas przetwarzania, magistrala usługowa usuwa blokadę zastosowaną do niej, a komunikat staje się dostępny do ponownego odebrania. Inny dostępny pracownik bierze tę wiadomość i zaczyna przetwarzać ją ponownie. Proszę, popraw mnie, jeśli się mylę, ale w twoim przypadku funkcja OnMessageAsync będzie wywoływana wiele razy z tą samą wiadomością, a skończysz z kilkoma zadaniami jednocześnie przetwarzając ją. Pod koniec procesu zostanie zgłoszony wyjątek MessageLockLost, ponieważ wiadomość nie ma zastosowanego blokady. Rozwiązałem to za pomocą następującego kodu.

_requestQueueClient.OnMessage(
      requestMessage => 
      { 
       RenewMessageLock(requestMessage); 
       var messageLockTimer = new System.Timers.Timer(TimeSpan.FromSeconds(290)); 
       messageLockTimer.Elapsed += (source, e) => 
       { 
        RenewMessageLock(requestMessage); 
       }; 
       messageLockTimer.AutoReset = false; // by deffault is true 
       messageLockTimer.Start(); 

       /* ----- handle requestMessage ----- */ 

       requestMessage.Complete(); 

       messageLockTimer.Stop(); 
      } 

private void RenewMessageLock(BrokeredMessage requestMessage) 
    { 
     try 
     { 
      requestMessage.RenewLock(); 
     } 
     catch (Exception exception) 
     { 

     } 
    } 

Istnieje kilka mocowań od twojego postu i być może rozwiązałeś to, więc możesz podzielić się swoim rozwiązaniem.

12

Aby obsłużyć długie przetwarzanie wiadomości, należy ustawić AutoRenewTimeout == 10 min (w twoim przypadku). Oznacza to, że blokada zostanie przedłużona w ciągu tych 10 minut za każdym razem, gdy wygasa LockDuration.

Jeśli na przykład Twój LockDuration wynosi 3 minuty, a AutoRenewTimeout ma 10 minut, to co 3 minuty blokada zostanie automatycznie odnowiona (po 3 minutach, 6 minutach i 9 minutach), a blokada zostanie automatycznie zwolniona po 12 minutach od otrzymania wiadomości strawiony.

+2

To bardzo pomocne wyjaśnienie. Nie mogłem go znaleźć nigdzie indziej. Dzięki! – ebashmakov

Powiązane problemy