如何检查Akka演员是否存在(akka 2.2)?

2022-09-02 02:46:50

我有一个java对象,它不是一个actor,它使用actorSelection(Path)从actor系统中选择actor。有可能,选定的参与者不存在于系统中。

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

我试图通过演员选择将消息发送给演员,然后对死信做出反应来解决这个问题。但是我没有得到任何死信。

如何使用 ActorSelection 检查 Actor 是否处于活动状态或不存在?

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);

答案 1

我最近发现了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
}

我仍在调查的一个问题是,定义此方法的方法可以并发调用(从其他参与者那里)。因此,如果 resolveOne 调用失败,则可能会获得一个争用条件,在该条件中,如果由于仍在创建执行组件而失败,则尝试创建执行组件两次。对于您的使用案例来说,这可能是也可能不是问题


答案 2

看起来 Akka 在 java api 上没有支持 。我稍微玩了一下代码,我发现了一些有效的东西。查看此代码是否适合您:ActorSelectionask

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

我只是研究了scala ask支持是如何工作的,并通过java连接到它。这对我有用;我希望它对你有用。


推荐