2013-05-20 20 views
11

Czy znasz fajny sposób w Akka/Scala, aby dodać/usunąć routerów do routera Broadcaster?Dynamicznie dodawaj/usuwaj skierowane do routera aktor

Spoglądam na Resizer - ale nie spełnia on moich potrzeb (nie widzę jak jawnie poprosić resizer o zmianę rozmiaru (dodać trasy) i usunięcie go wydaje się, że musisz wysłać Truciznę do aktora który jest następnie usuwany).

Dotychczas Mam router z listą ActorRef i wysyłać wiadomości AddRoutee i RemoveRoutee ....

Moja sprawa biznesu: Mam aktora pobieranie danych z sieci (poprzez pełnomocnika) i musi wysłać te dane niezależnym podmiotom do równoległego przetwarzania. Ze względu na graficzną charakterystykę odbiorców (DAG) wykres może ewoluować w czasie wykonywania, modyfikując wierzchołki/krawędzie, dlatego też konieczne jest dodawanie i usuwanie tras. W tym celu musi istnieć czystszy sposób.

Dzięki za wskazówki.

Przykład kodu Chciałbym Akka obsługiwać:

class MDActor extends Actor { 
    @volatile var routees = Set[ActorRef]() 

    def receive = { 
    case ar: AddRoutee => routees = routees + ar.actorRef 
    case rr: RemoveRoutee => routees = routees - rr.actorRef 
    case msg => routees.foreach(r => r forward msg) 
    } 
} 
+0

Czy możesz podać trochę więcej kontekstu w sytuacji, w której wystąpi kod, które powodują dodawanie/usuwanie tras z routera? Tego rodzaju informacje pomogą w znalezieniu rozwiązań. – cmbaxter

+1

W twoim przykładzie polecam użycie Set [ActorRef] zamiast listy [ActorRef], aby zapobiec powielaniu pracy. I użyj "naprzód" zamiast "!" aby zachować oryginalnego nadawcę. –

+0

Dzięki. To świetny pomysł. – jts

Odpowiedz

2

Ilekroć brakuje Ci funkcji w routerze, bardzo dobrze jest zacząć myśleć w innym kierunku: co jest nie tak z kodem aktora, który prezentujesz? O ile nie trzeba przesyłać więcej niż kilka milionów wiadomości na sekundę (co jest mało prawdopodobne, biorąc pod uwagę twój opis), taki aktor jest właśnie właściwym rozwiązaniem. Routery są bardzo wyspecjalizowanym konstruktem, który nie powinien być używany jako substytut; używaj ich tylko wtedy, gdy dokładnie spełniają twoje wymagania i porównałeś, że normalny aktor nie jest wystarczający.

+0

Roland, mój przypadek użycia jest bardzo specyficzny .. nawet dla "java". Tak więc powyższy schemat działa dobrze dla tego, co chcę, aby mój kod działał. Rzeczywiście, mogłem zrobić to w języku Java ... co byłoby w tym zabawne? – jts

+0

Nie rozumiem tego komentarza, ponieważ w mojej odpowiedzi nie mówiłem o Javie. Moja odpowiedź sprowadza się do "zorientowałeś się, przestań wyglądać" ;-) –

+0

Nie. Zawsze sprawdzam, czy jest lepszy sposób na robienie rzeczy :-) – jts

1

Nie wiesz, tam jest naprawdę lepszy sposób niż do utrzymania stanu o routees i zbudować nowy router o każdej zmianie lub nie używać router i użyj zwykłego aktora. Ostatnio też na to patrzyłem.

Nieporuszona niezmienność - Preferowanym rozwiązaniem będzie zatem wyrzucenie starego routera i/lub zbieranie i utworzenie nowego (routera lub zestawu/mapy aktorów).

Możesz po prostu śledzić swoich aktorów i nie korzystać z routera - jest to dobre rozwiązanie i zalecane w dokumentacji akka jako prostsza alternatywa dla routera. Routery powinny mieć przewagę wydajności nad pełnowartościowym aktorem.

Możesz budować routery z listami aktorów, jak pokazano tutaj. Po prostu rób to za każdym razem, gdy nastąpi zmiana. (Źródło: Akka dokumentacja - http://doc.akka.io/docs/akka/snapshot/scala/routing.html)

val actor1 = system.actorOf(Props[ExampleActor1]) 
val actor2 = system.actorOf(Props[ExampleActor1]) 
val actor3 = system.actorOf(Props[ExampleActor1]) 
val routees = Vector[ActorRef](actor1, actor2, actor3) 
val router2 = system.actorOf(Props().withRouter(
    RoundRobinRouter(routees = routees))) 

Tutaj pokazuje router roundrobin ale to nie jest inaczej niż przy użyciu transmisję jednego.

To trochę bardziej funkcjonalne, aby odtworzyć to.

+0

Czy to faktycznie działa? Podczas tworzenia ruterów pojawiają się błędy. – mbseid

+0

Cóż, upewnij się, że pasuje do wersji akka, której używasz:) Zwróć też uwagę na jedyną odpowiedź Rolanda Kuhna :) Odtworzono tablice odwołań aktora, do których losowo wysłaliśmy podczas budowania biblioteki orkiestracji/komunikacji. Możliwe są również routery regeneracyjne. – JasonG

+0

Gotcha. Bardziej przyglądałem się faktycznej kompilacji powyższego stwierdzenia. Musiałem użyć Props.empty. Prawdopodobnie była to wersja. – mbseid

Powiązane problemy