2017-11-21 11 views
0

私はPlayフレームワークWebアプリケーションを作成しましたが、次の問題があります。私はデータベースにアクセスするいくつかのDAOを持っており、データベースへの1つの要求は、別の要求からの情報に依存していることがあります。他のタスクに依存するCompletableFutureを実行

これは問題の1つです。私はgetLicenseByKeyメソッドを非同期で実行し、その結果を取得します。今度はversion_dao.getVersionUntilX()license_daoリクエストの結果で実行できます。ここで問題となるのは、という機能がHttpExecutionContext(Playフレームワーク)のHTTPスレッドの1つをブロックして実行され、このデータベース要求に時間がかかるとスレッドがブロックされるという問題です。

したがって、license_dao.getLicenseByKey()を非同期で実行し、この方法でversion_dao.getVersionUntilX()メソッドを非同期に実行するとどうなりますか?両方が終了した場合は、PlayのHttpExecutionContextからHTTPの結果を返したいとします。

public CompletionStage<Result> showDownloadScreen(String license_key) { 
    return license_dao.getLicenseByKey(license_key).thenApplyAsync(license -> { 
     try { 
      if(license!=null) { 

       if(license.isRegistered()) { 
        return ok(views.html.download.render(license, 
         version_dao.getVersionUntilX(license.getUpdates_until()) 
         .toCompletableFuture().get())); 
       }else { 
        return redirect(routes.LicenseActivationController.showActivationScreen(license_key)); 
       } 
      }else { 
       return redirect(routes.IndexController.index("Insert Key can not be found!")); 
      } 
     } catch (InterruptedException | ExecutionException e) { 
      return redirect(routes.IndexController.index("Error while checking the Verison")); 
     } 
    }, httpExecutionContext.current()); 
} 

答えて

0

利用代わりthenApplyAsync()thenComposeAsync()、そしてあなたの内側のラムダも返してい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()); 
} 

そのラムダが非常に複雑であるので、それはまた、別の方法にそれを抽出する価値があるだろうともう少しクリーンアップしてください。

関連する問題