微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

多线程 – 发件人成为演员[akka:// Main / deadLetters]

我无法弄清楚为什么我有错误“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)

  }
}

如您所见,如果在名为getIdList的方法中使用Future和阻塞,发送者将成为Actor [akka:// Main / deadLetters].这是为什么?我不应该使用它吗?

解决方法

问题是您在异步功能块中调用发件人.有一个简单的规则:

永远不要关闭可能异步执行的代码块中的sender方法

sender是一个返回当前处理的消息的发送者的函数.问题是,如果你像onComplete这样的回调中调用sender,这个回调会异步执行.这意味着在此期间,参与者可以处理其他消息,因此发送者功能可能不报告原始消息的发送者.

避免这种情况的一种方法是在执行异步代码之前将发送方存储在本地变量中:

def receive = {
  case Get =>
    val s = sender

    // call an asynchronous function
    myAsyncFunction onComplete{ result =>
      s ! result
    }
}

另一种方法是使用akka pipeto函数作为@Vadzim指出:

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

原文地址:https://www.jb51.cc/java/127557.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐