2014-10-24 3 views
8

Ich versuche einen Akteur auszuwählen, der bereits erstellt wurde. Hier ist ein Code:Wie Akka Schauspieler mit actorSelection auswählen?

val myActor = system.actorOf(Props(classOf[MyActor]), "myActorName") 
println("myActor path - " + akka.serialization.Serialization.serializedActorPath(myActor)) 
println("Selection from spec akka://unit-test/user/myActorName " + system.actorSelection("akka://unit-test/user/myActorName").resolveOne().value) 
println("Selection from spec /user/myActorName/ " + system.actorSelection("/user/myActorName/").resolveOne().value) 

Das Ergebnis ist:

myActor path - akka.tcp://[email protected]:46635/user/myActorName#1444872428 
Selection from spec akka://unit-test/user/myActorName None 
Selection from spec /user/myActorName/ None 

Auch ich eine Nachricht an Schauspieler passieren kann und es vervollständigt gut. Was habe ich bei actorSelection verpasst? Wie wählt man den Schauspieler richtig aus?

AKTUALISIERT

Es ist sehr seltsam, aber wenn ich system.actorSelection("/user/myActorName/").resolveOne().value mit system.actorFor("/user/myActorName/") alles funktioniert ersetzen. Ich meine actorFor gibt einen Schauspieler zurück. (Was ist keine richtige Lösung wegen actorFor ist veraltet)

Antwort

10

Bitte seien Sie vorsichtig mit Futures. In Ihrem Fall sind Sie empfangen Zukunft, die in dem anrufenden Moment wird nicht abgeschlossen ist, kann - so kann sein Wert leer sein:

scala> println("Selection from spec /user/myActorName/ " + system.actorSelection("/user/myActorName/").resolveOne().value) 
Selection from spec /user/myActorName/ None 

vs

scala> val fut = system.actorSelection("/user/myActorName/").resolveOne() 
fut: scala.concurrent.Future[akka.actor.ActorRef] = [email protected] 

<just wait some time here> 

scala> fut.value 
res21: Option[scala.util.Try[akka.actor.ActorRef]] = Some(Success(Actor[akka://default/user/myActorName#1625966960])) 

Wert zu erhalten, richtig verwenden onComplete oder einfach nur for- comprehesion:

import scala.concurrent.ExecutionContext.Implicits.global 

for (res <- system.actorSelection("/user/myActorName").resolveOne()) { 
    println(res) 
} 

beachten sie, dass onComplete/für so Zuhörer umgesetzt werden, so dass sie vielleicht in anderen Thread ausgeführt werden. Wenn Sie das Ergebnis im aktuellen Thread benötigen - verwenden Sie den klassischen Await.result.

+0

Sehr überraschend :) Ich dachte, dass "implizite Timeout" in "resolveOne" verwendet wird, um zu warten und das Ergebnis zu liefern. – Cherry

+0

Nein :). Scaladoc: "Es wird mit dem Fehler ActorNotFound abgeschlossen, wenn kein solcher Akteur existiert oder die Identifikation nicht innerhalb des angegebenen Timeouts abgeschlossen wurde." – dk14

+0

So Timeout wird nur verwendet, um die Zukunft zu vervollständigen oder fehlzuschlagen, aber Sie müssen diesen zukünftigen klassischen Weg noch verarbeiten – dk14