The difference between Actorref.tell and inbox.send in Akka

So, I started to learn Akka and tested the examples in typafe. So, Hello Akka application has the following code:

import akka.actor.{ ActorRef, ActorSystem, Props, Actor, Inbox } import scala.concurrent.duration._ case object Greet case class WhoToGreet(who: String) case class Greeting(message: String) class Greeter extends Actor { var greeting = "" def receive = { case WhoToGreet(who) => greeting = s"hello, $who" case Greet => sender ! Greeting(greeting) // Send the current greeting back to the sender } } object HelloAkkaScala extends App { // Create the 'helloakka' actor system val system = ActorSystem("helloakka") // Create the 'greeter' actor val greeter = system.actorOf(Props[Greeter], "greeter") // Create an "actor-in-a-box" val inbox = Inbox.create(system) // Tell the 'greeter' to change its 'greeting' message greeter.tell(WhoToGreet("akka"), ActorRef.noSender) // Ask the 'greeter for the latest 'greeting' // Reply should go to the "actor-in-a-box" inbox.send(greeter, Greet) // Wait 5 seconds for the reply with the 'greeting' message val Greeting(message1) = inbox.receive(5.seconds) println(s"Greeting: $message1") // Change the greeting and ask for it again greeter.tell(WhoToGreet("typesafe"), ActorRef.noSender) inbox.send(greeter, Greet) val Greeting(message2) = inbox.receive(5.seconds) println(s"Greeting: $message2") val greetPrinter = system.actorOf(Props[GreetPrinter]) // after zero seconds, send a Greet message every second to the greeter with a sender of the greetPrinter system.scheduler.schedule(0.seconds, 1.second, greeter, Greet)(system.dispatcher, greetPrinter) } // prints a greeting class GreetPrinter extends Actor { def receive = { case Greeting(message) => println(message) } } 

Now I'm stuck in understanding the difference between the two,

 greeter.tell(WhoToGreet("akka"), ActorRef.noSender) 

and

 inbox.send(greeter, Greet) 

In my opinion, the actor starts his own thread at the end

 val inbox = Inbox.create(system) 

Can someone explain what Actorref.tell does, and then what exactly is achieved by the Inbox.send line.

+7
scala akka
source share
2 answers

The tell target, also presented as ! , - send a message to the actor. Because participants interact through messaging, tell is the mechanism used to support the transmission of this message. It is asynchronous with the caller, so that as soon as the caller calls tell , they are separated from receiving and processing this message by the instance of the target actor. In this particular example, the code uses the tell command to force the greeter activist to update his internal state. Since this interaction does not lead to any kind of response (the receiving entity does not send the message back to the sender in response to this request), tell enough here.

To get a greeting from a greeting, the interaction is a little different. In this interaction, the sender expects a response message. This type of request / response interaction can be transmitted through ask (i.e. ? ), In which the caller receives Future back, which will be completed when the recipient answers, but ask was not used here. In this example, the encoder received request / response semantics, using instead Inbox , which can act like an actor and eliminates the need for futures. Inbox should look like an ActorRef recipient, allowing it to redirect the response to it with the following line:

 sender ! Greeting(greeting) 

The sender() method returns the ActorRef the one sent in the processed message. Inbox should be able to present itself as an ActorRef for this. But, as I said earlier, you could also use ask here to make request / response interaction work. I think this is just a matter of choice. The bottom line is that tell used to model the interaction with fire and forgetting, and a mailbox (or another actor or ask ) can be used when request / response semantics are required.

+13
source share

When you do the following, you are dealing directly with ActorRef

 greeter.tell(WhoToGreet("akka"), ActorRef.noSender) 

On the other hand, when you use Inbox , you are not dealing with an actor, but with an actor. One of the scenarios when this is useful is when you do not want to create your own actor, but still want to interact with other actors asynchronously. See this

Inbox is an act-like object that is interrogated from the outside. There is an actor in it, whose link can be transferred to other actors, as usual, and he can observe the life cycle of other participants.

The actor works in a thread pool (configured using the dispatcher). You can decide either by tuning, or by entering a code in which the dispatcher uses his actor to execute it.

+2
source share

All Articles