Skip to content
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

Custom inline cache implementation #60

Merged
merged 1 commit into from
May 17, 2024

Conversation

mikejholly
Copy link
Contributor

@mikejholly mikejholly commented May 14, 2024

This PR includes a new & simplified inline cache implementation that's compatible with the simple solver.

See comments in PR.

Earthly tests: earthly/earthly#4112

@mikejholly mikejholly force-pushed the mh/next-inline-cache-redux branch 3 times, most recently from a917e12 to 4afd23a Compare May 16, 2024 17:59
Cache []byte `json:"moby.buildkit.cache.v0"`
History []struct {
Cache []byte `json:"moby.buildkit.cache.v0"`
EarthlyInlineCache []byte `json:"earthly.inlinecache.v0"`
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This field is added to an image's "config" and can be viewed using something like crane config. The map of cache keys to registry layer digests is stored here.

@@ -53,7 +53,7 @@ func (w *runcExecutor) monitorContainerStats(ctx context.Context, id string, sam
for {
select {
case <-ctx.Done():
bklog.G(ctx).Infof("stats collection context done: %v", ctx.Err())
bklog.G(ctx).Debugf("stats collection context done: %v", ctx.Err())
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This helps with log noise.

if err != nil {
return nil, err
}
m["earthly.inlinecache.v0"] = dt
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is where the cache key to layer digest data is added.

}

err := inBuilderContext(ctx, b.builder, "earthly inline cache", "", func(ctx context.Context, g session.Group) error {
inlineCacheRemotes, err = registry.EarthlyInlineCacheRemotes(ctx, b.sm, w, b.registryHosts, g, cacheImport.Attrs)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is where remote manifests (including cache relation info) are fetched for the inline cache source.

return nil, err
}

sources := worker.NewCombinedResultSource(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Here's a new abstraction that allows the simple solver to load from a set of result sources. The inline cache remote source is specified here.

// }

if hasInlineCacheExporter(exp.CacheExporters) {
meta, err := earthlyInlineCache(ctx, j, e, cached)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Here, we determine if inline caching is enabled. If so, the cache relationship map is added to the image metadata before the image is passed to the Earthly exporter.


// Hijack the CacheKey type in order to export a reference from the new cache key to the ref ID.
expKeys = append(expKeys, ExportableCacheKey{
CacheKey: &CacheKey{
Copy link
Contributor Author

Choose a reason for hiding this comment

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

In the BuildKit remote caching approach, a complex chain of cache keys are added to ExportableCacheKey. Here, I'm able to stick with the return type (needed by the caller & caller parent) while using a simplified one-to-one cache key to worker ref ID relation.

mu sync.Mutex
}

type cacheMapDep struct {
selector string
computed string
selector digest.Digest
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I switched to digest.Digest in a few places because using strings were leading to annoying conversions. They're just strings with some helper methods.

return &inMemCache{cache: map[string]Result{}}
// RefIDStore uses a BoltDB database to store links from computed cache keys to
// worker ref IDs.
type RefIDStore struct {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I split the ref ID storage out from the result loader so that the former can be used in the solver & worker/simple.go.

@mikejholly mikejholly force-pushed the mh/next-inline-cache-redux branch 4 times, most recently from 750aa06 to bab4556 Compare May 16, 2024 20:21
cache/manager.go Outdated Show resolved Hide resolved
}

layerDone := progress.OneOff(ctx, fmt.Sprintf("inferred cache manifest type: %s", manifestType))
layerDone(nil)
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm guessing this is intentional since I see it done in cache/remotecache/azblob/importer.go, but as someone who's new to the OneOff, this seems confusing. but since it's a pattern that's already used in buildkit maybe it's fine.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Much of this code was taken from the preexisting inline cache code: https://github.com/earthly/buildkit/blob/earthly-main/cache/remotecache/import.go#L58

cmd/buildkitd/main.go Outdated Show resolved Hide resolved
cmd/buildkitd/main.go Outdated Show resolved Hide resolved
solver/llbsolver/bridge.go Outdated Show resolved Hide resolved
if err != nil {
return nil, err
bklog.G(ctx).Warnf("failed to import inline cache: %v", err)
Copy link
Contributor

Choose a reason for hiding this comment

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

did you intentionally mean to drop the return here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, it's probably not necessary to fail the build on an error. But now that you mention it, users may want to know. What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated to return the error and fail the build. It's likely useful to know when a network error has occurred.

}
}

// MH: Old-school remote & inline cache imports disabled.
Copy link
Contributor

Choose a reason for hiding this comment

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

should we just delete this instead?

solver/llbsolver/inline.go Outdated Show resolved Hide resolved
solver/llbsolver/inline.go Outdated Show resolved Hide resolved
solver/llbsolver/solver.go Outdated Show resolved Hide resolved
Copy link
Contributor

@alexcb alexcb left a comment

Choose a reason for hiding this comment

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

looking good! just a few minor questions.

@mikejholly mikejholly requested a review from alexcb May 16, 2024 22:30
Copy link
Contributor

@alexcb alexcb left a comment

Choose a reason for hiding this comment

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

looks good; but please squash your changes before merging.

Once squashed, you can also do a git merge --ff-only via the cli to get an even cleaner git history.

@mikejholly mikejholly merged commit 4339c3f into earthly-next May 17, 2024
21 of 23 checks passed
@mikejholly mikejholly deleted the mh/next-inline-cache-redux branch May 17, 2024 05:07
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.

2 participants