1
我有一場重要的角色需要撥打電話一個緩慢的一個場景(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;
}
的阿卡相當於這是目前看起來像:
// 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)
}
}
顯然,這是阻止壞,壞,壞的。閱讀this excellent article on handling non-blocking DB calls後,我的主要外賣的是,有兩個基本「艙壁」戰略,我可以使用:
- 將所有
SlowServiceActor
情況下,在自己的調度員,從其他演員隔離的延遲/阻塞岬/不直接與慢服務交互的線程;和 - 通過
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
? - 最後:我錯過了什麼嗎?我沒有使用/利用我應該的任何策略?
我不特別理解akka,但對於基於一般事件的系統,不應該有一個不同的處理程序來處理來自緩慢服務的結果? –
Thanks @RajatGarg(+1) - * yes *,但該處理程序將需要一種方法,不僅可以調用回執行者系統,還可以執行該特定執行上下文中的特定執行者。在不知道Akka的情況下,您很難理解爲什麼這會使典型的回調/處理器解決方案不可行。 – smeeb