2013-05-20 5 views
0

Après avoir suivi l'exemple de la documentation (2.1.4), j'avais des problèmes avec un message de traitement de l'acteur chargé de micronoyau, où la classe d'extension bootable est définie comme suit:instanciation dans AKKA Microkernel

class HelloKernel extends Bootable { 
    val system = ActorSystem("hellokernel") 
    def startup = { 
    system.actorOf(Props[HelloActor]) ! Start 
    } 
    def shutdown = { 
    system.shutdown() 
    } 
} 

Si un mannequin (c'est-à-dire non utilisé ailleurs dans le code) instance créée, comme indiqué ci-dessous, les messages sont ensuite traités comme prévu.

class HelloKernel extends Bootable { 
    val system = ActorSystem("hellokernel") 

    val dummyActor = system.actorOf(Props[HelloActor]) 

    def startup = { 
    system.actorOf(Props[HelloActor]) ! Start 
    } 
    def shutdown = { 
    system.shutdown() 
    } 
} 

Faut-il en effet une instanciation factice ou, en le faisant, que je causais un effet secondaire, ce qui dans les messages en cours de traitement?

Basé sur le code donné par Thomas Letschert dans Akka 2.1 minimal remote actor example J'ai transformé le côté serveur en un acteur hébergé Microkernel.

import akka.actor.Actor 
import akka.actor.ActorLogging 
import akka.actor.ActorSystem 
import akka.actor.Props 
import akka.kernel.Bootable 


class Joe extends Actor { 
    def receive = { 
    case msg: String => println("joe received " + msg + " from " + sender) 
    case _ => println("Received unknown msg ") 
    } 
} 

class GreetServerKernel extends Bootable { 
    val system = ActorSystem("GreetingSystem") 
    val joe = system.actorOf(Props[Joe], name = "joe") 
    println(joe.path) 
    joe ! "local msg!" 
    println("Server ready") 

    def startup = { 
    } 

    def shutdown = { 
    println("PrimeWorker: Shutting Down") 
    system.shutdown 
    } 

} 

Dans ce cas, l'instanciation factice, qui lorsque les messages supprimés ne sont pas traités, est

val joe = system.actorOf(Props[Joe], name = "joe") 

Le code de l'appelant est

import akka.actor._ 
import akka.actor.ActorDSL._ 

object GreetSender extends App { 
    implicit val system = ActorSystem("GreetingSystem") 
    val joe = system.actorFor("akka://[email protected]:2554/user/joe") 

    println(joe.path) 

    val a = actor(new Act { 
    whenStarting { joe ! "Hello Joe from remote" } 
    }) 

    joe ! "Hello" 

    println("Client has sent Hello to joe") 
} 
+0

Je ne pense pas que vous devriez avoir besoin d'une instanciation fictive. Quel type de problème existe-t-il avec le premier exemple? – cmbaxter

+0

Bien qu'il y ait une connexion réussie dans le premier exemple, indiquée par les messages d'erreur lorsque l'un des deux côtés est ensuite arrêté, aucun message n'est traité. Dès que l'instanciation est faite, sans autre changement dans le code ou les fichiers de configuration, les cas dans réception sont frappés et traités. –

+0

Pouvez-vous poster votre code 'HelloActor' s'il diffère de l'exemple microkernal? – cmbaxter

Répondre

1

Si le code affiché est en effet exact, puis déplacez simplement l'instance de l'instance joe dans l'opération startup au lieu de dans le constructeur de la classe de démarrage:

def startup = { 
    system.actorOf(Props[Joe], name = "joe") 
} 

L'acteur lié au nom joe doit avoir été démarré avant que quelqu'un puisse le chercher par nom et envoyer des messages. C'est fondamentalement la même chose que de le démarrer dans le constructeur de la classe bootable, mais je crois que cette convention impose de faire toutes les instantiations d'acteur dans la fonction startup par opposition au corps de la classe bootable (et donc le constructeur)

+0

Parfait. Cela fonctionne comme vous le décrivez. Merci pour votre temps. –