21

私は、actorSelection(Path) を使用してアクター システムからアクターを選択するアクターではない Java オブジェクトを持っています。選択したアクターがシステムに存在しない可能性があります。

Java API では、ActorSelection の ask() が存在しないため、アクターの選択にメッセージを送信して識別し、応答の送信者を使用することはできません。

とにかくアクターの選択を介してアクターにメッセージを送信し、デッドレターに反応することで問題を解決しようとしました。しかし、私はデッドレターを受け取りません。

アクターが生きているか存在しないかを 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);
4

5 に答える 5

13

AkkaActorSelectionask. 私はコードを少しいじって、うまくいくものを見つけました。このコードが機能するかどうかを確認してください。

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 経由でそれにフックするかを調べました。これは私にとってはうまくいきました。私はそれがあなたのために働くことを願っています.

于 2013-08-02T12:00:49.683 に答える
7

Akka は、特別なメッセージを使用してActorRefからを取得する機能を提供します。このメッセージに使用する必要はありません。単に識別メッセージを ActorSelection に渡し、返されるメッセージをリッスンします。Akka docs にまさにこれの例があります:アクター選択によるアクターの識別 (Java)ActorSelectionIdentifyask()ActorIdentity

このコードは例から取られ、変更されます:

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

ドキュメントには、ActorPath、ActorSelection、および Actor Lifecycle の関係を示す非常に優れたグラフィックもあります。

于 2013-08-02T11:20:06.257 に答える