@@ -16,13 +16,13 @@ import (
1616 "github.com/docker/docker/distribution/xfer"
1717 "github.com/docker/docker/image"
1818 "github.com/docker/docker/layer"
19- "github.com/docker/docker/pkg/compute"
2019 dockerreference "github.com/docker/docker/reference"
2120 "github.com/docker/docker/registry"
2221 "github.com/docker/libtrust"
2322 digest "github.com/opencontainers/go-digest"
2423 "github.com/pkg/errors"
2524 "github.com/sirupsen/logrus"
25+ "golang.org/x/sync/singleflight"
2626)
2727
2828type containerStore interface {
@@ -53,7 +53,7 @@ type ImageServiceConfig struct {
5353}
5454
5555// NewImageService returns a new ImageService from a configuration
56- func NewImageService (config ImageServiceConfig ) ( i * ImageService ) {
56+ func NewImageService (config ImageServiceConfig ) * ImageService {
5757 logrus .Debugf ("Max Concurrent Downloads: %d" , config .MaxConcurrentDownloads )
5858 logrus .Debugf ("Max Concurrent Uploads: %d" , config .MaxConcurrentUploads )
5959 logrus .Debugf ("Max Download Attempts: %d" , config .MaxDownloadAttempts )
@@ -71,12 +71,6 @@ func NewImageService(config ImageServiceConfig) (i *ImageService) {
7171 leases : config .Leases ,
7272 content : config .ContentStore ,
7373 contentNamespace : config .ContentNamespace ,
74- imageDiskUsageSingleton : compute .NewSingleton (func (ctx context.Context ) (interface {}, error ) {
75- return i .imageDiskUsage (ctx )
76- }),
77- layerDiskUsageSingleton : compute .NewSingleton (func (ctx context.Context ) (interface {}, error ) {
78- return i .layerDiskUsage (ctx )
79- }),
8074 }
8175}
8276
@@ -96,8 +90,7 @@ type ImageService struct {
9690 leases leases.Manager
9791 content content.Store
9892 contentNamespace string
99- imageDiskUsageSingleton * compute.Singleton
100- layerDiskUsageSingleton * compute.Singleton
93+ singleflightGroup singleflight.Group
10194}
10295
10396// DistributionServices provides daemon image storage services
@@ -229,11 +222,19 @@ func (i *ImageService) layerDiskUsage(ctx context.Context) (int64, error) {
229222// LayerDiskUsage returns the number of bytes used by layer stores
230223// called from disk_usage.go
231224func (i * ImageService ) LayerDiskUsage (ctx context.Context ) (int64 , error ) {
232- v , err := i .layerDiskUsageSingleton .Do (ctx )
233- if err != nil {
234- return 0 , err
225+ ch := i .singleflightGroup .DoChan ("layerDiskUsage" , func () (interface {}, error ) {
226+ return i .layerDiskUsage (ctx )
227+ })
228+ select {
229+ case <- ctx .Done ():
230+ go func () { <- ch }()
231+ return 0 , ctx .Err ()
232+ case res := <- ch :
233+ if res .Err != nil {
234+ return 0 , res .Err
235+ }
236+ return res .Val .(int64 ), nil
235237 }
236- return v .(int64 ), nil
237238}
238239
239240func (i * ImageService ) getLayerRefs () map [layer.ChainID ]int {
@@ -272,11 +273,19 @@ func (i *ImageService) imageDiskUsage(ctx context.Context) ([]*types.ImageSummar
272273
273274// ImageDiskUsage returns information about image data disk usage.
274275func (i * ImageService ) ImageDiskUsage (ctx context.Context ) ([]* types.ImageSummary , error ) {
275- v , err := i .imageDiskUsageSingleton .Do (ctx )
276- if err != nil {
277- return nil , err
276+ ch := i .singleflightGroup .DoChan ("imageDiskUsage" , func () (interface {}, error ) {
277+ return i .imageDiskUsage (ctx )
278+ })
279+ select {
280+ case <- ctx .Done ():
281+ go func () { <- ch }()
282+ return nil , ctx .Err ()
283+ case res := <- ch :
284+ if res .Err != nil {
285+ return nil , res .Err
286+ }
287+ return res .Val .([]* types.ImageSummary ), nil
278288 }
279- return v .([]* types.ImageSummary ), nil
280289}
281290
282291// UpdateConfig values
0 commit comments