我写了一个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
答案 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非常复杂,因此将其提取到单独的方法也值得进行更多清理。