import time import logging from yuxi.channel.extensions.intercom.constants import ( INTERCOM_DEDUPE_TTL_SECONDS, INTERCOM_DEDUPE_MAX_SIZE, ) logger = logging.getLogger(__name__) class DedupeCache: def __init__(self, ttl_seconds: int = INTERCOM_DEDUPE_TTL_SECONDS, max_size: int = INTERCOM_DEDUPE_MAX_SIZE): self._ttl = ttl_seconds self._max_size = max_size self._cache: dict[str, float] = {} def is_duplicate(self, event_id: str) -> bool: if not event_id: return False now = time.monotonic() if event_id in self._cache: if now - self._cache[event_id] < self._ttl: return True self._cache[event_id] = now self._evict_expired(now) return False def check_duplicate(self, event_id: str) -> bool: if not event_id: return False now = time.monotonic() if event_id in self._cache: if now - self._cache[event_id] < self._ttl: return True return False def mark_seen(self, event_id: str) -> None: if not event_id: return self._cache[event_id] = time.monotonic() self._evict_expired(time.monotonic()) def reset(self) -> None: self._cache.clear() def _evict_expired(self, now: float) -> None: if len(self._cache) <= self._max_size: expired = [k for k, v in self._cache.items() if now - v >= self._ttl] for k in expired: del self._cache[k] if len(self._cache) > self._max_size: sorted_keys = sorted(self._cache, key=self._cache.get) for k in sorted_keys[: len(self._cache) - self._max_size]: del self._cache[k] def clear(self) -> None: self._cache.clear()