Surender Raja Surender Raja - 1 year ago 58
Scala Question

How do we send back the result of processed message by actor to the actual sender

I created a simple Actor which receives a message from a sender and process that message and that processed result needs to be sent back to the sender .

I tried to achieve that above requirement via Actor model and sender

Actor Code :


class HelloWorld extends Actor {

var result:Int =0
def receive = {

case dataStr:String =>result =process(dataStr)
sender ! result


def process(str:String):Int ={

str.length +30

ActorApp Code :

import{ActorRef, ActorSystem, Props}

object ActorApp {

def main(args :Array[String]) ={

val system = ActorSystem("SimpleActorSystem")
val actorObj1:ActorRef = system.actorOf(Props[HelloWorld],"helloworld1")
val res =actorObj1 ! "Hi"



I got the below output :

[INFO] [10/08/2016 23:21:50.438] [] [akka://SimpleActorSystem/deadLetters] Message [java.lang.Integer] from Actor[akka://SimpleActorSystem/user/helloworld1#-233096668] to Actor[akka://SimpleActorSystem/deadLetters] was not delivered. [1] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.

I am expecting output as below in the main object(ActorApp) :


How do I send back the processed output back to sender? Also what does this INFO log say?

Answer Source

Consider what you're doing: You're sending a message to your HelloWorld actor, receive and process it there and then send a message from this actor to the actor who sent the original message (remember: sender returns an ActorRef).

But: What actor is that? There is only the one HelloWorld actor. So naturally sender isn't defined (since you didn't actually send the message from another actor). If you send messages to receivers which can't be delivered they go to akkas dead-letters system actor (Actor[akka://SimpleActorSystem/deadLetters]) - and that's what the log message says.

So how do you actually return a result? You use the ask-pattern.

import akka.pattern.ask and use a question mark instead of the exclamation mark to do so. Now you'll end up with a future which will (hopefully) be resolved with your result:

import akka.pattern.ask
import scala.concurrent.duration._

val system = ActorSystem("SimpleActorSystem")
val actorObj1:ActorRef = system.actorOf(Props[HelloWorld],"helloworld1")
val resFuture = (actorObj1 ? "Hi").mapTo[Int]
val res = Await.result(resFuture, 5 seconds)
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download