2014-12-05 47 views
2

我已經在使用Java的Akka框架中實現了一個應用程序。我有一個主角通過使用'Ask'方法並在60秒後超時來調用子角色,一旦從主角接收消息,工作人員調用另一個Java類方法。Subactor(worker)仍然在Java Akka的主演員超時之後工作

現在的問題是,雖然我的主演員在60秒後超時,但工作人員仍然可以與java類方法進行交談,然後該方法執行的操作不是必需的,因爲主要參與者無法接收由於超時而由子角色返回的響應。

是否有反正我可以殺死工人或阻止它進一步處理,如果我的主要演員超時? 我檢查了RecieveTimeOut()context.stop()和poisonpill等方法,但仍然沒有用。

感謝您的支持

下面的代碼

public class MainActor extends UntypedActor { 

    ActorRef subActorRef; 

    final Timeout timeout = new Timeout(Duration.create(60, TimeUnit.SECONDS)); 

    @Override 
    public void preStart() { 
     subActorRef = getContext().actorOf(
      SpringExtProvider.get(actorSystem).props(
       "SubActor"), "subActor"); 
    } 

    @Override 
    public void onReceive(Object message) throws Exception { 

     if (message instanceof BusinessRequestVO) { 
      BusinessRequestVO requestVo = (BusinessRequestVO) message; 
      ArrayList<Future<Object>> responseFutures = new ArrayList<Future<Object>>(); 

      // This part of code timeout after 60seconds 
      responseFutures.add(ask(subActorRef,requestVo, timeout)); 
     } 
    } 
} 

SubActor類

public class SubActor extends UntypedActor { 

    @Resource 
    @Inject 
    ServiceAdapter serviceAdapter; 

    @Override 
    public void onReceive(Object message) throws Exception { 
     try{ 
      if (message instanceof BusinessRequestVO) { 
       BusinessRequestVO requestVo = (BusinessRequestVO)message 

       // There is no time out here so it waits synchronously 
       // though Main actor timeouts 
       ServiceResponse response = serviceAdapter.getWorkOrder(requestVo); 

       getSender().tell(response, ActorRef.noSender()); 
      } catch (Exception e) { 
       getSender().tell(new akka.actor.Status.Failure(e), getSelf()); 
       throw e; 
      } 
     } 
    } 
} 

適配器類別

public class ServiceAdapterImpl implements ServiceAdapter{ 
    public ServiceResponse getWorkOrder(BusinessRequestVO request){ 
     // Some code here along with webservice calls 
    } 
} 
+0

發佈您的代碼。 – Ryan 2014-12-05 23:35:00

+0

'..從進一步處理..停頓',你的意思是你想中斷'.getWorkOrder()'呼叫在飛行中? – tariksbl 2014-12-07 14:59:01

+0

是的我想打斷.getWorkOrder(),如果家長演員超時 – 2014-12-08 05:51:58

回答

0

你不能爲你的孩子演員阻塞,從而canno t處理父母發送給他的任何「停止」消息(參與者在閱讀郵箱中的下一個消息之前一次處理一個消息)。

最好的辦法是將孩子執行的「緩慢」部分包裹在未來,你可以管到父母(詳見here)。

通過這種方式,如果您的超時過期,您可以讓父母發送自定義的「停止計算」消息,並且子角色可以終止未來。關於如何終止未來,見here

但是,這可能會在應用程序邏輯中根據執行中途終止的特定計算引入「髒」狀態。

在相關說明:你爲什麼要發送所有n請求到同一個孩子演員(你做了阻止)?這相當於順序執行。你應該讓孩子的演員非阻塞,或者(更好地)爲每個請求創建一個阻止角色。

編輯:根據OP的要求,添加片段。這是一個僞代碼混合Scala和Java的,因爲我不是超級高手Java語法期貨,我主要是在Scala中使用它,所以請適應了一點:

if (message instanceof BusinessRequestVO) { 
    new Future (
    BusinessRequestVO requestVo = (BusinessRequestVO)message 
    try { 
     ServiceResponse response = serviceAdapter.getWorkOrder(requestVo); 
     getSender().tell(response, ActorRef.noSender()); 
    } 
    catch (Exception e) { 
     getSender().tell(new akka.actor.Status.Failure(e), getSelf()); 
     throw e; 
    } 
) pipeTo sender 
} 

而且在main(見here爲java的future.cancel)

if (timeout) future.cancel(true) 
+0

感謝您的答覆,但我已經在主actor的哪個超時使用未來,但在subactor中沒有辦法超時subactor在subactor I我正在調用其他類的正常的java函數。 1。我可以使用future來調用普通的java類操作,或者這隻適用於AKKA actors/subactors ask/tell? 2.我們有未來在java併發性這個未來類似於AKKA有什麼? 請給我提供以下代碼超時的代碼片段 ServiceResponse response = serviceAdapter.getWorkOrder(requestVo); – 2014-12-08 05:59:31

+0

期貨不是來自Akka,它們是Java/Scala的東西。你可以在將來包裝很多東西,而不僅僅是問道。但有了您的要求,您可以輕鬆地將未來發送給發件人。 Akka未來是java/scala期貨。 – 2014-12-09 08:21:23