Search code examples
javascalaakkascala-2.11scala-2.12

how to get values from akka future onComplete callbacks 's Success and Failures blocks


i have a code in which i am checking if an actor does not exists already we will create it but the problem is my code is using future OnComplete call backs and i am doing this in an function/def and i just want to return the ActorRef here is my code

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
         }

and i am calling the code like this

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]

how can i get the actual ActorRef its giving me null but actor is creating and i tried to store the ref in both blocks by doing this

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

i think its returning the values before calling onComplete and returning null as i initialized the variable null in the start of the my function how can i fix this ? please help me how can i achieve my desired ActorRef


Solution

  • actorRef is a var that will get assigned not until sel.resolveOne() finishes, which could be before you are returning the value. If you really want to do what you are doing in that very way you can use

    import scala.concurrent._
    import scala.concurrent.duration._
    
    Await.result(f,Duration(6000,"millis"))
    

    Await result will block until the future delivers or 6 seconds pass.

    now, like others have stated this is not a good idea.

    since you seem to be creating that very actor you can access the children directly

    val child = child(name)
    child.getOrElse(getContext().actorOf(..., name))