Skip to content
This repository was archived by the owner on Aug 14, 2026. It is now read-only.

Default localCacheMode to move-directory; add EXDEV copy fallback - #41

Merged
frostebite merged 2 commits into
remove-canonical-overlay-cachefrom
default-move-directory-exdev-fallback
Aug 12, 2026
Merged

frostebite merged 2 commits into
remove-canonical-overlay-cachefrom
default-move-directory-exdev-fallback

Conversation

@frostebite

Copy link
Copy Markdown
Member

Summary

Stacked on #40 (canonical-overlay removal) — second piece of the game-ci/roadmap#11 caching workstream.

  • Switches the default localCacheMode from tar to move-directory. tar archives + extracts (copies bytes twice) on every restore/save; move-directory is an O(1) atomic rename. This matches the pattern child-workspace-service.ts already uses successfully.
  • tar remains fully available as an explicit opt-in (localCacheMode: tar) — still the right choice when distributing cache entries via the existing rclone/S3 built-in container hooks, since those push/pull tar archives.
  • Adds an EXDEV/EPERM → copy fallback (renameOrCopy helper) in both local-cache-service.ts and child-workspace-service.ts. Previously a cross-volume rename (e.g. localCacheRoot/parentCacheRoot misconfigured on a different volume than the workspace) was an unhandled failure — it threw, and the caller's catch-all just discarded the cache and started fresh. Now it degrades gracefully to a copy + source cleanup (same net effect as a successful rename, just slower).

Why

Audit and rationale in game-ci/roadmap#11 (workstream 1). Short version: tar's double-copy cost is the most expensive path for large Library trees and shouldn't be the silent default; move-directory already existed and already worked, it just wasn't chosen automatically. The EXDEV gap was a real correctness issue independent of the default question — worth fixing regardless of which mode is default.

Test plan

  • yarn typecheck — clean
  • yarn lint — 0 errors
  • yarn test — 923/924 passing (1 pre-existing, unrelated flaky timeout in cli-integration.test.ts, confirmed passing in isolation and untouched by this diff)
  • Updated 2 existing tests that implicitly relied on tar being the default to explicitly request tar mode
  • Added 4 new tests: default-mode rename on both restore and save, EXDEV fallback on both restore and save

Ref: game-ci/roadmap#11

Switches the default local cache mode from tar (archive+extract,
copies bytes twice) to move-directory (O(1) atomic rename), matching
child-workspace-service's already-proven pattern. tar remains
available as an explicit opt-in, e.g. for distributing cache entries
via the existing rclone/S3 built-in container hooks.

Adds a renameOrCopy fallback in both local-cache-service.ts and
child-workspace-service.ts: a cross-volume rename (EXDEV) or
permissions failure (EPERM) now degrades to a copy + source cleanup
instead of throwing and losing the cache entirely. Previously this
was an unhandled failure mode in both services.

Updates two existing tests that implicitly relied on tar being the
default to explicitly request tar mode, and adds new coverage for the
new default and the EXDEV fallback on both restore and save paths.

Part of the game-ci/roadmap#11 caching workstream, following on from
#40 (canonical-overlay removal).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 12, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 973694cc-b0f4-4407-bfc3-4c0c9ab899ff

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

frostebite added a commit to game-ci/documentation that referenced this pull request Aug 12, 2026
Follow-up to the earlier canonical-overlay removal commit, now that
game-ci/orchestrator#41 has landed switching the default localCacheMode
from tar to move-directory:

- build-services.mdx: updates the Cache Mode table and Inputs table to
  show move-directory as default, and notes the new automatic EXDEV
  copy fallback for cross-volume setups.
- caching.mdx: corrects the removal note (previously said tar was
  still the default) and updates the roadmap#11 follow-up summary to
  drop the now-completed default-switch item.
- Also removes an orphaned cacheSentinelCanary table row left over
  from the canonical-overlay removal edit, and restores a missing
  blank line before a heading.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
"local" no longer accurately describes this input now that
distributed caching via the rclone/S3 built-in container hooks is a
supported (if not-yet-unified, see #42) path.

localCacheMode keeps working as a deprecated alias — existing
workflows aren't broken, but get a one-time deprecation warning
pointing at cacheMode. Internal call sites now read config.cacheMode.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@frostebite
frostebite marked this pull request as ready for review August 12, 2026 21:39
@frostebite
frostebite merged commit fc7b901 into remove-canonical-overlay-cache Aug 12, 2026
1 check passed
@frostebite

Copy link
Copy Markdown
Member Author

⚠️ This PR shows as Merged, but its content never actually reached main. It was stacked on #40's branch and merged into that branch — but #40's branch was itself squash-merged into main 12 seconds before this merge happened, so this PR's payload (default cacheMode → move-directory, EXDEV/EPERM fallback, cacheMode rename) landed on a now-orphaned branch instead.

Superseded by #44, which cherry-picks this PR's actual content onto current main (plus one more fix — the deprecation warning was firing on every read instead of once).

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant