perf(main): 자동 리로드가 훑는 폴더를 소스만으로 좁힘

uvicorn StatReload 는 0.25초마다 지정 폴더를 rglob("*.py") 로 재귀로 훑는데,
폴더를 안 주면 현재 폴더가 대상이라 storage(27GB) · venv(파이썬 파일만
7,530개) · node_modules 까지 통째로 돌고 있었음.

파이썬이 실제로 사는 폴더 14개만 감시하게 함(산출물·의존성·백업 제외).
루트는 넣지 않음 — 넣으면 재귀라 도로 다 훑음. 그 대신 main.py 를 고칠 때는
서버를 손으로 다시 띄워야 함.

⚠ 이 변경이 「요청 없는 서버가 CPU 70%」를 고치지는 못했음. 그 CPU 는
감시 프로세스(0%)가 아니라 **앱 프로세스** 쪽이며 원인 미상 — 계획서에
남겼음. 이 커밋은 감시 낭비만 걷어낸 것임.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-07 06:30:37 +09:00
co-authored by Claude Opus 5
parent c90425db72
commit 351db312ee
+45
View File
@@ -493,6 +493,49 @@ app.include_router(b08_quantity_router, dependencies=protected_with_company)
# ───────────────────────────────────────────────────────────────────────── # ─────────────────────────────────────────────────────────────────────────
# 앱 실행 # 앱 실행
# ───────────────────────────────────────────────────────────────────────── # ─────────────────────────────────────────────────────────────────────────
def _reload_dirs() -> list[str]:
"""자동 리로드가 **훑을 폴더만** 골라 준다 — 폴더째 주면 서버가 쉬는 중에도 CPU를 먹는다.
uvicorn 의 StatReload 는 0.25초마다 지정 폴더를 통째로 훑는다. 아무것도 안 주면
현재 폴더가 대상이 되는데, 여기에는 `storage`(27GB · 프로젝트 산출물)와 `tmp`·`venv`·
`node_modules` 가 함께 들어 있다. 그래서 **요청이 하나도 없는 서버가 CPU 70%** 를 물고
있었고, 창 둘이 각각 그러니 기기가 늘 140% 눌린 채였다(2026-09-07 실측). 속도 계측이
회차마다 3배씩 흔들린 원인도 이것이다.
파이썬이 실제로 사는 폴더만 준다 — 화면 코드(TS)는 vite 가 따로 본다.
"""
root = Path(__file__).resolve().parent
# ⚠ 루트 자체는 넣지 않는다 — uvicorn 은 준 폴더를 `rglob("*.py")` 로 **재귀**로 훑으므로
# 루트를 주면 storage·venv(파이썬 파일만 7,530개)를 도로 다 훑는다. 그 대신 `main.py`
# 를 고칠 때는 서버를 손으로 다시 띄워야 한다(자주 있는 일이 아님).
watched: list[str] = []
for entry in sorted(root.iterdir()):
if not entry.is_dir() or entry.name.startswith(".") or entry.name in _RELOAD_SKIP:
continue
if any(entry.rglob("*.py")):
watched.append(str(entry))
return watched
# 파이썬이 있어도 훑지 않을 폴더 — 산출물·의존성·백업.
_RELOAD_SKIP = {
"storage",
"tmp",
"venv",
"node_modules",
"__pycache__",
"log",
"docs",
"resources",
"scratch",
"graphify-out",
"0_old",
"db_management",
"migrations",
"ui_template",
}
if __name__ == "__main__": if __name__ == "__main__":
import uvicorn import uvicorn
@@ -502,5 +545,7 @@ if __name__ == "__main__":
host=SERVER_HOST, host=SERVER_HOST,
port=SERVER_PORT, port=SERVER_PORT,
reload=DEBUG, reload=DEBUG,
# 폴더를 좁히지 않으면 리로더가 storage(27GB)까지 0.25초마다 훑는다 — 위 주석 참조.
reload_dirs=_reload_dirs() if DEBUG else None,
access_log=False, access_log=False,
) )