Skip to content

Commit 14e6ca1

Browse files
added retries for clone (#32)
* adde retries for clone * use backoff
1 parent 9408270 commit 14e6ca1

File tree

3 files changed

+49
-15
lines changed

3 files changed

+49
-15
lines changed

cloner/default.go

Lines changed: 46 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,19 @@ import (
1111
"os"
1212
"regexp"
1313
"strings"
14+
"time"
1415

16+
"github.com/cenkalti/backoff/v4"
1517
"github.com/go-git/go-git/v5"
1618
"github.com/go-git/go-git/v5/plumbing"
1719
"github.com/go-git/go-git/v5/plumbing/transport/http"
1820
)
1921

22+
const (
23+
maxRetries = 3
24+
backoffInterval = time.Second * 1
25+
)
26+
2027
// New returns a new cloner.
2128
func New(depth int, stdout io.Writer) Cloner {
2229
c := &cloner{
@@ -68,24 +75,48 @@ func (c *cloner) Clone(ctx context.Context, params Params) error {
6875
}
6976
}
7077
// clone the repository
71-
r, err := git.PlainClone(params.Dir, false, opts)
72-
if (errors.Is(plumbing.ErrReferenceNotFound, err) || matchRefNotFoundErr(err)) &&
73-
!strings.HasPrefix(params.Ref, "refs/") {
74-
// If params.Ref is provided without refs/*, then we are assuming it to either refs/heads/ or refs/tags.
75-
// Try clone again with inverse ref.
76-
if opts.ReferenceName.IsBranch() {
77-
opts.ReferenceName = plumbing.ReferenceName("refs/tags/" + params.Ref)
78-
} else if opts.ReferenceName.IsTag() {
79-
opts.ReferenceName = plumbing.ReferenceName("refs/heads/" + params.Ref)
80-
} else {
81-
return err
82-
}
78+
var (
79+
r *git.Repository
80+
err error
81+
)
82+
83+
retryStrategy := backoff.NewExponentialBackOff()
84+
retryStrategy.InitialInterval = backoffInterval
85+
retryStrategy.MaxInterval = backoffInterval * 5 // Maximum delay
86+
retryStrategy.MaxElapsedTime = backoffInterval * 60 // Maximum time to retry (1min)
87+
88+
b := backoff.WithMaxRetries(retryStrategy, uint64(maxRetries))
8389

90+
err = backoff.Retry(func() error {
8491
r, err = git.PlainClone(params.Dir, false, opts)
85-
if err != nil {
86-
return err
92+
if err == nil {
93+
return nil
8794
}
88-
} else if err != nil {
95+
if (errors.Is(plumbing.ErrReferenceNotFound, err) || matchRefNotFoundErr(err)) &&
96+
!strings.HasPrefix(params.Ref, "refs/") {
97+
originalRefName := opts.ReferenceName
98+
// If params.Ref is provided without refs/*, then we are assuming it to either refs/heads/ or refs/tags.
99+
// Try clone again with inverse ref.
100+
if opts.ReferenceName.IsBranch() {
101+
opts.ReferenceName = plumbing.ReferenceName("refs/tags/" + params.Ref)
102+
} else if opts.ReferenceName.IsTag() {
103+
opts.ReferenceName = plumbing.ReferenceName("refs/heads/" + params.Ref)
104+
} else {
105+
return err // Return err if the reference name is invalid
106+
}
107+
108+
r, err = git.PlainClone(params.Dir, false, opts)
109+
if err == nil {
110+
return nil
111+
}
112+
// Change reference name back to original
113+
opts.ReferenceName = originalRefName
114+
}
115+
return err
116+
}, b)
117+
118+
// If error not nil, then return it
119+
if err != nil {
89120
return err
90121
}
91122

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ require (
2929
github.com/acomagu/bufpipe v1.0.4 // indirect
3030
github.com/adrg/xdg v0.4.0 // indirect
3131
github.com/andreaskoch/go-fswatch v1.0.0 // indirect
32+
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
3233
github.com/cloudflare/circl v1.3.2 // indirect
3334
github.com/containerd/containerd v1.7.0 // indirect
3435
github.com/creack/pty v1.1.18 // indirect

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkY
2626
github.com/buildkite/yaml v2.1.0+incompatible h1:xirI+ql5GzfikVNDmt+yeiXpf/v1Gt03qXTtT5WXdr8=
2727
github.com/buildkite/yaml v2.1.0+incompatible/go.mod h1:UoU8vbcwu1+vjZq01+KrpSeLBgQQIjL/H7Y6KwikUrI=
2828
github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
29+
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
30+
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
2931
github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I=
3032
github.com/cloudflare/circl v1.3.2 h1:VWp8dY3yH69fdM7lM6A1+NhhVoDu9vqK0jOgmkQHFWk=
3133
github.com/cloudflare/circl v1.3.2/go.mod h1:+CauBF6R70Jqcyl8N2hC8pAXYbWkGIezuSbuGLtRhnw=

0 commit comments

Comments
 (0)