Difference between forward and tell in akka actors

ScalaAkkaActor

Scala Problem Overview


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
 

Scala Solutions


Solution 1 - Scala

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.

Solution 2 - Scala

Tell sets the sender as the actor sending the message.

Forward keeps the original sender of the message.

Solution 3 - Scala

> 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.

Solution 4 - Scala

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"
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMichał JurczukView Question on Stackoverflow
Solution 1 - ScalaKonrad 'ktoso' MalawskiView Answer on Stackoverflow
Solution 2 - ScalasksamuelView Answer on Stackoverflow
Solution 3 - ScalaSuresh KumarView Answer on Stackoverflow
Solution 4 - ScalaAamirView Answer on Stackoverflow