akka 2.0 sendet eine Nachricht an sich selbst
mit Akka 2.0, die versuchen, eine Nachricht zu senden, um selbst (unter Verwendung der ask-Muster)
import akka.pattern.ask
import scala.concurrent.{Await, Future}
import akka.actor.{Props, Actor, ActorSystem}
import scala.concurrent.duration._
import akka.util.Timeout
object askTest extends App{
implicit val timeout = Timeout(5 seconds)
val system = ActorSystem("AskTestSystem")
val myActor = system.actorOf(Props(new TestActor), name = "myActor")
val future: Future[Foo] = ask(myActor, Foo("test")).mapTo[Foo]
val result = Await.result(future, timeout.duration)
println(result)
}
case class Foo(name:String){
override def toString = "Foo "+name
}
class TestActor extends Actor {
def receive = {
case Foo(a) => self ! Foo("buzz "+a)
case any => println(any+" that was unexpected")
}
}
jedoch stürzt es ab mit Timeout-Ausnahme mit der folgenden trace :
Exception in thread "main" java.util.concurrent.TimeoutException: Futures timed out after [5 seconds]
at scala.concurrent.impl.Promise$DefaultPromise.ready(Promise.scala:96)
at scala.concurrent.impl.Promise$DefaultPromise.result(Promise.scala:100)
at scala.concurrent.Await$$anonfun$result$1.apply(package.scala:107)
at scala.concurrent.BlockContext$DefaultBlockContext$.blockOn(BlockContext.scala:53)
at scala.concurrent.Await$.result(package.scala:107)
at akkaTest.askTest$delayedInit$body.apply(askTest.scala:33)
at scala.Function0$class.apply$mcV$sp(Function0.scala:40)
at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
at scala.App$$anonfun$main$1.apply(App.scala:71)
at scala.App$$anonfun$main$1.apply(App.scala:71)
at scala.collection.immutable.List.foreach(List.scala:318)
at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:32)
at scala.App$class.main(App.scala:71)
at akkaTest.askTest$.main(askTest.scala:13)
at akkaTest.askTest.main(askTest.scala)
- warum brauchen Sie
system.shutdown()
? Ist es nicht eigentlich zu einer Abschaltung aller Akteure (in diesem Fall, bevor irgendetwas anderes getan hat)? - vielen Dank, es war ein Fehler , habe ich es entfernt jetzt . aber immer noch nicht senden kann, um selbst
Du musst angemeldet sein, um einen Kommentar abzugeben.
Dein code tut, was Sie gesagt haben, es zu tun: der Schauspieler, der auf unbestimmte Zeit sendet eine Nachricht an sich selbst. Denn es sendet die Nachricht an niemanden außer sich selbst, Ihre
ask
Muster kann einfach nicht funktionieren, weilask
wartet auf eine Nachricht gesendet werden, um die sender, nicht selbst.self
ist eine Referenz auf die aktuelle Schauspieler, die Sie verwenden, wenn Sie möchten, dass der Schauspieler die Nachricht senden zu sich selbst.sender
ist ein Verweis auf ein Schauspieler hat die Nachricht gesendet, die aktuell verarbeitet wird. Verwenden Sie es, wenn Sie wollen "Antwort" auf den sender.ask
Muster schafft eine implizite Schauspieler, die wirdsender
Referenz im Ziel-Schauspieler - ist dies sehr natürlich. So müssen Sie zum ändernself ! Foo("buzz " + a)
zusender ! Foo("buzz " + a)
, und Ihr code funktioniert.ask
Muster außerhalb der Schauspieler, so dass es einfach nicht in den Griff-Nachrichten gesendet, umself
.def foo(a: String) { this.foo("buzz " + a) }
. Es ist keine Art und Weise, es zu handhaben sind außerhalb der Funktion. Das gleiche gilt für die Darsteller.Können Sie das senden von Nachrichten an
self
, aber Sie können nicht warten auf eine Antwort. Denn Sie wird nicht die neue Nachricht erst dann, wenn Sie fertig Umgang mit der aktuellen Nachricht, und wenn Sieask
Sie nicht beenden Umgang mit der aktuellen Nachricht bis man eine Antwort auf die neue Nachricht! So erstellen Sie einen deadlock.Aber im Fall von code in Frage, Sie sind nicht Fragen
self
für eine Antwort an alle. Der Schauspieler erstellt vonask
wartet auf die Antwort vonmyActor
, und ist nicht bekommen (weil der code vonTestActor
nicht senden Antwort, und sendet eine Nachricht anself
statt).Können Sie sehen, dass
self ! message
kann durch ändernTestActor
ein bisschen:self
? Es ist nurself ! message
, wie Sie Sie haben.TestActor
erhält eineFoo
hat, sendet er ein weiteresFoo
zu sich selbst, dann verarbeitet, indem es die anderenFoo
zu sich selbst, usw. Siehe die Antwort bearbeitet.Meine Entschuldigung, ich weiß, das ist eigentlich eine alte Frage, aber es vor kurzem tauchte in mein use-cases. Wollte nur zu teilen, meine 2 cents.
Wollte ich verarbeiten einer Nachricht von der Weiterleitung an selbst mit aktualisierten Parametern. Und ich erwarte die Ergebnisse mit Fragen Muster. Damit dies funktioniert, musste ich einen zweiten proxy-Schauspieler, die Haupt-Zweck ist die relay-Nachricht zurück zu dem Hauptdarsteller.
Das hat mir erlaubt, zu Fragen, für die Ergebnisse, die sich auf Kosten von einigen zusätzlichen Gemeinkosten.