执行依赖于其他任务的CompletableFuture

时间:2017-11-21 10:25:09

标签: java asynchronous playframework completable-future

我写了一个Play框架Web应用程序,我有以下问题。我有一些访问数据库的DAO,有时一个对数据库的请求依赖于来自另一个请求的信息。

以下是其中一个问题:我以异步方式执行getLicenseByKey方法并获取结果。现在,我可以使用version_dao.getVersionUntilX()请求的结果执行license_dao。这里的问题是.get()的{​​{1}}函数在CompletableFuture上执行(阻塞Akka的一个HTTP线程(Play框架)),如果这个数据库请求需要很长时间时间,线程被阻止。

那么如何异步执行HttpExecutionContext然后,使用此方法的结果,异步执行license_dao.getLicenseByKey()方法?如果两者都完成了,我想从Play的version_dao.getVersionUntilX()返回HTTP结果。

HttpExecutionContext

1 个答案:

答案 0 :(得分:0)

使用thenComposeAsync()代替thenApplyAsync(),让内部lambda也返回CompletableFuture

public CompletionStage<Result> showDownloadScreen(String license_key) {
    return license_dao.getLicenseByKey(license_key).thenComposeAsync(license -> {
        try {
            if(license!=null) {
                if(license.isRegistered()) {
                    return version_dao.getVersionUntilX(license.getUpdates_until())
                        .toCompletableFuture()
                        .thenApply(v -> ok(views.html.download.render(license, v)));
                } else {
                    return CompletableFuture.completedFuture(redirect(routes.LicenseActivationController.showActivationScreen(license_key)));
                }
            } else {
                return CompletableFuture.completedFuture(redirect(routes.IndexController.index("Insert Key can not be found!")));
            }
        } catch (InterruptedException | ExecutionException e) {
            return CompletableFuture.completedFuture(redirect(routes.IndexController.index("Error while checking the Verison")));
        }
    }, httpExecutionContext.current());
}

由于lambda非常复杂,因此将其提取到单独的方法也值得进行更多清理。