github.com/secure-build/gitlab-runner@v12.5.0+incompatible/commands/helpers/retry_helper.go (about) 1 package helpers 2 3 import ( 4 "fmt" 5 "net/http" 6 "time" 7 8 "github.com/sirupsen/logrus" 9 ) 10 11 type retryHelper struct { 12 Retry int `long:"retry" description:"How many times to retry upload"` 13 RetryTime time.Duration `long:"retry-time" description:"How long to wait between retries"` 14 } 15 16 // retryableErr indicates that an error can be retried. To specify that an error 17 // can be retried simply wrap the original error. For example: 18 // 19 // retryableErr{err: errors.New("some error")} 20 type retryableErr struct { 21 err error 22 } 23 24 func (e retryableErr) Error() string { 25 return e.err.Error() 26 } 27 28 func (r *retryHelper) doRetry(handler func() error) error { 29 err := handler() 30 31 for i := 0; i < r.Retry; i++ { 32 if _, ok := err.(retryableErr); !ok { 33 return err 34 } 35 36 time.Sleep(r.RetryTime) 37 logrus.WithError(err).Warningln("Retrying...") 38 39 err = handler() 40 } 41 42 return err 43 } 44 45 // retryOnServerError will take the response and check if the the error should 46 // be of type retryableErr or not. When the status code is of 5xx it will be a 47 // retryableErr. 48 func retryOnServerError(resp *http.Response) error { 49 if resp.StatusCode/100 == 2 { 50 return nil 51 } 52 53 resp.Body.Close() 54 55 err := fmt.Errorf("received: %s", resp.Status) 56 57 if resp.StatusCode/100 == 5 { 58 err = retryableErr{err: err} 59 } 60 61 return err 62 }