I can't figure out why do I have the error "deadLetters
"
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, sender
becomes Actor[akka://Main/deadLetters]
in case of using Future
and blocking
in the method titled getIdList
. Why is that? Shouldn't I use that?
The problem is that you call sender
in an async function block. There is a simple rule for that:
never close over the sender method in a code block that may get executed 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
this callback gets executed asynchronously. That means that in the meantime the actor may process other messages and therefore the sender
function may not report the sender of the original message.
One way to avoid that is to store the sender in a local variable before execution asynchronous code:
def receive = {
case Get =>
val s = sender
// call an asynchronous function
myAsyncFunction onComplete{ result =>
s ! result
}
}
Another way is to use the akka pipeTo
function as @Vadzim pointed out:
import akka.pattern.pipe
def receive = {
case Get =>
// call an asynchronous function
val result = myAsyncFunction
result pipeTo sender
}
More information about that can be find in the akka documentation: http://doc.akka.io/docs/akka/snapshot/scala/futures.html#Use_With_Actors
Just use
import akka.pattern.pipe
getIdList pipeTo sender
See for explanation: Akka: Send a future message to an Actor
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With