Qual è la differenza tra punto esclamativo (!
) e punto interrogativo (?
) quando si inviano messaggi agli attori?Akka in Scala, punto esclamativo e punto interrogativo
myActor ! new hello(value1)
myActor ? new hello(value1)
Qual è la differenza tra punto esclamativo (!
) e punto interrogativo (?
) quando si inviano messaggi agli attori?Akka in Scala, punto esclamativo e punto interrogativo
myActor ! new hello(value1)
myActor ? new hello(value1)
spudoratamente copiato [impressionante]official doc (guarda Inviare messaggi per ulteriori):
I messaggi vengono inviati ad un attore attraverso uno dei seguenti metodi.
!
significa "fire-and-forget", ad es. inviare un messaggio in modo asincrono e restituire immediatamente. Conosciuto anche cometell
.
?
invia un messaggio in modo asincrono e restituisce unFuture
che rappresenta una possibile risposta. Conosciuto anche comeask
.
Dal punto di vista del destinatario, vede i messaggi tell
e ask
allo stesso modo. Tuttavia, quando si riceve un tell
il valore di sender
sarà il riferimento dell'attore che ha inviato il messaggio, mentre per lo sender
viene impostato in modo tale che qualsiasi risposta vada allo Future
creato nell'attore che ha effettuato la richiesta.
C'è un vantaggio in ask
, che è facile sapere che la risposta che stai ricevendo era sicuramente il risultato del messaggio che hai chiesto, mentre con Tell, potresti dover utilizzare ID univoci per ottenere un risultato simile . Tuttavia con ask
è necessario impostare un timeout
dopo il quale il Future
avrà esito negativo se non viene ricevuta alcuna risposta.
Nel codice seguente, lo stesso effetto si ottiene con un tell
e un 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!"
}
}