2017-03-21 1 views
0

Ich möchte einen kleinen HTTP Server mit Scala und Akka implementieren. Insbesondere möchte ich zwei Arten von Akteuren haben: EmployeeRouterActor und EmployeeEchoActor.Wie implementiert man Eltern-Kind-Modell mit Akka in Scala?

Die erste, ich möchte es wie ein Router verwenden, ich meine, dieser Akteur alle Nachrichten erhalten und es muss ein Kind (in diesem Fall EmployeeEchoActor) für jede Nachricht erstellen.

Jedes Kind, es wird eine Mitarbeiter Nachricht erhalten und es muss eine Zeichenfolge mit den Mitarbeiterinformationen zurückgeben.

Darüber hinaus muss das Kind sterben, nachdem das Kind seinen Prozess abgeschlossen hat. Ich denke, dass die Eltern sind, die den Lebenszyklus ihrer Kinder kontrollieren müssen.

In Akka Dokumentation, sehe ich nur über ein einziges Kind mit, wie this

Wie kann ich dies tun? Gibt es ein Beispiel oder eine andere Dokumentation von Akka?

Antwort

3

Etwas wie folgt aus:

object EmployeeRouterActor { 
    final case class Employee(id: String, name: String) 
    final case object StopChild 
    final case class ChildResponse(id: String, data: String) 
} 

final class EmployeeRouterActor extends Actor { 
    import EmployeeRouterActor._ 

    // Make a map which will store child actors 
    private var children = Map.empty[String, ActorRef] 

    override def receive: Receive = { 
    case e @ Employee(id, _) => getChild(id) ! e 
    case ChildResponse(id, _) => stopChild(id) 
    } 

    // Check whether child exists in context of this actor. 
    // If it doesn't, create new one. 
    private def getChild(id: String): ActorRef = 
    context.child(id).getOrElse { 
     val child = context.actorOf(EmployeeEchoActor.apply(), id) 
     children += (id -> child) 
     child 
    } 

    private def stopChild(id: String) = { 
    children(id) ! StopChild 
    children -= id 
    } 
} 

object EmployeeEchoActor { 
    def apply(): Props = Props(new EmployeeEchoActor) 
} 

final class EmployeeEchoActor extends Actor { 
    // self.path.name to access its id 
    override def receive: Receive = { 
    case EmployeeRouterActor.Employee => 
     // do stuff with Employee message... 
     context.parent ! EmployeeRouterActor.ChildResponse(self.path.name, "Done!") // Or pipeTo(context.parent) 
    case EmployeeRouterActor.StopChild => context.stop(self) 
    } 
} 

Grundsätzlich Kinderdarsteller erstellt und in einem Map gespeichert. Wenn sie ihre Aufgaben abgeschlossen haben, antworten sie mit der Antwortnachricht an ihre Eltern, die sie dann stoppt.

+0

Wow, danke für Ihre Antwort. Ich werde Ihre Lösung für mein Projekt überprüfen. –

+0

Ich implementierte diese Lösung und es funktioniert gut, außer ich bekomme immer tote Briefe, wenn EmployeeRouterActor die Antwort zurücksenden, nachdem sie ChildResponse erhalten. Ich arbeite daran. Vielen Dank für deine Hilfe. –

Verwandte Themen