mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-10-11 12:02:12 -03:00
fix(example-images): stop permanently blacklisting models on transient failures
The example-images download loop marked a model as failed in .download_progress.json whenever its metadata had no civitai images or processing raised any exception. Since failed_models is a permanent skip list for non-force runs (and excluded from the pending pre-check), models whose metadata simply had not been fetched yet — or that hit a transient error — were never retried. Users had to delete the progress file to unstick them, and the blacklist re-grew afterwards. - Distinguish 'metadata not fetched yet' (no civitai payload) from confirmed absences (civitai entry present but image-less, or the model is known to be gone from CivitAI via civitai_deleted/from_civitai). Only confirmed absences are marked failed; the rest stay pending. Retrying pending models only re-reads local metadata, so no extra provider API calls are introduced. - Transient processing errors no longer add the model to failed_models. - Add unblock_failed_example_image_models() to remove hashes from the persisted failed list (library-scoped and legacy locations) and from the live download manager's in-memory state. - Hook it into MetadataSyncService.update_model_metadata so a successful metadata fetch/relink immediately re-enables example image downloads for that model — no TTL polling needed.
This commit is contained in:
@@ -300,6 +300,57 @@ async def test_update_model_metadata_raises_when_sidecar_write_fails():
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_update_model_metadata_unblocks_example_image_failures(monkeypatch):
|
||||
"""Persisting fresh provider metadata re-enables example image downloads."""
|
||||
helpers = build_service()
|
||||
|
||||
from py.utils import example_images_download_manager as download_module
|
||||
|
||||
calls: list[list[str]] = []
|
||||
|
||||
def fake_unblock(hashes, library_name=None):
|
||||
calls.append(list(hashes))
|
||||
return len(hashes)
|
||||
|
||||
monkeypatch.setattr(
|
||||
download_module, "unblock_failed_example_image_models", fake_unblock
|
||||
)
|
||||
|
||||
result = await helpers.service.update_model_metadata(
|
||||
"path/to/model.metadata.json",
|
||||
{"sha256": "A" * 64, "model_name": "Local"},
|
||||
{"source": "api", "model": {"name": "Remote"}, "images": []},
|
||||
helpers.default_provider,
|
||||
)
|
||||
|
||||
assert result["model_name"] == "Remote"
|
||||
assert calls == [["a" * 64]]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_update_model_metadata_without_hash_skips_unblock(monkeypatch):
|
||||
helpers = build_service()
|
||||
|
||||
from py.utils import example_images_download_manager as download_module
|
||||
|
||||
def fail_unblock(hashes, library_name=None): # pragma: no cover - must not run
|
||||
raise AssertionError("unblock must not run without a sha256")
|
||||
|
||||
monkeypatch.setattr(
|
||||
download_module, "unblock_failed_example_image_models", fail_unblock
|
||||
)
|
||||
|
||||
result = await helpers.service.update_model_metadata(
|
||||
"path/to/model.metadata.json",
|
||||
{"model_name": "Local"},
|
||||
{"source": "api", "model": {"name": "Remote"}, "images": []},
|
||||
helpers.default_provider,
|
||||
)
|
||||
|
||||
assert result["model_name"] == "Remote"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_fetch_and_update_model_reports_sidecar_write_failure(tmp_path):
|
||||
"""Fetch fails the item (and leaves the cache untouched) when the sidecar
|
||||
|
||||
Reference in New Issue
Block a user