Scala 演员被随机触发

Scala 演员被随机触发,scala,akka,actor,dispatch,Scala,Akka,Actor,Dispatch,我正在使用Scala API运行AKKA Actors 2.3.9版 我有一群异类演员,每30分钟就要被触发一次。我看到,在一次运行中,并不是所有的演员都被触发。这完全是随机的。可以说,每个演员都不做任何繁重的任务。他们对NoSQL存储进行了大量读取和少量写入。不确定这里的实际问题是什么。我觉得有些地方我没有使用理想的方法 代码如下: val system = ActorSystem("pumpkinx-akka") import system.dispatcher val noOfActor

我正在使用Scala API运行AKKA Actors 2.3.9版

我有一群异类演员,每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()

您已经创建了5个路由器,每个路由器有50个参与者,因此它是250个*.actors.triggerator's。如果要在一次运行中向所有250个用户发送消息,您应该:

 def trigger = (1 to 50).foreach(_ => allActors.foreach(_ ! new Start))
它将向每个路由器发送50条消息。由于它是循环的,第一条消息到达路由器后,将发送给它的第一个参与者,第二个参与者-第二个参与者,依此类推,直到第50个参与者收到一条消息

只需要所有的演员!《新开始》只向50名演员中的一人发送一条信息——不是向所有演员发送,没有广播。比如说,a!Start只是将消息发送到a.actors.triggerator的一个实例

附:我的模特:

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
请注意,更准确地说,在工人内部的路由器内部要小心例外情况。如果路由器是顶级参与者,那么故障将传播到守护者,这将迫使整个系统关闭


另外,如果您还想为异构参与者使用循环,请参见

您已经创建了5个路由器,每个路由器有50个参与者,因此它是250个*.actors.triggerator'S。如果要在一次运行中向所有250个用户发送消息,您应该:

 def trigger = (1 to 50).foreach(_ => allActors.foreach(_ ! new Start))
它将向每个路由器发送50条消息。由于它是循环的,第一条消息到达路由器后,将发送给它的第一个参与者,第二个参与者-第二个参与者,依此类推,直到第50个参与者收到一条消息

只需要所有的演员!《新开始》只向50名演员中的一人发送一条信息——不是向所有演员发送,没有广播。比如说,a!Start只是将消息发送到a.actors.triggerator的一个实例

附:我的模特:

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
请注意,更准确地说,在工人内部的路由器内部要小心例外情况。如果路由器是顶级参与者,那么故障将传播到守护者,这将迫使整个系统关闭


另外,如果您还希望为异构参与者使用循环,请参见

不确定您的确切预期,您定义了RoundRobinRouter,这意味着并非所有参与者都收到消息。我的期望是:在一次运行中,我应该能够将开始消息发送给所有a、b、c、d、e参与者,而不必全部是50个a。至少一个“a”演员就可以了。我看到的问题是,“e”演员有时根本不会被触发,同样,“b”演员也不会被触发。这完全是随机的,很难观察到一种模式。不确定你到底期望什么,你定义了RoundRobinRouter,这意味着不是所有人都能收到消息。我的期望是:在一次运行中,我应该能够将开始消息发送给所有a、b、c、d、e参与者-不需要全部是50个a。至少一个“a”演员就可以了。我看到的问题是,“e”演员有时根本不会被触发,同样,“b”演员也不会被触发。这完全是随机的,很难观察到一个模式。我的理解是,每个RoundRobinRouter都只针对特定的演员。例如:路由器1将用于50个“a”演员,路由器2将用于50个“b”演员,依此类推。我希望在一次运行中至少向所有“a”、“b”、“c”、“d”、“e”演员发送一条消息。但这并不是以确定的方式发生的。我有什么遗漏吗?allActors.foreach!《新战略武器条约》只向50名演员中的一名发送了一份mesasge——不是向所有演员发送,没有广播。A.Start只是将消息发送到a.actors.triggeratorhmm的一个实例。我明白了。我不明白的是,为什么连《b》中的一个演员都没有在一次演出中被触发(例如)非常感谢,这是非常清楚的。我发现了真正的问题。问题在于参与者的基本逻辑。两个参与者中的case子句有一个“if条件”,它取决于数据库中另一个参与者更新的值。因此它是完全不确定的。作为一个附带问题,我是否可以在不同的演员之间进行循环?例如:在第一次运行中,我想触发“a”,在第二次运行中触发“b”,依此类推。是的,你可以-你需要这样做。你可能会读到这一点,我的理解是,每个RoundRobinRouter都只针对特定的演员。例如:路由器1将用于50个“a”演员,路由器2将用于50个“b”演员,依此类推。我希望在一次运行中至少向所有“a”、“b”、“c”、“d”、“e”演员发送一条消息。但这并不是以确定的方式发生的。我有什么遗漏吗?allActors.foreach!《新战略武器条约》只向50名演员中的一名发送了一份mesasge——不是向所有演员发送,没有广播。A.Start只是将消息发送到instanc中的一个
a.actors.triggerator的es。我明白了。我不明白的是,为什么连《b》中的一个演员都没有在一次演出中被触发(例如)非常感谢,这是非常清楚的。我发现了真正的问题。问题在于参与者的基本逻辑。两个参与者中的case子句有一个“if条件”,它取决于数据库中另一个参与者更新的值。因此它是完全不确定的。作为一个附带问题,我是否可以在不同的演员之间进行循环?例如:在第一次运行中,我想触发“a”,在第二次运行中触发“b”,依此类推。是的,你可以-你需要这样做。你可以读到这篇文章