Files
server-core/app/infrastructure/cache.py
T
Pine 980a2db6d9 refactor: 平台应用异步四层架构(接口/业务/领域/基础设施)
- 基础设施层 async:SQLAlchemy 异步引擎/会话、33 Repository async 化、models/security/seed 迁入 infrastructure、新增 cache.py(redis.asyncio) 与 oss.py(aioboto3)
- 接口层:routers 迁 api/routers 并全 async,dependencies 迁 api/dependencies(get_db/get_current_user async)
- 依赖:sqlalchemy[asyncio]/aiosqlite/asyncmy/redis/aioboto3;config 异步 URL + Redis/OSS 配置
- 删除废弃:旧同步 db/dependencies/repositories/storage
- 验证:平台 19 路由 + 培训 48 路由全注册;/health /auth/login /auth/me /admin/tasks /notifications 等接口 async 可用
2026-08-23 23:52:58 +08:00

61 lines
1.9 KiB
Python

# -*- coding: utf-8 -*-
"""基础设施层 · Redis 异步封装(缓存 / 限流 / 分布式锁)。"""
from __future__ import annotations
import asyncio
from typing import Any, Optional
from redis.asyncio import Redis
from .. import config
class Cache:
"""redis.asyncio 封装:连接池 / get / set / incr / 分布式锁(SET NX EX)。"""
def __init__(self, url: str | None = None) -> None:
self._redis: Optional[Redis] = None
self._url = url or config.REDIS_URL
async def connect(self) -> None:
if self._redis is None:
self._redis = Redis.from_url(self._url, decode_responses=True)
async def close(self) -> None:
if self._redis is not None:
await self._redis.aclose()
self._redis = None
async def get(self, key: str) -> str | None:
if self._redis is None:
return None
return await self._redis.get(key)
async def set(self, key: str, value: str, ttl: int | None = None) -> None:
if self._redis is None:
return
await self._redis.set(key, value, ex=ttl)
async def delete(self, key: str) -> None:
if self._redis is None:
return
await self._redis.delete(key)
async def incr(self, key: str) -> int:
if self._redis is None:
return 0
return int(await self._redis.incr(key))
async def lock(self, key: str, ttl: int = 30) -> bool:
"""分布式锁:SET key token NX EX ttl(成功拿到锁返回 True)。"""
if self._redis is None:
return True # 无 Redis 时降级为总是通过(单机部署)
token = f"{asyncio.get_event_loop().time()}"
ok = await self._redis.set(key, token, nx=True, ex=ttl)
return bool(ok)
async def unlock(self, key: str) -> None:
if self._redis is None:
return
await self._redis.delete(key)