Files
trex-core/docs/batches/bat-039_20260612_paper-seq-redis-persistence/implementation.md
T
genichinandClaude Opus 4.8 9871008bb6 fix(paper): BAT-039 — paper order seq Redis 영속화 (재시작 멱등 키 충돌 방지, REQ-011/issue #4)
REQ-011 change-req(CHG-20260612-01)→구현→confirm-req-implemented(CHG-20260612-02)
전체 delivery. paper 한정 결정성 버그(프로덕션 무관).

- seq_store.py 신규: SeqStore 포트 + RedisSeqStore(원자 INCR, 재시작 단조·영속)
  + InMemorySeqStore(폴백/테스트). REQ-016 token_cache 패턴 재사용.
- paper.py: optional seq_store 주입. 미주입 시 기존 in-memory 동작 byte-for-byte 유지.
- config.py/daemon.py: TREX_PAPER_REDIS_URL → RedisSeqStore wiring
  (key=trex:broker:paper:{instance_key}:order-seq).
- 런타임 Redis 오류는 전파(silent in-memory 폴백 금지 — 버그 재현 방지).
- tests: 재시작 단조성/correlation_id 비충돌/in-memory 폴백/fake redis INCR (5).
  434 passed (+5), ruff clean.

REQ-011 Approved→Implemented, BAT-039 release-candidate. issue #4 close.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 18:16:11 +09:00

2.4 KiB

BAT-039 Implementation

  • Status: completed
  • Batch: BAT-039

Plan Summary

  • seq_store.py 신규(SeqStore/RedisSeqStore/InMemorySeqStore), paper 어댑터에 optional 주입, config/daemon wiring, 재시작 모사 회귀 테스트.

Changed Files

  • trex_core/adapters/broker/seq_store.py (신규) — SeqStore Protocol, RedisSeqStore(INCR), InMemorySeqStore
  • trex_core/adapters/broker/paper.py — SeqStore import, __init__(seq_store=None), submit_order 발번 분기
  • trex_core/runtime/config.py — PaperBrokerConfig.redis_url + TREX_PAPER_REDIS_URL
  • trex_core/runtime/daemon.py — _build_broker paper 경로 RedisSeqStore wiring(key=trex:broker:paper:{instance_key}:order-seq)
  • tests/adapters/broker/test_paper_seq_store.py (신규, 5 테스트)

Execution Log

  1. seq_store.py: next_seq() 단일 메서드 포트. RedisSeqStore 는 from_url(socket_connect_timeout=2) + 원자 INCR(키 부재 시 1부터 → 첫 order_id PAPER-000001). InMemorySeqStore 는 lock 보호 카운터. 런타임 Redis 오류는 전파(silent in-memory 폴백 금지, 버그 재현 방지).
  2. paper.py: seq_store 주입 시 next_seq(), 미주입 시 기존 self._seq += 1(byte-for-byte 유지). _lock 안에서 발번.
  3. config.py: PaperBrokerConfig.redis_url: str = "", from_config 에서 TREX_PAPER_REDIS_URL 읽기.
  4. daemon.py: config.paper.redis_url 있으면 RedisSeqStore 생성·주입(instance_key 스코프 키).
  5. 테스트 5종: 재시작 단조성, 매수→재시작→매도 correlation_id 비충돌, (버그 문서화) store 없을 때 충돌 재현, in-memory 폴백 시작값, fake redis INCR 단조·공유.

Validation

  • pytest tests/adapters/broker/test_paper_seq_store.py — 5 passed
  • pytest tests/ — 434 passed, 45 skipped (BAT-038 429 → +5, 회귀 0)
  • ruff check trex_core tests — All checks passed
  • 폴백 회귀: test_in_memory_fallback_starts_at_one 으로 미주입 시 PAPER-000001 시작 확인(AC-1~3 기존 paper 테스트 회귀 없음).

Remaining Risks

  • 없음. R-1(런타임 오류 silent 폴백)은 전파 설계로 제거, R-2(자리수 초과)는 :06d 최소 패딩으로 무해, R-3(다중 인스턴스 키 공유)은 instance_key 스코프로 분리.
  • 라이브 Redis 통합 스모크는 운영 배포 단계 사항(테스트는 fake redis_module + InMemorySeqStore 로 INCR/단조 계약 검증). 실 KIS 는 본 변경 무관(odno 고유).