diff --git a/stock-lab/app/screener/router.py b/stock-lab/app/screener/router.py index bbf6905..43c0cfe 100644 --- a/stock-lab/app/screener/router.py +++ b/stock-lab/app/screener/router.py @@ -46,10 +46,11 @@ def _db_path() -> str: def _conn() -> sqlite3.Connection: # WAL 모드 + busy_timeout으로 동시 read/write lock 회피 - # (snapshot/refresh 직후 /run이 SELECT 시 OperationalError 'database is locked' 방지) - conn = sqlite3.connect(_db_path(), timeout=30.0) + # WAL은 reader vs writer 동시성만 해결 — writer 두 명은 직렬이므로 busy_timeout이 + # snapshot/refresh의 write 시간보다 길어야 함 (네이버 스크래핑 ~20초 + DB upsert). + conn = sqlite3.connect(_db_path(), timeout=120.0) conn.execute("PRAGMA journal_mode=WAL") - conn.execute("PRAGMA busy_timeout=30000") + conn.execute("PRAGMA busy_timeout=120000") return conn diff --git a/stock-lab/app/screener/snapshot.py b/stock-lab/app/screener/snapshot.py index 6633f6a..00a7eb5 100644 --- a/stock-lab/app/screener/snapshot.py +++ b/stock-lab/app/screener/snapshot.py @@ -22,8 +22,11 @@ NAVER_HEADERS = { "Referer": "https://finance.naver.com/", } -DEFAULT_FLOW_TOP_N = 500 +DEFAULT_FLOW_TOP_N = 100 DEFAULT_RATE_LIMIT_SEC = 0.2 +# 시총 상위 100종목 × 0.2초 = ~20초 — agent-office httpx timeout(180s) 안에 여유롭게 완료 +# 외국인 매수 시그널은 대형주에서 의미가 크므로 상위 100종목으로 충분. +# 더 많은 종목이 필요하면 별도 cron으로 분리 권장. @dataclass