속도 제한이나 쿼터 초과 같은 경고는 짧은 시간에 여러 번 발생하기 쉽습니다. 경고 로직과 쿨다운 상태를 엔티티 자체에 포함시킴으로써 외부 글로벌 관리를 피하면서 적절한 타이밍에만 경고를 발생시킬 수 있습니다.
코드
interface WarnableEntity { /** 마지막 경고 발생 시각 (밀리초) */ warnedAt: number | null /** 경고 쿨다운 기간 (밀리초) */ warnCooldown: number}
/** * 쿨다운 기반 경고 엔티티의 기본 클래스 */class CooldownWarner<T extends WarnableEntity> { constructor(protected entity: T) {}
/** * 경고를 발생시켜야 하는지 판단 */ protected shouldWarn(): boolean { const now = Date.now() if (this.entity.warnedAt === null) { return true } const elapsed = now - this.entity.warnedAt return elapsed >= this.entity.warnCooldown }
/** * 경고를 발생시키고 warnedAt 업데이트 */ protected warnBy(message: string): void { if (!this.shouldWarn()) { return } console.warn(message) this.entity.warnedAt = Date.now() }}
/** * 속도 제한 엔티티 구현 예제 */interface RateLimitEntity extends WarnableEntity { limit: number current: number}
class RateLimiter extends CooldownWarner<RateLimitEntity> { constructor(limit: number, cooldown: number = 60_000) { super({ limit, current: 0, warnedAt: null, warnCooldown: cooldown }) }
/** * 요청을 기록하고 필요시 경고 */ record(): void { this.entity.current++
if (this.entity.current >= this.entity.limit) { this.warnBy( `Rate limit reached: ${this.entity.current}/${this.entity.limit}` ) } }
/** * 카운터 리셋 */ reset(): void { this.entity.current = 0 }}사용 예제
// 분당 100개 요청 제한, 경고는 60초에 한 번까지const limiter = new RateLimiter(100, 60_000)
// 요청 기록for (let i = 0; i < 150; i++) { limiter.record() // 100번째에 경고, 이후 60초간 억제됨}
// 1분 후 다시 초과하면 경고 재발생setTimeout(() => { limiter.record() // 경고가 다시 표시됨}, 61_000)작동 원리
- 엔티티가
warnedAt과warnCooldown필드를 가짐 shouldWarn()이 현재 시각과 마지막 경고 시각의 차이를 비교- 쿨다운 기간이 경과했으면
true반환 warnBy()가shouldWarn()을 확인하고 조건 충족 시에만 경고 발생- 경고 후
warnedAt을 업데이트하여 쿨다운 시작
경고 로직과 상태가 엔티티 내부에 완결되어 있어 글로벌 맵이나 셋으로 관리할 필요가 없습니다.
장점
- 지역성: 경고 상태가 엔티티에 한정되어 외부 관리 불필요
- 재사용성: 임의의 엔티티에
WarnableEntity를 구현하기만 하면 사용 가능 - 테스트 용이: 시간을 주입하면 모킹 없이도 테스트 가능
- 확장 가능: 엔티티마다 독립적인 상태를 가져 병렬 처리에 강함
주의사항
Date.now()에 직접 의존하므로 테스트 시 시간을 주입할 수 있도록 설계를 확장해야 합니다. 또한 엔티티가 영속화되는 경우 warnedAt의 복원과 쿨다운 판정을 적절히 처리해야 합니다.
응용
- API 속도 제한 경고 알림
- 과금 시스템의 쿼터 초과 알림
- 잔액 부족 알림
- 노이지한 모니터링 조건의 알림 억제
- 로그 출력의 버스트 방지
hsb.horse