Skip to content

Commit 731a640

Browse files
committed
c8d/list: Generate image summary concurrently
Run `imageSummary` concurrently to avoid being IO blocked on the containerd gRPC. Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
1 parent dade279 commit 731a640

File tree

1 file changed

+41
-24
lines changed

1 file changed

+41
-24
lines changed

daemon/containerd/image_list.go

Lines changed: 41 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ package containerd
33
import (
44
"context"
55
"encoding/json"
6+
"runtime"
67
"sort"
78
"strings"
9+
"sync"
810
"time"
911

1012
"github.com/containerd/containerd/content"
@@ -27,6 +29,7 @@ import (
2729
"github.com/opencontainers/image-spec/identity"
2830
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
2931
"github.com/pkg/errors"
32+
"golang.org/x/sync/errgroup"
3033
)
3134

3235
// Subset of ocispec.Image that only contains Labels
@@ -91,16 +94,6 @@ func (i *ImageService) Images(ctx context.Context, opts imagetypes.ListOptions)
9194
return usage.Size, nil
9295
}
9396

94-
var (
95-
summaries = make([]*imagetypes.Summary, 0, len(imgs))
96-
root []*[]digest.Digest
97-
layers map[digest.Digest]int
98-
)
99-
if opts.SharedSize {
100-
root = make([]*[]digest.Digest, 0, len(imgs))
101-
layers = make(map[digest.Digest]int)
102-
}
103-
10497
uniqueImages := map[digest.Digest]images.Image{}
10598
tagsByDigest := map[digest.Digest][]string{}
10699
intermediateImages := map[digest.Digest]struct{}{}
@@ -152,24 +145,48 @@ func (i *ImageService) Images(ctx context.Context, opts imagetypes.ListOptions)
152145
tagsByDigest[dgst] = append(tagsByDigest[dgst], reference.FamiliarString(ref))
153146
}
154147

148+
resultsMut := sync.Mutex{}
149+
eg, egCtx := errgroup.WithContext(ctx)
150+
eg.SetLimit(runtime.NumCPU() * 2)
151+
152+
var (
153+
summaries = make([]*imagetypes.Summary, 0, len(imgs))
154+
root []*[]digest.Digest
155+
layers map[digest.Digest]int
156+
)
157+
if opts.SharedSize {
158+
root = make([]*[]digest.Digest, 0, len(imgs))
159+
layers = make(map[digest.Digest]int)
160+
}
161+
155162
for _, img := range uniqueImages {
156-
image, allChainsIDs, err := i.imageSummary(ctx, img, platformMatcher, opts, tagsByDigest)
157-
if err != nil {
158-
return nil, err
159-
}
160-
// No error, but image should be skipped.
161-
if image == nil {
162-
continue
163-
}
163+
img := img
164+
eg.Go(func() error {
165+
image, allChainsIDs, err := i.imageSummary(egCtx, img, platformMatcher, opts, tagsByDigest)
166+
if err != nil {
167+
return err
168+
}
169+
// No error, but image should be skipped.
170+
if image == nil {
171+
return nil
172+
}
164173

165-
summaries = append(summaries, image)
174+
resultsMut.Lock()
175+
summaries = append(summaries, image)
166176

167-
if opts.SharedSize {
168-
root = append(root, &allChainsIDs)
169-
for _, id := range allChainsIDs {
170-
layers[id] = layers[id] + 1
177+
if opts.SharedSize {
178+
root = append(root, &allChainsIDs)
179+
for _, id := range allChainsIDs {
180+
layers[id] = layers[id] + 1
181+
}
171182
}
172-
}
183+
resultsMut.Unlock()
184+
return nil
185+
})
186+
}
187+
188+
if err := eg.Wait(); err != nil {
189+
return nil, err
173190
}
174191

175192
if opts.SharedSize {

0 commit comments

Comments
 (0)