Skip to content

fix: use cached bootstrap registry files instead of downloading - #55

Merged
wolveix merged 4 commits into
mainfrom
fix/bootstrap-cache-reuse
Sep 4, 2026
Merged

fix: use cached bootstrap registry files instead of downloading#55
wolveix merged 4 commits into
mainfrom
fix/bootstrap-cache-reuse

Conversation

@wolveix

@wolveix wolveix commented Sep 4, 2026

Copy link
Copy Markdown
Member

Fixes #54.

Lookup() only loaded a cached Service Registry file into memory when the cache reported ShouldReload, which only DiskCache ever returns. A caller who pre-populates a MemoryCache (e.g. with a //go:embeded dns.json) therefore got a download anyway, which also overwrote their embedded copy.

Fixing that surfaced a second bug: Expired was handled nowhere, so a long-lived Client never refreshed its registries at all, contrary to the documented 24 hour refresh. Expired files are now re-downloaded, falling back to the stale cached copy if the download fails, since registry files change rarely and a stale copy beats a failed lookup.

Three regression tests, each verified to fail without the change, plus a doc example for the embed use case.

Summary by CodeRabbit

  • New Features

    • Pre-populated service registry cache data can now be used without an initial download.
    • Expired cached registry data is refreshed automatically when possible.
    • Registry lookups can fall back to previously loaded data if a refresh download fails.
    • Cached registry data is loaded into memory when needed for faster subsequent lookups.
  • Bug Fixes

    • Improved handling of corrupt cache data and failed downloads, with clearer error behavior.

Lookup() only parsed a cached Service Registry file into memory when the
cache reported ShouldReload, a state only DiskCache returns. Two bugs
followed from that:

A caller-populated cache was ignored. MemoryCache reports Good straight
after Save(), so a registry embedded with //go:embed left registries[type]
nil and triggered a download that also overwrote the embedded copy.

An expired file was never refreshed. Once parsed, registries[type] was
non-nil and Expired was ignored, so a long lived Client served the same
file forever, contrary to the documented 24 hour refresh.

Load from the cache whenever nothing is parsed yet and the cached copy is
usable, force a download once it expires, and fall back to the expired
copy if that download fails. Registry files change rarely, so a stale copy
beats a failed lookup, and this makes the "returned even if its State() is
Expired" contract of both caches reachable.

Fixes #54
@coderabbitai

coderabbitai Bot commented Sep 4, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

Next included review available in 46 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 2 included reviews currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: 134015ca-7bd6-4ecd-bba0-ee8965d2be17

📥 Commits

Reviewing files that changed from the base of the PR and between f73230a and 334576e.

📒 Files selected for processing (1)
  • bootstrap/client_test.go
📝 Walkthrough

Walkthrough

The bootstrap client loads pre-populated cache files into memory. It refreshes expired cache entries and uses cached registry data when downloads fail. New tests cover cache loading, refresh, fallback, and corrupt-cache errors. The module now targets Go 1.26.0, updates two dependencies, and tests only Go 1.26.x.

Merge Risk: 🔵 Low · up to f7323

The bootstrap client now uses embedded or cached registry data and falls back to stale data after refresh failures. Merge risk is low, but two cache tests may not detect download-behavior regressions, and the CI version comment is inaccurate.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The cache behavior and regression tests are in scope for issue #54. The Go version change, dependency upgrades, and workflow matrix changes are not directly related to the issue requirements. Move the Go version, dependency, and workflow changes to a separate pull request, or document why each change is required for the cache fix.
Docstring Coverage ⚠️ Warning Docstring coverage is 57.14% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 7 functions across 2 files. (1 skipped: 1… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: using cached bootstrap registry files instead of downloading them.
Linked Issues check ✅ Passed The bootstrap client now loads usable pre-populated cache files, avoids unnecessary downloads, refreshes expired files, and falls back to stale cached data when downloads fail. These changes satisfy i…
Full details: Linked Issues check

Explanation

The bootstrap client now loads usable pre-populated cache files, avoids unnecessary downloads, refreshes expired files, and falls back to stale cached data when downloads fail. These changes satisfy issue #54.

Full details: Docstring Coverage

Explanation

Docstring coverage is 57.14% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 7 functions across 2 files. (1 skipped: 1 unsupported.)

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/bootstrap-cache-reuse

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: e7566881-e48e-41fd-8c69-7fe2da251ac9

📥 Commits

Reviewing files that changed from the base of the PR and between c9246cb and 483fd30.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (3)
  • bootstrap/client.go
  • bootstrap/client_test.go
  • go.mod

Included review availability: Your plan provides up to 2 included reviews per hour; 1 remains after this review.

Comment thread bootstrap/client_test.go

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: 1c8fbf31-e5d5-4cb7-8d07-61a0224805e7

📥 Commits

Reviewing files that changed from the base of the PR and between 483fd30 and f73230a.

📒 Files selected for processing (1)
  • .github/workflows/tests.yml

Included review availability: Your plan provides up to 2 included reviews per hour; 0 remain after this review.

Comment thread .github/workflows/tests.yml
Both tests only checked the answer, so they passed for the wrong reasons.
TestLookupUsesPrePopulatedCache would stay green if Lookup downloaded
anyway, because the 404 hits the expired-copy fallback and keeps the
already-loaded registry. TestLookupFallsBackToExpiredCache would stay
green if the refresh attempt were skipped entirely.

Assert a httpmock call delta of 0 and 1 respectively.
@wolveix
wolveix merged commit b4d5927 into main Sep 4, 2026
4 checks passed
@wolveix
wolveix deleted the fix/bootstrap-cache-reuse branch September 4, 2026 00:59
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.

How do you create a new MemoryCache and populate it with an embedded copy of the dns.json file to prevent downloading the file?

1 participant