github.com/loggregator/cli@v6.33.1-0.20180224010324-82334f081791+incompatible/api/cloudcontroller/wrapper/retry_request.go (about) 1 package wrapper 2 3 import ( 4 "net/http" 5 6 "code.cloudfoundry.org/cli/api/cloudcontroller" 7 "code.cloudfoundry.org/cli/api/cloudcontroller/ccerror" 8 ) 9 10 // RetryRequest is a wrapper that retries failed requests if they contain a 5XX 11 // status code. 12 type RetryRequest struct { 13 maxRetries int 14 connection cloudcontroller.Connection 15 } 16 17 // NewRetryRequest returns a pointer to a RetryRequest wrapper. 18 func NewRetryRequest(maxRetries int) *RetryRequest { 19 return &RetryRequest{ 20 maxRetries: maxRetries, 21 } 22 } 23 24 // Wrap sets the connection in the RetryRequest and returns itself. 25 func (retry *RetryRequest) Wrap(innerconnection cloudcontroller.Connection) cloudcontroller.Connection { 26 retry.connection = innerconnection 27 return retry 28 } 29 30 // Make retries the request if it comes back with a 5XX status code. 31 func (retry *RetryRequest) Make(request *cloudcontroller.Request, passedResponse *cloudcontroller.Response) error { 32 var err error 33 34 for i := 0; i < retry.maxRetries+1; i++ { 35 err = retry.connection.Make(request, passedResponse) 36 if err == nil { 37 return nil 38 } 39 40 if retry.skipRetry(request.Method, passedResponse.HTTPResponse) { 41 break 42 } 43 44 // Reset the request body prior to the next retry 45 resetErr := request.ResetBody() 46 if resetErr != nil { 47 if _, ok := resetErr.(ccerror.PipeSeekError); ok { 48 return ccerror.PipeSeekError{Err: err} 49 } 50 return resetErr 51 } 52 } 53 return err 54 } 55 56 // skipRetry will skip retry if the request method is POST or contains a status 57 // code that is not one of following http status codes: 500, 502, 503, 504. 58 func (*RetryRequest) skipRetry(httpMethod string, response *http.Response) bool { 59 return httpMethod == http.MethodPost || 60 response != nil && 61 response.StatusCode != http.StatusInternalServerError && 62 response.StatusCode != http.StatusBadGateway && 63 response.StatusCode != http.StatusServiceUnavailable && 64 response.StatusCode != http.StatusGatewayTimeout 65 }