Akka: l'utilisation correcte du modèle `ask`?
Je suis en train de grok Futures
et demandez modèle à akka.
Donc, je fais deux acteurs, l'un demandant à l'autre à lui envoyer un message. Eh bien, selon akka du Futures
de la documentation, l'acteur devrait demander(?
) pour le message et il doit lui donner un Future
instanse. Ensuite, l'acteur devrait bloc (à l'aide de Await
) pour obtenir Future
résultats.
Bien, je n'ai jamais eu mon avenir en fait. Pourquoi est-ce?
Code est:
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"
}
}
}
Si je change Duration.Inf
à 5.seconds
puis acteur attend 5 secondes, raconte que mon avenir est Timeouted (en jetant TimeoutException
), et puis d'autres acteur de enfin les réponses avec le nécessaire de message. Donc, pas de async qui se passe. Pourquoi? 🙁
Comment dois-je les mettre en œuvre correctement ce modèle? Merci.
source d'informationauteur head_thrash
Vous devez vous connecter pour publier un commentaire.
Officiel Akka la documentation dit qui l'Attendent.le résultat sera la cause de la thread en cours de bloquer et d'attendre pour l'Acteur pour "compléter" l'Avenir avec elle de répondre.
Il est étrange que votre code bloque toujours là, vous avez un seul thread pour toutes vos applications?
De toute façon, je suppose un plus "idiomatiques" manière de coder, il serait d'utiliser un rappel sur la réussite future.
Deux raisons qui ne fonctionne pas.
Première, "node_1", demande lui-même et le "ping" ne sera pas traité car elle bloque en attente pour le demander.
Aussi, il y a une lacune de actorSelection pour les chemins relatifs ("../node_1"). Elle est traitée avec la transmission de message, et depuis votre acteur est-il le blocage ne peut pas traiter de tout autre message. Cela a été amélioré dans la prochaine version 2.3 d'Akka, mais vous devriez éviter le blocage de toute façon.