Skip to content

Commit

Permalink
added retries for clone (#32)
Browse files Browse the repository at this point in the history
* adde retries for clone

* use backoff
  • Loading branch information
raghavharness authored Apr 8, 2024
1 parent 9408270 commit 14e6ca1
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 15 deletions.
61 changes: 46 additions & 15 deletions cloner/default.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,19 @@ import (
"os"
"regexp"
"strings"
"time"

"github.com/cenkalti/backoff/v4"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/transport/http"
)

const (
maxRetries = 3
backoffInterval = time.Second * 1
)

// New returns a new cloner.
func New(depth int, stdout io.Writer) Cloner {
c := &cloner{
Expand Down Expand Up @@ -68,24 +75,48 @@ func (c *cloner) Clone(ctx context.Context, params Params) error {
}
}
// clone the repository
r, err := git.PlainClone(params.Dir, false, opts)
if (errors.Is(plumbing.ErrReferenceNotFound, err) || matchRefNotFoundErr(err)) &&
!strings.HasPrefix(params.Ref, "refs/") {
// If params.Ref is provided without refs/*, then we are assuming it to either refs/heads/ or refs/tags.
// Try clone again with inverse ref.
if opts.ReferenceName.IsBranch() {
opts.ReferenceName = plumbing.ReferenceName("refs/tags/" + params.Ref)
} else if opts.ReferenceName.IsTag() {
opts.ReferenceName = plumbing.ReferenceName("refs/heads/" + params.Ref)
} else {
return err
}
var (
r *git.Repository
err error
)

retryStrategy := backoff.NewExponentialBackOff()
retryStrategy.InitialInterval = backoffInterval
retryStrategy.MaxInterval = backoffInterval * 5 // Maximum delay
retryStrategy.MaxElapsedTime = backoffInterval * 60 // Maximum time to retry (1min)

b := backoff.WithMaxRetries(retryStrategy, uint64(maxRetries))

err = backoff.Retry(func() error {
r, err = git.PlainClone(params.Dir, false, opts)
if err != nil {
return err
if err == nil {
return nil
}
} else if err != nil {
if (errors.Is(plumbing.ErrReferenceNotFound, err) || matchRefNotFoundErr(err)) &&
!strings.HasPrefix(params.Ref, "refs/") {
originalRefName := opts.ReferenceName
// If params.Ref is provided without refs/*, then we are assuming it to either refs/heads/ or refs/tags.
// Try clone again with inverse ref.
if opts.ReferenceName.IsBranch() {
opts.ReferenceName = plumbing.ReferenceName("refs/tags/" + params.Ref)
} else if opts.ReferenceName.IsTag() {
opts.ReferenceName = plumbing.ReferenceName("refs/heads/" + params.Ref)
} else {
return err // Return err if the reference name is invalid
}

r, err = git.PlainClone(params.Dir, false, opts)
if err == nil {
return nil
}
// Change reference name back to original
opts.ReferenceName = originalRefName
}
return err
}, b)

// If error not nil, then return it
if err != nil {
return err
}

Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ require (
github.com/acomagu/bufpipe v1.0.4 // indirect
github.com/adrg/xdg v0.4.0 // indirect
github.com/andreaskoch/go-fswatch v1.0.0 // indirect
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
github.com/cloudflare/circl v1.3.2 // indirect
github.com/containerd/containerd v1.7.0 // indirect
github.com/creack/pty v1.1.18 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkY
github.com/buildkite/yaml v2.1.0+incompatible h1:xirI+ql5GzfikVNDmt+yeiXpf/v1Gt03qXTtT5WXdr8=
github.com/buildkite/yaml v2.1.0+incompatible/go.mod h1:UoU8vbcwu1+vjZq01+KrpSeLBgQQIjL/H7Y6KwikUrI=
github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I=
github.com/cloudflare/circl v1.3.2 h1:VWp8dY3yH69fdM7lM6A1+NhhVoDu9vqK0jOgmkQHFWk=
github.com/cloudflare/circl v1.3.2/go.mod h1:+CauBF6R70Jqcyl8N2hC8pAXYbWkGIezuSbuGLtRhnw=
Expand Down

0 comments on commit 14e6ca1

Please sign in to comment.