in compute/compute.go [253:297]
func shouldRetryWithWait(tripper http.RoundTripper, err error, multiplier int) bool {
if err == nil {
return false
}
tkValid := true
trans, ok := tripper.(*oauth2.Transport)
if ok {
if tk, err := trans.Source.Token(); err == nil {
tkValid = tk.Valid()
}
}
apiErr, ok := err.(*googleapi.Error)
var retry bool
switch {
case !ok && (strings.Contains(err.Error(), "connection reset by peer") || strings.Contains(err.Error(), "unexpected EOF")):
retry = true
case !ok && (strings.Contains(err.Error(), "server sent GOAWAY") || strings.Contains(err.Error(), "ENHANCE_YOUR_CALM")):
// The wait operation can return GOAWAY/ENHANCE_YOUR_CALM messages, so doubling the wait multiplier as it based on the retry count.
multiplier = multiplier * 2
retry = true
case !ok && tkValid:
// Not a googleapi.Error and the token is still valid.
return false
case apiErr.Code >= 500 && apiErr.Code <= 599:
retry = true
case apiErr.Code >= 429:
// Too many API requests.
retry = true
case apiErr.Code == 403 && strings.Contains(err.Error(), "rateLimitExceeded"):
// Quota errors are reported as 403.
// Generally we don't want to retry on quota errors, but if it's quota on rate (GetSerialPortOutput) - we should.
retry = true
case !tkValid:
// This was probably a failure to get new token from metadata server.
retry = true
}
if !retry {
return false
}
sleep := (time.Duration(rand.Intn(1000))*time.Millisecond + 1*time.Second) * time.Duration(multiplier)
time.Sleep(sleep)
return true
}