2017-11-21 2 views
0

Play 프레임 워크 웹 응용 프로그램을 작성했으며 다음과 같은 문제가 있습니다. 데이터베이스에 액세스하는 일부 DAO가 있고 때로는 데이터베이스에 대한 하나의 요청이 다른 요청의 정보에 의존합니다.다른 작업에 의존하는 CompletableFuture 실행

다음은 문제 중 하나입니다. getLicenseByKey 메서드를 비동기 방식으로 실행하고 결과를 얻습니다. 이제 version_dao.getVersionUntilX()을 실행하여 license_dao 요청의 결과를 얻을 수 있습니다. 여기서 문제는 CompletableFuture의 기능은 HttpExecutionContext (실행 프레임 워크)의 HTTP 스레드 중 하나를 차단하고이 데이터베이스 요청에 시간이 오래 걸리면 해당 스레드가 차단된다는 것입니다.

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()); 
} 

그 람다는 매우 복잡하기 때문에, 또한, 별도의 방법으로 추출하는 가치가있을 것입니다 및 좀 더 정리해라.

관련 문제