github.com/kubernetes-incubator/kube-aws@v0.16.4/flatcar/amiregistry/reliable_http.go (about)

     1  package amiregistry
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"net/http"
     7  )
     8  
     9  const MaxRetryCount = 2
    10  
    11  type reliableHttp interface {
    12  	Get(url string) (resp *http.Response, err error)
    13  }
    14  
    15  type reliableHttpImpl struct {
    16  	underlyingGet func(url string) (resp *http.Response, err error)
    17  }
    18  
    19  func newHttp() reliableHttpImpl {
    20  	return reliableHttpImpl{
    21  		underlyingGet: http.Get,
    22  	}
    23  }
    24  
    25  func statusCodeIsRetryable(c int) bool {
    26  	switch c {
    27  	case 504, 520, 522:
    28  		return true
    29  	}
    30  	return false
    31  }
    32  
    33  // Get sends a HTTP GET request to the url.
    34  // If a request had been failed and its status code was one in th "retryable" status codes, the request is retried up to `MaxRetryCount` times.
    35  // The "retryable" status codes are defined in the `statusCodesIsRetryable` func.
    36  func (i reliableHttpImpl) Get(url string) (resp *http.Response, err error) {
    37  	var r *http.Response
    38  	var e error
    39  
    40  	c := 0
    41  	for c <= MaxRetryCount {
    42  		c++
    43  		r, e = i.underlyingGet(url)
    44  
    45  		if r != nil && statusCodeIsRetryable(r.StatusCode) {
    46  			log.Printf("GET %s returned %d. retrying %d/%d", url, r.StatusCode, c, MaxRetryCount)
    47  		} else if e == nil {
    48  			return r, nil
    49  		}
    50  
    51  		if e != nil {
    52  			log.Printf("GET %s failed due to \"%v\". retrying %d/%d", url, e, c, MaxRetryCount)
    53  		}
    54  	}
    55  
    56  	return r, fmt.Errorf("max retry count exceeded: %v", e)
    57  }