Port the trex-orbit Redis token-cache pattern so the KIS access token
survives daemon restarts and is shared across processes, avoiding KIS
token-issuance rate limits. KISBroker._ensure_token now resolves L1
in-memory -> L2 cache -> issue, storing issued tokens back to the cache.
- adapters/broker/token_cache.py: TokenCache protocol + RedisTokenCache
(key trex:broker:kis:{account_ref}:token, token+expiry+app_key suffix
JSON, ex=ttl, best-effort with graceful fallback) + InMemoryTokenCache.
- kis.py: optional token_cache injection.
- runtime config/daemon: TREX_KIS_REDIS_URL wires a RedisTokenCache.
- pyproject: redis>=5.
Verification: 96 passed, ruff clean — cache hit avoids issuance, cache is
shared across instances (restart/multi-process survival), backend errors
fall back to issuance (no regression), and app_key-suffix mismatch
invalidates a stale cache. Tested deterministically with an in-memory
double (no Redis server required). Processed via the minor-change fast
path: REQ-016 -> Implemented, BAT-005 (batch-lite) -> release-candidate.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1.2 KiB
1.2 KiB
BAT-005 Verification
- Status: confirmed
- Batch: BAT-005
Acceptance Mapping
- REQ-016:
- AC1 캐시 히트 → HTTP 발급 없음 →
test_cache_hit_avoids_issuance(L1 drop 후 L2 히트, token call 1회 유지). PASS - AC2 인스턴스 간 공유(재기동/다중프로세스) →
test_shared_cache_across_instances(B 인스턴스 재발급 0). PASS - AC3 graceful fallback →
test_graceful_fallback_when_cache_errors(캐시 miss/오류 시 발급 진행). PASS - AC4 app_key suffix 안전 →
test_app_key_suffix_mismatch_ignores_cache(자격증명 교체 시 stale 무시 재발급). PASS
- AC1 캐시 히트 → HTTP 발급 없음 →
Evidence
- Test:
pytest4 token-cache passed; 전체 96 passed; ruff clean. - Manual: redis 라이브러리 import + RedisTokenCache wiring 확인. 실 Redis 서버 없이 인메모리 더블로 결정적 검증.
no architecture impact confirmed
- batch-lite, planning Design Gate=no. 기존 BrokerPort 뒤 토큰 캐시 계층 추가뿐 — 외부 인터페이스/슬롯 런타임 흐름 변경 없음. baseline 문서 영향 없음.
Result
- Ready for Release: true
- Blocking Issues:
- 없음. 실 Redis 서버 통합은 운영 환경 검증 사항(라이브러리/와이어링/폴백 검증 완료, 비차단).