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

Multiple cache exports #3024

Merged
merged 1 commit into from Nov 3, 2022

Conversation

a-palchikov
Copy link
Contributor

Fixes #2818.

@a-palchikov a-palchikov force-pushed the dima/2818/multiple-cache-exports branch from ce0b54d to 8115476 Compare August 15, 2022 12:38
@a-palchikov
Copy link
Contributor Author

There seems to be a regression in Go 1.18.5 visible in flightcontrol package tests - they seem to be up to 6 times slower:
median for last 4 PRs prior to Go version bump was 72.97s, after Go was updated it jumped (see this PR):

ok  	github.com/moby/buildkit/util/flightcontrol	420.389s	coverage: 65.8% of statements

And now it's not fitting the allotted 10min.

@crazy-max
Copy link
Member

There seems to be a regression in Go 1.18.5

Seems to be the same behavior in #3022

@crazy-max crazy-max mentioned this pull request Aug 16, 2022
@remidebette
Copy link

There seems to be a regression in Go 1.18.5

Seems to be the same behavior in #3022

So was the unit test issue solved there?

@a-palchikov
Copy link
Contributor Author

So was the unit test issue solved there?

Yes, I believe so - by bumping the test timeout to 30m here.
I'll fix the conflicts and update shortly.

@a-palchikov a-palchikov force-pushed the dima/2818/multiple-cache-exports branch from 8115476 to 864825f Compare August 30, 2022 14:43
if err := inBuilderContext(ctx, j, "exporting cache", j.SessionID+"-cache", func(ctx context.Context, _ session.Group) error {
prepareDone := progress.OneOff(ctx, "preparing build cache for export")
if err := res.EachRef(func(res solver.ResultProxy) error {
func exportInlineCache(ctx context.Context, e exporter.ExporterInstance, inlineExporter *RemoteCacheExporter, j *solver.Job, res *frontend.Result) (exporterResponse map[string]string, err error) {
Copy link
Member

Choose a reason for hiding this comment

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

This function needs to be split out more - I think we can keep everything except the if inlineExporter != nil in the Solve function, so that this function handles only the inline exporter.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The name might not be the most appropriate - I can rename to exportWithInlineCacheExporter - otherwise I believe it already contains the parts only relevant for the (non-cache) export.

Copy link
Member

Choose a reason for hiding this comment

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

The name is better for sure - I think we should split up the function to only contain the inline cache export though and to do the non-cache export completely separately. There is some dependency there, but we can do the inline cache export by modifying a pointer to an exporter.Source object.

})
var inlineExporter *RemoteCacheExporter
cacheExporters, inlineExporter = splitExporters(cacheExporters)
exporterResponse, err = exportInlineCache(ctx, e, inlineExporter, j, res)
Copy link
Member

@jedevc jedevc Sep 2, 2022

Choose a reason for hiding this comment

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

nit: we could put the check for inlineExporter != nil here in Solve for clarity.

for _, exp := range exporters {
exp := exp
eg.Go(func() error {
return inBuilderContext(ctx, j, "exporting cache", j.SessionID+"-cache", func(ctx context.Context, _ session.Group) error {
Copy link
Member

Choose a reason for hiding this comment

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

We should change "exporting cache" to also include the cache type here (probably shouldn't have any of the other parameters, though we possibly could), and make sure that the ID field (currently j.SessionID + "-cache") is unique for each exporter, or we'll get confusing build log output.

Personally, I'd like to have a .Name method on the remotecache.Exporter interface, similar to how we already have for exporter.ExporterInstance.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agree - I'll add the Name API on the remotecache.Exporter.

eg, ctx := errgroup.WithContext(ctx)
g := session.NewGroup(j.SessionID)
var cacheExporterResponse map[string]string
respCh := make(chan map[string]string, len(exporters))
Copy link
Member

Choose a reason for hiding this comment

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

The convention for these when we have a known number of outputs in parallel is to have an array and to assign to indexes in it: see here.

@a-palchikov a-palchikov force-pushed the dima/2818/multiple-cache-exports branch from 864825f to e436b23 Compare September 5, 2022 21:38
cache/remotecache/azblob/exporter.go Outdated Show resolved Hide resolved
solver/llbsolver/solver.go Outdated Show resolved Hide resolved
return res.Result(ctx)
})
var inlineCacheExporter *RemoteCacheExporter
cacheExporters, inlineCacheExporter = splitCacheExporters(cacheExporters)
Copy link
Member

Choose a reason for hiding this comment

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

Should this split be unconditional? If we reach a scenario where exp.Exporter == nil, we shouldn't attempt to build inline cache using runCacheExporters below, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ugh, right. Good point.

return inBuilderContext(ctx, j, fmt.Sprint("exporting ", exp.Exporter.Name()), id, func(ctx context.Context, _ session.Group) error {
prepareDone := progress.OneOff(ctx, "preparing build cache for export")
if err := res.EachRef(func(res solver.ResultProxy) error {
r, err := res.Result(ctx)
Copy link
Member

Choose a reason for hiding this comment

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

This isn't something changed in this PR, but I think we want to avoid calling Result twice. I think if we can do #3024 (comment) by moving the result conversion steps back into .Solve, we can just pass the cached variable into this function instead of res.

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 see that I can make use of both - cached and the immutable ref result. I'll update.

@a-palchikov a-palchikov force-pushed the dima/2818/multiple-cache-exports branch from e436b23 to 6f3bbad Compare September 13, 2022 15:00
@jedevc
Copy link
Member

jedevc commented Sep 14, 2022

LGTM (assuming CI passes) 🎉

PTAL @tonistiigi

solver/result/result.go Outdated Show resolved Hide resolved
Comment on lines +258 to +271
for i, exp := range exporters {
func(exp RemoteCacheExporter, i int) {
Copy link
Member

@crazy-max crazy-max Oct 3, 2022

Choose a reason for hiding this comment

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

Like cache imports I think we should store a cache export ID so we make sure the ref (registry, local, scope, ...) is dedup:

if prevCm, ok := b.cms[cmID]; !ok {

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'm looking into that.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@crazy-max added deduplication of cache exporters in 702ba77

@a-palchikov a-palchikov force-pushed the dima/2818/multiple-cache-exports branch from 188c5ad to 88eb404 Compare October 5, 2022 19:53
@a-palchikov a-palchikov force-pushed the dima/2818/multiple-cache-exports branch from 88eb404 to 702ba77 Compare October 31, 2022 11:33
@AkihiroSuda
Copy link
Member

Please squash commits

Fix cache import/export tests w.r.t inline caching.

Signed-off-by: a-palchikov <deemok@gmail.com>
@a-palchikov a-palchikov force-pushed the dima/2818/multiple-cache-exports branch from 702ba77 to cf45d28 Compare November 3, 2022 13:13
@a-palchikov
Copy link
Contributor Author

@AkihiroSuda done in cf45d28

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Supporting multiple cache exports
5 participants