2016-04-12 14 views
0

現在、私はAkka HTTPに"actor-per-request" pattern proposed by NET-A-PORTER devsを実装しようとしています。私が直面している問題は、このパターンはドキュメントのどこにも書かれていないということです。Akka HTTP「actor per request」パターン

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

リクエストごとに1人のスプライトを使用せずに1人のAkkaアクターを使用するにはどうすればよいですか?

+0

私はこのパターンに従わないでしょう。代わりに、akkaの例に従ってください。 –

+0

https://github.com/akka/akka/issues/18569によると、これは「かなり一般的なパターン」とみなされ、akka-http – giannoug

+0

については記載されていません。ここでは、「actor per request pattern "https://github.com/pjfanning/swagger-akka-http-sample.git –

答えて

0

HttpExtクラスは、この目的のために使用できる方法bindAndHAndleAsyncを持っています。このメソッドは次のシグネチャを持つ関数になります:だから

handler: (HttpRequest) ⇒ Future[HttpResponse] 

、我々はHttpRequestについて尋ねられたときHttpResponseを生産する俳優があるとします。

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

非効率的な回答を

あなたの質問は、要求ごとに1人のActorを使用する方法を明示的に求め、Actorクラスを使用してハンドラ関数を作成することができます:

一般的に、

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

効率的な回答

リクエストごとに新しいアクターを再作成するために、通常は必要ありません:

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] 
} 

現在で当社のサーバーをバインドするために、この機能を使用することができます1つのアクターを作成し、それをすべての要求に使用したいとします。
そこで我々はhandlerの外に俳優の作成を移動することができます。

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

を結合サーバーは現在、わずかに変更されます。

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

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