简体   繁体   中英

how to know if an actor exists in an actor system or not

hi i want to create an actor in an actor system if its already not created here is my code

val sel = actorSystem.actorSelection("akka://ActorSystem/user/ReadOnlyAdminIndexMongoActor");
val asker = new AskableActorSelection(sel);

val future = asker.ask( Identify(1),Timeout(30 seconds))
val identity=Await.result(future, timeout.duration).asInstanceOf[ActorIdentity]         

val reference = identity.getRef
if(reference != null){
     log.info("actor does not exists")
   }
   else
   {
     log.info("actor exists"+sel.toString())
   }

but this code is throwing exception

17:00:19.547 1822010 [ArteciateActorSystem-akka.actor.default-dispatcher-7] EmptyLocalActorRef INFO - Message [scala.Tuple2] from Actor[akka://ActorSystem/temp/$e] to Actor[akka://ActorSystem/user/ReadOnlyAdminIndexMongoActor] was not delivered. [5] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.
java.util.concurrent.TimeoutException: Futures timed out after [30 seconds]
    at scala.concurrent.impl.Promise$DefaultPromise.ready(Promise.scala:219)
    at scala.concurrent.impl.Promise$DefaultPromise.result(Promise.scala:223)
    at scala.concurrent.Await$$anonfun$result$1.apply(package.scala:190)
    at scala.concurrent.BlockContext$DefaultBlockContext$.blockOn(BlockContext.scala:53)
    at scala.concurrent.Await$.result(package.scala:190)
    at models.Global$.checkActor(Global.scala:71)

this is the code on line 71

val identity=Await.result(future, timeout.duration).asInstanceOf[ActorIdentity]   

please help me where i am mistaken and also i am using this code from this Link and this Link the code givein in an accepted answer

Using Identify is the proper way to determine if an actor exists. Receiving an ask timeout is generally an indicator that it does not, since there was no actor there to respond. I say generally because message traffic load and/or remoting could result in a timeout for other reasons.

My question is, since you have a well known address, under what circumstances could this actor not exist? Do you just want to create it lazily on demand, or are you trying to recover from a crash of the the actor?

For both scenarios, I would suggest a proxy pattern, ie have a simple, crash-proof (due to its simplicity) actor live at the well known address, which is responsible for creating the ReadOnlyAdminIndexMongoActor on demand and proxying messages to it. This proxy would also be the supervisor, recovering the actor on crash. It even allows you to idle timeout the ReadOnlyAdminIndexMongoActor if it makes sense, since everyone will always talk to it via the proxy.

A simplistic implementation of this proxy (without supervisor or idle timeout handling) might look like:

class OnDemandProxyActor(proxyProps: Props) extends Actor {

  def receive = waiting()

  def waiting: Receive = {
    case msg =>
       val target = context.actorOf(proxyProps)
       target forward msg
       context.become(proxying(target))
  }

  def proxying(target: ActorRef): Receive = {
    case msg => target forward msg
  }
}

where proxyProps are the Props for creating your actor on demand, waiting is the initial state where no message has been received and hence the proxy target has not yet been created and proxying is the state after the target is created. Both states use forward to send the received message to the target as if it had come from the original sender .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM