-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Multiple cache exports #3024
Conversation
ce0b54d
to
8115476
Compare
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:
And now it's not fitting the allotted 10min. |
Seems to be the same behavior in #3022 |
So was the unit test issue solved there? |
Yes, I believe so - by bumping the test timeout to 30m here. |
8115476
to
864825f
Compare
solver/llbsolver/solver.go
Outdated
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) { |
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.
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.
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.
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.
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.
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.
solver/llbsolver/solver.go
Outdated
}) | ||
var inlineExporter *RemoteCacheExporter | ||
cacheExporters, inlineExporter = splitExporters(cacheExporters) | ||
exporterResponse, err = exportInlineCache(ctx, e, inlineExporter, j, res) |
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.
nit: we could put the check for inlineExporter != nil
here in Solve
for clarity.
solver/llbsolver/solver.go
Outdated
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 { |
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.
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.
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.
Agree - I'll add the Name API on the remotecache.Exporter
.
solver/llbsolver/solver.go
Outdated
eg, ctx := errgroup.WithContext(ctx) | ||
g := session.NewGroup(j.SessionID) | ||
var cacheExporterResponse map[string]string | ||
respCh := make(chan map[string]string, len(exporters)) |
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.
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.
864825f
to
e436b23
Compare
solver/llbsolver/solver.go
Outdated
return res.Result(ctx) | ||
}) | ||
var inlineCacheExporter *RemoteCacheExporter | ||
cacheExporters, inlineCacheExporter = splitCacheExporters(cacheExporters) |
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.
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?
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.
Ugh, right. Good point.
solver/llbsolver/solver.go
Outdated
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) |
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.
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
.
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.
I see that I can make use of both - cached
and the immutable ref result. I'll update.
e436b23
to
6f3bbad
Compare
LGTM (assuming CI passes) 🎉 PTAL @tonistiigi |
6f3bbad
to
5f4124f
Compare
5f4124f
to
188c5ad
Compare
for i, exp := range exporters { | ||
func(exp RemoteCacheExporter, i int) { |
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.
Like cache imports I think we should store a cache export ID so we make sure the ref (registry, local, scope, ...) is dedup:
buildkit/solver/llbsolver/bridge.go
Line 83 in f2c41e1
if prevCm, ok := b.cms[cmID]; !ok { |
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.
I'm looking into that.
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.
@crazy-max added deduplication of cache exporters in 702ba77
188c5ad
to
88eb404
Compare
88eb404
to
702ba77
Compare
Please squash commits |
Fix cache import/export tests w.r.t inline caching. Signed-off-by: a-palchikov <[email protected]>
702ba77
to
cf45d28
Compare
@AkihiroSuda done in cf45d28 |
Fixes #2818.