105 lines
2.8 KiB
Python
105 lines
2.8 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
Redis缓存模块
|
||
用于缓存账户列表、邮件数据等,加速页面加载
|
||
"""
|
||
|
||
import json
|
||
import logging
|
||
import os
|
||
from typing import Any, Optional
|
||
|
||
import redis.asyncio as redis
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
REDIS_URL = 'redis://:redis_XMiXNa@127.0.0.1:6379/0'
|
||
|
||
# 缓存过期时间(秒)
|
||
TTL_ACCOUNTS = 300 # 账户列表 5分钟
|
||
TTL_MESSAGES = 180 # 邮件列表 3分钟
|
||
TTL_PAYMENT = 600 # 支付状态 10分钟
|
||
|
||
|
||
class RedisCache:
|
||
"""Redis缓存管理器"""
|
||
|
||
def __init__(self):
|
||
self._redis: Optional[redis.Redis] = None
|
||
|
||
async def connect(self):
|
||
try:
|
||
self._redis = redis.from_url(REDIS_URL, decode_responses=True)
|
||
await self._redis.ping()
|
||
logger.info(f"Redis连接成功: {REDIS_URL}")
|
||
except Exception as e:
|
||
logger.warning(f"Redis连接失败,将跳过缓存: {e}")
|
||
self._redis = None
|
||
|
||
async def close(self):
|
||
if self._redis:
|
||
await self._redis.aclose()
|
||
|
||
@property
|
||
def available(self) -> bool:
|
||
return self._redis is not None
|
||
|
||
async def get(self, key: str) -> Optional[Any]:
|
||
if not self._redis:
|
||
return None
|
||
try:
|
||
val = await self._redis.get(key)
|
||
return json.loads(val) if val else None
|
||
except Exception as e:
|
||
logger.debug(f"Redis get 失败 [{key}]: {e}")
|
||
return None
|
||
|
||
async def set(self, key: str, value: Any, ttl: int = 300):
|
||
if not self._redis:
|
||
return
|
||
try:
|
||
await self._redis.set(key, json.dumps(value, ensure_ascii=False), ex=ttl)
|
||
except Exception as e:
|
||
logger.debug(f"Redis set 失败 [{key}]: {e}")
|
||
|
||
async def delete(self, key: str):
|
||
if not self._redis:
|
||
return
|
||
try:
|
||
await self._redis.delete(key)
|
||
except Exception:
|
||
pass
|
||
|
||
async def delete_pattern(self, pattern: str):
|
||
"""删除匹配模式的所有key"""
|
||
if not self._redis:
|
||
return
|
||
try:
|
||
async for key in self._redis.scan_iter(match=pattern, count=100):
|
||
await self._redis.delete(key)
|
||
except Exception:
|
||
pass
|
||
|
||
# ---- 业务快捷方法 ----
|
||
|
||
def accounts_key(self) -> str:
|
||
return "cache:accounts"
|
||
|
||
def messages_key(self, email: str, folder: str) -> str:
|
||
return f"cache:messages:{email}:{folder}"
|
||
|
||
def payment_key(self) -> str:
|
||
return "cache:payment_status"
|
||
|
||
async def invalidate_accounts(self):
|
||
await self.delete(self.accounts_key())
|
||
|
||
async def invalidate_messages(self, email: str):
|
||
await self.delete_pattern(f"cache:messages:{email}:*")
|
||
|
||
async def invalidate_payment(self):
|
||
await self.delete(self.payment_key())
|
||
|
||
|
||
cache = RedisCache()
|