from __future__ import annotations import time from dataclasses import dataclass, field from typing import Any @dataclass class SentMessageEntry: message_id: str chat_id: str text: str sent_at: float status: str = "sent" metadata: dict[str, Any] = field(default_factory=dict) class SentMessageCache: MAX_ENTRIES = 500 TTL_SECONDS = 3600 def __init__(self, max_entries: int = MAX_ENTRIES): self._entries: dict[str, SentMessageEntry] = {} self._max_entries = max_entries def put(self, message_id: str, chat_id: str, text: str, metadata: dict[str, Any] | None = None) -> None: self._evict_if_needed() self._entries[message_id] = SentMessageEntry( message_id=message_id, chat_id=chat_id, text=text, sent_at=time.monotonic(), metadata=metadata or {}, ) def get(self, message_id: str) -> SentMessageEntry | None: entry = self._entries.get(message_id) if entry is None: return None if time.monotonic() - entry.sent_at > self.TTL_SECONDS: del self._entries[message_id] return None return entry def update_status(self, message_id: str, status: str) -> bool: entry = self._entries.get(message_id) if entry is None: return False entry.status = status return True def remove(self, message_id: str) -> bool: if message_id in self._entries: del self._entries[message_id] return True return False def clear(self) -> None: self._entries.clear() def size(self) -> int: return len(self._entries) def _evict_if_needed(self) -> None: while len(self._entries) >= self._max_entries: oldest_key = next(iter(self._entries)) del self._entries[oldest_key]