4

私はこのチュートリアルに従いました:http://doc.akka.io/docs/akka/2.0/intro/getting-started-first-scala.html

基本的に、これら2つのメッセージに応答するマスターアクターがあります。

def receive = {
    case Calculate => {
      //....
    }
    case Result(value) => {
      //....
    }
}

「計算」というメッセージを送信し、(スレーブアクターからの)いくつかの「結果」の後に正しい計算が行われます。

今、私はplay2コントローラーのアクションの中にいて、これを使用しています:

val promise = (master ? Calculate)(10.seconds).mapTo[String].asPromise

残念ながら(明らかに)Calculateメッセージは送信者へのメッセージで応答するため、何も得られません。

どういうわけか、Akka Actorを待機させたいのですが、計算が完了したら、送信者にメッセージを送り返します。

しかし、どうやって?...私が間違った方法でそれをモデル化していない限り!

4

2 に答える 2

4

スレーブへのメッセージ(同じ送信者を維持する)、またはforwardスレーブへのメッセージに送信者を含める必要があります。例えば:

def receive = {
  case Calculate => slave ! CalculateWithSender(sender)

  case res @ Result(value, originalSender) =>        
    val result = resultMap(originalSender) + res   // assuming results are just added
    resultMap += (originalSender -> result) 
    if (resultsAreFinished(originalSender))    
      originalSender ! result
}

また

def receive = {
  case Calculate => slave.forward(Calculate)

  case res @ Result(value, originalSender) => 
    val result = resultMap(originalSender) + res   // assuming results are just added 
    resultMap += (originalSender -> result) 
    if (resultsAreFinished(originalSender))    
      originalSender ! result
}

また

def receive = {
  case Calculate => slave.tell(Calculate, sender)

  case res @ Result(value, originalSender) => 
    val result = resultMap(originalSender) + res   // assuming results are just added 
    resultMap += (originalSender -> result) 
    if (resultsAreFinished(originalSender))    
      originalSender ! result
}

私はPlayの約束に精通していませんが、?ask)はAkkaを返しますFuture.asPromiseAkkaFutureをPlayに変換すると、Promise設定が完了します。

于 2012-10-05T15:46:03.490 に答える
1

計算ごとに新しいアクターをスピンアップします。計算メッセージを新しいアクターに転送します。新しいアクターは元の送信者を保存します。結果の準備ができると、結果は元の送信者に送信され、エフェメラルアクターは終了します。

class CalculateActor extends Actor {
    var origSender : ActorRef = _
    def receive {
        case Calculate => {
            origSender = sender
            slaveActors ! doStuff
            //....
    }
    case Result(value) => {
        if(results are ready) {
            origSender ! results
            self ! PoisonPill  // I'm done, time to die
        }
    }
}

class MasterActor extends Actor {
    def receive {
        case msg @ Calculate => {
            // forward sends without changing the sender
            context.actorOf(Props(new CalculateActor)).forward(msg)
        }
    }
}
于 2012-10-05T15:50:31.040 に答える