main_laptop_1 -> main byeonghap (4 hwangyeong 585 commits) #12
@@ -15,7 +15,9 @@ import logging
|
||||
import os
|
||||
import signal
|
||||
import subprocess
|
||||
import time
|
||||
from contextlib import asynccontextmanager
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
@@ -271,6 +273,17 @@ async def lifespan(app: FastAPI):
|
||||
# 시작
|
||||
logger.info(f"[{ENVIRONMENT}] 앱 시작 중...")
|
||||
|
||||
# 지금 도는 코드가 언제 것인지 못박아 둔다 — `/api/health` 가 `stale` 로 알린다(7-2).
|
||||
global _STARTED_AT, _CODE_MTIME_AT_START
|
||||
_STARTED_AT = time.time()
|
||||
if DEBUG:
|
||||
_CODE_MTIME_AT_START = _newest_source_mtime()
|
||||
logger.info(
|
||||
"[reload] 감시 폴더 %d개, 소스 최신 수정 %s",
|
||||
len(_reload_dirs()),
|
||||
datetime.fromtimestamp(_CODE_MTIME_AT_START).isoformat(timespec="seconds"),
|
||||
)
|
||||
|
||||
# 프론트엔드 빌드 (필수)
|
||||
build_frontend()
|
||||
|
||||
@@ -440,10 +453,44 @@ async def root():
|
||||
}
|
||||
|
||||
|
||||
#: 이 프로세스가 뜬 시각과, 뜰 때 본 **가장 최근 소스 수정 시각**. 기동 때 채운다
|
||||
#: (`_reload_dirs` 가 아래에 정의돼 있어 모듈 로드 시점에는 못 부른다).
|
||||
#: 자동 리로드가 조용히 죽는 일이 잦아(오늘만 세 번, 매번 틀린 결론을 냄) 「지금 도는 서버가
|
||||
#: 옛 코드인가」를 한 번에 가릴 수 있게 남긴다(2026-09-07, PLAN 7-2).
|
||||
_STARTED_AT = 0.0
|
||||
_CODE_MTIME_AT_START = 0.0
|
||||
|
||||
|
||||
def _newest_source_mtime() -> float:
|
||||
"""감시 대상 폴더의 `.py` 중 가장 최근 수정 시각. 못 읽으면 0."""
|
||||
newest = 0.0
|
||||
for folder in _reload_dirs():
|
||||
for path in Path(folder).rglob("*.py"):
|
||||
try:
|
||||
newest = max(newest, path.stat().st_mtime)
|
||||
except OSError:
|
||||
continue
|
||||
return newest
|
||||
|
||||
|
||||
@app.get("/api/health")
|
||||
async def health():
|
||||
"""헬스 체크"""
|
||||
return {"status": "ok", "environment": ENVIRONMENT}
|
||||
"""헬스 체크.
|
||||
|
||||
개발 모드에서는 **코드가 최신인지**도 함께 알린다 — `stale: true` 면 소스가 더 새로우니
|
||||
(자동 리로드가 안 붙은 것) 재시작 전에는 어떤 측정도 믿으면 안 된다.
|
||||
"""
|
||||
body: dict[str, Any] = {"status": "ok", "environment": ENVIRONMENT}
|
||||
if DEBUG:
|
||||
newest = _newest_source_mtime()
|
||||
body["started_at"] = datetime.fromtimestamp(_STARTED_AT).isoformat(timespec="seconds")
|
||||
body["code_mtime"] = datetime.fromtimestamp(_CODE_MTIME_AT_START).isoformat(
|
||||
timespec="seconds"
|
||||
)
|
||||
body["source_mtime"] = datetime.fromtimestamp(newest).isoformat(timespec="seconds")
|
||||
# 1초 여유 — 저장 직후의 미세한 시각차로 헛경고가 뜨지 않게.
|
||||
body["stale"] = newest > _CODE_MTIME_AT_START + 1.0
|
||||
return body
|
||||
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user