Akka w Scali, wykrzyknik i znak zapytania

Jaka jest różnica między wykrzyknikiem (!) A znakiem zapytania (?) podczas wysyłania wiadomości do aktorów?

myActor ! Hello(value1)
myActor ? Hello(value1)
Author: ticofab, 2013-07-15

2 answers

Bezwstydnie skopiowane [awesome] oficjalny doc (Zobacz Wyślij wiadomość sekcja więcej):

Wiadomości są wysyłane do aktora za pomocą jednej z następujących metod.

! oznacza "fire-and-forget", np. wyślij wiadomość asynchronicznie i wracaj natychmiast. Znany również jako tell.

? wysyła wiadomość asynchronicznie i zwraca Future reprezentującą możliwą odpowiedź. Znany również jako ask.

 103
Author: om-nom-nom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-05 15:25:15

Z punktu widzenia odbiorcy, widzi tell i ask wiadomości w ten sam sposób. Jednak przy odbiorze tell wartość sender będzie referencją aktora, który wysłał wiadomość, podczas gdy dla ask, sender jest ustawiona w taki sposób, że każda odpowiedź trafia do Future utworzonego w aktora, który wysłał wiadomość.

Jest zaleta ask, że łatwo jest wiedzieć, że odpowiedź, którą otrzymujesz, była zdecydowanie wynikiem wiadomości, o którą pytałeś, podczas gdy Tell, możesz może być konieczne użycie unikalnych identyfikatorów, aby osiągnąć podobny wynik. Jednak z ask Musisz ustawić timeout, po czym Future zakończy się niepowodzeniem, jeśli nie otrzymasz odpowiedzi.

W poniższym kodzie ten sam efekt uzyskuje się za pomocą tell oraz 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!"
  }
}
 17
Author: mattinbits,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-17 11:20:35