6

私の現在のアプリケーションは akka 1.1 に基づいています。ProjectAnalysisActors特定のプロジェクトの分析タスクを処理する責任がそれぞれ複数あります。このようなアクターが一般的な開始メッセージを受信すると、分析が開始されます。1 つのステップが終了すると、次のステップが定義されている限り、それ自体にメッセージを送信します。実行コードは基本的に次のようになります


sealed trait AnalysisEvent {
   def run(project: Project): Future[Any]
   def nextStep: AnalysisEvent = null
}

case class StartAnalysis() extends AnalysisEvent {
   override def run ...
   override def nextStep: AnalysisEvent = new FirstStep
}

case class FirstStep() extends AnalysisEvent {
   override def run ...
   override def nextStep: AnalysisEvent = new SecondStep
}

case class SecondStep() extends AnalysisEvent {
   ...
}

class ProjectAnalysisActor(project: Project) extends Actor {

    def receive = {
        case event: AnalysisEvent =>
            val future = event.run(project)
            future.onComplete { f =>
                self ! event.nextStep
            }
    }

}

各分析ステップの実行方法のコードを実装する方法に問題があります。現時点では、各実行メソッド内で新しい未来を作成しています。この未来の内部では、すべてのフォローアップ メッセージをさまざまなサブシステムに送信します。それらのいくつかはノンブロッキングのファイアアンドフォーゲットメッセージですが、次の分析ステップが開始される前に保存する必要がある結果を返すものもあります。

現時点では、典型的な実行方法は次のようになります


def run(project: Project): Future[Any] = {
    Future {
        progressActor ! typicalFireAndForget(project.name)
        val calcResult = (calcActor1 !! doCalcMessage(project)).getOrElse(...)

        val p: Project = ... // created updated project using calcResult

        val result = (storage !! updateProjectInformation(p)).getOrElse(...)
        result
    }
}

これらのブロッキングメッセージは避けるべきなので、これが正しい方法かどうか疑問に思っています. このユースケースでそれらを使用することは理にかなっていますか、それとも避けるべきですか? もしそうなら、適切な解決策は何ですか?

4

1 に答える 1

7

どうやらの唯一の目的は、ProjectAnalysisActor将来の呼び出しを連鎖させることです。第 2 に、runs メソッドも結果を待って計算を続けるようです。

したがって、ここで説明されているように、Future Compositionを使用するようにコードをリファクタリングしてみることができると思います: http://akka.io/docs/akka/1.1/scala/futures.html

def run(project: Project): Future[Any] = {
  progressActor ! typicalFireAndForget(project.name)
  for( 
      calcResult <- calcActor1 !!! doCalcMessage(project);
      p = ... // created updated project using calcResult
      result <- storage !!! updateProjectInformation(p)
  ) yield (
    result
  )
}
于 2011-07-13T13:47:50.180 に答える