Implement a two-level caching system (memory + disk) to optimize topic switch response speed, support asynchronous writing, and automatically clean up expired data.

This commit is contained in:
戒酒的李白
2025-02-09 22:06:46 +08:00
parent 607db7317e
commit 8249ec0048
2 changed files with 143 additions and 16 deletions
+116
View File
@@ -0,0 +1,116 @@
import json
import os
import time
from datetime import datetime, timedelta
import threading
import queue
class PredictionCache:
_instance = None
_lock = threading.Lock()
def __new__(cls):
with cls._lock:
if cls._instance is None:
cls._instance = super(PredictionCache, cls).__new__(cls)
return cls._instance
def __init__(self):
if not hasattr(self, 'initialized'):
self.cache_dir = 'cache/predictions'
self.cache_duration = timedelta(hours=24) # 缓存24小时
self.cache = {}
self.cache_queue = queue.Queue()
self.initialized = True
# 确保缓存目录存在
os.makedirs(self.cache_dir, exist_ok=True)
# 启动缓存清理线程
self.cleanup_thread = threading.Thread(target=self._cleanup_old_cache, daemon=True)
self.cleanup_thread.start()
# 加载现有缓存
self._load_cache()
def _load_cache(self):
"""加载磁盘上的缓存文件"""
try:
for filename in os.listdir(self.cache_dir):
if filename.endswith('.json'):
filepath = os.path.join(self.cache_dir, filename)
with open(filepath, 'r', encoding='utf-8') as f:
cache_data = json.load(f)
# 检查缓存是否过期
if self._is_cache_valid(cache_data['timestamp']):
topic = filename[:-5] # 移除.json后缀
self.cache[topic] = cache_data
else:
# 删除过期缓存文件
os.remove(filepath)
except Exception as e:
print(f"加载缓存失败: {e}")
def _cleanup_old_cache(self):
"""定期清理过期缓存的后台线程"""
while True:
try:
# 检查并清理内存缓存
current_time = datetime.now()
expired_topics = []
for topic, cache_data in self.cache.items():
if not self._is_cache_valid(cache_data['timestamp']):
expired_topics.append(topic)
# 删除过期缓存
for topic in expired_topics:
del self.cache[topic]
cache_file = os.path.join(self.cache_dir, f"{topic}.json")
if os.path.exists(cache_file):
os.remove(cache_file)
# 休眠1小时后再次检查
time.sleep(3600)
except Exception as e:
print(f"清理缓存时出错: {e}")
time.sleep(3600) # 发生错误时也等待1小时
def _is_cache_valid(self, timestamp):
"""检查缓存是否有效"""
cache_time = datetime.fromtimestamp(timestamp)
return datetime.now() - cache_time < self.cache_duration
def get(self, topic):
"""获取话题的预测缓存"""
if topic in self.cache and self._is_cache_valid(self.cache[topic]['timestamp']):
return self.cache[topic]['prediction']
return None
def set(self, topic, prediction):
"""设置话题的预测缓存"""
cache_data = {
'prediction': prediction,
'timestamp': datetime.now().timestamp()
}
# 更新内存缓存
self.cache[topic] = cache_data
# 异步保存到磁盘
self.cache_queue.put((topic, cache_data))
threading.Thread(target=self._save_cache_to_disk, daemon=True).start()
def _save_cache_to_disk(self):
"""异步保存缓存到磁盘"""
try:
while not self.cache_queue.empty():
topic, cache_data = self.cache_queue.get()
cache_file = os.path.join(self.cache_dir, f"{topic}.json")
with open(cache_file, 'w', encoding='utf-8') as f:
json.dump(cache_data, f, ensure_ascii=False, indent=2)
except Exception as e:
print(f"保存缓存到磁盘失败: {e}")
# 创建全局缓存实例
prediction_cache = PredictionCache()