2013-04-28 11 views
6

Perché quando seleziono un percorso assoluto con ActorContext non funziona (l'attore non è selezionato correttamente e non riceve il messaggio HelloResponse)?Selezione attore

//From Actor2: 
//This doesn't work (Message never received) 
context.actorSelection("/user/actor1") ! HelloResponse("hello back1") 
//This works (actor 1 receives the message) 
context.system.actorSelection("/user/actor1") ! HelloResponse("hello back2") 

Sono novizio di Scala/Akka ma reading documentation sembra che dovrebbe funzionare.

+0

Si prega di fornire le seguenti: 1) le versioni Scala/Akka 2) Il codice che mostra come 'actor1' è creato 3) Che cosa si intende per "non lo fa lavoro"? Compila? Genera un'eccezione in fase di runtime? 'Actor1' non riceve il messaggio' HelloResponse ("ciao back1") '? Cosa dice il messaggio di errore? – agilesteel

+0

Ho aggiunto una spiegazione su cosa non funziona, grazie per l'interesse. – lujop

risposta

2

Quando si utilizza context.actorSelection all'interno di un attore, ciò che si sta dicendo è trovare un attore sotto il controllo dell'attore corrente (avviato da/supervisionato da). Poiché l'attore1 probabilmente non è stato avviato da actor2 (o non è supervisionato da actor2), non si risolverà in nulla. Se l'attore1 fosse effettivamente posseduto/iniziato da actor2, probabilmente potresti fare context.actorSelection("/actor1") per ottenere quell'attore bambino dell'attore2. Il motivo context.system.actorSelection funziona perché prima di iniziare la ricerca e qualificare completamente il percorso per l'attore, devi andare "su" fino a system. Il sistema "possiede" actor1 se lo avvii come system.actorOf, quindi l'utilizzo di quel percorso ti consentirà di raggiungerlo a partire da system.

Un po 'di codice per mostrare cosa intendo:

class Actor1 extends Actor{ 
    override def preStart = { 
    context.actorOf(Props[Actor2], "actor2") 
    } 
    def receive = { 
    case _ => 
    } 
} 

class Actor2 extends Actor{ 
    override def preStart = {println("my path is: " + context.self.path)} 
    def receive = { 
    case _ => 
    } 
} 

object FutureTesting { 
    def main(args: Array[String]) { 
    val sys = ActorSystem("test") 
    implicit val ec = sys.dispatcher 

    //Starting an Actor2 from system 
    sys.actorOf(Props[Actor2], "actor2") 

    //Starting an Actor1 from system which in turn starts an Actor2 
    sys.actorOf(Props[Actor1], "actor1") 
    } 
} 

Quando si esegue questo esempio, si vedrà:

my path is: akka://test/user/actor1/actor2 
my path is: akka://test/user/actor2 

Così si può vedere che ho 2 istanze di Actor2 esecuzione in il mio sistema; uno generato direttamente da sys legato a /user/actor2 come percorso di ricerca e uno avviato da un'istanza di Actor1 legata a /user/actor1/actor2 per il suo percorso.

Il sistema di attori è gerarchico e questo esempio lo mostra. Lo stesso ActorSystem è la radice di tutto. La selezione di attori è quindi simile a XPath in quanto il contesto in cui si sta eseguendo la selezione è importante.

1

Da actor2 dovrai utilizzare

context.actorSelection("/actor1") 

Sono d'accordo che non è intuitivo dato la metafora è un filesystem e quando si utilizza un file system leader / è un percorso assoluto che significa inizio alla radice. Inoltre è in contrasto con actorFor perché

context.actorFor("/user/actor1") 

restituisce il livello superiore Actor1 (vedi Absolute and Relative Paths)

EDIT - questo è stato un bug che è stato fissato in Akka 2.1.4 (vedi risposta di Roland). Dal 2.1.4 in poi è possibile utilizzare context.actorSelection("/user/actor1").

+0

Il primo snippet: context.actorSelection ("/ actor1") non funzionerà neanche. Se esiste la barra diretta, ActorSelection si risolverà a partire dal tutore della radice come menzionato da Roland. – neowulf33

+0

Stava funzionando ma era un bug e da allora è stato corretto. – sourcedelica

+0

Appena testato con Akka 2.3-M2 e context.actorSelection ("/ actor1") non funziona. ActorSelection inizierà la risoluzione sul root guardian. – neowulf33

Problemi correlati