add retry logic for bundle fetcher

This commit is contained in:
vyzo 2022-05-12 10:00:20 +03:00
parent 26d07fd987
commit 7b6f109401

View File

@ -6,10 +6,12 @@ import (
"encoding/hex" "encoding/hex"
"fmt" "fmt"
"io" "io"
"net"
"net/http" "net/http"
"os" "os"
"path/filepath" "path/filepath"
"strings" "strings"
"time"
"golang.org/x/xerrors" "golang.org/x/xerrors"
@ -69,14 +71,22 @@ func (b *BundleFetcher) Fetch(version int, release, netw string) (path string, e
func (b *BundleFetcher) fetchURL(url, path string) error { func (b *BundleFetcher) fetchURL(url, path string) error {
log.Infof("fetching URL: %s", url) log.Infof("fetching URL: %s", url)
for i := 0; i < 3; i++ {
resp, err := http.Get(url) //nolint resp, err := http.Get(url) //nolint
if err != nil { if err != nil {
if isTemporary(err) {
log.Warnf("temporary error fetching %s: %s; retrying in 1s", url, err)
time.Sleep(time.Second)
continue
}
return xerrors.Errorf("error fetching %s: %w", url, err) return xerrors.Errorf("error fetching %s: %w", url, err)
} }
defer resp.Body.Close() //nolint defer resp.Body.Close() //nolint
if resp.StatusCode != http.StatusOK { if resp.StatusCode != http.StatusOK {
return xerrors.Errorf("error fetching %s: http response status is %d", url, resp.StatusCode) log.Warnf("unexpected response fetching %s: %s (%d); retrying in 1s", url, resp.Status, resp.StatusCode)
time.Sleep(time.Second)
continue
} }
f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644) f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
@ -90,6 +100,9 @@ func (b *BundleFetcher) fetchURL(url, path string) error {
} }
return nil return nil
}
return xerrors.Errorf("all attempts to fetch %s failed", url)
} }
func (b *BundleFetcher) fetch(release, bundleBasePath, bundleFile, bundleHash string) error { func (b *BundleFetcher) fetch(release, bundleBasePath, bundleFile, bundleHash string) error {
@ -149,3 +162,11 @@ func (b *BundleFetcher) check(bundleBasePath, bundleFile, bundleHash string) err
return nil return nil
} }
func isTemporary(err error) bool {
if ne, ok := err.(net.Error); ok {
return ne.Temporary()
}
return false
}