Files
TEMP_spec_system_noad/cache_utils.py
2025-09-25 08:44:44 +08:00

97 lines
3.2 KiB
Python

"""
快取輔助函數
用於提升應用程式效能
"""
from functools import wraps
from flask import request, current_app
from app import cache
import hashlib
import json
def cache_key(*args, **kwargs):
"""生成快取鍵值"""
key_data = {
'args': args,
'kwargs': kwargs,
'user_id': getattr(request, 'user_id', 'anonymous'),
'path': request.path if hasattr(request, 'path') else ''
}
key_string = json.dumps(key_data, sort_keys=True, default=str)
return hashlib.md5(key_string.encode('utf-8')).hexdigest()
def cached_route(timeout=300):
"""路由快取裝飾器"""
def decorator(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if not current_app.config.get('CACHE_TYPE') or current_app.debug:
return f(*args, **kwargs)
key = f"route:{f.__name__}:{cache_key(*args, **kwargs)}"
# 嘗試從快取獲取
cached_result = cache.get(key)
if cached_result is not None:
current_app.logger.debug(f"快取命中: {key}")
return cached_result
# 執行函數並快取結果
result = f(*args, **kwargs)
cache.set(key, result, timeout=timeout)
current_app.logger.debug(f"快取設定: {key}")
return result
return decorated_function
return decorator
def cached_query(timeout=300):
"""資料庫查詢快取裝飾器"""
def decorator(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if not current_app.config.get('CACHE_TYPE') or current_app.debug:
return f(*args, **kwargs)
key = f"query:{f.__name__}:{cache_key(*args, **kwargs)}"
# 嘗試從快取獲取
cached_result = cache.get(key)
if cached_result is not None:
current_app.logger.debug(f"查詢快取命中: {key}")
return cached_result
# 執行查詢並快取結果
result = f(*args, **kwargs)
cache.set(key, result, timeout=timeout)
current_app.logger.debug(f"查詢快取設定: {key}")
return result
return decorated_function
return decorator
def invalidate_cache(pattern):
"""清除快取"""
try:
if hasattr(cache, 'delete_many'):
# Redis backend
keys = cache.cache._read_clients.keys(f"flask_cache_{pattern}*")
if keys:
cache.delete_many(*keys)
current_app.logger.info(f"清除快取: {len(keys)} 個項目")
else:
# Simple cache backend
cache.clear()
current_app.logger.info("清除所有快取")
except Exception as e:
current_app.logger.error(f"清除快取失敗: {e}")
# 快取統計
def cache_stats():
"""獲取快取統計資訊"""
try:
if hasattr(cache.cache, 'info'):
return cache.cache.info()
else:
return {"status": "simple cache", "info": "無統計資訊"}
except Exception as e:
return {"error": str(e)}