簡體   English   中英

我怎樣才能檢查Akka演員是否存在(akka 2.2)?

[英]How can i check if an Akka actor exists (akka 2.2)?

我有一個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);

我最近發現了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
}

我正在研究的一個問題是,定義它的方法可能同時被調用(來自其他actor)。 因此,如果由於仍在創建actor而使resolveOne調用失敗,則可能會遇到競爭條件,其中您嘗試創建兩次actor。 這可能是也可能不是您的用例的問題

它看起來像阿卡不放過支持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);
  }
}

我只是看看scala如何通過java來支持支持工作並將其掛鈎。 這對我有用; 我希望它適合你。

Akka提供了使用特殊消息IdentifyActorSelection獲取ActorRef的功能。 您不必對此消息使用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
            }
        }
     }
}

還有一個非常漂亮的圖形 ,顯示了Actor中的ActorPath,ActorSelection和Actor Lifecycle之間的關系。

正如其他答案所述, ActorSelection.resolveOne()處理此問題。

一個警告:在引擎蓋下,這是通過向相關演員發送消息來實現的。 這意味着如果該actor忙,它將不會回復,並且失敗(超時)。

在純粹的最佳實踐 - 阿卡,這可能是一個角落案例。 在一個更混合的普通Java / Akka設置中,它很容易被咆哮。 特別是,actor的線程中的代碼找不到對該actor的引用。

使用版本2.3.4

一些Scala的例子,也許可以提供幫助

  val zed2 = Akka.system().actorSelection("path")
  val fs:FiniteDuration = (100).millis

  val x = zed2.resolveOne(fs).value
  if (x.isDefined){
    println(x.get.isFailure)
  }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM