2016-12-22 4 views
1

akka-httpでは、HttpEntityボディー(Sourceを除く)を除き、akka-httpのHttpRequestHttpResponseはほとんど不変オブジェクトです。アクター間でAkka HttpEntityを送信する

リクエスト、レスポンス、またはソリッドエンティティを別のアクタ(特にリモートアクタ)に送信することは安全ですか、または予防策が必要ですか?

+0

あなたはセットアップあなたの俳優することができます。私はそれを遠隔システムに渡すことは実際にはうまくいくとは想像できません。 – Falmarri

+0

'Source'(と' HttpEntity')も実際は不変であるため、ローカルのアクターに渡すと動作する可能性があります。しかし、それらはシリアライズ可能ではありません(@Falmarriのコメントによると)ので、リモーティングは動作しません。 –

+0

動作させる方法はありますか? akka-http具体的にまたはリモートソースを一般的に使用していますか?リモートアクターとの間でakkaストリーミングが動作することを想像します。おそらく、そのソースをリモートストリーミング構造によって消費される可能性のあるシンクまで引き上げるでしょうか? – kag0

答えて

0

コメントに記載されているとおり:HttpEntityをリモートActorに送信することは、ソケットの制限のためにうまくいかない可能性があります。さらなる証拠は、the documentation(強調かれら)で見つけることができます:

重要:メッセージは、オブジェクトの任意の種類であってもよいが 不変でなければならないことができます。 Scalaは(まだ)不変性を強制することはできませんので、これは の規則でなければなりません。延ByteStringは不変であるので、

しかし、Sourceから来るByteString値は、ソース自体と同じ制限がありません。単にローカルのakka-http ActorSystemでSourceを排水して、ByteStringの値をリモートのActorに送ることができます。

たとえば、utf-8ベースのHttpEntityのすべての文字を大文字にするには、Actorを使用するとします。

class UpperActor extends Actor { 
    override def receive : Receive = { 
    case b : ByteString => sender() ! b.toString.toUpperCase 
    } 
} 

のように次に、あなたのアッカ-HTTPは見ることができる:ソースはそのデータから来ているソケットのライフサイクルにバインドされている

val actorRef = ??? //setup the ref to remote UpperActor 

/**Query the Actor*/ 
val dispatchByteString : (ByteString) => Future[String] = 
    (byteString : ByteString) => (actorRef ? byteString).mapTo[String] 

val parallelism = 10 // should match your Actor's mailbox size 

/**Construct the Response Source.*/ 
val requestToSrc : (HttpRequest) => Source[ChunkStreamPart,_] = 
    (_ : HttpRequest).entity 
        .dataBytes 
        .mapAsync(parallelism)(dispatchByteString) 
        .map(ChunkStreamPart.apply) 

val contentType = ContentTypes.`text/plain(UTF-8)` 

val route = extractRequest { request => 
    complete(HttpResponse(entity = Chunked(contentType, requestToSrc(request)))) 
} 
関連する問題