4

私は akka を初めて使用します。たとえば、メッセージのリストに対して akka Actors のリストを一度に実行したいと思います (ここでは scala を使用しています)。

入力

message_1
message_2
message_3

各メッセージの出力:

1
2
3

List一度に 3 つの akka アクターを実行して、リストから各パラメーターをそれぞれに渡します。後でそれらの結果を回答として使用したいと思います。理想的には、次のような操作を探しています:

runActorsForListAndWaitForAnswer(messagesList).map(_.toInt()).sum

そのような方法があるかどうかはわかりませんが、役に立ちます。どんな助けでも大歓迎です、ありがとう!

4

1 に答える 1

13

まず第一に、命令的でブロックする考え方を放棄しなければなりません。Akka は、すべてが非同期のときに最高の味を出します。他のアクターの返信を待ってブロックしないでください。代わりに、Future[T]オブジェクトを取得してそれに関数を適用できます。この関数は、 future が完了したときに呼び出されます。

例を作ってみましょう: をSquareActor取り、そのInt2 乗を返す a があります。返信を求める正しい方法は次のとおりです。

squareActor ? 9 map {result =>
  println(result)  //81
}
//more code

非常に重要: を含むコード ブロックはブロックされprintlnません。さらに多くのコードがすぐに実行され、しばらくしてコールバック メソッドが呼び出されます。

そうは言っても、ユースケースの実装を開始できます。私の理解が正しければ、アクターのリストと整数のリストがあります。すべての整数を正確に 1 つのアクターに送信したいとします。擬似コードは次のとおりです。

val actors: List[ActorRef] = //...
val numbers: List[Int] = //...
val actorsWithArguments: List[(ActorRef, Int)] = actors zip numbers
val futuresOfAny: List[Future[Any]] = actorsWithArguments map { case (actor, number) => actor ? number}
val futures: List[Future[Int]] = futuresOfAny map {_.mapTo[Int]}
val futureOfAllResults: Future[List[Int]] = Future.sequence(futures)
val future: Future[Int] = futureOfAllResults map { _.sum}

コードを理解するのに役立つように、意図的に明示的な型を残しました。一歩一歩進みましょう:

  • actorsWithArgumentsListタプルの です。各アイテムには、アクターとメッセージのペアが保持されます - (actor1, message1), (actor2, message2), ...

  • futuresOfAny呼び出しのFuture結果のリストが含まれています。次の理由で aを返します: a) 結果が (まだ) わかっていない、b) Akka が結果の型を知らない (応答メッセージ)actor ? number?Future[Any]

  • futures各返信がInt. 私たちはmapToそれぞれFuture[Any]Future[Int]

  • futureOfAllResultsList[Future[Int]]aから への本当に素晴らしい変換を採用していFuture[List[Int]]ます。言い換えれば、将来の結果のリストを、すべての項目を含む単一の将来の結果に変えただけです。

  • futureあなたの結果を保持します(将来も保持します)。

大量のコードだと思われる場合は、教育目的のためだけに作成されたものです。連鎖と型推論は魔法のようにできます:

val future = Future.sequence(actors zip numbers map { case (actor, number) => actor ? number} map { _.mapTo[Int]}) map { _.sum} }

最後に、あなたはあなたの結果を得ました。まあ、あなたは将来得るでしょう。その結果を別のアクターに送り返したい場合は、次のように言います。

future map {sum => otherActor ! sum}
//or even...
future map otherActor.!

これをすべて明確にするために、公式ドキュメントの先物に関する章を読むことを強くお勧めします。

于 2013-01-13T20:06:43.740 に答える