2017-06-07 8 views
2

Future[httpResponse]を受け取った後、私はsenderにメッセージを送信しようとしていますが、senderの参照が失われています。Akka http送信元の参照を失う

def receive = { 
     case Seq(method: HttpMethod, endpoint: String, payload: String) ⇒ { 
      // I have the correct sender reference 
      implicit val materializer: ActorMaterializer = ActorMaterializer(ActorMaterializerSettings(context.system)) // needed by singleRequest method below 
      // I have the correct sender reference 

      val response: Future[HttpResponse] = Http(context.system).singleRequest(HttpRequest(method = method, uri = endpoint, entity = payload)) 
      println("http request sent") 
      // I have the correct sender reference 
      response onSuccess { 
      case HttpResponse(statusCode, _, entity, _) ⇒ { 
       entity.dataBytes.runFold(ByteString.empty)(_ ++ _).foreach { body ⇒ 
       // NO Reference to sender 
       sender ! HttpConsumerResponse(statusCode = statusCode, contentType = entity.contentType, body = body.utf8String) 
       } 
      } 
      case _ => println("http request success 2") 
      } 

      response onFailure { 
      case exception: Throwable ⇒ { 
       println("http request failure") 
       throw exception 
      } // Adopting let-it-crash fashion by re-throwning the exception 
      } 
     } 
     case _ => println("I am httpConsumerActor and I don't know") 
     } 

私はこのようなコードを変更した場合::

def receive = { 
     case Seq(method: HttpMethod, endpoint: String, payload: String) ⇒ { 
      // I have the correct sender reference 
      implicit val materializer: ActorMaterializer = ActorMaterializer(ActorMaterializerSettings(context.system)) // needed by singleRequest method below 
      // I have the correct sender reference 

      val response: Future[HttpResponse] = Http(context.system).singleRequest(HttpRequest(method = method, uri = endpoint, entity = payload)) 
      println("http request sent") 
      // I have the correct sender reference 
      val mySender = sender 
      response onSuccess { 
      case HttpResponse(statusCode, _, entity, _) ⇒ { 
       entity.dataBytes.runFold(ByteString.empty)(_ ++ _).foreach { body ⇒ 
       // NO Reference to sender 
       mySender ! HttpConsumerResponse(statusCode = statusCode, contentType = entity.contentType, body = body.utf8String) 
       } 
      } 
      case _ => println("http request success 2") 
      } 

      response onFailure { 
      case exception: Throwable ⇒ { 
       println("http request failure") 
       throw exception 
      } // Adopting let-it-crash fashion by re-throwning the exception 
      } 
     } 
     case _ => println("I am httpConsumerActor and I don't know") 
     } 

をすべての作品が、私はと同じように俳優の参照を送信する必要がここ

は私の受信方法のコードですこの行と私はこれを行うための最良の方法ではないことを知っています:

val mySender = sender 

答えて

6

あなたの拳のアプローチの理由動作しないのは、あなたが「可変状態を閉じる」ことです。つまり、onCompleteが実行されたときにsender()メソッドが実行され、参照がそれ以上含まれていません。これはAkkaのかなり一般的な間違いです、我々はすべてそこにいました! :)

あなたがすでに知っているように、適切な解決策は、リファレンスを事前に保存することです。 「何かになる」などの他の選択肢がありますが、あなたの使用のために、プレストアは「良い」と「単純」の間のトレードオフの観点から適切なアプローチであると言います。参考のため

は、これらのリソースを参照してください。SO questionBlog post

+1

追加の参照、アッカのドキュメント:http://doc.akka.io/docs/akka/current/scala/additional/faq.html#sender-getsenderなぜなら、私の俳優は、 – johanandren

関連する問題