daily-briefing/server/cache.py

42 lines
1.1 KiB
Python
Raw Normal View History

"""Simple async-safe TTL cache."""
from __future__ import annotations
import asyncio
import time
from typing import Any, Dict, Optional, Tuple
class TTLCache:
"""Thread/async-safe in-memory cache with per-key TTL."""
def __init__(self) -> None:
self._store: Dict[str, Tuple[Any, float]] = {}
self._lock = asyncio.Lock()
async def get(self, key: str) -> Optional[Any]:
async with self._lock:
entry = self._store.get(key)
if entry is None:
return None
value, expires_at = entry
if time.time() > expires_at:
del self._store[key]
return None
return value
async def set(self, key: str, value: Any, ttl: int) -> None:
async with self._lock:
self._store[key] = (value, time.time() + ttl)
async def invalidate(self, key: str) -> None:
async with self._lock:
self._store.pop(key, None)
async def clear(self) -> None:
async with self._lock:
self._store.clear()
cache = TTLCache()