2017-07-06 4 views
1

ここは私のコントローラです。私はそれが働いているかどうかテストするために郵便配達員を使いましたが、私は空の応答を得ています。私はアプリケーション構成で@EnableAsync、サービスでは@Asyncを使用しました。サービスレイヤで@Asyncを削除すると動作しますが、非同期には実行されません。@AsyncでCompletableFutureを使用すると、スプリングブートAPIの空の応答が返されます。

@ApiOperation(value = "search person by passing search criteria event/title/role/host/is_current", response = ElasticSearchResultData.class) 
@RequestMapping(value = "/async2/searchPerson", produces = "application/json", method = RequestMethod.POST) 
public @ResponseBody CompletableFuture<ElasticSearchResultData> searchPersonAsync2(@RequestBody SearchCriteriaTo criteriaForDivNetFolderTo, 
     HttpServletRequest request, HttpServletResponse response){ 
    LOGGER.info("searchPerson controller start"); 
    SearchCriteria searchCriteria = criteriaForDivNetFolderTo.getSearchCriteria(); 
    if (Util.isNull(searchCriteria)) 
     throw new IllegalArgumentException("search criteria should not be null."); 

    try { 
     CompletableFuture<ElasticSearchResultData> searchPerson = cubService.searchPersonAsync2(criteriaForDivNetFolderTo); 
     ObjectMapper mapper = new ObjectMapper(); 
     LOGGER.info("search Person "+mapper.writeValueAsString(searchPerson)); 
     return searchPerson; 
    } catch (Exception e) { 
     LOGGER.error("Exception in searchPersonAsync controller "+e.getMessage()); 
    } 
    return null; 
} 

サービス

@Async 
@Override 
public CompletableFuture<ElasticSearchResultData> searchPersonAsync2(SearchCriteriaTo searchCriteriaForDivNetFolderTo) { 
    Long start = System.currentTimeMillis(); 
    LOGGER.info(":in searchPerson"); 
    CompletableFuture<ElasticSearchResultData> completableFuture = new CompletableFuture<>(); 
    ElasticSearchResultData searchResultData = null; 
    SearchCriteria searchCriteria = searchCriteriaForDivNetFolderTo.getSearchCriteria(); 
    try { 
     LOGGER.info("************ Started searchPerson by criteria ************"); 
     StringBuilder url = new StringBuilder(); 
     url.append(equilarSearchEngineApiUrl) 
     .append(focusCompanySearchUrl) 
     .append("/") 
     .append("searchPerson") 
     .append("?view=").append(VIEW_ALL) 
     .append("&isProcessing=true"); 

     LOGGER.debug("Calling equilar search engine for focused company search, URL : " + url); 
     LOGGER.info(searchCriteria.toString()); 
     String output = null; 
     if (redisEnable != null && redisEnable) { 
      output = cacheDao.getDataFromRestApi(url.toString(), RequestMethod.POST.name(), searchCriteria); 
     } else { 
      output = Util.getDataFromRestApi(url.toString(), RequestMethod.POST.name(), searchCriteria); 
     } 
     if (!Util.isEmptyString(output)) { 
      ObjectMapper objectMapper = new ObjectMapper(); 
      objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); 
      objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); 
      searchResultData = objectMapper.readValue(output, 
          objectMapper.getTypeFactory().constructType(ElasticSearchResultData.class)); 
     } 
     List<PersonSearchDetails> newPersonDetails = new ArrayList<PersonSearchDetails>(); 
     if (!Util.isNull(searchResultData) && !Util.isNullOrEmptyCollection(searchResultData.getPersonDetails()) 
       && !Util.isNullOrEmptyCollection(searchCriteriaForDivNetFolderTo.getNetworkFoldersData())) { 
      for (PersonSearchDetails personDetail : searchResultData.getPersonDetails()) { 
       String logoUrl = null; 
       if(!Util.isNull(searchCriteria.getTargetFolderId())){ 
        List<DiversityNetworkFolderTo> filteredFolderTos = searchCriteriaForDivNetFolderTo 
          .getNetworkFoldersData() 
          .stream() 
          .filter(folder -> folder.getId() 
          .longValue() == searchCriteria 
          .getTargetFolderId()) 
          .collect(Collectors.toList()); 
        logoUrl = getLogoUrl(personDetail.getPersonId(), 
          filteredFolderTos); 
       } else { 
        logoUrl = getLogoUrl(personDetail.getPersonId(), 
          searchCriteriaForDivNetFolderTo.getNetworkFoldersData()); 
       } 
       personDetail.setLogoUrl(logoUrl); 
       newPersonDetails.add(personDetail); 
      } 
      searchResultData.setPersonDetails(newPersonDetails); 
     } 
     completableFuture.complete(searchResultData); 
     return completableFuture; 
    } catch (Exception e) { 
     completableFuture.completeExceptionally(e); 
     LOGGER.error(
       " ************** Error in proccessing searchPerson by criteria ************** " + e.getMessage()); 
    } 
    Long end = System.currentTimeMillis(); 
    LOGGER.info(TIME_DURATION+(end - start)+"ms"); 
    return null; 
} 
+0

この*非同期*要件はどこから来るのか、私は表示されません。ここでは、必要な作業を行い、要求を取得し、DBからデータをフェッチした後、すぐに応答します。非同期の方法では何もできません。しかし、私の場合、クライアントがUIから* async *呼び出しを要求しているように聞こえますが、おそらく** AJAX **などです。これはこのコードとは関係ありません。この* Future *ロジックをすべて削除することをお勧めします。 – Zilvinas

+0

オートメーションエンジニアはapiのパフォーマンスを低下させる100人の現行ユーザーでapiをテストしています。前回の@asyncでDefferredResult <>を使用しました。パフォーマンスを50%改善しました.so CompletableFuture <>を試したかったのです。 – vk1

+0

私はあなたがそれは、私が – Zilvinas

答えて

0

非同期処理についての詳細を読むのが良いでしょう。 javadocsは通常素晴らしいスタートです!

将来のメソッドから実際に結果を得たい場合は、それを待つ必要があります。

CompletableFuture APIにはメソッドpublic T get()があり、結果が作成されるのを待って終了したら結果を返すことができます。

あなたの仕事がデータベースを検索して結果を返すのであれば、まだそれを待たなければなりません。非同期はあまり役に立ちません。同時に複数のものを作成する必要がある場合は、それが役に立ちます。 DB、Webサービスなどのコールを同時に呼び出すと、一連の未来を作成し、それらのすべてが完了するまで待つことができます。

それとも、あなたはすぐに入力を検証し、迅速UIへの応答を返すとがあなたの非同期メソッドが完了しますを期待しつつ、DB非同期に保存するために送信することができますので、あなたがPOSTメソッドを作成しているとしましょう別のスレッドでエラーをUIに返さないようにします。

あなたは何をやっている知っているが、あなたが本当にそれを使用する前に、それを必要とするとき&場合を考えるとき、これは素晴らしい技術です。

これを「修正」するために短い方法は次のとおりです。

CompletableFuture<ElasticSearchResultData> searchPerson = cubService.searchPersonAsync2(criteriaForDivNetFolderTo); 
ElasticSearchResultData result = searchPerson.get(); 
ObjectMapper mapper = new ObjectMapper(); 
LOGGER.info("search Person "+mapper.writeValueAsString(result)); 
return result; 

(と明らかにはメソッドの戻り値の署名を変更する)

+0

私は戻り値の型としてDefferedResult <>を使用し、別のAPI実装でサービスにすぎ@async使用を取得使用せずにそこに応答を得ていた待っていないと、結果 – vk1

+0

Used ElasticSearchResultData result = searchPerson.get()空白の応答がまだ返っています – vk1

関連する問題