web-dev-qa-db-fra.com

Akka in Scala, point d'exclamation et point d'interrogation

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)
63
ticofab

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 de tell.

? envoie un message de manière asynchrone et renvoie un Future représentant une réponse possible. Également connu sous le nom de ask.

111
om-nom-nom

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!"
  }
}
20
mattinbits