3

私はscalaでakkaを始めようとしています。メインの scala スレッドで、akka アクターを開始し、それに 1 つのメッセージを送信して、そのアクターが終了するまでブロックしたいと思います。これを行う最善の方法は何ですか?

たとえば、自分自身に繰り返しメッセージを送信するテスト アクターがあります。

class Incrementer() extends Actor {

  val maxMessages = 5
  var counter = 0

  def receive() = {
    case DoIncr() => {
      if (counter < maxMessages) {
        counter += 1
        self ! DoIncr()
      } else {
        self.stop()
      }
    }
  }
}

そしてそれは次の方法で呼び出されます:

val inc = actorOf(new Incrementer()).start()
val result = inc !! DoIncr()
println(result) // this should block this thread, but it doesn't seem to.

// do other stuff

そのブロックの実行には、数ミリ秒と予想されるのではなく、5,000 ミリ秒強かかるため、デフォルトの将来のタイムアウトに関係しているようで、プログラムは実際には終了しません。私が実際にやろうとしているのは、x 数のメッセージを送信するパフォーマンスの時間を測定することだけです。何が起きてる?

4

1 に答える 1

4

Viktor が述べたように、 が!!正常に終了するには、メッセージに返信する必要があります。構成可能なアクターのデフォルトのタイムアウトを表示している 5 秒の遅延。詳細については、Akka のサイトを参照してください。

の代わりにを使用forwardしてメッセージを送信すると!self.replyは元の送信者に応答します。

Akka アクターに送信する最初のメッセージは、他のメッセージを処理するときに発生しないいくつかのセットアップを実行します。タイミングについては、必ずそれを考慮に入れてください。

修正されたコードは次のようになります。

import akka.actor._

object DoIncr

class Incrementer extends Actor {
  val maxMessages = 5
  var counter = 0

  def receive = {
    case DoIncr =>
      if (counter < maxMessages) {
        counter += 1
        self forward DoIncr
      } else {
        self.reply(()) // replying with () since we have nothing better to say
        self.stop()
      }
  }
}

余談ですが、慣用的な Scala に合わせてコードを作成するために、他にもいくつか変更を加えました。これらの変更を加えなくてもコードは機能しますが、より典型的な Scala コードのように見えます。

  • パラメーター リストのないケース クラスは非推奨になりました。object代わりに s を使用してください。
  • パラメータリストのないクラスがある場合は、括弧を省略できます
  • Actorreceiveメソッドには括弧がありません。実装クラスにもそれらを含める必要はありません。
  • これは純粋にスタイルの問題ですが、caseステートメントの本文には中かっこは必要ありません。
于 2011-05-18T06:22:19.767 に答える