2015-04-16 2 views
1

Я использую AKKA Actors (версия 2.3.9) с использованием Scala API.Активатор запускается случайно

У меня есть группа гетерогенных актеров, которые нужно запускать каждые 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() 
+0

Не знаете, что именно вы ожидали, вы определили RoundRobinRouter, и это означает, что не все из них получают сообщение. – sap1ens

+0

Мое ожидание: за один проход я должен был бы отправить сообщение «Старт» всем актерам a, b, c, d, e. Не нужно быть всеми 50 а. По крайней мере, один «актер» будет в порядке. Проблема, которую я вижу, заключается в том, что «e» актер вообще не срабатывает, также, как правило, «b» не срабатывает вообще. Это совершенно случайно и трудно наблюдать образец. – user1189332

ответ

4

Вы создали 5 маршрутизаторов с 50 актерами каждый, так что 250 *.actors.TriggerActor «с. Если вы хотите отправить сообщение всем 250 в один проход, вы должны:

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

Он будет посылать 50 сообщений каждому маршрутизатору. Поскольку это крутой робот, первое сообщение пришло к маршрутизатору, которое пойдет к его первому актеру, второе - ко второму и так далее, пока 50-й актер не получит сообщение.

Только 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

+0

Я понимаю, что каждый из «RoundRobinRouter» предназначен только для этого конкретного актера. Например: Router 1 будет для 50 '' актеров, Router 2 будет для 50 'b' актеров и так далее. Я хотел бы надежно отправить по крайней мере одно сообщение всем участникам «a», «b», «c», «d», «e» за один проход. Но это не происходит детерминированным образом. Что-нибудь мне не хватает? – user1189332

+0

это правильно (я представил его с помощью «*») – dk14

+0

'allActors.foreach (_! New Start)' отправляет только в mesasge одному из 50 участников - не для всех из них, нет трансляции. 'a! Start' просто отправляет сообщение в один из экземпляров 'a.actors.TriggerActor' – dk14

Смежные вопросы