2014-10-24 10 views
8

Sto provando a selezionare un attore che ha già creato. Ecco un codice:Come selezionare l'attore Akka con actorSelection?

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) 

Il risultato è:

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 

Inoltre posso passare un messaggio con l'attore e completa bene. Cosa mi è mancato durante actorSelection? Come selezionare correttamente l'attore?

AGGIORNATO

E 'molto strano, ma quando sostituisco system.actorSelection("/user/myActorName/").resolveOne().value con system.actorFor("/user/myActorName/") tutto funziona. Intendo dire che actorFor restituisce un attore. (Che non è una soluzione giusta a causa di actorFor è deprecato)

risposta

10

Per favore, state attenti con i futures. Nel tuo caso si sta ricevendo futura, che potrebbe non essere completato al momento di chiamata - per cui il suo valore può essere vuoto:

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])) 

Per ottenere il valore utilizzare onComplete o semplicemente per- correttamente comprehesion:

import scala.concurrent.ExecutionContext.Implicits.global 

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

Tenete a mente che onComplete/a sono implementate come ascoltatori, in modo che possa essere eseguito in thread diverso. Se hai bisogno del risultato nel thread corrente, utilizza il classico Await.result.

+0

Molto sorprendente :) Ho pensato che "timeout implicito" in 'resolveOne' è usato per aspettare e fornire il risultato. – Cherry

+0

No :). Scaladoc: "Si completa con fallimento ActorNotFound se nessun attore di questo tipo esiste o l'identificazione non è stata completata entro il timeout fornito" – dk14

+0

Quindi timeout appena utilizzato per completare o fallire il reso futuro, ma è comunque necessario elaborare questo modo classico futuro – dk14