diff --git a/src/main/java/com/kamco/cd/kamcoback/upload/service/UploadService.java b/src/main/java/com/kamco/cd/kamcoback/upload/service/UploadService.java index 0c018467..7372b7e2 100644 --- a/src/main/java/com/kamco/cd/kamcoback/upload/service/UploadService.java +++ b/src/main/java/com/kamco/cd/kamcoback/upload/service/UploadService.java @@ -108,20 +108,48 @@ public class UploadService { if (Objects.equals(chunkIndex, chunkTotalIndex)) { upAddReqDto.setUploadId(dto.getUploadId()); - upAddReqDto.setStatus(FileUploadStatus.DONE.name()); + upAddReqDto.setStatus(FileUploadStatus.DONE.name()); // DONE 말고 MERGING 추천 uploadSessionCoreService.updateUploadSessionStatus(upAddReqDto); + log.info( + "merge start: uploadId={}, fileName={}, chunkIndex={}, chunkTotalIndex={}, tmpDir={}, finalDir={}", + dto.getUploadId(), + fileName, + chunkIndex, + chunkTotalIndex, + tmpDataSetDir, + fianlDir); + try { this.mergeChunks(tmpDataSetDir, fianlDir, fileName, chunkTotalIndex); - upAddReqDto.setUploadId(dto.getUploadId()); upAddReqDto.setStatus("MERGED"); uploadSessionCoreService.updateUploadSessionStatus(upAddReqDto); + log.info( + "merge success: uploadId={}, fileName={}, outputDir={}", + dto.getUploadId(), + fileName, + fianlDir); + } catch (IOException e) { - // throw new RuntimeException(e); + + // 실패 상태도 남기는 걸 강추 + upAddReqDto.setStatus("MERGE_FAIL"); + uploadSessionCoreService.updateUploadSessionStatus(upAddReqDto); + + log.error( + "merge failed: uploadId={}, fileName={}, chunkIndex={}, chunkTotalIndex={}, tmpDir={}, finalDir={}", + dto.getUploadId(), + fileName, + chunkIndex, + chunkTotalIndex, + tmpDataSetDir, + fianlDir, + e); + upRes.setRes("fail"); - upRes.setResMsg("파일Chunk 병합(merge) 애러"); + upRes.setResMsg("파일Chunk 병합(merge) 오류"); return upRes; } } @@ -212,28 +240,64 @@ public class UploadService { return dto; } - public void mergeChunks(String tmpDir, String fianlDir, String fileName, int chunkTotalIndex) + public void mergeChunks(String tmpDir, String finalDir, String fileName, int chunkTotalIndex) throws IOException { + long start = System.currentTimeMillis(); + Path outputPath = Paths.get(finalDir, fileName); + + log.info( + "mergeChunks start: fileName={}, tmpDir={}, outputPath={}, lastChunkIndex={}", + fileName, + tmpDir, + outputPath, + chunkTotalIndex); + + long totalBytes = 0; - Path outputPath = Paths.get(fianlDir, fileName); try (FileChannel outChannel = - FileChannel.open(outputPath, StandardOpenOption.CREATE, StandardOpenOption.WRITE)) { + FileChannel.open( + outputPath, + StandardOpenOption.CREATE, + StandardOpenOption.WRITE, + StandardOpenOption.TRUNCATE_EXISTING)) { + for (int i = 0; i <= chunkTotalIndex; i++) { - Path chunkPath = Paths.get(tmpDir, i + ""); + Path chunkPath = Paths.get(tmpDir, String.valueOf(i)); try (FileChannel inChannel = FileChannel.open(chunkPath, StandardOpenOption.READ)) { - long transferred = 0; long size = inChannel.size(); + long transferred = 0; while (transferred < size) { transferred += inChannel.transferTo(transferred, size - transferred, outChannel); } + totalBytes += size; } - // 병합 후 즉시 삭제하여 디스크 공간 확보 + Files.delete(chunkPath); } + + try { + FIleChecker.deleteFolder(tmpDir); + } catch (Exception e) { + log.warn("tmpDir delete failed (merge already succeeded): tmpDir={}", tmpDir, e); + } + + } catch (IOException e) { + log.error( + "mergeChunks failed: fileName={}, tmpDir={}, outputPath={}, lastChunkIndex={}", + fileName, + tmpDir, + outputPath, + chunkTotalIndex, + e); + throw e; } - // 병합후 임시 폴더 삭제 - FIleChecker.deleteFolder(tmpDir); + log.info( + "mergeChunks done: fileName={}, outputPath={}, bytes={}, elapsedMs={}", + fileName, + outputPath, + totalBytes, + (System.currentTimeMillis() - start)); } }