Akka优先邮箱和藏匿/解冻

时间:2015-08-30 19:23:15

标签: scala akka actor messages

我遇到这种情况:

  • ActorA每30-40秒发送ActorB个开始/停止消息
  • ActorA发送ActorB字符串进行打印(始终)
  • ActorB必须打印他收到的字符串,但前提是ActorA只发送了一条开始消息

我的代码:

case object Start
case object Stop
case object TriggerStateChange
case object SendMessage

class ActorB extends Actor with Stash {
  override def receive: Receive = {
    case Start =>
      context.become(printingBehavior, false)
      unstashAll()
    case x => stash()
  }

  def printingBehavior: Receive = {
    case msg: String => println(msg)
    case Stop => context.unbecome()
  }
}

class ActorA(val actorB: ActorRef) extends Actor {

  var counter = 0
  var started = false

  override def preStart: Unit = {
    import context.dispatcher

    this.context.system.scheduler.schedule(0 seconds, 5 seconds, self, TriggerStateChange)
    this.context.system.scheduler.schedule(0 seconds, 1 seconds, self, SendMessage)
  }

  override def receive: Actor.Receive = {
    case SendMessage =>
      actorB ! "Message: " + counter
      counter += 1
    case TriggerStateChange =>
      actorB ! (if (started) {
        started = false
        Stop
      } else {
        started = true
        Start
      })
  }
}

object Akka {
  def main(args: Array[String]) = {
    val system = ActorSystem.create("TestActorSystem")

    val actorB = system.actorOf(Props(classOf[ActorB]), "ActorB")
    val actorA = system.actorOf(Props(classOf[ActorA], actorB), "ActorA")

    system.awaitTermination()
  }
}

我使用了这段代码suggested by another user,但我遇到了问题。 ActorB一旦收到停止消息就应该停止(因此,如果在打印M1时接收到M1-M2-M3和停止消息,则它不能打印M2和M3)。我想使用优先级邮箱,但stash()unstash()不能使用优先级邮箱。有没有办法只使用优先邮箱?

如果我有序列M1-M2-M3-Stop-M4-Start-M5(并且在打印M1时停止接收),我应该得到第一个打印“M1”和第二个打印“M2-M3-M4 -M5“(因此必须在新的M4之前打印旧的M2和M3)。 Stash()unstash()不能与优先邮箱一起使用,所以我的想法是创建具有最高优先级的启动/停止消息,M1,M2等...具有最低优先级的消息,并且在我使用之后become(),我虽然ActorB可以再次发送已保存的消息,但这次具有中等优先级(因此它们将在新消息之前读取,但在停止消息之后)。可能吗?有更好的解决方案吗?

1 个答案:

答案 0 :(得分:0)

如果可以引入新的ActorC,可以像这样解决:

  • ActorAActorC
  • 发送要打印和启动/停止消息的消息
  • ActorB在准备好打印时向ActorC发送消息
  • 如果ActorC之前收到来自ActorA的“开始”消息,则会发送下一条消息以打印到ActorB。否则它只是等待Start消息并且不向ActorB发送任何内容。

这样,如果在ActorB仍在打印M1时M1-M2-M3-Stop序列到来,则在下一个开始消息之前不会打印任何消息。