Skip to content

codeartifact: add bounded metadata caching across package formats - #16

Open
ravi-pplx wants to merge 5 commits into
pplx/mainfrom
ravi/codeartifact-npm-metadata-cache
Open

ravi-pplx wants to merge 5 commits into
pplx/mainfrom
ravi/codeartifact-npm-metadata-cache

Conversation

@ravi-pplx

@ravi-pplx ravi-pplx commented Sep 18, 2026

Copy link
Copy Markdown

Repeated package resolution downloads large metadata documents and repeats URL rewriting even when nothing changes. Sampled CodeArtifact metadata endpoints lacked usable validators, so conditional requests did not avoid downloading the full document.

Add an opt-in, process-local metadata cache shared across npm, PyPI, Cargo, and Swift. Format-specific route and response checks admit metadata; existing artifact download paths retain their behavior. Equivalent concurrent reads share a complete response, and each representation has a non-sliding freshness window.

Configure this inside the existing codeartifact strategy. The enclosing strategy supplies the origin; "*" selects all repositories at that origin. Explicit repository lists are also supported, including PrivateLink routing.

metadata-cache {
  repositories = ["*"]
  formats = ["npm", "pypi", "cargo", "swift"]
  ttl = "30s"
  max-bytes = 67108864
  max-concurrent = 4
}
Format Admitted metadata Handling
npm Package packuments, including scoped packages Rewrite URLs; isolate full/abbreviated and encoding variants.
PyPI Normalized project indexes under /simple/project/ Preserve HTML or Simple API v1 JSON, including links, hashes, and yank attributes.
Cargo Registry config.json and canonical sparse index entries Rewrite config URLs/auth requirement; preserve index bytes and checksums.
Swift Package listings and explicit version.json documents Rewrite URLs; preserve Content-Version: 1.

Swift extensionless version URLs can return archives and remain excluded. NuGet, Maven, Ruby, PyPI distribution sidecars, and other non-admitted routes keep their existing behavior. This replaces the earlier draft npm-metadata-cache block; formats = ["npm"] provides npm-only scope. Package-policy checks still run on every request, without expanding their supported formats.

All selected repositories and formats share the retained-byte budget, 1,024-entry limit, and fill concurrency limit within each strategy instance. Captures above 1 MiB spool to private temporary files. Responses too large to retain are delivered and released after the last reader, including cancellations and write failures. Incomplete streams become 502 responses and cannot populate the cache. Temporary storage and active transformations require resources beyond the retained-byte budget. The existing 64 MiB decoded-input guard for JSON rewriting remains; raw PyPI and Cargo indexes are not subject to that parsing limit.

Origin restrictions, age, and shorter freshness remain authoritative. Forced refresh discards the old representation; final 401/403/404/410/451 responses invalidate all resource variants and prevent older fills from republishing them, even if the error body is truncated. No stale-on-error fallback is used. Conditional, range, cookie, and query requests bypass reuse/storage. Downstream metadata requires revalidation through Cachew. This is an explicit short-lived freshness policy, not ETag-based origin revalidation.

The block is disabled by default. Enabling it can delay visibility of new versions, yanks, removals, or permission changes by the configured interval, and each pod warms independently. Saturated fill capacity returns 503 with Retry-After: 1; callers and service-owned fills each have a one-minute deadline. Metrics use cache_mode=metadata and tier=metadata, with no package names or URLs as labels. README documents configuration, resource requirements, and freshness implications.

Validated the candidate against real CodeArtifact origins for npm, PyPI, Cargo config, Cargo sparse indexes, and Swift listings: each cold/warm pair returned identical bodies with only one upstream request. These checks exercised the local candidate HTTP handler; they were not deployed latency benchmarks or package-manager installation tests.

Allow selected npm repositories to reuse rewritten metadata for an explicit short freshness window. Bound retained data and concurrent fills, coalesce equivalent requests independently of client cancellation, and preserve origin cache restrictions. Invalidate all variants on authoritative removal or revocation and prevent older fills from republishing them. Keep the feature disabled by default and document the visibility-delay tradeoff.
Invalidate retained variants and older fills when bypassed requests observe removal or revoked access. Forced bypasses discard their previous representation even when the origin fails. Recognize PrivateLink repository prefixes only for VPC endpoint origins while preserving domain isolation in full URL keys.

Separate eviction coverage from expiry using an injectable cache clock, and synchronize followers before releasing coalesced fills. Add regression coverage and clarify origin scoping in the documentation.
Separate delivery to concurrent metadata callers from cache retention so errors and oversized responses do not cause serialized refetches. Keep private responses isolated and bound the total wait across retries to one minute.

Expose metadata cache outcomes through bounded metrics and preserve valid responses that expand past the decoded-input limit during rewriting. Cover concurrency, deadline, isolation, and response-size behavior with regression tests.

Verified the full race-enabled integration suite, repeated concurrency regressions, expanded metadata delivery, and golangci-lint.
Add explicit npm, PyPI, Cargo, and Swift route admission to a shared cache, with origin-scoped repository wildcards and encoding-aware keys. Preserve raw Python and Cargo index responses, Swift protocol headers, and existing artifact routes.

Propagate origin stream failures to cache fills and spool larger captures to temporary files, cleaning them up after the last waiter. Add HTTP coverage for cross-format freshness, truncation, repository and format selection, and spool cleanup. Document the replacement metadata-cache schema and supported boundaries.
Observe authoritative origin statuses before capturing their bodies so a truncated error response cannot leave another cached representation available. The caller still receives 502 for an incomplete body.

Add regressions for all invalidating statuses and for concurrent readers sharing an oversized spool when the last writer fails. The invalidation regression failed before the fix; focused race tests pass across five runs.
@ravi-pplx ravi-pplx changed the title codeartifact: add bounded npm metadata caching codeartifact: add bounded metadata caching across package formats Sep 18, 2026
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