как получить значения из блоков Success и Failure обратных вызовов akka future onComplete

у меня есть код, в котором я проверяю, не существует ли актер уже, мы создадим его, но проблема в том, что мой код использует будущие обратные вызовы OnComplete, и я делаю это в функции/def, и я просто хочу вернуть ActorRef вот мой код

def getRegularAdminIndexMongoActor():ActorRef= {
        var actorRef:ActorRef=null
    val sel = actorSystem.actorSelection("akka://ActorSystem/user/RegularAdminIndexMongoActor");
     val future:Future[ActorRef] = sel.resolveOne().mapTo[ActorRef] 
     future.onComplete { 
          case Success(result)=>  
          if(result != null){
            log.info("actor exists" + result)
          }
          actorRef=result
          actorRef
         case Failure(e)=>
           log.warn("in failure block actor does not exists" + e)
           val regularAdminIndexMongoActor=system.actorOf(Props[RegularAdminIndexMongoActor],name = "RegularAdminIndexMongoActor")
           log.info("created a new one "+regularAdminIndexMongoActor.path.toString())
           actorRef=regularAdminIndexMongoActor      
     }
log.info("whats is in actorRef " + actorRef)
     actorRef
         }

и я вызываю код следующим образом

log.info("getting ref"+getRegularAdminIndexMongoActor)

and the output is 
15:33:39.082 555049 [play-internal-execution-context-1] Global$ INFO - whats in actorRef null
15:33:39.082 555049 [play-internal-execution-context-1] Global$ INFO - getting ref null
15:33:39.083 555050 [play-internal-execution-context-1] play INFO - Application started (Dev)
15:33:39.151 555118 [ForkJoinPool-4-worker-7] Global$ INFO - actor exists Actor[akka://ActorSystem/user/RegularAdminIndexMongoActor#-1022921773]

как я могу получить фактический ActorRef, который дает мне ноль, но актер создает, и я попытался сохранить ссылку в обоих блоках, выполнив это

actorRef=result //success block
actorRef=regularAdminIndexMongoActor //failure block

я думаю, что он возвращает значения перед вызовом onComplete и возвращает null, поскольку я инициализировал переменную null в начале моей функции, как я могу это исправить? пожалуйста, помогите мне, как я могу достичь желаемого ActorRef


person swaheed    schedule 30.12.2015    source источник
comment
что-то вроде sel.resolveOne().mapTo[ActorRef].recover{case t => system.actorOf(Props[RegularAdminIndexMongoActor],name = "RegularAdminIndexMongoActor")} даст вам Future[ActorRef]. Если вам нужно ActorRef - используйте блокировку Await.result(f, timeout)   -  person dk14    schedule 30.12.2015
comment
использование vars - совершенно плохая идея, так как ваш onSuccess/onFailure вызывается в другом потоке и может вызываться после возврата getRegularAdminIndexMongoActor   -  person dk14    schedule 30.12.2015


Ответы (1)


actRef — это переменная, которая будет назначена только после завершения sel.resolveOne(), что может произойти до того, как вы вернете значение. Если вы действительно хотите делать то, что делаете именно таким образом, вы можете использовать

import scala.concurrent._
import scala.concurrent.duration._

Await.result(f,Duration(6000,"millis"))

Ожидание результата будет заблокировано до тех пор, пока не будет получено будущее или не пройдет 6 секунд.

теперь, как и другие заявили, что это не очень хорошая идея.

поскольку вы, кажется, создаете того самого актера, вы можете напрямую обращаться к детям

val child = child(name)
child.getOrElse(getContext().actorOf(..., name))
person Luis Ramirez-Monterosa    schedule 04.01.2016