Spaces:
Running on Zero
Running on Zero
File size: 1,060 Bytes
7982d01 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | """In-memory user snapshots (so most updates need ZERO database round-trips)
plus per-user locks (same user's updates run one at a time)."""
import asyncio
import time
import weakref
from typing import Optional
_TTL = 600 # seconds
_MAX = 20_000
_snapshots: dict[int, tuple[float, dict]] = {}
_locks: "weakref.WeakValueDictionary[int, asyncio.Lock]" = weakref.WeakValueDictionary()
def get(user_id: int) -> Optional[dict]:
item = _snapshots.get(user_id)
if item is None:
return None
expires, data = item
if expires < time.monotonic():
_snapshots.pop(user_id, None)
return None
return dict(data)
def put(user_id: int, data: dict) -> None:
if len(_snapshots) >= _MAX:
_snapshots.clear()
_snapshots[user_id] = (time.monotonic() + _TTL, dict(data))
def invalidate(user_id: int) -> None:
_snapshots.pop(user_id, None)
def lock_for(user_id: int) -> asyncio.Lock:
lock = _locks.get(user_id)
if lock is None:
lock = asyncio.Lock()
_locks[user_id] = lock
return lock
|