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
- 不再使用
,因为您已经有了一个refchildren.foreach