Scala 死信和ActorRef错误

Scala 死信和ActorRef错误,scala,akka,Scala,Akka,我在运行无法解决的项目时遇到错误 这是我的密码: import akka.actor._ import akka.actor.Actor import akka.actor.ActorSystem import akka.actor.Props import akka.actor.ScalaActorRef import akka.pattern.gracefulStop import akka.util._ import java.util.Calendar import java.util.

我在运行无法解决的项目时遇到错误

这是我的密码:

import akka.actor._
import akka.actor.Actor
import akka.actor.ActorSystem
import akka.actor.Props
import akka.actor.ScalaActorRef
import akka.pattern.gracefulStop
import akka.util._
import java.util.Calendar
import java.util.concurrent._
import java.text.SimpleDateFormat
import scala.Array._
import scala.concurrent._
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global

sealed trait Message
case class ReturnInfluenceMessage(source: ActorRef) extends Message
case class SetInfluences(source: ActorRef) extends Message
case class GetInfluence() extends Message

class Listener extends Actor {
    def receive = {
        case ReturnInfluenceMessage(s0urce) => println ("Listener: received influence (" +     s0urce + ")")
    }
}

class Entity extends Actor {
    val Influences = context.actorOf(Props[Influences], name = "Influences")
    def receive = {
        case SetInfluences(s0urce) => context.children foreach     (_.forward(SetInfluences(s0urce)))
        case GetInfluence => context.children foreach (_.forward(GetInfluence))
        case ReturnInfluenceMessage(source) =>
            source ! ReturnInfluenceMessage(source)
    }
}

class Influences extends Actor {
    private var source: ActorRef = _
    def receive = {
        case SetInfluences(s0urce)  => 
            source = s0urce
            println ("Influences: received " + s0urce)
            println ("Influences: Influence set to " + source)
        case GetInfluence =>
            println ("Influences: influence sent to " + source)
            sender ! ReturnInfluenceMessage(source)
    }
}

object main extends App {
    val system = akka.actor.ActorSystem("mySystem")
    val Abel = system.actorOf(Props[Listener], name = "Listener")
    val Cain = system.actorOf(Props[Entity], name = "Entity")

    system.scheduler.scheduleOnce(1500 milliseconds, Cain, SetInfluences(Abel))
    system.scheduler.scheduleOnce(3000 milliseconds, Cain, GetInfluence)
}
下面是错误:

 [INFO] [08/29/2014 15:39:08.330] [mySystem-akka.actor.default-dispatcher-2] [akka://mySystem
 /deadLetters] Message [ReturnInfluenceMessage] from Actor[akka://mySystem/user/Entity
 /Shadow/Influences#1407138271] to Actor[akka://mySystem/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'.
我试图设置
Cain
actor的变量
source
,让最后一个变量发送
Abel
ActorRef
,并向其显示一条表示
source
变量的消息。 错误发生在这里:

source ! ReturnInfluenceMessage(source)

,我不知道为什么会出现这种情况。

当您使用

system.scheduler.scheduleOnce(...)
该消息的发送者是死信,这就是您试图发送消息的目的地

sender ! ReturnInfluenceMessage(source)

这也是错误消息所说的。

当您使用

system.scheduler.scheduleOnce(...)
该消息的发送者是死信,这就是您试图发送消息的目的地

sender ! ReturnInfluenceMessage(source)

这也是错误消息所说的。

当您使用

system.scheduler.scheduleOnce(...)
该消息的发送者是死信,这就是您试图发送消息的目的地

sender ! ReturnInfluenceMessage(source)

这也是错误消息所说的。

当您使用

system.scheduler.scheduleOnce(...)
该消息的发送者是死信,这就是您试图发送消息的目的地

sender ! ReturnInfluenceMessage(source)

这也是错误消息所说的。

@Martynas是正确的,因为当您的代码按原样设置时,
发送方
ref将成为
死信
ref。主要问题是,您从actor系统外部(通过调度程序)发送消息,然后当您使用
forward
时,您会继续将没有发送者的事实传播到下一个actor。您可以通过使用
告诉(!)
而不是转发来解决此问题。我修改了您的代码示例以显示这一点(以及代码示例之后描述的一些其他更改):

当我运行这个时,我没有收到任何死信。其他变化包括:

  • 格式设置(缩进2个空格,var/VAL的大小写正确)
  • 已将
    GetInfluence
    更改为案例对象,因为它没有任何字段
  • 当我们需要发送消息时,在case语句中使用变量绑定来捕获对消息的引用(通过
    @
    符号)
  • 影响
    参与者使用两种状态设置,首先等待设置状态(源ref),然后切换到能够正确响应
    GetInfluences
    消息的状态。可能希望在初始状态下显式处理
    GetInfluences
    消息,因为现在它只是一条未处理的消息
  • 不再使用
    children.foreach
    ,因为您已经有了对该参与者的唯一子级的引用,所以似乎没有必要使用此构造。如果要发送的孩子数量可变,而在本例中没有,我会使用该结构

    • @Martynas是正确的,因为当您的代码按原样设置时,
      发送方
      ref将是
      死信
      ref。主要问题是,您从actor系统外部(通过调度程序)发送消息,然后当您使用
      forward
      时,您会继续将没有发送者的事实传播到下一个actor。您可以通过使用
      告诉(!)
      而不是转发来解决此问题。我修改了您的代码示例以显示这一点(以及代码示例之后描述的一些其他更改):

      当我运行这个时,我没有收到任何死信。其他变化包括:

      • 格式设置(缩进2个空格,var/VAL的大小写正确)
      • 已将
        GetInfluence
        更改为案例对象,因为它没有任何字段
      • 当我们需要发送消息时,在case语句中使用变量绑定来捕获对消息的引用(通过
        @
        符号)
      • 影响
        参与者使用两种状态设置,首先等待设置状态(源ref),然后切换到能够正确响应
        GetInfluences
        消息的状态。可能希望在初始状态下显式处理
        GetInfluences
        消息,因为现在它只是一条未处理的消息
      • 不再使用
        children.foreach
        ,因为您已经有了对该参与者的唯一子级的引用,所以似乎没有必要使用此构造。如果要发送的孩子数量可变,而在本例中没有,我会使用该结构

        • @Martynas是正确的,因为当您的代码按原样设置时,
          发送方
          ref将是
          死信
          ref。主要问题是,您从actor系统外部(通过调度程序)发送消息,然后当您使用
          forward
          时,您会继续将没有发送者的事实传播到下一个actor。您可以通过使用
          告诉(!)
          而不是转发来解决此问题。我修改了您的代码示例以显示这一点(以及代码示例之后描述的一些其他更改):

          当我运行这个时,我没有收到任何死信。其他变化包括:

          • 格式设置(缩进2个空格,var/VAL的大小写正确)
          • 已将
            GetInfluence
            更改为案例对象,因为它没有任何字段
          • 当我们需要发送消息时,在case语句中使用变量绑定来捕获对消息的引用(通过
            @
            符号)
          • 影响
            参与者使用两种状态设置,首先等待设置状态(源ref),然后切换到能够正确响应
            GetInfluences
            消息的状态。可能希望在初始状态下显式处理
            GetInfluences
            消息,因为现在它只是一条未处理的消息
          • 不再使用
            children.foreach
            ,因为您已经有了一个ref