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)
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ż jakotell
.
?
wysyła wiadomość asynchronicznie i zwracaFuture
reprezentującą możliwą odpowiedź. Znany również jakoask
.
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!"
}
}
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