""" 快取輔助函數 用於提升應用程式效能 """ 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)}