【问题标题】:How to Create a Timer Actor that receives如何创建接收的 Timer Actor
【发布时间】:2014-06-03 13:23:14
【问题描述】:

我想创建一个 Timer Actor 来跟踪整个程序的进度(并估计剩余的执行时间)。由于计时器参与者必须持有可变变量,即“当前进度”,我认为它应该在最高主管下构建,而不是由较低级别的参与者生成。所以我创建了这个:

object Entry extends App {
    val system: ActorSystem = ActorSystem("Twitter")
    val sup = system.actorOf(Props[Supervisor])
    sup ! Sentence(.....)
}

class Supervisor extends Actor {

  def receive = {
    case sen: Sentence =>
      val timer = context.actorOf(Props[Timer])
      val pcfg = context.actorOf(Props[PCFGParser])
      pcfg ! sen.copy()
  }
}

然后我有这个较低的演员来做所有的动作:

class PCFGParser extends Actor{

   def receive = {
     case sen: Sentence =>
       //....business logic
        val ps = context.actorOf(Props[PatternSearch]) //create another actor
        ps ! sen.copy(tree = Some(tree))
        context.actorSelection("../timer") ! PCFGAddOne
   }
}

所以在这一点上,我认为它应该将消息发送回那个 Timer Actor。但是如何!?我尝试了actorSelection,但我得到的只是“死信”错误。消息未送达。而且这个 PCFGParser 演员似乎也未能向其子演员和计时器演员发送消息:

[INFO] [06/03/2014 01:35:25.290] [Twitter-akka.actor.default-dispatcher-4] [akka://Twitter/user/$a/$h/$a] 消息[TwitterProject.PCFGParserMsg$Sentence] 来自 Actor[akka://Twitter/user/$a/$h#11 90256968] 到 Actor[akka://Twitter/user/$a/$h/$a#-1918790382] 未交付。 [6] 遇到死信。

[INFO] [06/03/2014 01:35:25.291] [Twitter-akka.actor.default-dispatcher-17] [akka://Twitter/user/$a/$d/../timer ] 来自 Actor[akka://Twitter/user/$a/ 的消息 [TwitterProject.TimerMsg$PCFGAddOne$] $d#-1685001108] 到 Actor[akka://Twitter/user/$a/$d/../timer] 没有送达。 [7] 遇到死信。

首先,我承认这个演员的业务逻辑内部可能有一些错误导致了这个错误(或者真的吗??死演员会触发消息未传递错误吗?)其次,这个 PCFGParser 演员的正确方法是什么向远处的演员发送消息?

谢谢!

【问题讨论】:

    标签: scala akka


    【解决方案1】:

    如果你想通过相对路径访问你的 Timer actor,比如

    context.actorSelection("../timer")
    

    您首先需要将此 Timer 演员实例命名为“计时器”

    val timer = context.actorOf(Props[Timer], name = "timer")
    

    另外一点,如果您在Receive 块中使用context.actorOf,您将为处理的每条消息创建新的actor 实例。我不认为这是你想在这里做的。

    例如,如果每个主管参与者的实例都是唯一的,您应该编写。

    class Supervisor extends Actor {
      val timer = context.actorOf(Props[Timer])
      val pcfg = context.actorOf(Props[PCFGParser])
    
      def receive = {
        case sen: Sentence => pcfg ! sen.copy()
      }
    }
    

    【讨论】:

    • 对不起,我还有一个问题:如果我想保留进度记录,那些工作的演员必须向同一个Timer演员发送消息对吗?如果我创建 100 个Supervisoractors,就会有 100 个Timeractors,它们的内部状态都不同吧?
    • 没错。如果您需要一个唯一的 Timer 实例,请在之前创建它并将其 ActorRef 作为 Supervisor 的构造函数参数传递。然后所有的主管都会向同一个 Timer 报告。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-19
    • 2018-07-17
    • 1970-01-01
    • 2015-05-05
    • 2019-11-14
    相关资源
    最近更新 更多