簡體   English   中英

Akka演員的防空策略

[英]Bulkheading strategies for Akka actors

我遇到了一個重要角色需要向慢速(15-20 )遠程系統進行呼叫的情況:

// Non-actor code equivalent
public Result makeSlowNetworkCall(Request request) {
    Result result = slowServiceClient.soooooSlow(request);      // Could be up to 15 - 20 SECONDS (mehhhh)
    return result;
}

與此等效的Akka 當前看起來像:

// Groovy
class SlowServiceActor extends UntypedActor {
    @Override
    void onReceive(Object message) {
        if(message instanceof CallSlowService) {
            Request request = (message as CallSlowService).request
            Result result = makeSlowNetworkCall(request)
            // ...now do something with result, some 15 seconds later
        }
    }

    Result makeSlowNetworkCall(Request request) {
        slowServiceClient.soooooSlow(request)
    }
}

顯然,這是障礙,壞,壞,壞。 在閱讀了有關處理非阻塞數據庫調用的出色文章之后,我的主要收獲是,我可以采用兩種基本的“ 隔離 ”策略:

  • 將所有SlowServiceActor實例放置在自己的調度程序中,以將其延遲/阻塞程度與未與Slow Service直接交互的其他actor /線程隔離開;
  • 通過Futures調用慢速服務以實現真正的“ 異步性

因此,到目前為止,我最大的嘗試是:

// In application.conf:
slowServiceDispatcher {
    ...config here
}

class CallSlowService implements Callable<Result> {
    @Override
    Result call() throws Exception {
        slowServiceClient.soooooSlow(request)
    }
}

// Created using the "slowServiceDispatcher"
class SlowServiceActor extends UntypedActor {
    @Override
    void onReceive(Object message) {
        if(message instanceof CallSlowService) {
            Request request = (message as CallSlowService).request
            Future<Result> callSlowServiceFuture = Futures.future(new CallSlowService())

            Result result = ???

            // ...now do something with result, some 15 seconds later
        }
    }
}

但是如您所見,我有一些問題:

  • 我認為我誤解了Futures.future(...) API; 我認為這不是為了構建新的Futures
  • 我實際上如何以非阻塞方式獲取result
  • 最后:我在這里錯過了什么嗎? 我沒有利用/利用的任何策略?

如果我正確地理解了這一點,那么您在這里有兩種選擇:聆聽Future的完成,或者對結果做一些事情:

如果您想聽,可以使用一些回調,例如

final ExecutionContext ec = system.dispatcher();

future.onSuccess(new OnSuccess<String>() {
  public void onSuccess(String result) {
    if ("bar" == result) {
      //Do something if it resulted in "bar"
    } else {
      //Do something if it was some other String
    }
  }
}, ec);

另一種方法是map未來的結果。 所以你有類似的東西:

callSlowServiceFuture.map(new Mapper<ReturnType1, ReturnType2>() {
  public ReturnType2 apply(ReturnType1 s) {
    // do something with 's'
  }
}, ec);

這樣一來,您說“ ...當我從服務電話獲得結果時,請按照Apply ...中所述操作它。”

暫無
暫無

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

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