如何知道演员系统中是否存在演员

时间:2015-12-29 12:16:51

标签: java scala akka actor

嗨我想在演员系统中创建一个演员,如果它已经没有在这里创建我的代码

function time_since ( date ) {

    var seconds = Math.floor(( new Date() - date ) / 1000 );

    var interval = Math.floor( seconds / 31536000 );

    if ( interval == 1 ) {

        return interval + " year ago";
    }
    if ( interval > 1 ) {

        return interval + " years ago";
    }

    interval = Math.floor( seconds / 2592000 );
    if ( interval == 1 ) {

        return interval + " month ago";
    }
    if ( interval > 1 ) {

        return interval + " months ago";
    }

    interval = Math.floor( seconds / 86400 );
    if ( interval == 1 ) {

        return interval + " day ago";
    }
    if ( interval > 1 ) {

        return interval + " days ago";
    }

    interval = Math.floor( seconds / 3600 );
    if ( interval == 1 ) {

        return interval + " hour ago";
    }
    if ( interval > 1 ) {

        return interval + " hours ago";
    }

    interval = Math.floor( seconds / 60 );
    if ( interval < 2 ) {

        return interval + " min ago";
    } else {

        return interval + " mins ago";
    }

    return Math.floor(seconds) + " seconds ago";
}

但此代码抛出异常

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())
   }

这是第71行的代码

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)

请在我误解的地方帮助我,并且我正在使用此Link和此Link the code givein in an accepted answer

中的代码

1 个答案:

答案 0 :(得分:1)

使用Identify是确定演员是否存在的正确方法。接收请求超时通常指示它没有,因为没有演员在那里做出响应。我说通常是,因为消息流量加载和/或远程处理可能会因其他原因导致超时。

我的问题是,既然你有一个众所周知的地址,在什么情况下这个演员不存在?你只是想根据需要懒洋洋地创建它,还是试图从演员的崩溃中恢复过来?

对于这两种情况,我建议使用一种代理模式,即在一个众所周知的地址上有一个简单的,防崩溃的(由于其简单性)演员,它负责根据需要创建ReadOnlyAdminIndexMongoActor和代理消息给它。这个代理也将是主管,在崩溃时恢复演员。如果它有意义,它甚至允许你将ReadOnlyAdminIndexMongoActor空闲超时,因为每个人都会通过代理与它通话。

此代理的简单实现(没有管理程序或空闲超时处理)可能如下所示:

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
  }
}

其中proxyProps是用于按需创建演员的Propswaiting是初始状态,其中未收到任何消息,因此代理target尚未已创建,proxying是创建target后的状态。这两个州都使用forward将收到的邮件发送到target,就像它来自原始sender一样。