PostgreSQL + async refactoring, WebSocket server, Redis caching, minified assets

This commit is contained in:
2026-07-25 13:31:40 +00:00
parent 47c7f17c90
commit 17da0b6d79
28 changed files with 1840 additions and 3244 deletions
+67
View File
@@ -0,0 +1,67 @@
import os
import json
import asyncio
from typing import Optional, Any, Callable, Awaitable
from datetime import timedelta
REDIS_URL = os.getenv("REDIS_URL", "redis://localhost:6379/0")
CACHE_TTL = int(os.getenv("CACHE_TTL", "300"))
_redis_pool = None
_lock = asyncio.Lock()
async def get_redis():
global _redis_pool
if _redis_pool is None:
import aioredis
async with _lock:
if _redis_pool is None:
_redis_pool = await aioredis.from_url(REDIS_URL, decode_responses=True)
return _redis_pool
async def cache_get(key: str) -> Optional[Any]:
try:
r = await get_redis()
val = await r.get(key)
if val:
return json.loads(val)
except Exception:
pass
return None
async def cache_set(key: str, value: Any, ttl: int = CACHE_TTL):
try:
r = await get_redis()
await r.setex(key, ttl, json.dumps(value, default=str))
except Exception:
pass
async def cache_delete(key: str):
try:
r = await get_redis()
await r.delete(key)
except Exception:
pass
async def cache_get_or_set(key: str, factory: Callable[[], Awaitable[Any]], ttl: int = CACHE_TTL) -> Any:
cached = await cache_get(key)
if cached is not None:
return cached
value = await factory()
await cache_set(key, value, ttl)
return value
async def cache_invalidate_pattern(pattern: str):
try:
r = await get_redis()
keys = await r.keys(pattern)
if keys:
await r.delete(*keys)
except Exception:
pass