Skip to content

Commit

Permalink
feat: 이미지 병렬 업로드 기능 추가 (#816)
Browse files Browse the repository at this point in the history
* feat: 이미지 병렬 업로드 기능 추가

* feat: 이미지 업로드 예외 처리 추가

* refactor: 불필요 배열 사이즈 제거
  • Loading branch information
Arachneee authored Nov 5, 2024
1 parent 7b835c9 commit 724fd20
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -30,18 +32,26 @@ public class ImageService {
private String directoryPath;

private final S3Client s3Client;
private final ExecutorService executorService;

public List<String> uploadImages(List<MultipartFile> images) {
return images.stream()
.map(this::uploadImage)
List<CompletableFuture<String>> futures = images.stream()
.map(image -> CompletableFuture.supplyAsync(() -> uploadImage(image), executorService))
.toList();

CompletableFuture<List<String>> 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);
}
}

Expand All @@ -61,6 +71,14 @@ private String uploadImageToStorage(InputStream inputStream, MultipartFile image
return imageName;
}

private String getFuture(CompletableFuture<String> 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)
Expand Down
9 changes: 9 additions & 0 deletions server/src/main/java/server/haengdong/config/S3Config.java
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}

0 comments on commit 724fd20

Please sign in to comment.