Skip to content

Commit

Permalink
feat: 스레드 풀 생성 및 사용하게 지정
Browse files Browse the repository at this point in the history
  • Loading branch information
youngsu5582 committed Nov 18, 2024
1 parent 5e41977 commit 6ca2bc3
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 5 deletions.
21 changes: 21 additions & 0 deletions backend/src/main/java/corea/global/config/ThreadPoolConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package corea.global.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;

@Configuration
public class ThreadPoolConfig {

@Bean(name = "apiExecutor")
public Executor apiExecutor() {
final ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(100);
executor.setMaxPoolSize(200);
executor.setQueueCapacity(50);
executor.initialize();
return executor;
}
}
5 changes: 5 additions & 0 deletions backend/src/main/java/corea/global/util/FutureUtil.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
package corea.global.util;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.function.Supplier;

public class FutureUtil {

public static <T> CompletableFuture<T> supplyAsync(Supplier<T> supplier) {
return CompletableFuture.supplyAsync(supplier);
}

public static <T> CompletableFuture<T> supplyAsync(final Supplier<T> supplier, final Executor executor) {
return CompletableFuture.supplyAsync(supplier, executor);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,22 @@
import corea.exception.ExceptionType;
import corea.review.dto.GithubPullRequestReview;
import corea.review.dto.GithubPullRequestReviewInfo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static corea.global.util.FutureUtil.supplyAsync;

@Slf4j
@Component
@RequiredArgsConstructor
public class GithubReviewProvider {

private static final String HTTP_SECURE_PREFIX = "https://";
Expand All @@ -30,6 +32,13 @@ public class GithubReviewProvider {

private final GithubPullRequestReviewClient reviewClient;
private final GithubPullRequestCommentClient commentClient;
private final Executor apiExecutor;

public GithubReviewProvider(GithubPullRequestReviewClient reviewClient, GithubPullRequestCommentClient commentClient, @Qualifier("apiExecutor") Executor apiExecutor) {
this.reviewClient = reviewClient;
this.commentClient = commentClient;
this.apiExecutor = apiExecutor;
}

public GithubPullRequestReviewInfo provideReviewInfo(String prLink) {
validatePrLink(prLink);
Expand All @@ -38,12 +47,15 @@ public GithubPullRequestReviewInfo provideReviewInfo(String prLink) {
}

private GithubPullRequestReviewInfo getGithubPullRequestReviewInfo(String prLink) {
CompletableFuture<List<GithubPullRequestReview>> reviewFuture = supplyAsync(() -> reviewClient.getPullRequestReviews(prLink));
CompletableFuture<List<GithubPullRequestReview>> commentFuture = supplyAsync(() -> commentClient.getPullRequestReviews(prLink));
CompletableFuture<List<GithubPullRequestReview>> reviewFuture = supplyAsync(() -> reviewClient.getPullRequestReviews(prLink), apiExecutor);
CompletableFuture<List<GithubPullRequestReview>> commentFuture = supplyAsync(() -> commentClient.getPullRequestReviews(prLink), apiExecutor);

return reviewFuture
.thenCombine(commentFuture, this::collectPullRequestReviews)
.exceptionally(e -> {throw new CoreaException(ExceptionType.GITHUB_SERVER_ERROR);})
.exceptionally(e -> {
log.warn("[리뷰 API 중 깃허브 에러 발생] 발생 링크 : {}, 에러 : {}", prLink, e.getStackTrace());
throw new CoreaException(ExceptionType.GITHUB_SERVER_ERROR);
})
.thenApply(GithubPullRequestReviewInfo::new)
.join();
}
Expand Down
33 changes: 33 additions & 0 deletions backend/src/test/java/corea/global/util/FutureUtilTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package corea.global.util;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

import static org.junit.jupiter.api.Assertions.assertTrue;

class FutureUtilTest {

@Test
@DisplayName("지정하지 않으면 ForkedJoinPool 에서 동작한다.")
void default_is_work_with_forked_join_pool() throws ExecutionException, InterruptedException {
CompletableFuture<String> future = FutureUtil.supplyAsync(() -> Thread.currentThread().getName());
String threadName = future.get();
assertTrue(threadName.startsWith("ForkJoinPool"));
}

@Test
@DisplayName("지정하면 지정한 Executors 가 제공한 스레드에서 동작한다.")
void work_with_specific_executor() throws ExecutionException, InterruptedException {
final ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setThreadNamePrefix("testExecutor");
executor.initialize();

CompletableFuture<String> future = FutureUtil.supplyAsync(() -> Thread.currentThread().getName(), executor);
String threadName = future.get();
assertTrue(threadName.startsWith("testExecutor"));
}
}

0 comments on commit 6ca2bc3

Please sign in to comment.