perf(B05): 측구 방향 역반영을 스레드 한 번 + 쓰기 한 문장으로 묶음
route/confirm 이 측점마다 종단 정본을 다시 열고(13.8ms) 행마다 DB 에 썼음(24.5ms). 건당 38.3ms 라 30건이면 1.15초, 67건이면 2.57초로 측점 수에 선형으로 늘었음 (보조 창 서버 내부 측정). - 다시 계산할 측점을 먼저 고른 뒤 asyncio.to_thread 를 **한 번만** 돌림. 그 안에서 종단 정본과 포장 제안표·세월교 하강표를 한 번 읽어 측점마다 돌려 씀. - read_cross_design_inputs 에 preloaded 인자 추가(종단 경로·내용·포장 제안표). 경로 검증은 resolve_longitudinal_path 로 떼어 재사용. - 쓰기는 merge_cross_section_designs 한 문장. 자체검증(공용 브라우저 [저장] 3회) — route/confirm 470~834ms -> 324/351/356ms. 버튼 전체 대기 2,624~3,415ms -> 1,826/2,766/2,979ms. (오늘 누적: 4,137ms -> 1,826~2,979ms) 시험 400 통과·17 건너뜀. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -251,19 +251,37 @@ def default_section_modes(longitudinal: dict[str, Any]) -> dict[float, str]:
|
||||
return mapping
|
||||
|
||||
|
||||
def read_cross_design_inputs(
|
||||
project_root: Path, longitudinal_file_path: str, chainage_m: float
|
||||
) -> tuple[list[dict], float | None, bool, dict[str, Any]]:
|
||||
"""(지반 샘플, 계획고, 포장 제안, 측점 기록) — 측점 기록은 곡선부 확폭 입력을 담고 있다."""
|
||||
def resolve_longitudinal_path(project_root: Path, longitudinal_file_path: str) -> Path:
|
||||
"""종단 정본 파일 경로를 검증해 돌려준다 — 저장소 밖 경로를 막는다."""
|
||||
root = project_root.resolve()
|
||||
longitudinal_path = (root / longitudinal_file_path).resolve()
|
||||
if root not in longitudinal_path.parents:
|
||||
path = (root / longitudinal_file_path).resolve()
|
||||
if root not in path.parents:
|
||||
raise ValueError("종단면 파일 경로가 프로젝트 저장소를 벗어났습니다.")
|
||||
if not longitudinal_path.is_file():
|
||||
if not path.is_file():
|
||||
raise FileNotFoundError("종단면 상세 파일을 찾을 수 없습니다.")
|
||||
longitudinal = json.loads(longitudinal_path.read_text(encoding="utf-8"))
|
||||
return path
|
||||
|
||||
|
||||
def read_cross_design_inputs(
|
||||
project_root: Path,
|
||||
longitudinal_file_path: str,
|
||||
chainage_m: float,
|
||||
preloaded: tuple[Path, dict[str, Any], dict[float, bool]] | None = None,
|
||||
) -> tuple[list[dict], float | None, bool, dict[str, Any]]:
|
||||
"""(지반 샘플, 계획고, 포장 제안, 측점 기록) — 측점 기록은 곡선부 확폭 입력을 담고 있다.
|
||||
|
||||
`preloaded` 는 (종단 경로, 종단 내용, 포장 제안표)다. 여러 측점을 잇달아 볼 때
|
||||
종단 정본을 측점마다 다시 읽지 않게 넘긴다 — 그 재읽기가 측점당 13.8ms 였다
|
||||
(2026-09-06 실측, 측구 방향 역반영 루프).
|
||||
"""
|
||||
if preloaded is not None:
|
||||
longitudinal_path, longitudinal, pavement = preloaded
|
||||
else:
|
||||
longitudinal_path = resolve_longitudinal_path(project_root, longitudinal_file_path)
|
||||
longitudinal = json.loads(longitudinal_path.read_text(encoding="utf-8"))
|
||||
pavement = pavement_suggestions(longitudinal)
|
||||
design_elevation = design_elevation_from_longitudinal(longitudinal, chainage_m)
|
||||
suggested = pavement_suggestions(longitudinal).get(round(chainage_m, 3), False)
|
||||
suggested = pavement.get(round(chainage_m, 3), False)
|
||||
cross_dir = longitudinal_path.parent.parent / "cross_sections"
|
||||
cross_path = (cross_dir / cross_filename(chainage_m)).resolve()
|
||||
if cross_dir.resolve() not in cross_path.parents or not cross_path.is_file():
|
||||
|
||||
Reference in New Issue
Block a user