【问题标题】:Akka priority mailbox and stash/unstashAkka 优先邮箱和 stash/unstash
【发布时间】:2015-08-30 19:23:15
【问题描述】:

我有这种情况:

  • 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"(所以旧的 M2 和 M3 必须在新的 M4 之前打印)。 Stash()unstash() 不适用于优先邮箱,所以我的想法是创建具有最高优先级的启动/停止消息、M1、M2 等...具有最低优先级的消息,在我使用 become() 之后,我虽然ActorB 可以再次发送保存的消息,但这次具有中等优先级(因此它们将在新消息之前被读取,但在停止消息之后)。是否可以?有没有更好的解决方案?

【问题讨论】:

  • 这种情况永远不会发生在您在此场景中描述的发送者-接收者对中。 Akka 明确保证这一点:doc.akka.io/docs/akka/snapshot/general/…
  • 所以如果我有一个优先邮箱,即使它们具有相同的优先级,邮件的顺序可能会改变?
  • 实际上,我误解了您的帖子,似乎优先邮箱可以完成您的建议。如果 stash 和 unstash 不起作用,您可以使用队列。

标签: scala akka actor messages


【解决方案1】:

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

  • ActorAActorC 发送要打印的消息和开始/停止消息
  • 当准备好打印时,ActorB 会向ActorC 发送一条消息
  • 如果ActorC 早先从ActorA 收到开始消息,则它会发送下一条消息以打印到ActorB。否则它只会等待 Start 消息并且什么也不发送到 ActorB

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

【讨论】:

    猜你喜欢
    • 2021-06-06
    • 2020-06-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-24
    相关资源
    最近更新 更多