From 4bdf9beb9647a0782919bf11b6757c6a829364fe Mon Sep 17 00:00:00 2001 From: Arachne <66822642+Arachneee@users.noreply.github.com> Date: Mon, 4 Nov 2024 22:42:03 +0900 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20?= =?UTF-8?q?=EB=B3=91=EB=A0=AC=20=EC=97=85=EB=A1=9C=EB=93=9C=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../haengdong/application/ImageService.java | 15 +++++++++++++-- .../java/server/haengdong/config/S3Config.java | 9 +++++++++ 2 files changed, 22 insertions(+), 2 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..e67e5bb81 100644 --- a/server/src/main/java/server/haengdong/application/ImageService.java +++ b/server/src/main/java/server/haengdong/application/ImageService.java @@ -6,6 +6,9 @@ import java.io.InputStream; import java.util.List; import java.util.UUID; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; +import java.util.concurrent.ExecutorService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; @@ -30,11 +33,19 @@ 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[futures.size()])) + .thenApply(v -> futures.stream() + .map(CompletableFuture::join) + .toList()); + + return result.join(); } private String uploadImage(MultipartFile image) { 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); + } } From dcb5521bc3ecff9d0ddd9bd53459025e64087d91 Mon Sep 17 00:00:00 2001 From: Arachne <66822642+Arachneee@users.noreply.github.com> Date: Tue, 5 Nov 2024 10:58:16 +0900 Subject: [PATCH 2/3] =?UTF-8?q?feat:=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20?= =?UTF-8?q?=EC=97=85=EB=A1=9C=EB=93=9C=20=EC=98=88=EC=99=B8=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../haengdong/application/ImageService.java | 15 +++++++++++---- .../haengdong/exception/HaengdongException.java | 5 +++++ 2 files changed, 16 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 e67e5bb81..2f64dda08 100644 --- a/server/src/main/java/server/haengdong/application/ImageService.java +++ b/server/src/main/java/server/haengdong/application/ImageService.java @@ -7,14 +7,13 @@ import java.util.List; import java.util.UUID; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionException; +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; @@ -42,7 +41,7 @@ public List uploadImages(List images) { CompletableFuture> result = CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()])) .thenApply(v -> futures.stream() - .map(CompletableFuture::join) + .map(this::getFuture) .toList()); return result.join(); @@ -52,7 +51,7 @@ 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); } } @@ -72,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/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; + } } From e22f0215b79292780e8278281c766bf5b4bee308 Mon Sep 17 00:00:00 2001 From: Arachne <66822642+Arachneee@users.noreply.github.com> Date: Tue, 5 Nov 2024 14:09:56 +0900 Subject: [PATCH 3/3] =?UTF-8?q?refactor:=20=EB=B6=88=ED=95=84=EC=9A=94=20?= =?UTF-8?q?=EB=B0=B0=EC=97=B4=20=EC=82=AC=EC=9D=B4=EC=A6=88=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/server/haengdong/application/ImageService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/main/java/server/haengdong/application/ImageService.java b/server/src/main/java/server/haengdong/application/ImageService.java index 2f64dda08..b6d64b033 100644 --- a/server/src/main/java/server/haengdong/application/ImageService.java +++ b/server/src/main/java/server/haengdong/application/ImageService.java @@ -39,7 +39,7 @@ public List uploadImages(List images) { .map(image -> CompletableFuture.supplyAsync(() -> uploadImage(image), executorService)) .toList(); - CompletableFuture> result = CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()])) + CompletableFuture> result = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])) .thenApply(v -> futures.stream() .map(this::getFuture) .toList());