-
Notifications
You must be signed in to change notification settings - Fork 199
Write to cache when building a template #1133
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
d141efb to
f8f1a6f
Compare
68ece42 to
5130329
Compare
|
@djeebus Let's split to PR preparing for this change (refactor) and adding the caching behavior. |
2b47e2d to
5e6fc67
Compare
OK, I've removed all the nice-to-haves, the rest will go in other PRs. |
|
There is currently a mismatch between reading/writing whole files and reading/writing chunked files. We need to do things:
|
|
This is blocked by #1361 ; will refactor after that gets merged. |
b258581 to
77192cf
Compare
# Conflicts: # packages/shared/pkg/feature-flags/flags.go
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| go c.writeFileToCache( | ||
| context.WithoutCancel(ctx), | ||
| bytes.NewReader(p), | ||
| cacheOpWrite, | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid async caching from caller buffer after Write returns
The new Write implementation spawns a goroutine that streams bytes.NewReader(p) into the cache while immediately returning the result of inner.Write. Because p is provided by the caller, the io.Writer contract allows the caller to reuse or mutate the slice as soon as Write returns; the goroutine may therefore read modified data or race with the caller and cache corrupted bytes even when the remote write succeeded. Copy the data or defer launching the cache write until after the payload is safely owned to prevent serving incorrect cached content.
Useful? React with 👍 / 👎.
|
My one concern here is that because some teams are building tens of thousands of templates, this might start ejecting things disproportionately. |
| templateStorage = storage.NewCachedProvider(path, templateStorage) | ||
| } | ||
|
|
||
| index := cache.NewHashIndex(bc.CacheScope, builder.buildStorage, templateStorage) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: NFS cache wrapping not applied to storage operations
The templateStorage variable is wrapped with NewCachedProvider at lines 229-231 to enable NFS caching, but the unwrapped builder.templateStorage is then passed to layerExecutor (line 241), baseBuilder (line 251), and postProcessingBuilder (line 293). Additionally, the unwrapped builder.templateStorage is used at line 327 for getRootfsSize. This means the cache wrapping is never actually used for any storage operations, defeating the entire purpose of the caching feature introduced in this PR.
|
|
||
| c.writeFileToCache(ctx, input, cacheOpWriteFromFileSystem) | ||
| }(context.WithoutCancel(ctx)) | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: File descriptor leak in WriteFromFileSystem cache operation
In WriteFromFileSystem, a file is opened at line 93 but never closed. The *os.File is passed as an io.Reader to writeFileToCache, which cannot close it since it only accepts the io.Reader interface. The goroutine runs asynchronously and leaves the file handle open, causing file descriptor leaks over time.
|
Okay, I'll work on getting a cache effectiveness dashboard added. We can monitor that to see if cache effectiveness goes down, and disable via flag if it doesn't improve things. Does that work? |
Note
Adds an NFS-backed cache for template builds behind a feature flag, introduces atomic file writes, updates storage interfaces, and enhances cache metrics/tracing with comprehensive tests.
templateStoragewithstorage.NewCachedProviderduring build viauseNFSCache, gated byfeatureflags.BuildingFeatureFlagNameandSharedChunkCacheDir.BuildingFeatureFlagName(use-nfs-for-building-templates).WriteFromFSCtx; updateObjectProviderandSeekableObjectProviderto use it.lock.AtomicFilewithOpenFilefor atomic, lock-guarded writes; tests included.DeleteObjectsWithPrefix.ops,bytes) with hit/miss and operation tags.Write/WriteFromFileSystem, write to remote and cache concurrently; uselock.OpenFilefor atomic cache writes.ReadAt/Sizeto report cache hit/miss, record errors, and async backfill cache.moveWithoutReplaceand cleanup helpers; refine EOF handling.Written by Cursor Bugbot for commit 83bcfe4. This will update automatically on new commits. Configure here.