繁体   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