You've already forked FrameTour-RenderWorker
perf(cache): 优化缓存下载逻辑并添加性能指标追踪
- 实现了带等待时间统计的缓存锁获取功能 - 新增 get_or_download_with_metrics 方法返回详细的性能指标 - 在 tracing span 中记录锁等待时间、锁获取状态和缓存路径使用情况 - 优化缓存命中路径避免不必要的锁获取操作 - 添加了缓存文件就绪检查和复制功能的独立方法 - 增加了针对缓存锁超时但仍可使用就绪缓存的处理逻辑 - 新增了多个单元测试验证缓存锁定和指标报告功能
This commit is contained in:
@@ -13,3 +13,89 @@ def test_cache_lock_acquire_release(tmp_path):
|
||||
assert os.path.exists(lock_path)
|
||||
cache._release_lock(lock_path)
|
||||
assert not os.path.exists(lock_path)
|
||||
|
||||
|
||||
def test_get_or_download_cache_hit_does_not_wait_lock(tmp_path, monkeypatch):
|
||||
cache = MaterialCache(cache_dir=str(tmp_path), enabled=True, max_size_gb=0)
|
||||
url = "https://example.com/path/video.mp4?token=abc"
|
||||
cache_path = cache.get_cache_path(url)
|
||||
with open(cache_path, 'wb') as file_obj:
|
||||
file_obj.write(b'cached-data')
|
||||
destination = tmp_path / "result.bin"
|
||||
|
||||
def _unexpected_acquire(*args, **kwargs):
|
||||
raise AssertionError("cache hit path should not acquire lock")
|
||||
|
||||
monkeypatch.setattr(cache, "_acquire_lock", _unexpected_acquire)
|
||||
|
||||
assert cache.get_or_download(url, str(destination), timeout=1) is True
|
||||
assert destination.read_bytes() == b'cached-data'
|
||||
|
||||
|
||||
def test_get_or_download_lock_timeout_can_still_use_ready_cache(tmp_path, monkeypatch):
|
||||
cache = MaterialCache(cache_dir=str(tmp_path), enabled=True, max_size_gb=0)
|
||||
url = "https://example.com/path/audio.aac?token=abc"
|
||||
cache_path = cache.get_cache_path(url)
|
||||
with open(cache_path, 'wb') as file_obj:
|
||||
file_obj.write(b'audio-cache')
|
||||
destination = tmp_path / "audio.aac"
|
||||
download_called = {"value": False}
|
||||
|
||||
monkeypatch.setattr(cache, "_acquire_lock", lambda *args, **kwargs: None)
|
||||
|
||||
def _fake_download(*args, **kwargs):
|
||||
download_called["value"] = True
|
||||
return False
|
||||
|
||||
monkeypatch.setattr("services.cache.storage.download_file", _fake_download)
|
||||
|
||||
assert cache.get_or_download(url, str(destination), timeout=1) is True
|
||||
assert destination.read_bytes() == b'audio-cache'
|
||||
assert download_called["value"] is False
|
||||
|
||||
|
||||
def test_get_or_download_uses_short_lock_timeout(tmp_path, monkeypatch):
|
||||
cache = MaterialCache(cache_dir=str(tmp_path), enabled=True, max_size_gb=0)
|
||||
url = "https://example.com/path/segment.ts?token=abc"
|
||||
destination = tmp_path / "segment.ts"
|
||||
captured = {"timeout_sec": None}
|
||||
|
||||
def _fake_acquire(cache_key, timeout_sec=None):
|
||||
captured["timeout_sec"] = timeout_sec
|
||||
return None
|
||||
|
||||
monkeypatch.setattr(cache, "_acquire_lock", _fake_acquire)
|
||||
monkeypatch.setattr("services.cache.storage.download_file", lambda *args, **kwargs: True)
|
||||
|
||||
assert cache.get_or_download(url, str(destination), timeout=1) is True
|
||||
assert captured["timeout_sec"] == cache.DOWNLOAD_LOCK_TIMEOUT_SEC
|
||||
|
||||
|
||||
def test_get_or_download_with_metrics_cache_hit_wait_zero(tmp_path):
|
||||
cache = MaterialCache(cache_dir=str(tmp_path), enabled=True, max_size_gb=0)
|
||||
url = "https://example.com/path/hit.mp4?token=abc"
|
||||
cache_path = cache.get_cache_path(url)
|
||||
with open(cache_path, 'wb') as file_obj:
|
||||
file_obj.write(b'hit-data')
|
||||
destination = tmp_path / "hit.mp4"
|
||||
|
||||
success, metrics = cache.get_or_download_with_metrics(url, str(destination), timeout=1)
|
||||
assert success is True
|
||||
assert metrics["lock_wait_ms"] == 0
|
||||
assert metrics["lock_acquired"] is False
|
||||
assert metrics["cache_path_used"] == "cache"
|
||||
|
||||
|
||||
def test_get_or_download_with_metrics_reports_lock_wait_ms(tmp_path, monkeypatch):
|
||||
cache = MaterialCache(cache_dir=str(tmp_path), enabled=True, max_size_gb=0)
|
||||
url = "https://example.com/path/miss.mp4?token=abc"
|
||||
destination = tmp_path / "miss.mp4"
|
||||
|
||||
monkeypatch.setattr(cache, "_acquire_lock_with_wait", lambda *args, **kwargs: (None, 4321))
|
||||
monkeypatch.setattr("services.cache.storage.download_file", lambda *args, **kwargs: True)
|
||||
|
||||
success, metrics = cache.get_or_download_with_metrics(url, str(destination), timeout=1)
|
||||
assert success is True
|
||||
assert metrics["lock_wait_ms"] == 4321
|
||||
assert metrics["lock_acquired"] is False
|
||||
assert metrics["cache_path_used"] == "direct"
|
||||
|
||||
Reference in New Issue
Block a user