Merge pull request '임시폴더생성 api 추가' (#59) from feat/training_260202 into develop

Reviewed-on: #59
This commit was merged in pull request #59.
This commit is contained in:
2026-02-12 17:23:53 +09:00

View File

@@ -7,7 +7,6 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Slf4j @Slf4j
@Service @Service
@@ -17,48 +16,74 @@ public class TmpDatasetService {
@Value("${train.docker.requestDir}") @Value("${train.docker.requestDir}")
private String requestDir; private String requestDir;
@Transactional(readOnly = true)
public Path buildTmpDatasetSymlink(String uid, List<String> datasetUids) throws IOException { public Path buildTmpDatasetSymlink(String uid, List<String> datasetUids) throws IOException {
// 환경에 맞게 yml로 빼는 걸 추천 log.info("========== buildTmpDatasetSymlink START ==========");
log.info("uid={}", uid);
log.info("datasetUids={}", datasetUids);
log.info("requestDir(raw)={}", requestDir);
Path BASE = toPath(requestDir); Path BASE = toPath(requestDir);
Path tmp = BASE.resolve("tmp").resolve(uid); Path tmp = BASE.resolve("tmp").resolve(uid);
log.info("requestDir(raw)={}", requestDir); log.info("BASE={}", BASE);
log.info("BASE(abs)={}", BASE.toAbsolutePath().normalize());
log.info("BASE exists? {}", Files.isDirectory(BASE)); log.info("BASE exists? {}", Files.isDirectory(BASE));
log.info("tmp={}", tmp);
long noDir = 0, scannedDirs = 0, regularFiles = 0, symlinksMade = 0;
// mkdir -p "$TMP"/train/{input1,input2,label} ...
for (String type : List.of("train", "val")) { for (String type : List.of("train", "val")) {
for (String part : List.of("input1", "input2", "label")) { for (String part : List.of("input1", "input2", "label")) {
Files.createDirectories(tmp.resolve(type).resolve(part)); Path dir = tmp.resolve(type).resolve(part);
Files.createDirectories(dir);
log.info("createDirectories: {}", dir);
} }
} }
for (String id : datasetUids) { for (String id : datasetUids) {
Path srcRoot = BASE.resolve(id); Path srcRoot = BASE.resolve(id);
log.info("---- dataset id={} srcRoot={} exists? {}", id, srcRoot, Files.isDirectory(srcRoot));
for (String type : List.of("train", "val")) { for (String type : List.of("train", "val")) {
for (String part : List.of("input1", "input2", "label")) { for (String part : List.of("input1", "input2", "label")) {
Path srcDir = srcRoot.resolve(type).resolve(part); Path srcDir = srcRoot.resolve(type).resolve(part);
log.info("srcRoot={} exists={}", srcRoot, Files.isDirectory(srcRoot));
// zsh NULL_GLOB: 폴더가 없으면 그냥 continue if (!Files.isDirectory(srcDir)) {
if (!Files.isDirectory(srcDir)) continue; log.warn("SKIP (not directory): {}", srcDir);
noDir++;
continue;
}
scannedDirs++;
log.info("SCAN dir={}", srcDir);
try (DirectoryStream<Path> stream = Files.newDirectoryStream(srcDir)) { try (DirectoryStream<Path> stream = Files.newDirectoryStream(srcDir)) {
for (Path f : stream) { for (Path f : stream) {
if (!Files.isRegularFile(f)) continue; if (!Files.isRegularFile(f)) {
log.debug("skip non-regular file: {}", f);
continue;
}
regularFiles++;
String dstName = id + "__" + f.getFileName(); String dstName = id + "__" + f.getFileName();
Path dst = tmp.resolve(type).resolve(part).resolve(dstName); Path dst = tmp.resolve(type).resolve(part).resolve(dstName);
// 이미 있으면 스킵(원하면 덮어쓰기 로직으로 바꿀 수 있음) try {
if (Files.exists(dst)) continue; // ✅ 덮어쓰기
if (Files.exists(dst) || Files.isSymbolicLink(dst)) {
Files.delete(dst);
log.debug("deleted existing: {}", dst);
}
// ln -s "$f" "$dst" 와 동일 Files.createSymbolicLink(dst, f.toAbsolutePath());
Files.createSymbolicLink(dst, f.toAbsolutePath()); symlinksMade++;
log.debug("created symlink: {} -> {}", dst, f.toAbsolutePath());
} catch (Exception e) {
log.error("FAILED create symlink: {} -> {}", dst, f.toAbsolutePath(), e);
}
} }
} }
} }
@@ -66,6 +91,13 @@ public class TmpDatasetService {
} }
log.info("tmp dataset created: {}", tmp); log.info("tmp dataset created: {}", tmp);
log.info(
"summary: scannedDirs={}, noDir={}, regularFiles={}, symlinksMade={}",
scannedDirs,
noDir,
regularFiles,
symlinksMade);
return tmp; return tmp;
} }