Skip to content

[Fix] Scope artifact caches to registry endpoint - #72

Open
Snakinya wants to merge 1 commit into
modelscope:mainfrom
Snakinya:fix/endpoint-scoped-cache
Open

Snakinya wants to merge 1 commit into
modelscope:mainfrom
Snakinya:fix/endpoint-scoped-cache

Conversation

@Snakinya

Copy link
Copy Markdown

Summary

  • Bind artifact caches from custom registries to a normalized endpoint namespace.
  • Keep the existing cache layout for the default ModelScope service.
  • Apply the same namespace to downloads, offline lookup, verification, scanning, clearing, and download locks.

Problem

HubApi supports selecting a registry with endpoint, but the physical cache identity currently contains only:

cache_dir / repo_type / repo_id / revision / file_path

The endpoint that supplied the bytes is not represented. If two compatible registries expose the same logical coordinates, the second request can return the first registry's cached artifact without making an artifact request to the current registry.

Minimal sequence:

  1. Create clients for registry A and registry B.
  2. Use the same cache_dir, repo id, revision, and file path with both clients.
  3. Let A return an A-specific canary and B return a B-specific canary.
  4. Download through A, then request the same file through B.

Before this change, the B request returns A's bytes and B receives no artifact GET. The behavior also reproduces in the reverse order. This allows content from one registry to remain effective after the caller switches to another registry using the same cache.

The regression test exercises the public HubApi.download_file() path with two registry identities and endpoint-specific payloads.

Implementation

The default service retains the historical path so existing ModelScope caches remain usable:

{cache_dir}/{type}s/{owner}--{name}/...

Custom registries use a SHA-256 namespace derived from their normalized endpoint:

{cache_dir}/endpoints/{endpoint_sha256}/{type}s/{owner}--{name}/...

Unscoped legacy caches are only reused by the default endpoint. Cache inspection, verification and deletion operate on the current client's endpoint namespace as well.

Users of custom endpoints will download artifacts once into the new namespace. Explicit local_dir behavior is unchanged because that path is caller-managed rather than an SDK cache.

Verification

The issue was reproduced against both:

  • released v0.4.5 (c8f3505530a9a7eaa1b0a9eb8ac3c797f6c92965);
  • current main (0b2a3bacef4cbeccfd9a64545149d56cb1bb98a1).

Three fresh loopback-registry processes per target reproduced both A-to-B and B-to-A reuse. In every baseline run, the second registry received zero artifact GETs. Three fresh verification processes with this patch returned the current registry's canary in both directions and issued one artifact GET to that registry.

Local checks:

pytest tests/ --ignore=tests/integration -q
1160 passed, 38 skipped

ruff check src/ tests/
All checks passed

ruff format --check src/ tests/
109 files already formatted

mypy src/modelscope_hub/
Success: no issues found in 46 source files

Keep the historical cache layout for the default service while assigning every custom registry a stable endpoint namespace. Apply the same namespace to downloads, offline lookup, verification, scanning, clearing, and download locks.

Add regression coverage for cross-registry artifact isolation, legacy-cache handling, cache management, and verification.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant