From 00cca12e77708639d5609e06733da9b9a2c13119 Mon Sep 17 00:00:00 2001 From: Aaron Lehmann Date: Fri, 13 Nov 2015 16:59:01 -0800 Subject: [PATCH] Improved push and pull with upload manager and download manager This commit adds a transfer manager which deduplicates and schedules transfers, and also an upload manager and download manager that build on top of the transfer manager to provide high-level interfaces for uploads and downloads. The push and pull code is modified to use these building blocks. Some benefits of the changes: - Simplification of push/pull code - Pushes can upload layers concurrently - Failed downloads and uploads are retried after backoff delays - Cancellation is supported, but individual transfers will only be cancelled if all pushes or pulls using them are cancelled. - The distribution code is decoupled from Docker Engine packages and API conventions (i.e. streamformatter), which will make it easier to split out. This commit also includes unit tests for the new distribution/xfer package. The tests cover 87.8% of the statements in the package. Signed-off-by: Aaron Lehmann --- docs/session.go | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/docs/session.go b/docs/session.go index 645e5d44..5017aeac 100644 --- a/docs/session.go +++ b/docs/session.go @@ -17,7 +17,6 @@ import ( "net/url" "strconv" "strings" - "time" "github.com/Sirupsen/logrus" "github.com/docker/distribution/reference" @@ -270,7 +269,6 @@ func (r *Session) GetRemoteImageJSON(imgID, registry string) ([]byte, int64, err // GetRemoteImageLayer retrieves an image layer from the registry func (r *Session) GetRemoteImageLayer(imgID, registry string, imgSize int64) (io.ReadCloser, error) { var ( - retries = 5 statusCode = 0 res *http.Response err error @@ -281,14 +279,9 @@ func (r *Session) GetRemoteImageLayer(imgID, registry string, imgSize int64) (io if err != nil { return nil, fmt.Errorf("Error while getting from the server: %v", err) } - // TODO(tiborvass): why are we doing retries at this level? - // These retries should be generic to both v1 and v2 - for i := 1; i <= retries; i++ { - statusCode = 0 - res, err = r.client.Do(req) - if err == nil { - break - } + statusCode = 0 + res, err = r.client.Do(req) + if err != nil { logrus.Debugf("Error contacting registry %s: %v", registry, err) if res != nil { if res.Body != nil { @@ -296,11 +289,8 @@ func (r *Session) GetRemoteImageLayer(imgID, registry string, imgSize int64) (io } statusCode = res.StatusCode } - if i == retries { - return nil, fmt.Errorf("Server error: Status %d while fetching image layer (%s)", - statusCode, imgID) - } - time.Sleep(time.Duration(i) * 5 * time.Second) + return nil, fmt.Errorf("Server error: Status %d while fetching image layer (%s)", + statusCode, imgID) } if res.StatusCode != 200 {