Akka : der richtige Einsatz von `bitten` Muster?
Ich versuche zu verstehen Futures
und bitten Muster in akka.
So, ich mache zwei Akteure, und man fragt, eine andere, ihn zurück zu senden a message. Gut, nach akka ist Futures
Dokumentation, Schauspieler sollte Fragen(?
) für die Meldung und es wird ihm eine Future
instanse. Dann Schauspieler blockieren sollte (mit Await
) Future
Ergebnisse.
Gut, bekomme ich nie meine Zukunft gemacht. Warum ist das so?
Code:
package head_thrash
import akka.actor._
import akka.util.Timeout
import scala.concurrent.Await
import scala.concurrent.duration._
object Main extends App {
val system = ActorSystem("actors")
val actor1 = system.actorOf(Props[MyActor], "node_1")
val actor2 = system.actorOf(Props[MyActor], "node_2")
actor2 ! "ping_other"
system.awaitTermination()
Console.println("Bye!")
}
class MyActor extends Actor with ActorLogging {
import akka.pattern.ask
implicit val timeout = Timeout(100.days)
def receive = {
case "ping_other" => {
val selection = context.actorSelection("../node_1")
log.info("Sending ping to node_1")
val result = Await.result(selection ? "ping", Duration.Inf) //<-- Blocks here forever!
log.info("Got result " + result)
}
case "ping" => {
log.info("Sending back pong!")
sender ! "pong"
}
}
}
Wenn ich Duration.Inf
zu 5.seconds
, dann Schauspieler, wartet 5 Sekunden, berichtet, dass meine Zukunft ist Timeouted (durch das werfen TimeoutException
), und dann die anderen Schauspieler schließlich antwortet mit der Nachricht benötigt. Also, keine async passiert. Warum? 🙁
Wie soll ich richtig realisieren, dass das Muster? Danke.
InformationsquelleAutor head_thrash | 2013-11-21
Du musst angemeldet sein, um einen Kommentar abzugeben.
Den offiziellen Akka Dokumentation sagt, die Sie Erwarten.Ergebnis führen wird der aktuelle thread blockiert und warten Sie, bis die Schauspieler zur "Vervollständigung" der Zukunft mit seiner Antwort.
Es ist seltsam, dass Ihr code-Blöcke immer da, Sie haben nur einen thread für alle Ihre Anwendung?
Ja, ich denke, eine "idiomatische" Weg, um code, es wäre ein callback zu verwenden, die auf den Erfolg in der Zukunft.
Ich brauchte, um etwas importieren, um Ihre Methode der Arbeit:
import scala.concurrent.Future import scala.concurrent.ExecutionContext.Implicits.global
Ein Akka-app ist nicht single threaded. Die Weise, die es funktioniert ist, dass die Akteure Prozess mailbox-Nachrichten auf einen thread aus einem threadpool und dann loslassen, der thread, sobald die Nachricht bearbeitet wird. Das bedeutet, dass wenn Sie den block in einen erhalten, dieser thread ist gesperrt, und der Schauspieler wird nicht verarbeiten mehr Nachrichten. Sie sollten daher vermeiden, blockiert.
Stimmen. Ganz einfach: dies ist ein schlechtes Beispiel!
Mehr "idiomatischen" Weise - Verwendung
pipe
zu senden das Ergebnis einer Zukunft zu einem SchauspielerInformationsquelleAutor Arnaud Gourlay
Zwei Gründe, warum das nicht funktioniert.
Erste, "node_1", fragt sich und das "ping" nicht bearbeitet werden, weil es blockiert in warten auf die Fragen.
Auch, es ist ein Manko der actorSelection für relative Pfade ("../node_1"). Verarbeitet wird es mit message passing, und da die Schauspieler blockiert es nicht verarbeiten kann jede andere Nachricht. Dies wurde verbessert in der kommenden version 2.3 von Akka, aber Sie sollten vermeiden, blockiert trotzdem.
ping_other
Nachricht an node_2, die ausgewählt node_1, und schickteping
zu node_1, ja, es schien mir nicht, dass node_1, fragt sich. Oder habe ich da etwas verpasst?InformationsquelleAutor Patrik Nordwall