Reputation: 29
I think when I add @Async notation for this method, it returns an empty result. The method is to get data from a website and return the data. It works when I remove @Async. When I am not using @Async, it is using a thread called "http-nio-8080-exec-1", when I use @Async, it is using a thread with my naming prefix "My-thread1". I do not know if I need to config anywhere else like xml or something. Thank you!
@Async
public CompletableFuture<List<Post>> searchByTag(String[] tags, String sortBy, String direction ) throws ExecutionException, InterruptedException, IOException {
logger.info("I am here---------------------------------------------------------- ");
if(tags == null || tags.length == 0){
throw new ResponseStatusException(HttpStatus.BAD_REQUEST , "Tags parameter is required");
}
if(sortBy == null){
sortBy = "id";
} else if(!sortBy.equals("id") && !sortBy.equals("reads") && !sortBy.equals("likes") && !sortBy.equals("popularity")){
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "sortBy parameter is invalid");
}
if(direction == null){
direction = "asc";
} else if(!direction.equals("asc") && !direction.equals("desc")){
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "direction parameter is invalid");
}
long start = System.currentTimeMillis();
Set<Post> postSet = new HashSet<Post>();
String baseUrl = "https://api.hatchways.io/assessment/blog/posts?tag=";
HttpClient client = HttpClient.newHttpClient();
// send a get request to get all the posts with certain tag
for(int i = 0; i < tags.length; i++){
String url = baseUrl + tags[i];
HttpRequest request = HttpRequest.newBuilder()
.GET()
.header("Accept", "application/json")
.uri(URI.create(url))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
ObjectMapper mapper = new ObjectMapper();
// HttpResponse<String> result = response.get();
String responseBody = response.body().substring(9, response.body().length()-1);
logger.info("Using Thread: " + Thread.currentThread().getName());
List<Post> posts = mapper.readValue(responseBody, new TypeReference<List<Post>>() {});
// put all the posts into a set to filter out all the repeated posts
postSet.addAll(posts);
}
ArrayList<Post> postList = new ArrayList<>(postSet);
sortThePosts(sortBy, direction, postList);
long end = System.currentTimeMillis();
logger.info("Total time: " + Long.toString(end-start));
return CompletableFuture.completedFuture(postList);
}
Following is my config:
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
@Configuration
@EnableAsync
public class AsyncConfig {
@Bean(name = "threadPoolTaskExecutor")
public Executor taskExecutor(){
ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
threadPoolTaskExecutor.setCorePoolSize(3);
threadPoolTaskExecutor.setMaxPoolSize(5);
threadPoolTaskExecutor.setQueueCapacity(20);
threadPoolTaskExecutor.setThreadNamePrefix("My_Thread");
threadPoolTaskExecutor.initialize();
return threadPoolTaskExecutor;
}
}
Upvotes: 0
Views: 588
Reputation: 26
The configuration looks fine. Have you created searchByTag() method in the same class you are calling the method from? If so try creating a separate service class that will contain your Async methods.
Upvotes: 1