2013-08-20 23 views
8

Próbuję użyć routera broadcast w Scala, jeśli się nie mylę to powinno wyglądać w ten sposób:Jak tworzyć routery w akka z sparametryzowanymi aktorami?

val system = ActorSystem("My beautiful system") 
val workerRouter = system.actorOf(Props[Agent].withRouter(BroadcastRouter(individualDefinitions.size)), name = "agentRouter") 

To co rozumiem z the tutorial I am following.

WorkerRouter działa jak inny aktor i mogę wysyłać wiadomości do tego routera, który wyśle ​​je do wszystkich agentów (tyle ile mam w definicji IndividualDefinitions).

Problem polega na tym, że chciałbym użyć indywidualnych definicji do zbudowania agentów, faktycznie pobierają niektóre parametry w konstruktorze, a te parametry są w poszczególnych definicjach.

Pytanie: W jaki sposób mogę przekazać routerowi, aby przekazał te parametry do każdego z nich jako część konstruktora?

Uwaga: każdy aktor powinien otrzymać jeden indywidualny Definicja i wszystkie są różne. Nie mogę użyć rozwiązania w pokrewnym pytaniu, w którym konstruktor otrzymuje stałe: In Akka Java actor model, can a router create actors with non-default constructor?

Należy zauważyć, że tutaj każdy aktor powinien mieć różne parametry, jeśli jeden z nich zostanie ponownie uruchomiony, powinien uzyskać takie same parametry, jakie otrzymał. Nie wiem, czy to rozwiązanie można zmodyfikować, aby to zrobić.

Możliwe rozwiązanie może polegać na użyciu aktora jako routera w celu oddzielenia kreacji (konstruktora) i routingu, tak jak w pytaniu Akka (java), non blocking broadcast to all children.

Nie jestem pewien, czy jest to "właściwe" podejście w tym przypadku. Używanie aktora jako routera ma kilka problemów (oprócz elegancji). Jestem zaniepokojony aktorem, który działa jako restart routera i traci wszystkich swoich subskrybentów. Jeśli aktor zostanie ponownie uruchomiony w połowie pętli, niektórzy aktorzy mogą również przegapić niektóre wiadomości, jeśli się nie mylę.

Dziękuję.

Odpowiedz

7

Możesz tworzyć routery, określając jako trasy niektóre już utworzone podmioty, zbudowane według dowolnej logiki.

Poniższy przykład spowoduje utworzenie 2 aktorów stworzonych w inny sposób, a następnie utworzenie routera round-robin, który będzie kierował wiadomości do nich.

class MyActor(param1: String) extends Actor with ActorLogging { 
    def receive: Actor.Receive = { 
    case msg => log.info("Message from {}: {}", param1, msg) 
    } 
} 

object MyActor { 
    def apply(param: String): Props = Props(new MyActor(param)) 
} 

object Main extends App { 
    val system = ActorSystem() 

    val a1 = system.actorOf(MyActor("actor1")) 
    val a2 = system.actorOf(MyActor("actor2")) 

    val routerProps = Props.empty.withRouter(RoundRobinRouter(routees = Vector(a1, a2))) 

    val router = system.actorOf(routerProps) 

    for (i <- 1 to 10) { 
    router ! i 
    } 

    readLine() 
    system.shutdown() 
} 

Więcej szczegółów tutaj: http://doc.akka.io/docs/akka/2.2.0/scala/routing.html

+0

Świetnie, rozwiązuje to i dowiedziałem się trochę więcej o Akce. Samouczki powinny zawierać linki do dokumentacji;) (przepraszam za to) – Trylks

1
public class Master extends UntypedActor { 
    ----- 
    ----- 
    public Master() { 
     workerRouter = this.getContext().actorOf(Worker.createWorker().withRouter(new RoundRobinRouter(8)), "workerRouter"); 
    } 

Z Akce 2.4.2, możemy po prostu użyć:

workerRouter = this.getContext().actorOf(new RoundRobinPool(noOfWorkers).props(Props.create(Worker.class)), "workerRouter"); 

Jest to najlepszy kod Wysiłek wykonywany w min. czas w Akka.