From 724fd20458a8da634649ba77645ab6803421ddf8 Mon Sep 17 00:00:00 2001 From: Arachne <66822642+Arachneee@users.noreply.github.com> Date: Tue, 5 Nov 2024 14:11:08 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EB=B3=91?= =?UTF-8?q?=EB=A0=AC=20=EC=97=85=EB=A1=9C=EB=93=9C=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20(#816)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 이미지 병렬 업로드 기능 추가 * feat: 이미지 업로드 예외 처리 추가 * refactor: 불필요 배열 사이즈 제거 --- .../haengdong/application/ImageService.java | 26 ++++++++++++++++--- .../server/haengdong/config/S3Config.java | 9 +++++++ .../exception/HaengdongException.java | 5 ++++ 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/server/src/main/java/server/haengdong/application/ImageService.java b/server/src/main/java/server/haengdong/application/ImageService.java index 6e0ffdb76..b6d64b033 100644 --- a/server/src/main/java/server/haengdong/application/ImageService.java +++ b/server/src/main/java/server/haengdong/application/ImageService.java @@ -6,12 +6,14 @@ import java.io.InputStream; import java.util.List; import java.util.UUID; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; -import server.haengdong.application.response.ImageNameAppResponse; import server.haengdong.exception.HaengdongErrorCode; import server.haengdong.exception.HaengdongException; import software.amazon.awssdk.services.s3.S3Client; @@ -30,18 +32,26 @@ public class ImageService { private String directoryPath; private final S3Client s3Client; + private final ExecutorService executorService; public List uploadImages(List images) { - return images.stream() - .map(this::uploadImage) + List> futures = images.stream() + .map(image -> CompletableFuture.supplyAsync(() -> uploadImage(image), executorService)) .toList(); + + CompletableFuture> result = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])) + .thenApply(v -> futures.stream() + .map(this::getFuture) + .toList()); + + return result.join(); } private String uploadImage(MultipartFile image) { try (InputStream inputStream = image.getInputStream()) { return uploadImageToStorage(inputStream, image); } catch (IOException e) { - throw new HaengdongException(HaengdongErrorCode.IMAGE_UPLOAD_FAIL); + throw new HaengdongException(HaengdongErrorCode.IMAGE_UPLOAD_FAIL, e); } } @@ -61,6 +71,14 @@ private String uploadImageToStorage(InputStream inputStream, MultipartFile image return imageName; } + private String getFuture(CompletableFuture future) { + try { + return future.get(); + } catch (InterruptedException | ExecutionException e) { + throw new HaengdongException(HaengdongErrorCode.IMAGE_UPLOAD_FAIL, e); + } + } + public void deleteImage(String imageName) { DeleteObjectRequest deleteObjectRequest = DeleteObjectRequest.builder() .bucket(bucketName) diff --git a/server/src/main/java/server/haengdong/config/S3Config.java b/server/src/main/java/server/haengdong/config/S3Config.java index 13aa51546..cdac7c1dc 100644 --- a/server/src/main/java/server/haengdong/config/S3Config.java +++ b/server/src/main/java/server/haengdong/config/S3Config.java @@ -1,5 +1,7 @@ package server.haengdong.config; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import software.amazon.awssdk.regions.Region; @@ -8,10 +10,17 @@ @Configuration public class S3Config { + private static final int THREAD_POOL_SIZE = 10; + @Bean public S3Client s3Client() { return S3Client.builder() .region(Region.AP_NORTHEAST_2) .build(); } + + @Bean + public ExecutorService executorService() { + return Executors.newFixedThreadPool(THREAD_POOL_SIZE); + } } diff --git a/server/src/main/java/server/haengdong/exception/HaengdongException.java b/server/src/main/java/server/haengdong/exception/HaengdongException.java index 4454fe7bf..212b5bed5 100644 --- a/server/src/main/java/server/haengdong/exception/HaengdongException.java +++ b/server/src/main/java/server/haengdong/exception/HaengdongException.java @@ -16,4 +16,9 @@ public HaengdongException(HaengdongErrorCode errorCode, Object... args) { super(String.format(errorCode.getMessage(), args)); this.errorCode = errorCode; } + + public HaengdongException(HaengdongErrorCode errorCode, Throwable cause) { + super(errorCode.getMessage(), cause); + this.errorCode = errorCode; + } }