Merge remote-tracking branch 'origin/main_laptop_1' into sub_laptop_2

This commit is contained in:
2026-10-20 09:51:16 +09:00
9 changed files with 209 additions and 168 deletions
+17 -8
View File
@@ -4,8 +4,8 @@
- DB 행 — `projects` 한 줄 · `project_workflow_stages` · `routes` 와 자식 넷(`route_points` ·
`route_statistics` · `longitudinal_sections` · `cross_sections`)
- 노선 바뀐 저장(6-B)이면 지표면 모델 확정 상태(`surface_models.status` · 설계 지형 바꿈)
- storage — 저장 차례가 쓰는 폴더(`STORAGE_SCOPE` · 관 차례 · 노선 저장이면 배수 폴더 · 초기값
사본도)
- storage — 저장 차례가 쓰는 폴더(`STORAGE_SCOPE` · 관 차례 · 노선 저장이면 배수 폴더 · 추천
[적용]이면 초기값 사본도) · 뒤에서 도는 미리 셈이 뜨는 사이 지운 파일은 건너뜀(`_derived`)
를 떠 두고, 하나라도 실패하면 둘 다 되돌린다. 되돌림 쓰기는 바뀐 것만(시놀로지 동기 — 안 바뀐
파일 · 표는 안 씀). 같은 프로젝트 저장이 겹치면 뒤 요청이 기다림(`project_lock`).
"""
@@ -35,7 +35,7 @@ STORAGE_SCOPE = (
)
#: 관 · 관 옵션 차례 · [확정](배수유역 다시 셈)이 쓰는 자리.
PIPE_SCOPE = ("B04_PreProcess/drainage",)
#: 노선 초기화(추천 [적용] · 모양 바뀐 노선 [저장] · 492)가 다시 뜨는 초기값 사본.
#: 노선 초기화(추천 [적용])가 다시 뜨는 초기값 사본.
INITIAL_SCOPE = ("initial_snapshot",)
#: 노선 아래 표(노선 행이 지워지면 함께 지워짐 · CASCADE).
ROUTE_CHILDREN = ("route_points", "route_statistics", "longitudinal_sections", "cross_sections")
@@ -52,8 +52,12 @@ def project_lock(project_id: str) -> asyncio.Lock:
# ── storage ────────────────────────────────────────────────────────────────
def _stamp(path: Path) -> tuple[int, int]:
stat = path.stat()
def _stamp(path: Path) -> tuple[int, int] | None:
"""(크기, 바뀐 때) · 그 사이 지워졌으면 None."""
try:
stat = path.stat()
except FileNotFoundError:
return None
return stat.st_size, stat.st_mtime_ns
@@ -85,7 +89,7 @@ class StorageSnapshot:
now = _files(self.root, self.scope)
for relative, path in now.items():
if relative not in self.stamps:
path.unlink()
path.unlink(missing_ok=True)
written += 1
elif _stamp(path) != self.stamps[relative]:
shutil.copy2(self.copy_dir / relative, path)
@@ -113,8 +117,13 @@ def snapshot_storage(root: Path, scope: tuple[str, ...]) -> StorageSnapshot:
for relative, path in _files(snap.root, scope).items():
target = copy_dir / relative
target.parent.mkdir(parents=True, exist_ok=True)
shutil.copy2(path, target)
snap.stamps[relative] = _stamp(path)
try: # 뒤 미리 셈(추천 노선 · `_derived` 원자 쓰기 · 정리)이 그 사이 지움 = 없던 파일
shutil.copy2(path, target)
except FileNotFoundError:
continue
stamp = _stamp(path)
if stamp is not None:
snap.stamps[relative] = stamp
return snap