Quelle est la différence entre le point d'exclamation (!
) et le point d'interrogation (?
) lors de l'envoi de messages aux acteurs?
myActor ! Hello(value1)
myActor ? Hello(value1)
Copie sans vergogne [génial]doc officiel (regardez Envoyez des messages section pour plus):
Les messages sont envoyés à un acteur via l'une des méthodes suivantes.
!
signifie "tirer et oublier", par ex. envoyer un message de manière asynchrone et revenir immédiatement. Également connu sous le nom detell
.
?
envoie un message de manière asynchrone et renvoie unFuture
représentant une réponse possible. Également connu sous le nom deask
.
Du point de vue du destinataire, il voit les messages tell
et ask
de la même manière. Cependant lors de la réception d'un tell
la valeur de sender
sera la référence de l'acteur qui a envoyé le message, alors que pour un ask
, le sender
est défini de telle sorte que toute réponse va au Future
créé dans l'acteur qui a fait la demande.
Il y a un avantage dans ask
, car il est facile de savoir que la réponse que vous recevez est définitivement le résultat du message que vous avez demandé, alors qu'avec Tell, vous devrez peut-être utiliser des ID uniques pour obtenir un résultat similaire. résultat. Cependant, avec ask
, vous devez définir un timeout
, après quoi Future
échouera si aucune réponse n'est reçue.
Dans le code ci-dessous, le même effet est obtenu avec un tell
et et ask
.
import akka.actor.{Props, Actor}
import scala.concurrent.duration._
import akka.pattern.ask
class TellActor extends Actor {
val recipient = context.actorOf(Props[ReceiveActor])
def receive = {
case "Start" =>
recipient ! "Hello" // equivalent to recipient.tell("hello", self)
case reply => println(reply)
}
}
class AskActor extends Actor {
val recipient = context.actorOf(Props[ReceiveActor])
def receive = {
case "Start" =>
implicit val timeout = 3 seconds
val replyF = recipient ? "Hello" // equivalent to recipient.ask("Hello")
replyF.onSuccess{
case reply => println(reply)
}
}
}
class ReceiveActor extends Actor {
def receive = {
case "Hello" => sender ! "And Hello to you!"
}
}