You've already forked FrameTour-RenderWorker
feat(cache): 实现上传文件缓存功能
- 在文件上传成功后将文件加入缓存系统 - 添加 add_to_cache 方法支持本地文件缓存 - 实现原子操作确保缓存写入安全 - 集成锁机制防止并发冲突 - 自动触发缓存清理策略 - 记录详细的缓存操作日志
This commit is contained in:
@@ -464,6 +464,11 @@ class BaseHandler(TaskHandler, ABC):
|
|||||||
if result:
|
if result:
|
||||||
file_size = os.path.getsize(file_path)
|
file_size = os.path.getsize(file_path)
|
||||||
logger.info(f"[task:{task_id}] Uploaded: {file_path} ({file_size} bytes)")
|
logger.info(f"[task:{task_id}] Uploaded: {file_path} ({file_size} bytes)")
|
||||||
|
|
||||||
|
# 将上传成功的文件加入缓存
|
||||||
|
if access_url:
|
||||||
|
self.material_cache.add_to_cache(access_url, file_path)
|
||||||
|
|
||||||
return access_url
|
return access_url
|
||||||
else:
|
else:
|
||||||
logger.error(f"[task:{task_id}] Upload failed: {file_path}")
|
logger.error(f"[task:{task_id}] Upload failed: {file_path}")
|
||||||
|
|||||||
@@ -251,6 +251,66 @@ class MaterialCache:
|
|||||||
finally:
|
finally:
|
||||||
self._release_lock(lock_path)
|
self._release_lock(lock_path)
|
||||||
|
|
||||||
|
def add_to_cache(self, url: str, source_path: str) -> bool:
|
||||||
|
"""
|
||||||
|
将本地文件添加到缓存
|
||||||
|
|
||||||
|
Args:
|
||||||
|
url: 对应的 URL(用于生成缓存键)
|
||||||
|
source_path: 本地文件路径
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
是否成功
|
||||||
|
"""
|
||||||
|
if not self.enabled:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if not os.path.exists(source_path):
|
||||||
|
logger.warning(f"Source file not found for cache: {source_path}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
cache_key = _extract_cache_key(url)
|
||||||
|
lock_path = self._acquire_lock(cache_key)
|
||||||
|
if not lock_path:
|
||||||
|
logger.warning(f"Cache lock unavailable for adding: {url[:80]}...")
|
||||||
|
return False
|
||||||
|
|
||||||
|
try:
|
||||||
|
cache_path = self.get_cache_path(url)
|
||||||
|
|
||||||
|
# 先复制到临时文件
|
||||||
|
temp_cache_path = os.path.join(
|
||||||
|
self.cache_dir,
|
||||||
|
f"{cache_key}.{uuid.uuid4().hex}.adding"
|
||||||
|
)
|
||||||
|
|
||||||
|
shutil.copy2(source_path, temp_cache_path)
|
||||||
|
|
||||||
|
# 原子替换
|
||||||
|
os.replace(temp_cache_path, cache_path)
|
||||||
|
|
||||||
|
# 更新访问时间
|
||||||
|
os.utime(cache_path, None)
|
||||||
|
|
||||||
|
logger.info(f"Added to cache: {url[:80]}... <- {source_path}")
|
||||||
|
|
||||||
|
# 检查清理
|
||||||
|
if self.max_size_bytes > 0:
|
||||||
|
self._cleanup_if_needed()
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Failed to add to cache: {e}")
|
||||||
|
if 'temp_cache_path' in locals() and os.path.exists(temp_cache_path):
|
||||||
|
try:
|
||||||
|
os.remove(temp_cache_path)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
return False
|
||||||
|
finally:
|
||||||
|
self._release_lock(lock_path)
|
||||||
|
|
||||||
def _cleanup_if_needed(self) -> None:
|
def _cleanup_if_needed(self) -> None:
|
||||||
"""
|
"""
|
||||||
检查并清理缓存(LRU 策略)
|
检查并清理缓存(LRU 策略)
|
||||||
|
|||||||
Reference in New Issue
Block a user