我无法弄清楚为什么我会有错误" 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) } }
正如你所看到的,sender
变成Actor[akka://Main/deadLetters]
在使用的情况下Future
,并blocking
在标题为方法getIdList
.这是为什么?我不应该使用它吗?
只是用
import akka.pattern.pipe getIdList pipeTo sender
请参阅解释: Akka:向演员发送未来消息
问题是你sender
在异步功能块中调用.有一个简单的规则:
永远不要关闭可能异步执行的代码块中的sender方法
sender
是一个返回当前处理的消息的发件人的函数.问题是,如果你调用sender
回调函数,那么onComplete
回调就会异步执行.这意味着在此期间,参与者可以处理其他消息,因此该sender
功能可能不报告原始消息的发送者.
避免这种情况的一种方法是在执行异步代码之前将发送方存储在本地变量中:
def receive = {
case Get =>
val s = sender
// call an asynchronous function
myAsyncFunction onComplete{ result =>
s ! result
}
}
另一种方法是使用pipeTo
@Vadzim指出的akka 函数:
import akka.pattern.pipe def receive = { case Get => // call an asynchronous function val result = myAsyncFunction result pipeTo sender }
有关它的更多信息可以在akka文档中找到:http://doc.akka.io/docs/akka/snapshot/scala/futures.html#Use_With_Actors