from __future__ import annotations import asyncio from collections import OrderedDict from typing import Any, TYPE_CHECKING if TYPE_CHECKING: pass _MAX_CACHE_SIZE = 100 class MessageCache: def __init__(self): self._cache: dict[str, OrderedDict[str, dict[str, Any]]] = {} self._sent_ids: OrderedDict[str, float] = OrderedDict() self._sent_max = 200 self._lock = asyncio.Lock() async def cache_message(self, msg_id: str, channel_id: str, content: str, author: str) -> None: entry = { "id": msg_id, "author": author, "content": content, } async with self._lock: if channel_id not in self._cache: self._cache[channel_id] = OrderedDict() if msg_id: self._cache[channel_id][msg_id] = entry self._cache[channel_id].move_to_end(msg_id) if len(self._cache[channel_id]) > _MAX_CACHE_SIZE: self._cache[channel_id].popitem(last=False) async def get_channel_history(self, channel_id: str, limit: int = 50) -> list[dict[str, Any]]: async with self._lock: if channel_id not in self._cache: return [] items = list(self._cache[channel_id].values()) return items[-limit:] async def get_recent(self, channel_id: str, limit: int = 50) -> list[dict[str, Any]]: async with self._lock: if channel_id not in self._cache: return [] items = list(self._cache[channel_id].values()) return items[-limit:] async def track_sent_message(self, msg_id: str) -> None: import time async with self._lock: self._sent_ids[msg_id] = time.monotonic() self._sent_ids.move_to_end(msg_id) if len(self._sent_ids) > self._sent_max: self._sent_ids.popitem(last=False) async def is_sent(self, msg_id: str) -> bool: async with self._lock: return msg_id in self._sent_ids async def clear_channel(self, channel_id: str) -> None: async with self._lock: self._cache.pop(channel_id, None)