我遇到这种情况:
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
可以再次发送已保存的消息,但这次具有中等优先级(因此它们将在新消息之前读取,但在停止消息之后)。可能吗?有更好的解决方案吗?
答案 0 :(得分:0)
如果可以引入新的ActorC
,可以像这样解决:
ActorA
向ActorC
ActorB
在准备好打印时向ActorC
发送消息ActorC
之前收到来自ActorA
的“开始”消息,则会发送下一条消息以打印到ActorB
。否则它只是等待Start消息并且不向ActorB
发送任何内容。这样,如果在ActorB
仍在打印M1时M1-M2-M3-Stop序列到来,则在下一个开始消息之前不会打印任何消息。