What is a difference between tell and forward, in case I will send the same message:
case msg: Message =>
otherActor tell (msg,sender)
and
case msg: Message =>
otherActor forward msg
What is a difference between tell and forward, in case I will send the same message:
case msg: Message =>
otherActor tell (msg,sender)
and
case msg: Message =>
otherActor forward msg
The sender()
will be different on the receiving end.
Message sends using tell (also known as !
):
A
tells message M
to B
.
B
tells that message to C
.
C
thinks the sender()
of message M
is B
.
Message sends using forward:
A
tells message M
to B
.
B
forwards that message to C
.
C
thinks the sender()
of message M
is A
.
Worth pointing out is, that you can achieve the same as forward
when explicitly setting the sender of a message using tell
, however this is not typical Akka-style:
// inside `B`, when received `msg` from `A`
C tell (msg, A)
==
C forward msg
For more info refer to the docs about forward.
Tell sets the sender as the actor sending the message.
Forward keeps the original sender of the message.
target.tell(message, getSelf()); final Object result = ""; target.forward(result, getContext());
Here, getself() is the self reference of the actor. getcontext() is the supervisor reference.
import akka.actor.{Actor, ActorSystem, Props}
case object FromActor3
/**
* forward method: Forwards the message and passes the original sender actor as the sender.
*/
object ActorForward extends App {
class ActorExample extends Actor {
def receive = {
case message: String =>
println(s"Message received from ${sender.path.name}, message = $message")
val child = context.actorOf(Props[Actor2], "ChildActor")
child ! message
case FromActor3 => println("Response when forwarded by Actor2 to Actor3")
}
}
class Actor2 extends Actor {
def receive = {
case message: String =>
println(s"Message received from ${sender.path.name}, message = $message")
val child = context.actorOf(Props[Actor3], "ChildActor")
println("forwarding...")
child forward message
case _ => println("Unknown message")
}
}
class Actor3 extends Actor {
def receive = {
case message: String =>
println(s"Message received from ${sender.path.name}, message = $message")
sender ! FromActor3
case _ => println("Unknown message")
}
}
val actorSystem = ActorSystem("ActorSystem")
val actor = actorSystem.actorOf(Props[ActorExample], "RootActor")
actor ! "Hello"
}