2016-09-01 30 views
6

Używam AKKA.NET w moim bieżącym projekcie .NET.Ponów/ponów komunikaty o błędach w AKKA

Moje pytanie brzmi następująco: W jaki sposób doświadczeni programiści AKKA wdrażają wzorzec powtórnej transmisji po awarii przy użyciu najnowszych bibliotek AKKA dla Javy lub .NET?

Oto kilka szczegółów.

Chcę zagwarantować, że komunikat nieudany (to znaczy komunikat otrzymany przez aktora prowadzącego do wyjątku) jest odtwarzany/ponawiany kilka razy z przedziałem czasowym między nimi. Zwykle aktor jest restartowany, ponieważ nieudany komunikat jest odrzucany.

Napisałem mój własny mały metoda pomocnika tak go rozwiązać:

public void WithRetries(int noSeconds, IUntypedActorContext context, IActorRef receiver, IActorRef sender, Object message, Action action) 
    { 
      try 
      { 
       action(); 
      } 
      catch (Exception e) 
      { 
       context.System.Scheduler.ScheduleTellOnce(new TimeSpan(0, 0, noSeconds), receiver, message, sender); 
       throw; 
      } 
     } 
    } 

Teraz moi aktorzy zwykle wygląda tak:

Receive<SomeMessage>(msg => 
     { 

      ActorHelper.Instance.WithRetries(-1, Context, Self, Sender, msg,() =>  { 
       ...here comes the actual message processing 
      }); 
     }); 

Lubię powyższe rozwiązanie, ponieważ jest prosta. Jednak nie podoba mi się to, że dodaje on jeszcze jedną warstwę pośrednią w moim kodzie, a kod staje się nieco bardziej brudny, jeśli użyję tej metody pomocnika w wielu miejscach. Ponadto ma pewne ograniczenia. Po pierwsze, liczba ponownych prób nie jest regulowana przez metodę pomocnika. Jest regulowany przez strategię nadzoru nadzorcy, która moim zdaniem jest nieporządna. Co więcej, interwał czasowy jest ustalony, podczas gdy w niektórych przypadkach byłby to przedział czasowy, który wzrasta dla każdego powtórzenia.

Wolałbym coś, co można skonfigurować za pomocą HOCON. Lub coś, co można zastosować jako zagadnienie wzajemne.

Widzę różne propozycje zarówno AKKA dla Scala, AKKA dla Java i AKKA.NET. Widziałem przykłady z routerami, przykłady z Circuit Breaker (np. http://getakka.net/docs/CircuitBreaker#examples) i tak dalej. Też widziałem kilka przykładów wykorzystujących tę samą ideę, co powyżej. Ale mam wrażenie, że powinno być jeszcze prostsze. Być może wiąże się to z pewnym użyciem AKKA Persistence i wydarzeń.

Tak, aby powtórzyć moje pytanie: W jaki sposób doświadczeni programiści AKKA wdrażają wzorzec powtórzenia komunikatu po awarii przy użyciu najnowszych bibliotek AKKA dla Javy lub .NET?

+0

Jak to zrobić Ponów/powtórz w przypadku nieudanej wiadomości w java z akka. Jeśli ktokolwiek wie, proszę o pomoc. –

Odpowiedz

2

Spojrzałem w tym ostatnim roku kiedyś - ja jestem z dala od mojego komputera dev, więc nie mogę sprawdzić, więc to wszystko przychodzi z pamięci:

wydaje mi się, rozwiązanie to było połączenie stashing i strategie nadzoru i haki cyklu życia :)

I myślę, że można zawinąć kod aktorka dziecka w try-catch, a następnie w przypadku błędu, ukryć wiadomość i ponownie rzucić wyjątek, aby był obsługiwany przez przełożony i wszystkie zwykłe strategie nadzoru wchodzą w grę. I think wznowisz, a nie wznowisz. Następnie w odpowiednim komunikacie cyklu życia (onresume ?!) wyrzuć wiadomości, które powinny oznaczać, że wiadomość nie została przetworzona ponownie.

Teraz to nie jest wszystko, co różni się od tego, co już pisał wyżej, więc mam nadzieję, że ktoś ma lepsze rozwiązanie :)

+0

Po pierwsze, wiem, że inni ludzie doszli do podobnego wniosku co ja. –

+0

@NikolaSchou Mam do czynienia z tym samym problemem. Czy możesz wskazać mi przykładowy kod, na który mogę zaglądać. Jestem nowy w Akka/Scala. Więc potrzebuję małej pomocy. Dzięki. –

+0

Dobrze @SomBhattacharyya można zasadniczo wziąć kod, który napisałem powyżej, ponieważ faktycznie działa tak, jak powinien. Pytam tylko, czy inni ludzie przychodzą do różnych rozwiązań niż ja. –

0

To może być późno. Ale innym rozwiązaniem jest przekazanie komendy (lub podstawowych parametrów) do konstruktora aktora i wysłanie polecenia do islef po utworzeniu i użycie dyrektywy Restart.

// Scala code 
class ResilientActor(cmd:Comman) extends Actor { 
    def receive = { 
    ... 
    } 
    self ! cmd 
} 

... 

override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 3){ 
    case _: SomeRetryableException => Restart 
    case t => super.supervisorStrategy.decider.applyOrElse(t, (_:Any) => Escalate) 
}