From a56227ace9392e75e438ca59370d4e2bdea2f3ca Mon Sep 17 00:00:00 2001 From: kyu Date: Wed, 3 Jun 2026 10:32:11 +0900 Subject: [PATCH] =?UTF-8?q?fix(kis-api):=20=ED=82=A4=EC=9B=80=20=ED=86=A0?= =?UTF-8?q?=ED=81=B0=20=EA=B0=B1=EC=8B=A0=20race=20=EC=A0=9C=EA=B1=B0=20(a?= =?UTF-8?q?syncio.Lock=20+=20double-check)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 장 시작 09:00 토큰 만료 시 여러 잡이 동시 재발급 → 키움 앱키당 토큰 1개 정책으로 무효 토큰을 붙들어 ka10001 전건 실패(ok:0) → 시세 stale(텔레그램 현재가 불일치). KiwoomToken.get()에 락+재확인 추가, _refresh 분리. Co-Authored-By: Claude Opus 4.8 (1M context) --- kis-api/main.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/kis-api/main.py b/kis-api/main.py index 251f521..1827553 100644 --- a/kis-api/main.py +++ b/kis-api/main.py @@ -44,10 +44,19 @@ scheduler = AsyncIOScheduler(timezone="Asia/Seoul") class KiwoomToken: token: str = "" expires_at: datetime = datetime.min + _lock = asyncio.Lock() async def get(self, client: httpx.AsyncClient) -> str: if self.token and datetime.now() < self.expires_at: return self.token + # 동시 갱신 방지: 락 안에서 재확인(double-check) — 키움은 앱키당 토큰 1개만 + # 유효(재발급 시 이전 토큰 무효화)하므로 thundering-herd 시 무효 토큰을 붙들게 됨 + async with self._lock: + if self.token and datetime.now() < self.expires_at: + return self.token + return await self._refresh(client) + + async def _refresh(self, client: httpx.AsyncClient) -> str: resp = await client.post( f"{KIWOOM_BASE_URL}/oauth2/token", json={"grant_type": "client_credentials",