Multithreading – the sender becomes an actor [akka: / / main / deadletters]
I can't figure out why I made a mistake "dead letters"
class MyActor extends Actor {
private def getIdList = Future { blocking(getIdListSync) }
private def getIdListSync = {
val inputStreamRaw = new URL(url).openConnection.getInputStream
val inputStream = scala.io.source fromInputStream inputStreamRaw
val json = parse(inputStream getLines() mkString "\n")
val jsonIds = json \ "ids" \\ classOf[JInt]
jsonIds take idLimit map (_.toInt)
}
def receive = {
case Get =>
//doesn't work,the error is "sender" becomes "Actor[akka://Main/deadLetters]"
// getIdList onComplete {
// case Success(idList) =>
// sender ! Result(idList)
//
// case Failure(e) => // todo
// }
//works well
val idList = getInternalIdListSync
sender ! Result(idList)
}
}
As you can see, if future and blocking are used in the method named getidlist, the sender will become actor [akka: / / main / deadletters] Why? Shouldn't I use it?
Solution
The problem is that you invoke the sender in the asynchronous function block. There is a simple rule:
Never close the sender method in a block of code that may execute asynchronously
Sender is a function that returns the sender of the currently processed message The problem is that if you call sender in a callback like onComplete, the callback will be executed asynchronously. This means that during this period, participants can process other messages, so the sender function may not report the sender of the original message
One way to avoid this is to store the sender in a local variable before executing asynchronous code:
def receive = {
case Get =>
val s = sender
// call an asynchronous function
myAsyncFunction onComplete{ result =>
s ! result
}
}
Another method is to use the akka pipeto function as @ vadzim and point out:
import akka.pattern.pipe
def receive = {
case Get =>
// call an asynchronous function
val result = myAsyncFunction
result pipeTo sender
}
More information about it can be found in the akka documentation: http://doc.akka.io/docs/akka/snapshot/scala/futures.html#Use_With_Actors
