Voici mon contrôleur. J'ai utilisé un facteur pour tester si ça fonctionne mais je reçois une réponse vide. J'ai utilisé @EnableAsync
dans la configuration de l'application et @Async
sur le service. Si je supprime @Async
sur la couche de service, cela fonctionne mais il ne s'exécute pas de manière asynchrone.L'utilisation de CompletableFuture avec @Async renvoie une réponse vide pour l'API de démarrage par ressort
@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;
}
service
@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;
}
je ne vois pas où cela * * async exigence vient. Ici, vous faites ce que vous devez faire, obtenez la requête, récupérez les données de la BD, et une fois que vous l'avez, répondez immédiatement. Il n'y a rien à faire de manière asynchrone. Cependant, pour moi, il semble que votre client demande de faire un appel * async * à partir de l'interface utilisateur, qui est peut-être ** AJAX ** ou similaire, ce qui n'a rien à voir avec ce code. Je recommande de supprimer toute cette logique * Future *. – Zilvinas
L'ingénieur d'automatisation teste l'API avec 100 utilisateurs courants ce qui dégrade les performances de l'API. J'ai utilisé DefferredResult <> avec @async auparavant.Il a amélioré les performances de 50%. Donc j'ai voulu essayer CompletableFuture <>. – vk1
Je me demande quelle performance il a amélioré si vous n'attendez pas et n'obtenez pas le résultat – Zilvinas