Add writer open helper to handle unavailable refs
Updates blob writer helper to use new open and ensure unavailable errors are always handled. Removes duplication of unavailable handling code. Signed-off-by: Derek McGowan <derek@mcgstyle.net>
This commit is contained in:
@@ -25,7 +25,6 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -256,10 +255,9 @@ func (c *Converter) fetchBlob(ctx context.Context, desc ocispec.Descriptor) erro
|
||||
log.G(ctx).Debug("fetch blob")
|
||||
|
||||
var (
|
||||
ref = remotes.MakeRefKey(ctx, desc)
|
||||
calc = newBlobStateCalculator()
|
||||
retry = 16
|
||||
size = desc.Size
|
||||
ref = remotes.MakeRefKey(ctx, desc)
|
||||
calc = newBlobStateCalculator()
|
||||
size = desc.Size
|
||||
)
|
||||
|
||||
// size may be unknown, set to zero for content ingest
|
||||
@@ -267,20 +265,9 @@ func (c *Converter) fetchBlob(ctx context.Context, desc ocispec.Descriptor) erro
|
||||
size = 0
|
||||
}
|
||||
|
||||
tryit:
|
||||
cw, err := c.contentStore.Writer(ctx, ref, size, desc.Digest)
|
||||
cw, err := content.OpenWriter(ctx, c.contentStore, ref, size, desc.Digest)
|
||||
if err != nil {
|
||||
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) {
|
||||
if !errdefs.IsAlreadyExists(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@@ -20,10 +20,8 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"math/rand"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/containerd/containerd/content"
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
@@ -83,38 +81,14 @@ func FetchHandler(ingester content.Ingester, fetcher Fetcher) images.HandlerFunc
|
||||
func fetch(ctx context.Context, ingester content.Ingester, fetcher Fetcher, desc ocispec.Descriptor) error {
|
||||
log.G(ctx).Debug("fetch")
|
||||
|
||||
var (
|
||||
ref = MakeRefKey(ctx, desc)
|
||||
cw content.Writer
|
||||
err error
|
||||
retry = 16
|
||||
)
|
||||
for {
|
||||
cw, err = ingester.Writer(ctx, ref, desc.Size, desc.Digest)
|
||||
if err != nil {
|
||||
if errdefs.IsAlreadyExists(err) {
|
||||
return nil
|
||||
} else if !errdefs.IsUnavailable(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO: On first time locked is encountered, get status
|
||||
// of writer and abort if not updated recently.
|
||||
|
||||
select {
|
||||
case <-time.After(time.Millisecond * time.Duration(rand.Intn(retry))):
|
||||
if retry < 2048 {
|
||||
retry = retry << 1
|
||||
}
|
||||
continue
|
||||
case <-ctx.Done():
|
||||
// Propagate lock error
|
||||
return err
|
||||
}
|
||||
cw, err := content.OpenWriter(ctx, ingester, MakeRefKey(ctx, desc), desc.Size, desc.Digest)
|
||||
if err != nil {
|
||||
if errdefs.IsAlreadyExists(err) {
|
||||
return nil
|
||||
}
|
||||
defer cw.Close()
|
||||
break
|
||||
return err
|
||||
}
|
||||
defer cw.Close()
|
||||
|
||||
ws, err := cw.Status()
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user