2016-04-12 9 views
0

Derzeit versuche ich die "actor-per-request" pattern proposed by NET-A-PORTER devs in Akka HTTP zu implementieren. Das Problem, mit dem ich konfrontiert bin, ist, dass dieses Muster nirgends in den Dokumenten dokumentiert ist. Es scheint nicht ein Weg, um die folgenden Funktionen ausführen:Akka HTTP "Schauspieler pro Anfrage" Muster

IO(Http) ! Http.Bind(serviceActor, "localhost", port = 38080) 

Wie kann ich einen Akka Schauspieler pro Anfrage ohne Spray zu verwenden?

+0

ich dieses Muster nicht folgen würde. Folgen Sie stattdessen den Akka-Beispielen. –

+0

Nach https://github.com/akka/akka/issues/18569 wird dies als ein "ziemlich häufiges Muster" betrachtet, es ist nur nicht dokumentiert für akka-http – giannoug

+0

Hier finden Sie Beispiel-App mit "Schauspieler pro Anfrage Muster "https://github.com/pjfanning/swagger-akka-http-sample.git –

Antwort

0

Die Klasse HttpExt hat eine Methode bindAndHAndleAsync, die für diesen Zweck verwendet werden kann. Diese Methode nimmt in einer Funktion mit der folgenden Signatur:

handler: (HttpRequest) ⇒ Future[HttpResponse] 
So

an, dass wir einen Schauspieler, die eine HttpResponse produzieren wird, wenn man über eine HttpRequest gestellt:

class HttpResponseHandlerActor extends Actor { 
    override def receive = { 
    case _ : HttpRequest => 
     sender() ! HttpResponse(200, entity = "Response From Actor") 
    } 
} 

Ineffiziente Antwort

Ihre Frage fragt explizit, wie 1 Actor pro Anfrage verwendet werden soll. Dazu können wir jetzt unsere Actor-Klasse verwenden, um eine Handler-Funktion zu erstellen:

implicit val actorSystem = ActorSystem() 

implicit val timeout = Timeout(5 seconds) 

val handler : (HttpRequest) => Future[HttpResponse] = (httpRequest) = { 
    val actorHandlerRef = 
    system.actorOf(Props[HttpResponseHandlerActor], "responseActor") 

    (actorHandlerRef ask httpRequest).mapTo[HttpResponse] 
} 

Wir können nun diese Funktion nutzen, um unsere Server zu binden mit:

val serverBinding : Future[ServerBinding] = 
    Http().bindAndHandleAsync(handler, "localhost", 8080) 

Effiziente Antwort

Es ist normalerweise nicht notwendig, einen neuen Darsteller für jede Anforderung neu zu erstellen, in der Regel Sie möchten 1 Akteur erstellen und für jede Anfrage verwenden.
Deshalb können wir die Schauspieler Schöpfung außerhalb von handler bewegen:

val handler : (ActorRef) => (HttpRequest) => Future[HttpResponse] = 
    (actorRef) => (httpRequest) => 
    (actorRef ask httpRequest).mapTo[HttpResponse] 

Der Server ist nun leicht modifizierte Bindung:

val singleResponseActorRef = 
    system.actorOf(Props[HttpResponseHandlerActor], "responseActor") 

val serverBinding : Future[ServerBinding] = 
    Http().bindAndHandleAsync(handler(singleResponseActorRef), 
          "localhost", 
          8080) 
Verwandte Themen