我怎样才能检查Akka演员是否存在(akka 2.2)?

sch*_*ums 21 java actor akka

我有一个java对象,它不是一个使用actorSelection(Path)从actor系统中选择actor的actor.系统中可能存在所选的actor.

在Java Api中,ActorSelection不存在ask(),因此我无法向actor选择发送和识别消息并使用响应的发送者.

我试图通过演员选择向演员发送消息然后对deadletter做出反应来解决问题.但我没有任何动静.

如果演员是活着还是不存在,我如何检查ActorSelection?

ActorSystem system = ActorSystem.create("test");

//create test actor
system.actorOf(Props.create(TestActor.class), "testActor");

//add dead letter listener to the system
ActorRef eventBusActor = asys.actorOf(Props.create(EventBusActor.class), "eventbusactor");
system.eventStream().subscribe(eventBusActor, DeadLetter.class);


//This works. The test actor receives the message      
ActorSelection a1 = asys.actorSelection("/user/testActor");
a1.tell("hello", ActorRef.noSender());

//This does not work and does not send dead letters      
ActorSelection a2 = asys.actorSelection("/user/doesnotexist");
a2.tell("hello", ActorRef.noSender());

//Does not compile, because ask needs an ActorRef as first argument
ActorSelection a3 = asys.actorSelection("/user/test");
Future f = Patterns.ask(a3, new Identify(), 1000);
Run Code Online (Sandbox Code Playgroud)

Mar*_*mou 25

我最近发现了ActorSelection.resolveOne方法:

val name = "myActor"
implicit val timeout = 5000 // Timeout for the resolveOne call
system.actorSelection(name).resolveOne().onComplete {
  case Success(actor) => actor ! message

  case Failure(ex) =>
    val actor = system.actorOf(Props(classOf[ActorClass]), name)
    actor ! message
}
Run Code Online (Sandbox Code Playgroud)

我正在研究的一个问题是,定义它的方法可能同时被调用(来自其他actor).因此,如果由于仍在创建actor而使resolveOne调用失败,则可能会遇到竞争条件,其中您尝试创建两次actor.这可能是也可能不是您的用例的问题


cmb*_*ter 13

看起来Akka没有停止ActorSelection对java api的支持ask.我玩了一些代码,但我发现了一些有用的东西.看看这段代码是否适合你:

import java.util.concurrent.TimeUnit;

import scala.concurrent.Await;
import scala.concurrent.Future;

import akka.actor.ActorIdentity;
import akka.actor.ActorRef;
import akka.actor.ActorSelection;
import akka.actor.ActorSystem;
import akka.actor.Identify;
import akka.actor.Props;
import akka.pattern.AskableActorSelection;
import akka.util.Timeout;

public class AskTest {

  public static void main(String[] args) throws Exception{
    ActorSystem sys = ActorSystem.apply("test");
    sys.actorOf(Props.create(TestActor.class), "mytest");

    ActorSelection sel = sys.actorSelection("/user/mytest");

    Timeout t = new Timeout(5, TimeUnit.SECONDS);
    AskableActorSelection asker = new AskableActorSelection(sel);
    Future<Object> fut = asker.ask(new Identify(1), t);
    ActorIdentity ident = (ActorIdentity)Await.result(fut, t.duration());
    ActorRef ref = ident.getRef();
    System.out.println(ref == null);
  }
}
Run Code Online (Sandbox Code Playgroud)

我只是看看scala如何通过java来支持支持工作并将其挂钩.这对我有用; 我希望它适合你.


Bjö*_*obs 6

阿卡提供了一个功能来得到一个ActorRefActorSelection使用一个特殊的消息Identify.您不必使用ask()此消息.只需将Identify-message传递给ActorSelection,然后侦听ActorIdentity将传递给您的消息.在Akka文档中有一个这样的例子:通过Actor选择识别Actor(Java)

此代码取自示例并已修改:

final String identifyId = "1";

@Override
public void onReceive(Object message) {
    if (message instanceof ActorIdentity) {
        ActorIdentity identity = (ActorIdentity) message; 
        if (identity.correlationId().equals(identifyId)) {
            ActorRef ref = identity.getRef();
            if (ref == null)
                // Actor does not exist
            else {
                // Actor does exist
            }
        }
     }
}
Run Code Online (Sandbox Code Playgroud)

还有一个非常漂亮的图形,显示了Actor中的ActorPath,ActorSelection和Actor Lifecycle之间的关系.