用akka和scala切换actor行为

时间:2016-03-16 11:41:35

标签: scala akka

在演员之间切换活动的正确方法是什么。

例如,

actorA - 向actorB发送100条消息。 ActorB会将其打印到控制台中。在100条消息之后,actorB将向actorA发送100条消息,而actorA将打印它。每100 msg切换演员行为。

Thansk

1 个答案:

答案 0 :(得分:0)

这是我将如何做到的(这是一个非常快速的解决方案,可能不是最优雅的解决方案,欢迎提出改进建议)。主要部分是以下actor,它可以发送或接收消息。它在发送(分别接收)超过Public Class colInfoSet Inherits CollectionBase 条消息后改变其行为。

numberOfMessages

最初,演员处于一种状态,即它不知道它是发送者还是接收者。在这种情况下,可能会发生两件事:

  1. 演员收到一条消息,在这种情况下,它知道它是一个接收者,因此import akka.actor._ import scala.concurrent.duration._ object SenderReceiver { case class StartSending(other: ActorRef) // see explanation below case object TheMessage // dummy placeholder for actual message case object SendMessage // a reminder for the actor itself to send a message def props(numberOfMessages: Int): Props = Props(new SenderReceiver(numberOfMessages)) } class SenderReceiver(numberOfMessages: Int) extends Actor with ActorLogging { import context._ import SenderReceiver._ // initial receive in order to determine the actor's initial role def receive = { case StartSending(other) => log.info("I'm sending first, yay!") sendNext(0, other) case TheMessage => log.info("It seems, I'm receiving messages first.") become(receiveMessages(1)) } // receive function for when actor is a receiver of messages def receiveMessages(messagesReceived: Int) : Receive = { case TheMessage => log.info("Message received") val messagesReceivedNew = messagesReceived + 1 if (messagesReceivedNew < numberOfMessages - 1) become(receiveMessages(messagesReceivedNew)) else sendNext(0, sender) } // receive function for when actor is a sender of messages def sendMessages(messagesSent: Int, other: ActorRef) : Receive = { case SendMessage => other ! TheMessage log.info("Message sent") val messagesSentNew = messagesSent + 1 if (messagesSentNew < numberOfMessages - 1) sendNext(messagesSentNew, other) else become(receiveMessages(0)) } def sendNext(messagesSent: Int, other: ActorRef) { system.scheduler.scheduleOnce(500 milliseconds, self, SendMessage) become(sendMessages(messagesSent, other)) } } 是一个接收者。
  2. 在另一种情况下,演员需要明确告知其是发件人(特别是,它需要知道发送到哪里!),才能become发件人。
  3. 一旦演员知道它的角色是什么,它就完全按照它应该做的去做。它发送(或接收)一定数量的消息,然后切换到另一种行为。

    为了运行此代码,以下是您可能需要的更多代码段。首先,这里有一个简单的辅助演员设置整个系统并在一段时间后停止它(十秒左右后会变得有点无聊......)

    become

    而且,为了完整起见,一个简单的object Terminator { case object StopThem } class Terminator extends Actor with ActorLogging { import Terminator._ import SenderReceiver.StartSending import context._ val actorA = system.actorOf(SenderReceiver.props(3), "actorA") val actorB = system.actorOf(SenderReceiver.props(3), "actorB") actorB ! StartSending(actorA) system.scheduler.scheduleOnce(10 seconds, self, StopThem) def receive = { case StopThem => log.info("Stopping actors now") system.shutdown } } 开始一切

    App