演员被随机触发

时间:2015-04-16 17:51:55

标签: scala akka actor dispatch

我正在使用Scala API运行AKKA Actors(版本2.3.9)。

我有一堆异构的Actors需要每30分钟触发一次。我看到,在一次运行中,并非所有演员都被触发。这完全是随机的。每个演员都不会做任何重量级的任务。他们对NoSQL商店和一些写入进行了大量读取。不确定这里的实际问题是什么。我觉得有些地方我没有使用理想的方法。

这是代码:

 val system = ActorSystem("pumpkinx-akka")
import system.dispatcher
val noOfActors = 50
val allActors = List(
      system.actorOf(Props[a.actors.TriggerActor].withRouter(new RoundRobinRouter(noOfActors)), "aTriggerActor"),
      system.actorOf(Props[b.actors.TriggerActor].withRouter(new RoundRobinRouter(noOfActors)), "bTriggerActor"),
      system.actorOf(Props[c.actors.TriggerActor].withRouter(new RoundRobinRouter(noOfActors)), "cTriggerActor"),
      system.actorOf(Props[d.actors.TriggerActor].withRouter(new RoundRobinRouter(noOfActors)), "dTriggerActor"),
      system.actorOf(Props[e.actors.TriggerActor].withRouter(new RoundRobinRouter(noOfActors)), "eTriggerActor"))
def trigger = allActors.foreach(_ ! new Start)
system.scheduler.schedule(0 seconds, 30 minutes)(trigger)
system.awaitTermination()

1 个答案:

答案 0 :(得分:4)

你创建了5个路由器,每个路由器有50个演员,所以它是250 *.actors.TriggerActor。如果你想在一次运行中向所有250发送消息,你应该:

 def trigger = (1 to 50).foreach(_ => allActors.foreach(_ ! new Start))

它将向每个路由器发送50条消息。作为它的循环,第一个消息来到路由器将转到它的第一个演员,第二个 - 到第二个,依此类推,直到第50个演员收到消息。

Just allActors.foreach(_ ! new Start)只向50位演员之一发送消息 - 而不是向所有演员发送消息,没有广播。例如,a ! Start只是将消息发送到a.actors.TriggerActor

的一个实例

P.S。我的建模:

class Trigger extends Actor { 
    def receive = { 
       case x => println(context.parent.path.name + " " + self.path.name + " " + x) 
    }
}
defined class Trigger

val system = ActorSystem("pumpkinx-akka")

val allActors = List(
      system.actorOf(Props[Trigger].withRouter(new RoundRobinRouter(noOfActors)), "aTriggerActor"),
      system.actorOf(Props[Trigger].withRouter(new RoundRobinRouter(noOfActors)), "bTriggerActor"),
      system.actorOf(Props[Trigger].withRouter(new RoundRobinRouter(noOfActors)), "cTriggerActor"),
      system.actorOf(Props[Trigger].withRouter(new RoundRobinRouter(noOfActors)), "dTriggerActor"),
      system.actorOf(Props[Trigger].withRouter(new RoundRobinRouter(noOfActors)), "eTriggerActor"))

scala> allActors.foreach(_ ! "m") //everyone received a message
aTriggerActor $a m
bTriggerActor $a m
cTriggerActor $a m
dTriggerActor $a m
eTriggerActor $a m

scala> (0 to 5).foreach(_ => allActors(1) ! "m") //only to b-router
bTriggerActor $b m //bcdefg (round-robin)
bTriggerActor $g m
bTriggerActor $f m
bTriggerActor $d m
bTriggerActor $e m
bTriggerActor $c m

scala> (0 to 5).foreach(_ => allActors(1) ! "m") //only to b-router
bTriggerActor $h m //hijklm (round-robin)
bTriggerActor $l m
bTriggerActor $j m
bTriggerActor $k m
bTriggerActor $i m
bTriggerActor $m m

P.S。小心这些路由器内部的异常(更确切地说,在工作者内部)。如果路由器是顶级参与者 - 失败将传播给监护人,这会迫使整个系统关闭。

P.S。如果您还希望循环使用异构演员 - 请使用RoundRobinGroup,请参阅examples