Jaka jest różnica między wykrzyknikiem (!
) a znakiem zapytania (?
) podczas wysyłania wiadomości do aktorów?Akka w Scala, wykrzyknik i znak zapytania
myActor ! new hello(value1)
myActor ? new hello(value1)
Jaka jest różnica między wykrzyknikiem (!
) a znakiem zapytania (?
) podczas wysyłania wiadomości do aktorów?Akka w Scala, wykrzyknik i znak zapytania
myActor ! new hello(value1)
myActor ? new hello(value1)
Bezwstydnie kopiowane [super]official doc (patrz wysyłać wiadomości sekcję dłużej):
Wiadomości są wysyłane do aktora przez jedną z następujących metod.
oznacza "ogień i zapomnij", np. wyślij wiadomość asynchronicznie i odbierz natychmiast. Znany również pod nazwą
tell
.
?
wysyła asynchronicznie wiadomość i zwracaFuture
reprezentującą możliwą odpowiedź. Znany również pod nazwąask
.
Z punktu widzenia odbiorcy, widzi wiadomości w taki sam sposób jak tell
i ask
. Jednak po otrzymaniu tell
wartość sender
będzie odniesieniem aktora, który wysłał wiadomość, podczas gdy dla ask
, sender
jest skonfigurowany w taki sposób, że każda odpowiedź trafia do Future
utworzonej przez aktora, który zadał pytanie.
Istnieje pewna zaleta w , że łatwo zauważyć, że odpowiedź, którą otrzymujesz, była zdecydowanie wynikiem wiadomości, o którą prosiłeś, podczas gdy w przypadku Tell możesz potrzebować unikalnych identyfikatorów, aby osiągnąć podobny wynik . Jednak pod numerem ask
należy ustawić wartość timeout
, po której Future
zakończy się niepowodzeniem, jeśli nie zostanie odebrana żadna odpowiedź.
W poniższym kodzie ten sam efekt uzyskuje się za pomocą tell
i 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!"
}
}