Problem
RedisUsageStorage는 기록된 record idempotency key를 로컬 Map에 24시간 동안 저장하지만, 만료된 key는 같은 key가 다시 조회될 때만 제거됩니다. 장기 실행 프로세스에서 unique record id가 계속 들어오면 메모리가 불필요하게 증가할 수 있습니다.
Evidence
packages/metering-core/src/libs/RedisUsageStorage.ts:16-17는 RECORD_IDEMPOTENCY_TTL_SECONDS = 86400와 recordedRecordKeys = new Map<string, number>()를 둡니다.
packages/metering-core/src/libs/RedisUsageStorage.ts:164-166는 성공 기록 시 key를 로컬 Map에 저장합니다.
packages/metering-core/src/libs/RedisUsageStorage.ts:252-264는 같은 key를 다시 확인할 때만 만료 key를 삭제합니다.
packages/metering-core/src/libs/RedisUsageStorage.ts:267-270은 expiry를 저장하지만 주기적 sweep, max size, lifecycle cleanup이 없습니다.
Desired Outcome
로컬 idempotency 캐시는 TTL 의미를 실제 메모리 사용에도 반영해야 하며, 장기 프로세스에서 unbounded growth로 이어지면 안 됩니다.
Suggested Approach
- max entries 또는 periodic sweep을 도입합니다.
- write path에서 opportunistic pruning을 제한된 비용으로 수행합니다.
- Redis idempotency와 로컬 short-circuit cache의 책임을 분리해 문서화합니다.
Acceptance Criteria
- 만료된 로컬 idempotency key가 같은 key 재조회 없이도 제거될 수 있습니다.
- 캐시 크기에 상한 또는 예측 가능한 pruning 정책이 있습니다.
- fake timer 기반 regression test가 추가됩니다.
Validation
pnpm test --filter=@croco/metering-core
- RedisUsageStorage idempotency cache pruning test
Problem
RedisUsageStorage는 기록된 record idempotency key를 로컬Map에 24시간 동안 저장하지만, 만료된 key는 같은 key가 다시 조회될 때만 제거됩니다. 장기 실행 프로세스에서 unique record id가 계속 들어오면 메모리가 불필요하게 증가할 수 있습니다.Evidence
packages/metering-core/src/libs/RedisUsageStorage.ts:16-17는RECORD_IDEMPOTENCY_TTL_SECONDS = 86400와recordedRecordKeys = new Map<string, number>()를 둡니다.packages/metering-core/src/libs/RedisUsageStorage.ts:164-166는 성공 기록 시 key를 로컬 Map에 저장합니다.packages/metering-core/src/libs/RedisUsageStorage.ts:252-264는 같은 key를 다시 확인할 때만 만료 key를 삭제합니다.packages/metering-core/src/libs/RedisUsageStorage.ts:267-270은 expiry를 저장하지만 주기적 sweep, max size, lifecycle cleanup이 없습니다.Desired Outcome
로컬 idempotency 캐시는 TTL 의미를 실제 메모리 사용에도 반영해야 하며, 장기 프로세스에서 unbounded growth로 이어지면 안 됩니다.
Suggested Approach
Acceptance Criteria
Validation
pnpm test --filter=@croco/metering-core