Deliver BAT-005: KIS token Redis cache (REQ-016, minor-change)

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>
This commit is contained in:
2026-06-04 18:44:09 +09:00
co-authored by Claude Opus 4.8
parent 97d58318db
commit ac6061f510
13 changed files with 475 additions and 3 deletions
+6
View File
@@ -33,9 +33,15 @@ def _build_broker(config: DaemonConfig) -> BrokerPort:
from trex_core.adapters.broker.kis import KISBroker
k = config.kis
token_cache = None
if k.redis_url:
from trex_core.adapters.broker.token_cache import RedisTokenCache
token_cache = RedisTokenCache(k.redis_url)
return KISBroker(
k.account_ref, app_key=k.app_key, app_secret=k.app_secret,
base_url=k.base_url, timeout=k.timeout, allow_live=k.allow_live,
token_cache=token_cache,
)
return PaperBroker()