Skip to content

Commit 6a84f43

Browse files
committed
build: add cache to resolvedNode
Currently it is possible for boot() to be called multiple times, resulting multiple slow requests to establish connection (eg. multiple container inspects for container driver). Signed-off-by: Tonis Tiigi <[email protected]> (cherry picked from commit 99777ea)
1 parent cf68b5b commit 6a84f43

File tree

1 file changed

+48
-8
lines changed

1 file changed

+48
-8
lines changed

build/driver.go

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package build
33
import (
44
"context"
55
"fmt"
6+
"sync"
67

78
"github.com/containerd/containerd/platforms"
89
"github.com/docker/buildx/builder"
@@ -46,10 +47,22 @@ func (dp resolvedNode) BuildOpts(ctx context.Context) (gateway.BuildOpts, error)
4647

4748
type matchMaker func(specs.Platform) platforms.MatchComparer
4849

50+
type cachedGroup[T any] struct {
51+
g flightcontrol.Group[T]
52+
cache map[int]T
53+
cacheMu sync.Mutex
54+
}
55+
56+
func newCachedGroup[T any]() cachedGroup[T] {
57+
return cachedGroup[T]{
58+
cache: map[int]T{},
59+
}
60+
}
61+
4962
type nodeResolver struct {
50-
nodes []builder.Node
51-
clients flightcontrol.Group[*client.Client]
52-
opt flightcontrol.Group[gateway.BuildOpts]
63+
nodes []builder.Node
64+
clients cachedGroup[*client.Client]
65+
buildOpts cachedGroup[gateway.BuildOpts]
5366
}
5467

5568
func resolveDrivers(ctx context.Context, nodes []builder.Node, opt map[string]Options, pw progress.Writer) (map[string][]*resolvedNode, error) {
@@ -63,7 +76,9 @@ func resolveDrivers(ctx context.Context, nodes []builder.Node, opt map[string]Op
6376

6477
func newDriverResolver(nodes []builder.Node) *nodeResolver {
6578
r := &nodeResolver{
66-
nodes: nodes,
79+
nodes: nodes,
80+
clients: newCachedGroup[*client.Client](),
81+
buildOpts: newCachedGroup[gateway.BuildOpts](),
6782
}
6883
return r
6984
}
@@ -179,6 +194,7 @@ func (r *nodeResolver) resolve(ctx context.Context, ps []specs.Platform, pw prog
179194
resolver: r,
180195
driverIndex: 0,
181196
})
197+
nodeIdxs = append(nodeIdxs, 0)
182198
} else {
183199
for i, idx := range nodeIdxs {
184200
node := &resolvedNode{
@@ -237,11 +253,24 @@ func (r *nodeResolver) boot(ctx context.Context, idxs []int, pw progress.Writer)
237253
for i, idx := range idxs {
238254
i, idx := i, idx
239255
eg.Go(func() error {
240-
c, err := r.clients.Do(ctx, fmt.Sprint(idx), func(ctx context.Context) (*client.Client, error) {
256+
c, err := r.clients.g.Do(ctx, fmt.Sprint(idx), func(ctx context.Context) (*client.Client, error) {
241257
if r.nodes[idx].Driver == nil {
242258
return nil, nil
243259
}
244-
return driver.Boot(ctx, baseCtx, r.nodes[idx].Driver, pw)
260+
r.clients.cacheMu.Lock()
261+
c, ok := r.clients.cache[idx]
262+
r.clients.cacheMu.Unlock()
263+
if ok {
264+
return c, nil
265+
}
266+
c, err := driver.Boot(ctx, baseCtx, r.nodes[idx].Driver, pw)
267+
if err != nil {
268+
return nil, err
269+
}
270+
r.clients.cacheMu.Lock()
271+
r.clients.cache[idx] = c
272+
r.clients.cacheMu.Unlock()
273+
return c, nil
245274
})
246275
if err != nil {
247276
return err
@@ -272,14 +301,25 @@ func (r *nodeResolver) opts(ctx context.Context, idxs []int, pw progress.Writer)
272301
continue
273302
}
274303
eg.Go(func() error {
275-
opt, err := r.opt.Do(ctx, fmt.Sprint(idx), func(ctx context.Context) (gateway.BuildOpts, error) {
276-
opt := gateway.BuildOpts{}
304+
opt, err := r.buildOpts.g.Do(ctx, fmt.Sprint(idx), func(ctx context.Context) (gateway.BuildOpts, error) {
305+
r.buildOpts.cacheMu.Lock()
306+
opt, ok := r.buildOpts.cache[idx]
307+
r.buildOpts.cacheMu.Unlock()
308+
if ok {
309+
return opt, nil
310+
}
277311
_, err := c.Build(ctx, client.SolveOpt{
278312
Internal: true,
279313
}, "buildx", func(ctx context.Context, c gateway.Client) (*gateway.Result, error) {
280314
opt = c.BuildOpts()
281315
return nil, nil
282316
}, nil)
317+
if err != nil {
318+
return gateway.BuildOpts{}, err
319+
}
320+
r.buildOpts.cacheMu.Lock()
321+
r.buildOpts.cache[idx] = opt
322+
r.buildOpts.cacheMu.Unlock()
283323
return opt, err
284324
})
285325
if err != nil {

0 commit comments

Comments
 (0)