remotes/docker/schema1: back off on locked ref
To allow concurrent pull of images of the v1 persuasion, we need to backoff when multiple pullers are trying to operate on the same resource. The back off logic is ported to v1 pull to match the behavior for other images. A little randomness is also added to the backoff to prevent thundering herd and to reduce expected recovery time. Signed-off-by: Stephen J Day <stephen.day@docker.com>
This commit is contained in:
parent
5fb3a0e0cf
commit
8eee47cf82
@ -9,6 +9,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
@ -215,13 +216,26 @@ func (c *Converter) fetchManifest(ctx context.Context, desc ocispec.Descriptor)
|
||||
func (c *Converter) fetchBlob(ctx context.Context, desc ocispec.Descriptor) error {
|
||||
log.G(ctx).Debug("fetch blob")
|
||||
|
||||
ref := remotes.MakeRefKey(ctx, desc)
|
||||
|
||||
calc := newBlobStateCalculator()
|
||||
var (
|
||||
ref = remotes.MakeRefKey(ctx, desc)
|
||||
calc = newBlobStateCalculator()
|
||||
retry = 16
|
||||
)
|
||||
|
||||
tryit:
|
||||
cw, err := c.contentStore.Writer(ctx, ref, desc.Size, desc.Digest)
|
||||
if err != nil {
|
||||
if !errdefs.IsAlreadyExists(err) {
|
||||
if errdefs.IsUnavailable(err) {
|
||||
select {
|
||||
case <-time.After(time.Millisecond * time.Duration(rand.Intn(retry))):
|
||||
if retry < 2048 {
|
||||
retry = retry << 1
|
||||
}
|
||||
goto tryit
|
||||
case <-ctx.Done():
|
||||
return err
|
||||
}
|
||||
} else if !errdefs.IsAlreadyExists(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"github.com/containerd/containerd/content"
|
||||
@ -84,7 +85,7 @@ func fetch(ctx context.Context, ingester content.Ingester, fetcher Fetcher, desc
|
||||
// of writer and abort if not updated recently.
|
||||
|
||||
select {
|
||||
case <-time.After(time.Millisecond * time.Duration(retry)):
|
||||
case <-time.After(time.Millisecond * time.Duration(rand.Intn(retry))):
|
||||
if retry < 2048 {
|
||||
retry = retry << 1
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user