What is the difference between exclamation mark (!
) and question mark (?
) when sending messages to Actors?
myActor ! Hello(value1)
myAc
Shamelessly copied [awesome] official doc (look Send messages section for more):
Messages are sent to an Actor through one of the following methods.
!
means “fire-and-forget”, e.g. send a message asynchronously and return immediately. Also known astell
.
?
sends a message asynchronously and returns aFuture
representing a possible reply. Also known asask
.
From the recipient's point of view, it sees tell
and ask
messages the same way. However when receiving a tell
the value of sender
will be the reference of the actor who sent the message, whereas for an ask
, the sender
is set up such that any reply goes to the Future
created in the actor who did the asking.
There is an advantage in ask
, that it is easy to know that the response you're receiving was definitely a result of the message you asked, whereas with Tell, you may need to use unique IDs to achieve a similar result. However with ask
you need to set a timeout
after which the Future
will fail if no response is received.
In the code below, the same effect is achieved with a tell
and and 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!"
}
}