Akka演员 - 发件人指向死信

时间:2017-04-13 15:45:26

标签: scala asynchronous akka actor

考虑以下示例:

case class Payload(message: String, async: Boolean)

class EchoActor extends Actor {
  override def receive: Receive = {
    case Payload(message, async) =>
      if (async) Future {
        println(s"from: $sender")
        sender ! message
      } else {
        println(s"from: $sender")
        sender ! message
      }
  }
}

def main(args: Array[String]): Unit = {
  val system = ActorSystem("demo")
  val echo = system.actorOf(Props[EchoActor])
  implicit val timeout = Timeout(2 seconds)

  (echo ? Payload("Hello", async = false)).mapTo[String].foreach(println(_))
  (echo ? Payload("Async Hello", async = true)).mapTo[String].foreach(println(_))

  StdIn.readLine()
  system.terminate()
}

控制台输出:

from: Actor[akka://demo/temp/$a]
Hello
from: Actor[akka://demo/deadLetters]
[INFO] [04/13/2017 19:56:58.516] [demo-akka.actor.default-dispatcher-4] [akka://demo/deadLetters] Message [java.lang.String] from Actor[akka://demo/user/$a#2112869650] to Actor[akka://demo/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'.

即。从另一个线程访问时,发件人指向deadLetters

背后的原因是什么? 这是一个错误吗?

尽管如此,我们可以保留对实际发件人的引用,以使其有效:

if (async) {
  val currentSender = sender()
  Future {
    println(s"from: $currentSender")
    currentSender ! message
  }
}

但......有没有更好的方法?

2 个答案:

答案 0 :(得分:4)

这不是错误,而是记录在案的行为 -

http://doc.akka.io/docs/akka/2.5.0/scala/actors.html#Send_messages

使用Future表示调用不是Actor类实例的匿名函数,因此sender()引用映射到deadLetters邮箱

答案 1 :(得分:1)

更好的方法是.stack-work模式。

pipe

问题是import akka.pattern.pipe class EchoActor extends Actor { override def receive: Receive = { case Payload(message, async) => if (async) { Future { message }.pipeTo(sender) } else { sender ! message } } } 是一个函数,只有在处理传入消息的同一线程上调用时,它的值才有效。当你在将来召唤sender时,它会从另一个线程和另一个时间点被调用,特别是在演员的接收函数已经返回之后。

sender在与actor相同的线程上以及在返回receive函数之前捕获当前发送方的值。这实际上与您使用pipeTo值的方法相同。